diff options
author | asmyasnikov <asmyasnikov@ydb.tech> | 2022-09-06 16:48:30 +0300 |
---|---|---|
committer | asmyasnikov <asmyasnikov@ydb.tech> | 2022-09-06 16:48:30 +0300 |
commit | bc5eb0177b4e454aec6b55e2fe68cf02de57cdbe (patch) | |
tree | 50746fd0fbb216d8e5a4b3fa34cdf33ac17e92bf | |
parent | 6454e0216ce8a315903c3231411ef80416de1e24 (diff) | |
download | ydb-bc5eb0177b4e454aec6b55e2fe68cf02de57cdbe.tar.gz |
add recipes for driver init and go's database/sql
add recipes for driver init and go's database/sql
88 files changed, 2279 insertions, 1298 deletions
diff --git a/ydb/docs/ru/core/reference/ydb-sdk/_includes/auth.md b/ydb/docs/ru/core/reference/ydb-sdk/_includes/auth.md index 366e803395d..56e559925c6 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/_includes/auth.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/_includes/auth.md @@ -13,7 +13,7 @@ ## Методы создания объекта генерации токенов {#auth-provider} -На приведенные ниже методы можно кликнуть, чтобы перейти к исходному коду релевантного примера в репозитории. Также можно ознакомиться с [рецептами кода Аутентификации](../recipes/auth/index.md). +На приведенные ниже методы можно кликнуть, чтобы перейти к исходному коду релевантного примера в репозитории. Также можно ознакомиться с [рецептами кода Аутентификации](../recipes/auth.md). {% list tabs %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/_includes/install.md b/ydb/docs/ru/core/reference/ydb-sdk/_includes/install.md index cec72f4e7b1..e6b946b4e96 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/_includes/install.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/_includes/install.md @@ -20,7 +20,7 @@ {% include [install/cmd_go.md](install/cmd_go.md) %} - Для успешной установки в вашем окружении должен быть установлен [Go](https://go.dev/doc/install) версии не ниже 1.13. + Для успешной установки в вашем окружении должен быть установлен [Go](https://go.dev/doc/install) версии не ниже 1.16. - С# (.NET) diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/archive/example-go-v2.md b/ydb/docs/ru/core/reference/ydb-sdk/example/archive/example-go-v2.md index a9c3b30add2..7a193b8031e 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/example/archive/example-go-v2.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/archive/example-go-v2.md @@ -136,28 +136,28 @@ if err != nil { Результат выполнения запроса: ```go - var ( - id *uint64 - title *string - date *[]byte - ) + var ( + id *uint64 + title *string + date *[]byte + ) log.Println("> select_simple_transaction:") - for res.NextResultSet(ctx, "series_id", "title", "release_date") { - for res.NextRow() { - err = res.Scan(&id, &title, &date) - if err != nil { - return err - } + for res.NextResultSet(ctx, "series_id", "title", "release_date") { + for res.NextRow() { + err = res.Scan(&id, &title, &date) + if err != nil { + return err + } log.Printf( "# SeriesID: %d , Title: %s, Date: %s\n", *id, *title, *date, ) - } - } - if err = res.Err(); err != nil { - return err - } - return nil + } + } + if err = res.Err(); err != nil { + return err + } + return nil } ``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/go/index.md b/ydb/docs/ru/core/reference/ydb-sdk/example/go/index.md index 84553b58f76..2f02f153db5 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/example/go/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/go/index.md @@ -24,8 +24,9 @@ git clone https://github.com/ydb-platform/ydb-go-examples/ ```go import ( - // общие импорты + // общие импорты из стандартной библиотеки "context" + "log" "path" // импорты пакетов ydb-go-sdk @@ -34,6 +35,7 @@ import ( "github.com/ydb-platform/ydb-go-sdk/v3/table/options" // для работы с table-сервисом "github.com/ydb-platform/ydb-go-sdk/v3/table/result" // для работы с table-сервисом "github.com/ydb-platform/ydb-go-sdk/v3/table/result/named" // для работы с table-сервисом + "github.com/ydb-platform/ydb-go-sdk/v3/table/types" // для работы с типами YDB и значениями "github.com/ydb-platform/ydb-go-sdk-auth-environ" // для аутентификации с использованием перменных окружения "github.com/ydb-platform/ydb-go-yc" // для работы с YDB в Яндекс Облаке ) @@ -48,8 +50,7 @@ dsn := "grpcs://ydb.serverless.yandexcloud.net:2135/?database=/ru-central1/b1g8s // IAM-токен token := "t1.9euelZrOy8aVmZKJm5HGjceMkMeVj-..." // создаем объект подключения db, является входной точкой для сервисов YDB -db, err := ydb.Open(ctx, - dsn, +db, err := ydb.Open(ctx, dsn, // yc.WithInternalCA(), // используем сертификаты Яндекс Облака ydb.WithAccessTokenCredentials(token), // аутентификация с помощью токена // ydb.WithAnonimousCredentials(), // анонимная аутентификация (например, в docker ydb) @@ -61,9 +62,7 @@ if err != nil { // обработка ошибки подключения } // закрытие драйвера по окончании работы программы обязательно -defer func() { - _ = db.Close(ctx) -} +defer db.Close(ctx) ``` Объект `db` является входной точкой для работы с сервисами `YDB`. @@ -77,8 +76,7 @@ defer func() { Для создания таблиц используется метод `table.Session.CreateTable()`: ```go -err = db.Table().Do( - ctx, +err = db.Table().Do(ctx, func(ctx context.Context, s table.Session) (err error) { return s.CreateTable(ctx, path.Join(db.Name(), "series"), options.WithColumn("series_id", types.TypeUint64), // not null column @@ -98,8 +96,7 @@ if err != nil { С помощью метода `table.Session.DescribeTable()` можно вывести информацию о структуре таблицы и убедиться, что она успешно создалась: ```go -err = db.Table().Do( - ctx, +err = db.Table().Do(ctx, func(ctx context.Context, s table.Session) (err error) { desc, err := s.DescribeTable(ctx, path.Join(db.Name(), "series")) if err != nil { @@ -110,7 +107,7 @@ err = db.Table().Do( log.Printf(" > column, name: %s, %s\n", c.Type, c.Name) } return - } + }, ) if err != nil { // обработка ситуации, когда не удалось выполнить запрос @@ -131,8 +128,7 @@ var ( table.CommitTx(), ) ) -err := db.Table().Do( - ctx, +err := db.Table().Do(ctx, func(ctx context.Context, s table.Session) (err error) { var ( res result.Result @@ -161,9 +157,7 @@ err := db.Table().Do( if err != nil { return err } - defer func() { - _ = res.Close() // закрытие result'а обязательно - }() + defer res.Close() // закрытие result'а обязательно log.Printf("> select_simple_transaction:\n") for res.NextResultSet(ctx) { for res.NextRow() { @@ -205,8 +199,7 @@ var ( ` res result.StreamResult ) -err = c.Do( - ctx, +err = c.Do(ctx, func(ctx context.Context, s table.Session) (err error) { res, err = s.StreamExecuteScanQuery(ctx, query, table.NewQueryParameters( @@ -221,9 +214,7 @@ err = c.Do( if err != nil { return err } - defer func() { - _ = res.Close() // закрытие result'а обязательно - }() + defer res.Close() // закрытие result'а обязательно var ( seriesID uint64 seasonID uint64 diff --git a/ydb/docs/ru/core/reference/ydb-sdk/example/java/index.md b/ydb/docs/ru/core/reference/ydb-sdk/example/java/index.md index 3a46fa0a687..d30981eac61 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/example/java/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/example/java/index.md @@ -27,8 +27,8 @@ git clone https://github.com/yandex-cloud/ydb-java-sdk Основные параметры инициализации драйвера * Cтрока подключения с информацией об [эндпоинте](../../../../concepts/connect.md#endpoint) и [базе данных](../../../../concepts/connect.md#database). Единственный обязательный параметр. -* Провайдер [аутенфикации](../../auth.md##auth-provider). В случае отсутствия прямого указания будет использоваться [анонимное подключение](../../../../concepts/auth.md). -* Настройки [пула сессий](../../recipes/session_pool_limit/index.md) +* Провайдер [аутенфикации](../../recipes/auth.md##auth-provider). В случае отсутствия прямого указания будет использоваться [анонимное подключение](../../../../concepts/auth.md). +* Настройки [пула сессий](../../recipes/session-pool-limit.md) Фрагмент кода приложения для инициализации драйвера: diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/go_appendix.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/_includes/debug-logs-go-appendix.md index e69de29bb2d..e69de29bb2d 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/go_appendix.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/_includes/debug-logs-go-appendix.md diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/_includes/debug-logs-go-sql-appendix.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/_includes/debug-logs-go-sql-appendix.md new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/_includes/debug-logs-go-sql-appendix.md diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-access-token.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-access-token.md new file mode 100644 index 00000000000..632a8d800ab --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-access-token.md @@ -0,0 +1,124 @@ +# Аутентификация при помощи токена + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода аутентификации при помощи токена в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithAccessTokenCredentials(os.Getenv("YDB_TOKEN")), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + {% cut "Если используется коннектор для создания подключения к {{ ydb-short-name }}" %} + + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithAccessTokenCredentials(os.Getenv("YDB_TOKEN")), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + + {% endcut %} + + {% cut "Если используется строка подключения" %} + + ```go + package main + + import ( + "context" + "database/sql" + "os" + + _ "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + db, err := sql.Open("ydb", "grpcs://localohost:2135/local?token="+os.Getenv("YDB_TOKEN")) + if err != nil { + panic(err) + } + defer db.Close() + ... + } + ``` + + {% endcut %} + + +- Java + + ```java + public void work(String connectionString, String accessToken) { + AuthProvider authProvider = CloudAuthProvider.newAuthProvider( + IamTokenCredentialProvider.builder() + .token(accessToken) + .build() + ); + + GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) + .withAuthProvider(authProvider) + .build(); + + TableClient tableClient = TableClient + .newClient(GrpcTableRpc.ownTransport(transport)) + .build()); + + doWork(tableClient); + + tableClient.close(); + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-anonymous.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-anonymous.md new file mode 100644 index 00000000000..f9521e5fedb --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-anonymous.md @@ -0,0 +1,93 @@ +# Анонимная аутентификация + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода анонимной аутентификации в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + Анонимная аутентификация является аутентификацией по умолчанию. + Явным образом анонимную аутентификацию можно включить так: + ```go + package main + + import ( + "context" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithAnonymousCredentials(), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + Анонимная аутентификация является аутентификацией по умолчанию. + Явным образом анонимную аутентификацию можно включить так: + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithAnonymousCredentials(), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +- Java + + ```java + public void work(String connectionString) { + AuthProvider authProvider = NopAuthProvider.INSTANCE; + + GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) + .withAuthProvider(authProvider) + .build(); + + TableClient tableClient = TableClient + .newClient(GrpcTableRpc.ownTransport(transport)) + .build()); + + doWork(tableClient); + + tableClient.close(); + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-env.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-env.md new file mode 100644 index 00000000000..72ebe9eb69e --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-env.md @@ -0,0 +1,101 @@ +# Аутентификация при помощи переменных окружения + +{% include [work in progress message](_includes/addition.md) %} + +При использовании данного метода режим аутентификации и его параметры будут определены окружением, в котором запускается приложение, в [описанном здесь порядке](../auth.md#env). + +Установив одну из следующих переменных окружения, можно управлять способом аутентификации: + +* `YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS=<path/to/sa_key_file>` — использовать файл сервисного аккаунта в Яндекс Облаке. +* `YDB_ANONYMOUS_CREDENTIALS="1"` — Использовать анонимную аутентификацию. Актуально для тестирования против докер-контейнера с {{ ydb-short-name }}. +* `YDB_METADATA_CREDENTIALS="1"` — использовать сервис метаданных внутри Яндекс Облака (Яндекс функция или виртуальная машина). +* `YDB_ACCESS_TOKEN_CREDENTIALS=<access_token>` — использовать аутентификацию с токеном. + +Ниже приведены примеры кода аутентификации при помощи переменных окружения в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + environ "github.com/ydb-platform/ydb-go-sdk-auth-environ" + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + environ.WithEnvironCredentials(ctx), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + ```go + package main + + import ( + "context" + "database/sql" + "os" + + environ "github.com/ydb-platform/ydb-go-sdk-auth-environ" + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + environ.WithEnvironCredentials(ctx), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +- Java + + ```java + public void work(String connectionString) { + AuthProvider authProvider = CloudAuthHelper.getAuthProviderFromEnviron(); + + GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) + .withAuthProvider(authProvider) + .build(); + + TableClient tableClient = TableClient + .newClient(GrpcTableRpc.ownTransport(transport)) + .build()); + + doWork(tableClient); + + tableClient.close(); + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-metadata.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-metadata.md new file mode 100644 index 00000000000..6f5bd33871d --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-metadata.md @@ -0,0 +1,97 @@ +# Аутентификация при помощи сервиса метаданных + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода аутентификации при помощи переменных окружения в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + yc "github.com/ydb-platform/ydb-go-yc" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + yc.WithMetadataCredentials(ctx), + yc.WithInternalCA(), // append Yandex Cloud certificates + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + yc "github.com/ydb-platform/ydb-go-yc" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + yc.WithMetadataCredentials(ctx), + yc.WithInternalCA(), // append Yandex Cloud certificates + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +- Java + + ```java + public void work(String connectionString) { + AuthProvider authProvider = CloudAuthProvider.newAuthProvider( + ComputeEngineCredentialProvider.builder() + .build() + ); + + GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) + .withAuthProvider(authProvider) + .build(); + + TableClient tableClient = TableClient + .newClient(GrpcTableRpc.ownTransport(transport)) + .build()); + + doWork(tableClient); + + tableClient.close(); + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-service-account.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-service-account.md new file mode 100644 index 00000000000..05ca46ab0ae --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-service-account.md @@ -0,0 +1,102 @@ +# Аутентификация при помощи файла сервисного аккаунта + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода аутентификации при помощи файла сервисного аккаунта в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + yc "github.com/ydb-platform/ydb-go-yc" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + yc.WithServiceAccountKeyFileCredentials( + os.Getenv("YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS"), + ), + yc.WithInternalCA(), // append Yandex Cloud certificates + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + yc "github.com/ydb-platform/ydb-go-yc" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + yc.WithServiceAccountKeyFileCredentials( + os.Getenv("YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS"), + ), + yc.WithInternalCA(), // append Yandex Cloud certificates + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +- Java + + ```java + public void work(String connectionString, Path saKeyPath) { + AuthProvider authProvider = CloudAuthProvider.newAuthProvider( + ApiKeyCredentialProvider.builder() + .fromFile(saKeyPath) + .build() + ); + + GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) + .withAuthProvider(authProvider) + .build(); + + TableClient tableClient = TableClient + .newClient(GrpcTableRpc.ownTransport(transport)) + .build()); + + doWork(tableClient); + + tableClient.close(); + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-static.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-static.md new file mode 100644 index 00000000000..3513cdda7d7 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth-static.md @@ -0,0 +1,110 @@ +# Аутентификация при помощи логина и пароля + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода аутентификации при помощи логина и пароля в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- C++ + + ```c++ + auto driverConfig = NYdb::TDriverConfig() + .SetEndpoint(endpoint) + .SetDatabase(database) + .SetCredentialsProviderFactory(NYdb::CreateLoginCredentialsProviderFactory({ + .User = "user", + .Password = "password", + })); + + NYdb::TDriver driver(driverConfig); + ``` + +- Go (native) + + Передать логин и пароль можно в составе строки подключения. Например, так: + ```shell + "grpcs://login:password@localohost:2135/local" + ``` + + Также можно передать логин и пароль явно через опцию `ydb.WithStaticCredentials`: + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithStaticCredentials("user", "password"), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + Передать логин и пароль можно в составе строки подключения. Например, так: + ```go + package main + + import ( + "context" + + _ "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + db, err := sql.Open("ydb", "grpcs://login:password@localohost:2135/local") + if err != nil { + panic(err) + } + defer db.Close() + ... + } + ``` + + Также можно передать логин и пароль явно при инициализации драйвера через коннектор с помощью специальной опции `ydb.WithStaticCredentials`: + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithStaticCredentials("user", "password"), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth.md index ebd3eb83f5a..3c6d09f7c68 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth.md @@ -1,7 +1,15 @@ # Аутентификация -{% include [work in progress message](../../_includes/addition.md) %} +{% include [work in progress message](_includes/addition.md) %} {{ ydb-short-name }} поддерживает несколько способов аутентификации подключения к серверной стороне. Каждый из них, как правило, специфичен для конкретной пары окружений: где находится клиентское приложение (в доверенной зоне {{ ydb-short-name }} или вне ее) и серверная часть {{ ydb-short-name }} (докер-контейнер, {{ yandex-cloud }}, data cloud, установка на отдельном кластере) -В данном разделе содержатся рецепты кода с настройкой аутентификации в разных {{ ydb-short-name }} SDK. Общее описание принципов аутентификации в SDK можно прочитать в статье [Аутентификация в SDK](../../../auth.md). +В данном разделе содержатся рецепты кода с настройкой аутентификации в разных {{ ydb-short-name }} SDK. Общее описание принципов аутентификации в SDK можно прочитать в статье [Аутентификация в SDK](auth.md). + +Содержание: +- [С помощью токена](auth-access-token.md) +- [Анонимная](auth-anonymous.md) +- [Файл сервисного аккаунта](auth-service-account.md) +- [Сервис метаданных](auth-metadata.md) +- [С помощью переменных окружения](auth-env.md) +- [С помощью логина и пароля](auth-static.md) diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token.md deleted file mode 100644 index b371b3079ab..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token.md +++ /dev/null @@ -1,19 +0,0 @@ -# Аутентификация при помощи токена - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода аутентификации при помощи токена в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](access_token/go.md) %} - -- Java - - - {% include [java.md](access_token/java.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token/go.md deleted file mode 100644 index dacd18352a6..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token/go.md +++ /dev/null @@ -1,25 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithAccessTokenCredentials(os.Getenv("YDB_TOKEN")), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token/java.md deleted file mode 100644 index ae48d716db2..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/access_token/java.md +++ /dev/null @@ -1,21 +0,0 @@ -```java -public void work(String connectionString, String accessToken) { - AuthProvider authProvider = CloudAuthProvider.newAuthProvider( - IamTokenCredentialProvider.builder() - .token(accessToken) - .build() - ); - - GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) - .withAuthProvider(authProvider) - .build(); - - TableClient tableClient = TableClient - .newClient(GrpcTableRpc.ownTransport(transport)) - .build()); - - doWork(tableClient); - - tableClient.close(); -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous.md deleted file mode 100644 index 78203438a5d..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous.md +++ /dev/null @@ -1,20 +0,0 @@ -# Анонимная аутентификация - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода анонимной аутентификации в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](anonymous/go.md) %} - - -- Java - - - {% include [java.md](anonymous/java.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous/go.md deleted file mode 100644 index dcb95d4a3cc..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous/go.md +++ /dev/null @@ -1,24 +0,0 @@ -```go -package main - -import ( - "context" - - "github.com/ydb-platform/ydb-go-sdk/v3" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithAnonymousCredentials(), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous/java.md deleted file mode 100644 index b795713ddf7..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/anonymous/java.md +++ /dev/null @@ -1,17 +0,0 @@ -```java -public void work(String connectionString) { - AuthProvider authProvider = NopAuthProvider.INSTANCE; - - GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) - .withAuthProvider(authProvider) - .build(); - - TableClient tableClient = TableClient - .newClient(GrpcTableRpc.ownTransport(transport)) - .build()); - - doWork(tableClient); - - tableClient.close(); -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env.md deleted file mode 100644 index bd4256752d4..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env.md +++ /dev/null @@ -1,28 +0,0 @@ -# Аутентификация при помощи переменных окружения - -{% include [work in progress message](../../_includes/addition.md) %} - -При использовании данного метода режим аутентификации и его параметры будут определены окружением, в котором запускается приложение, в [описанном здесь порядке](../../../auth.md#env). - -Установив одну из следующих переменных окружения, можно управлять способом аутентификации: - -* `YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS=<path/to/sa_key_file>` — использовать файл сервисного аккаунта в Яндекс Облаке. -* `YDB_ANONYMOUS_CREDENTIALS="1"` — Использовать анонимную аутентификацию. Актуально для тестирования против докер-контейнера с {{ ydb-short-name }}. -* `YDB_METADATA_CREDENTIALS="1"` — использовать сервис метаданных внутри Яндекс Облака (Яндекс функция или виртуальная машина). -* `YDB_ACCESS_TOKEN_CREDENTIALS=<access_token>` — использовать аутентификацию с токеном. - -Ниже приведены примеры кода аутентификации при помощи переменных окружения в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](env/go.md) %} - -- Java - - - {% include [java.md](env/java.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env/go.md deleted file mode 100644 index 3d5ab05993e..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env/go.md +++ /dev/null @@ -1,26 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - environ "github.com/ydb-platform/ydb-go-sdk-auth-environ" - "github.com/ydb-platform/ydb-go-sdk/v3" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - environ.WithEnvironCredentials(ctx), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env/java.md deleted file mode 100644 index cfff5c1a836..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/env/java.md +++ /dev/null @@ -1,17 +0,0 @@ -```java -public void work(String connectionString) { - AuthProvider authProvider = CloudAuthHelper.getAuthProviderFromEnviron(); - - GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) - .withAuthProvider(authProvider) - .build(); - - TableClient tableClient = TableClient - .newClient(GrpcTableRpc.ownTransport(transport)) - .build()); - - doWork(tableClient); - - tableClient.close(); -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata.md deleted file mode 100644 index f6e5ac104ba..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata.md +++ /dev/null @@ -1,19 +0,0 @@ -# Аутентификация при помощи сервиса метаданных - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода аутентификации при помощи переменных окружения в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](metadata/go.md) %} - -- Java - - - {% include [java.md](metadata/java.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata/go.md deleted file mode 100644 index ac77d35c623..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata/go.md +++ /dev/null @@ -1,27 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - yc "github.com/ydb-platform/ydb-go-yc" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - yc.WithMetadataCredentials(ctx), - yc.WithInternalCA(), // append Yandex Cloud certificates - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata/java.md deleted file mode 100644 index ceb04396fae..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/metadata/java.md +++ /dev/null @@ -1,20 +0,0 @@ -```java -public void work(String connectionString) { - AuthProvider authProvider = CloudAuthProvider.newAuthProvider( - ComputeEngineCredentialProvider.builder() - .build() - ); - - GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) - .withAuthProvider(authProvider) - .build(); - - TableClient tableClient = TableClient - .newClient(GrpcTableRpc.ownTransport(transport)) - .build()); - - doWork(tableClient); - - tableClient.close(); -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account.md deleted file mode 100644 index 59e06312a64..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account.md +++ /dev/null @@ -1,19 +0,0 @@ -# Аутентификация при помощи файла сервисного аккаунта - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода аутентификации при помощи файла сервисного аккаунта в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](service_account/go.md) %} - -- Java - - - {% include [java.md](service_account/java.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account/go.md deleted file mode 100644 index 1a5d26021a0..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account/go.md +++ /dev/null @@ -1,29 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - yc "github.com/ydb-platform/ydb-go-yc" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - yc.WithServiceAccountKeyFileCredentials( - os.Getenv("YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS"), - ), - yc.WithInternalCA(), // append Yandex Cloud certificates - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account/java.md deleted file mode 100644 index a75034440c5..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/_includes/service_account/java.md +++ /dev/null @@ -1,21 +0,0 @@ -```java -public void work(String connectionString, Path saKeyPath) { - AuthProvider authProvider = CloudAuthProvider.newAuthProvider( - ApiKeyCredentialProvider.builder() - .fromFile(saKeyPath) - .build() - ); - - GrpcTransport transport = GrpcTransport.forConnectionString(connectionString) - .withAuthProvider(authProvider) - .build(); - - TableClient tableClient = TableClient - .newClient(GrpcTableRpc.ownTransport(transport)) - .build()); - - doWork(tableClient); - - tableClient.close(); -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/access_token.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/access_token.md deleted file mode 100644 index 606d617e7d0..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/access_token.md +++ /dev/null @@ -1,3 +0,0 @@ - -{% include [access_token.md](_includes/access_token.md) %} - diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/anonymous.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/anonymous.md deleted file mode 100644 index 49b00e9286b..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/anonymous.md +++ /dev/null @@ -1,2 +0,0 @@ - -{% include [anonymous.md](_includes/anonymous.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/env.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/env.md deleted file mode 100644 index 004e4f5d392..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/env.md +++ /dev/null @@ -1 +0,0 @@ -{% include [index.md](_includes/env.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/index.md deleted file mode 100644 index bd4e95cb411..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/index.md +++ /dev/null @@ -1,3 +0,0 @@ - -{% include [index.md](_includes/index.md) %} - diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/metadata.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/metadata.md deleted file mode 100644 index d15b521addf..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/metadata.md +++ /dev/null @@ -1 +0,0 @@ -{% include [index.md](_includes/metadata.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/service_account.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/service_account.md deleted file mode 100644 index 70996edf715..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/service_account.md +++ /dev/null @@ -1 +0,0 @@ -{% include [index.md](_includes/service_account.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/static.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/static.md deleted file mode 100644 index e3862e1fde0..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/static.md +++ /dev/null @@ -1,51 +0,0 @@ -# Аутентификация при помощи логина и пароля - -{% include [work in progress message](../_includes/addition.md) %} - -Ниже приведены примеры кода аутентификации при помощи логина и пароля в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- C++ - - ```c++ - auto driverConfig = NYdb::TDriverConfig() - .SetEndpoint(endpoint) - .SetDatabase(database) - .SetCredentialsProviderFactory(NYdb::CreateLoginCredentialsProviderFactory({ - .User = "user", - .Password = "password", - })); - - NYdb::TDriver driver(driverConfig); - ``` - -- Go - - ```go - package main - - import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - ) - - func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithStaticCredentials("user", "password"), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() - } - ``` - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/toc_i.yaml b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/toc_i.yaml deleted file mode 100644 index faac8b32bce..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/toc_i.yaml +++ /dev/null @@ -1,15 +0,0 @@ -items: -- name: Обзор - href: index.md -- name: С помощью токена - href: access_token.md -- name: Анонимная - href: anonymous.md -- name: Файл сервисного аккаунта - href: service_account.md -- name: Сервис метаданных - href: metadata.md -- name: С помощью переменных окружения - href: env.md -- name: С помощью логина и пароля - href: static.md
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/toc_p.yaml b/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/toc_p.yaml deleted file mode 100644 index 5bfec4365de..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/auth/toc_p.yaml +++ /dev/null @@ -1,2 +0,0 @@ -items: -- include: { mode: link, path: toc_i.yaml }
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-prefer-local.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-prefer-local.md new file mode 100644 index 00000000000..8a78c9fb513 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-prefer-local.md @@ -0,0 +1,85 @@ +# Предпочитать ближайший дата-центр + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода установки опции алгоритма балансировки "предпочитать ближайший дата-центр" в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/balancers" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithBalancer( + balancers.PreferLocalDC( + balancers.RandomChoice(), + ), + ), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + Клиентская балансировка в `database/sql` драйвере для {{ ydb-short-name }} осуществляется только в момент установления нового соединения (в терминах `database/sql`), которое представляет собой сессию {{ ydb-short-name }} на конкретной ноде. После того, как сессия создана, все запросы на этой сессии направляются на ту ноду, на которой была создана сессия. Балансировка запросов на одной и той же сессии {{ ydb-short-name }} между разными нодами {{ ydb-short-name }} не происходит. + + Пример кода установки алгоритма балансировки "предпочитать ближайший дата-центр": + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/balancers" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithBalancer( + balancers.PreferLocalDC( + balancers.RandomChoice(), + ), + ), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-prefer-location.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-prefer-location.md new file mode 100644 index 00000000000..dc5c9bd1470 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-prefer-location.md @@ -0,0 +1,89 @@ +# Предпочитать конкретную зону доступности + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода установки опции алгоритма балансировки "предпочитать зону доступности" в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/balancers" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithBalancer( + balancers.PreferLocations( + balancers.RandomChoice(), + "a", + "b", + ), + ), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + Клиентская балансировка в `database/sql` драйвере для {{ ydb-short-name }} осуществляется только в момент установления нового соединения (в терминах `database/sql`), которое представляет собой сессию {{ ydb-short-name }} на конкретной ноде. После того, как сессия создана, все запросы на этой сессии направляются на ту ноду, на которой была создана сессия. Балансировка запросов на одной и той же сессии {{ ydb-short-name }} между разными нодами {{ ydb-short-name }} не происходит. + + Пример кода установки алгоритма балансировки "предпочитать зону доступности": + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/balancers" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithBalancer( + balancers.PreferLocations( + balancers.RandomChoice(), + "a", + "b", + ), + ), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-random-choice.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-random-choice.md new file mode 100644 index 00000000000..182cbed166c --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing-random-choice.md @@ -0,0 +1,83 @@ +# Равномерный случайный выбор + +{% include [work in progress message](_includes/addition.md) %} + +{{ ydb-short-name }} SDK использует алгоритм `random_choice` (равномерную случайную балансировку) по умолчанию. + +Ниже приведены примеры кода принудительной установки алгоритма балансировки "равномерный случайный выбор" в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/balancers" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithBalancer( + balancers.RandomChoice(), + ), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + Клиентская балансировка в `database/sql` драйвере для {{ ydb-short-name }} осуществляется только в момент установления нового соединения (в терминах `database/sql`), которое представляет собой сессию {{ ydb-short-name }} на конкретной ноде. После того, как сессия создана, все запросы на этой сессии направляются на ту ноду, на которой была создана сессия. Балансировка запросов на одной и той же сессии {{ ydb-short-name }} между разными нодами {{ ydb-short-name }} не происходит. + + Пример кода установки алгоритма балансировки "равномерный случайный выбор": + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/balancers" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithBalancer( + balancers.RandomChoice(), + ), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + +{% endlist %}
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing.md new file mode 100644 index 00000000000..9702784724f --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing.md @@ -0,0 +1,16 @@ + +# Балансировка + +{% include [work in progress message](_includes/addition.md) %} + +{{ ydb-short-name }} использует клиентскую балансировку, потому что клиентская балансировка эффективнее, когда на базу данных приходит большой трафик от множества клиентских приложений. +В большинстве случаев она просто работает в {{ ydb-short-name }} SDK. Однако иногда нужны специфичные настройки клиентской балансировки, например, для уменьшения серверных хопов, сокращения времени запроса или распределения нагрузки по зонам доступности. + +Следует отметить, что клиентская балансировка работает в ограниченном режиме в отношении сессий {{ ydb-short-name }}. Клиентская балансировка в {{ ydb-short-name }} SDK осуществляется только в момент создания новой сессии {{ ydb-short-name }} на конкретной ноде. После того, как сессия создана, все запросы на этой сессии направляются на ту ноду, на которой была создана сессия. Балансировка запросов на одной и той же сессии {{ ydb-short-name }} между разными нодами {{ ydb-short-name }} не происходит. + +В данном разделе содержатся рецепты кода с настройкой клиентской балансировки в разных {{ ydb-short-name }} SDK + +Содержание: +- [Равномерный случайный выбор](balancing-random-choice.md) +- [Предпочитать ближайший дата-центр](balancing-prefer-local.md) +- [Предпочитать конкретную зону доступности](balancing-prefer-location.md) diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/index.md deleted file mode 100644 index 20ebf855e35..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/index.md +++ /dev/null @@ -1,8 +0,0 @@ -# Балансировка - -{% include [work in progress message](../../_includes/addition.md) %} - -{{ ydb-short-name }} использует клиентскую балансировку, потому что клиентская балансировка эффективнее, когда на базу данных приходит большой трафик от множества клиентских приложений. -В большинстве случаев она просто работает в {{ ydb-short-name }} SDK. Однако иногда нужны специфичные настройки клиентской балансировки, например, для уменьшения серверных хопов, сокращения времени запроса или распределения нагрузки по зонам доступности. - -В данном разделе содержатся рецепты кода с настройкой клиентской балансировки в разных {{ ydb-short-name }} SDK diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_local.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_local.md deleted file mode 100644 index 04c2aef2ab0..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_local.md +++ /dev/null @@ -1,15 +0,0 @@ -# Предпочитать ближайший дата-центр - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода установки опции алгоритма балансировки "предпочитать ближайший дата-центр" в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](prefer_local/go.md) %} - - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_local/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_local/go.md deleted file mode 100644 index fc43c67df84..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_local/go.md +++ /dev/null @@ -1,30 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/balancers" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithBalancer( - balancers.PreferLocalDC( - balancers.RandomChoice(), - ), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_location.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_location.md deleted file mode 100644 index beea8711e7a..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_location.md +++ /dev/null @@ -1,15 +0,0 @@ -# Предпочитать зону доступности - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода установки опции алгоритма балансировки "предпочитать зону доступности" в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](prefer_location/go.md) %} - - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_location/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_location/go.md deleted file mode 100644 index 7d360849b94..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/prefer_location/go.md +++ /dev/null @@ -1,32 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/balancers" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithBalancer( - balancers.PreferLocations( - balancers.RandomChoice(), - "a", - "b", - ), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/random_choice.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/random_choice.md deleted file mode 100644 index e1ecfae0bb4..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/random_choice.md +++ /dev/null @@ -1,17 +0,0 @@ -# Равномерный случайный выбор - -{% include [work in progress message](../../_includes/addition.md) %} - -{{ ydb-short-name }} SDK использует алгоритм `random_choice` (равномерную случайную балансировку) по умолчанию. - -Ниже приведены примеры кода принудительной установки алгоритма балансировки "равномерный случайный выбор" в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](random_choice/go.md) %} - - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/random_choice/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/random_choice/go.md deleted file mode 100644 index a52aaa7827b..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/_includes/random_choice/go.md +++ /dev/null @@ -1,28 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/balancers" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithBalancer( - balancers.RandomChoice(), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/index.md deleted file mode 100644 index e5687972c21..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/index.md +++ /dev/null @@ -1,3 +0,0 @@ - -{% include [balancing.md](_includes/index.md) %} - diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/prefer_local.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/prefer_local.md deleted file mode 100644 index ba06e91a9af..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/prefer_local.md +++ /dev/null @@ -1 +0,0 @@ -{% include [index.md](_includes/prefer_local.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/prefer_location.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/prefer_location.md deleted file mode 100644 index 825e8ccb448..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/prefer_location.md +++ /dev/null @@ -1 +0,0 @@ -{% include [index.md](_includes/prefer_location.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/random_choice.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/random_choice.md deleted file mode 100644 index ecd24b7afc9..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/random_choice.md +++ /dev/null @@ -1 +0,0 @@ -{% include [index.md](_includes/random_choice.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/toc_i.yaml b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/toc_i.yaml deleted file mode 100644 index 2fcf647d9cc..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/toc_i.yaml +++ /dev/null @@ -1,9 +0,0 @@ -items: -- name: Обзор - href: index.md -- name: Равномерный случайный выбор - href: random_choice.md -- name: Предпочитать ближайший дата-центр - href: prefer_local.md -- name: Предпочитать зону доступности - href: prefer_location.md
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/toc_p.yaml b/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/toc_p.yaml deleted file mode 100644 index 5bfec4365de..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/balancing/toc_p.yaml +++ /dev/null @@ -1,2 +0,0 @@ -items: -- include: { mode: link, path: toc_i.yaml }
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk-upsert.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk-upsert.md new file mode 100644 index 00000000000..7ba25218fe7 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk-upsert.md @@ -0,0 +1,89 @@ +# Пакетная вставка данных + +{% include [work in progress message](_includes/addition.md) %} + +{{ ydb-short-name }} поддерживает пакетную вставку большого количества строк без гарантий атомарности. Запись данных разбивается на несколько независимых транзакций, каждая их которых затрагивает единственную партицию, с параллельным исполнением. За счет этого такой подход более эффективен чем `YQL`. В случае успеха метод `BulkUpsert` гарантирует вставку всех данных, переданных в рамках данного запроса. + +Ниже приведены примеры кода использования встроенных в {{ ydb-short-name }} SDK средств выполнения пакетной вставки: + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/table" + "github.com/ydb-platform/ydb-go-sdk/v3/table/types" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithAccessTokenCredentials(os.Getenv("YDB_TOKEN")), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + type logMessage struct { + App string + Host string + Timestamp time.Time + HTTPCode uint32 + Message string + } + // prepare native go data + const batchSize = 10000 + logs := make([]logMessage, 0, batchSize) + for i := 0; i < batchSize; i++ { + message := logMessage{ + App: fmt.Sprintf("App_%d", i/256), + Host: fmt.Sprintf("192.168.0.%d", i%256), + Timestamp: time.Now().Add(time.Millisecond * time.Duration(i%1000)), + HTTPCode: 200, + } + if i%2 == 0 { + message.Message = "GET / HTTP/1.1" + } else { + message.Message = "GET /images/logo.png HTTP/1.1" + } + logs = append(logs, message) + } + // execute bulk upsert with native ydb data + err = db.Table().Do( // Do retry operation on errors with best effort + ctx, // context manage exiting from Do + func(ctx context.Context, s table.Session) (err error) { // retry operation + rows := make([]types.Value, 0, len(logs)) + for _, msg := range logs { + rows = append(rows, types.StructValue( + types.StructFieldValue("App", types.UTF8Value(msg.App)), + types.StructFieldValue("Host", types.UTF8Value(msg.Host)), + types.StructFieldValue("Timestamp", types.TimestampValueFromTime(msg.Timestamp)), + types.StructFieldValue("HTTPCode", types.Uint32Value(msg.HTTPCode)), + types.StructFieldValue("Message", types.UTF8Value(msg.Message)), + )) + } + return s.BulkUpsert(ctx, "/local/bulk_upsert_example", types.ListValue(rows...)) + }, + ) + if err != nil { + fmt.Printf("unexpected error: %v", err) + } + } + ``` + +- Go (database/sql) + + Реализация `database/sql` драйвера для {{ ydb-short-name }} не поддерживает нетранзакционную пакетную вставку данных. + Для пакетной вставки следует пользоваться [транзакционной вставкой](./upsert.md). + + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk_upsert/_includes/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk_upsert/_includes/go.md deleted file mode 100644 index 3876c0d5220..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk_upsert/_includes/go.md +++ /dev/null @@ -1,71 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/table" - "github.com/ydb-platform/ydb-go-sdk/v3/table/types" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithAccessTokenCredentials(os.Getenv("YDB_TOKEN")), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() - type logMessage struct { - App string - Host string - Timestamp time.Time - HTTPCode uint32 - Message string - } - // prepare native go data - const batchSize = 10000 - logs := make([]logMessage, 0, batchSize) - for i := 0; i < batchSize; i++ { - message := logMessage{ - App: fmt.Sprintf("App_%d", i/256), - Host: fmt.Sprintf("192.168.0.%d", i%256), - Timestamp: time.Now().Add(time.Millisecond * time.Duration(i%1000)), - HTTPCode: 200, - } - if i%2 == 0 { - message.Message = "GET / HTTP/1.1" - } else { - message.Message = "GET /images/logo.png HTTP/1.1" - } - logs = append(logs, message) - } - // execute bulk upsert with native ydb data - err = db.Table().Do( // Do retry operation on errors with best effort - ctx, // context manage exiting from Do - func(ctx context.Context, s table.Session) (err error) { // retry operation - rows := make([]types.Value, 0, len(logs)) - for _, msg := range logs { - rows = append(rows, types.StructValue( - types.StructFieldValue("App", types.UTF8Value(msg.App)), - types.StructFieldValue("Host", types.UTF8Value(msg.Host)), - types.StructFieldValue("Timestamp", types.TimestampValueFromTime(msg.Timestamp)), - types.StructFieldValue("HTTPCode", types.Uint32Value(msg.HTTPCode)), - types.StructFieldValue("Message", types.UTF8Value(msg.Message)), - )) - } - return s.BulkUpsert(ctx, "/local/bulk_upsert_example", types.ListValue(rows...)) - }, - ) - if err != nil { - fmt.Printf("unexpected error: %v", err) - } -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk_upsert/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk_upsert/index.md deleted file mode 100644 index 2264fff9513..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/bulk_upsert/index.md +++ /dev/null @@ -1,16 +0,0 @@ -# Пакетная вставка данных - -{% include [work in progress message](../_includes/addition.md) %} - -{{ ydb-short-name }} поддерживает пакетную вставку большого количества строк без гарантий атомарности. Запись данных разбивается на несколько независимых транзакций, каждая их которых затрагивает единственную партицию, с параллельным исполнением. За счет этого такой подход более эффективен чем `YQL`. В случае успеха метод `BulkUpsert` гарантирует вставку всех данных, переданных в рамках данного запроса. - -Ниже приведены примеры кода использования встроенных в {{ ydb-short-name }} SDK средств выполнения пакетной вставки: - -{% list tabs %} - -- Go - - - {% include [go.md](_includes/go.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-jaeger.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-jaeger.md new file mode 100644 index 00000000000..b55e8553ae1 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-jaeger.md @@ -0,0 +1,139 @@ +# Включение трассировки в Jaeger + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода включения трассировки в Jaeger в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "time" + + "github.com/opentracing/opentracing-go" + jaegerConfig "github.com/uber/jaeger-client-go/config" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + + tracing "github.com/ydb-platform/ydb-go-sdk-opentracing" + ) + + const ( + tracerURL = "localhost:5775" + serviceName = "ydb-go-sdk" + ) + + func main() { + tracer, closer, err := jaegerConfig.Configuration{ + ServiceName: serviceName, + Sampler: &jaegerConfig.SamplerConfig{ + Type: "const", + Param: 1, + }, + Reporter: &jaegerConfig.ReporterConfig{ + LogSpans: true, + BufferFlushInterval: 1 * time.Second, + LocalAgentHostPort: tracerURL, + }, + }.NewTracer() + if err != nil { + panic(err) + } + + defer closer.Close() + + // set global tracer of this application + opentracing.SetGlobalTracer(tracer) + + span, ctx := opentracing.StartSpanFromContext(context.Background(), "client") + defer span.Finish() + + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + tracing.WithTraces(tracing.WithDetails(trace.DetailsAll)), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + ```go + package main + + import ( + "context" + "database/sql" + "time" + + "github.com/opentracing/opentracing-go" + jaegerConfig "github.com/uber/jaeger-client-go/config" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + + tracing "github.com/ydb-platform/ydb-go-sdk-opentracing" + ) + + const ( + tracerURL = "localhost:5775" + serviceName = "ydb-go-sdk" + ) + + func main() { + tracer, closer, err := jaegerConfig.Configuration{ + ServiceName: serviceName, + Sampler: &jaegerConfig.SamplerConfig{ + Type: "const", + Param: 1, + }, + Reporter: &jaegerConfig.ReporterConfig{ + LogSpans: true, + BufferFlushInterval: 1 * time.Second, + LocalAgentHostPort: tracerURL, + }, + }.NewTracer() + if err != nil { + panic(err) + } + + defer closer.Close() + + // set global tracer of this application + opentracing.SetGlobalTracer(tracer) + + span, ctx := opentracing.StartSpanFromContext(context.Background(), "client") + defer span.Finish() + + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + tracing.WithTraces(tracing.WithDetails(trace.DetailsAll)), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpnDB(connector) + defer db.Close() + ... + } + ``` + + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-logs.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-logs.md new file mode 100644 index 00000000000..56ac7e1f333 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-logs.md @@ -0,0 +1,341 @@ +# Включение логирования + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода включения логирования в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + Есть несколько способов включить логи в приложении, использующем `ydb-go-sdk`: + + {% cut "Через переменную окружения `YDB_LOG_SEVERITY_LEVEL`" %} + + Данная переменная окружения включает встроенный в `ydb-go-sdk` логгер (синхронный, неблочный) с выводом в стандартный поток вывода. + Выставить переменную окружения можно так: + ```shell + export YDB_LOG_SEVERITY_LEVEL=info + ``` + (доступные значения `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `quiet`, по умолчанию `quiet`). + + {% endcut %} + + {% cut "Подключить сторонний логгер `go.uber.org/zap`" %} + ```go + package main + + import ( + "context" + "os" + + "go.uber.org/zap" + + ydbZap "github.com/ydb-platform/ydb-go-sdk-zap" + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var log *zap.Logger // zap-logger with init out of this scope + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydbZap.WithTraces( + log, + ydbZap.WithDetails(trace.DetailsAll), + ), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + {% endcut %} + + {% cut "Подключить сторонний логгер `github.com/rs/zerolog`" %} + ```go + package main + + import ( + "context" + "os" + + "github.com/rs/zerolog" + + ydbZerolog "github.com/ydb-platform/ydb-go-sdk-zerolog" + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var log zerolog.Logger // zap-logger with init out of this scope + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydbZerolog.WithTraces( + log, + ydbZerolog.WithDetails(trace.DetailsAll), + ), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + {% endcut %} + + {% include [overlay](_includes/debug-logs-go-appendix.md) %} + + {% cut "Подключить собственную имплементацию логгера `github.com/ydb-platform/ydb-go-sdk/v3/log.Logger`" %} + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/log" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var logger log.Logger // logger implementation with init out of this scope + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithLogger( + trace.DetailsAll, + ydb.WithExternalLogger(logger), + ), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + {% endcut %} + + {% cut "Реализовать собственный пакет логирования" %} + + Реализовать собственный пакет логирования можно на основе событий драйвера в пакете трассировки `github.com/ydb-platform/ydb-go-sdk/v3/trace`. Пакет трассировки `github.com/ydb-platform/ydb-go-sdk/v3/trace` содержит описание всех протоколируемых событий драйвера. + + {% endcut %} + +- Go (database/sql) + + Есть несколько способов включить логи в приложении, использующем `ydb-go-sdk`: + + {% cut "Через переменную окружения `YDB_LOG_SEVERITY_LEVEL`" %} + + Данная переменная окружения включает встроенный в `ydb-go-sdk` логгер (синхронный, неблочный) с выводом в стандартный поток вывода. + Выставить переменную окружения можно так: + ```shell + export YDB_LOG_SEVERITY_LEVEL=info + ``` + (доступные значения `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `quiet`, по умолчанию `quiet`). + + {% endcut %} + + {% cut "Подключить сторонний логгер `go.uber.org/zap`" %} + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "go.uber.org/zap" + + ydbZap "github.com/ydb-platform/ydb-go-sdk-zap" + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var log *zap.Logger // zap-logger with init out of this scope + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydbZap.WithTraces( + log, + ydbZap.WithDetails(trace.DetailsAll), + ), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpnDB(connector) + defer db.Close() + ... + } + ``` + {% endcut %} + + {% cut "Подключить сторонний логгер `github.com/rs/zerolog`" %} + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/rs/zerolog" + + ydbZerolog "github.com/ydb-platform/ydb-go-sdk-zerolog" + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var log zerolog.Logger // zap-logger with init out of this scope + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydbZerolog.WithTraces( + log, + ydbZerolog.WithDetails(trace.DetailsAll), + ), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpnDB(connector) + defer db.Close() + ... + } + ``` + {% endcut %} + + {% include [overlay](_includes/debug-logs-go-sql-appendix.md) %} + + {% cut "Подключить собственную имплементацию логгера `github.com/ydb-platform/ydb-go-sdk/v3/log.Logger`" %} + ```go + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/log" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + var logger log.Logger // logger implementation with init out of this scope + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithLogger( + trace.DetailsAll, + ydb.WithExternalLogger(logger), + ), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpnDB(connector) + defer db.Close() + ... + } + ``` + {% endcut %} + + {% cut "Реализовать собственный пакет логирования" %} + + Реализовать собственный пакет логирования можно на основе событий драйвера в пакете трассировки `github.com/ydb-platform/ydb-go-sdk/v3/trace`. Пакет трассировки `github.com/ydb-platform/ydb-go-sdk/v3/trace` содержит описание всех протоколируемых событий драйвера. + + {% endcut %} + +- Java + + В {{ ydb-short-name }} Java SDK для логирования используется библиотека slf4j, которая позволяет использовать различные уровни логирования (`error`, `warn`, `info`, `debug`, `trace`) для одного или нескольких логгеров. В текущей реализации доступны следующие логгеры: + + * Логгер `com.yandex.ydb.core.grpc` предоставляет информацию о внутренней реализации grpc протокола + * уровень `debug` логирует все операции по протоколу grpc, рекомедуется использовать только для отладки + * уровень `info` рекомендуется использовать по умолчанию + + * Логгер `com.yandex.ydb.table.impl` на уровне `debug` позволяет отслеживать внутреннее состояние драйвера ydb, в частности работу пула сессий. + + * Логгер `com.yandex.ydb.table.SessionRetryContext` на уровне `debug` будет информировать о количестве ретраев, результатах выполненных запросов, времени выполнения отдельных ретраев и общем времени выполнения всей операции + + * Логгер `com.yandex.ydb.table.Session` на уровне `debug` предоставляет информацию о тексте запроса, статусе ответа и времени выполнения для различных операций сессии + + + Включение и настройка логгеров Java SDK зависит от используемой реализации `slf4j-api`. + Здесь приведен пример конфигурации `log4j2` для библиотеки `log4j-slf4j-impl` + + ```xml + <Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + </Appenders> + + <Loggers> + <Logger name="io.netty" level="warn" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + <Logger name="io.grpc.netty" level="warn" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + <Logger name="com.yandex.ydb.core.grpc" level="info" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + <Logger name="com.yandex.ydb.table.impl" level="info" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + <Logger name="com.yandex.ydb.table.SessionRetryContext" level="debug" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + <Logger name="com.yandex.ydb.table.Session" level="debug" additivity="false"> + <AppenderRef ref="Console"/> + </Logger> + + <Root level="debug" > + <AppenderRef ref="Console"/> + </Root> + </Loggers> + </Configuration> + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-prometheus.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-prometheus.md new file mode 100644 index 00000000000..03886ffbf38 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug-prometheus.md @@ -0,0 +1,85 @@ +# Включение метрик в Prometheus + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода включения метрик в Prometheus в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + + "github.com/prometheus/client_golang/prometheus" + metrics "github.com/ydb-platform/ydb-go-sdk-prometheus" + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx := context.Background() + registry := prometheus.NewRegistry() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + metrics.WithTraces( + registry, + metrics.WithDetails(trace.DetailsAll), + metrics.WithSeparator("_"), + ), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + ```go + package main + + import ( + "context" + "database/sql" + + "github.com/prometheus/client_golang/prometheus" + metrics "github.com/ydb-platform/ydb-go-sdk-prometheus" + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/trace" + ) + + func main() { + ctx := context.Background() + registry := prometheus.NewRegistry() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + metrics.WithTraces( + registry, + metrics.WithDetails(trace.DetailsAll), + metrics.WithSeparator("_"), + ), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + + db := sql.OpnDB(connector) + defer db.Close() + ... + } + ``` + + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug.md index 75e76e5b6ea..43529397826 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug.md @@ -1,7 +1,13 @@ # Диагностика проблем -{% include [work in progress message](../../_includes/addition.md) %} +{% include [work in progress message](_includes/addition.md) %} При диагностике проблем, связанных с {{ ydb-short-name }}, помогают средства диагностики, такие как логирование, метрики, трассы OpenTracing/Jaeger. Мы настоятельно рекомендуем подключать средства диагностики заранее, пока не случилось проблем. Как минимум при расследовании можно увидеть изменения картины до проблем, во время и после. Это сильно ускоряет расследование происшествия и нашу помощь. В данном разделе содержатся рецепты кода с подключением средств диагностики в разных {{ ydb-short-name }} SDK. + +Содержание: +- [Включить логирование](debug-logs.md) +- [Подключить метрики в Prometheus](debug-prometheus.md) +- [Подключить трассировку в Jaeger](debug-jaeger.md) + diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/jaeger.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/jaeger.md deleted file mode 100644 index 3602b68df9d..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/jaeger.md +++ /dev/null @@ -1,15 +0,0 @@ -# Включение трассировки в Jaeger - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода включения трассировки в Jaeger в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](jaeger/go.md) %} - - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/jaeger/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/jaeger/go.md deleted file mode 100644 index a99be9ede99..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/jaeger/go.md +++ /dev/null @@ -1,60 +0,0 @@ -```go -package main - -import ( - "context" - "time" - - "github.com/opentracing/opentracing-go" - jaegerConfig "github.com/uber/jaeger-client-go/config" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/trace" - - tracing "github.com/ydb-platform/ydb-go-sdk-opentracing" -) - -const ( - tracerURL = "localhost:5775" - serviceName = "ydb-go-sdk" -) - -func main() { - tracer, closer, err := jaegerConfig.Configuration{ - ServiceName: serviceName, - Sampler: &jaegerConfig.SamplerConfig{ - Type: "const", - Param: 1, - }, - Reporter: &jaegerConfig.ReporterConfig{ - LogSpans: true, - BufferFlushInterval: 1 * time.Second, - LocalAgentHostPort: tracerURL, - }, - }.NewTracer() - if err != nil { - panic(err) - } - - defer closer.Close() - - // set global tracer of this application - opentracing.SetGlobalTracer(tracer) - - span, ctx := opentracing.StartSpanFromContext(context.Background(), "client") - defer span.Finish() - - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - tracing.WithTraces( - tracing.WithDetails(trace.DetailsAll), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs.md deleted file mode 100644 index 22e03fdf53e..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs.md +++ /dev/null @@ -1,19 +0,0 @@ -# Включение логирования - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода включения логирования в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](logs/go.md) %} - -- Java - - - {% include [java.md](logs/java.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/go.md deleted file mode 100644 index 00da506429a..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/go.md +++ /dev/null @@ -1,109 +0,0 @@ -Есть несколько способов включить логи в приложении, использующем `ydb-go-sdk`: -* Выставить переменную окружения `YDB_LOG_SEVERITY_LEVEL=info` (доступные значения `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `quiet`, по умолчанию `quiet`). - Данная переменная окружения включает встроенный в `ydb-go-sdk` логгер (синхронный, неблочный) с выводом в стандартный поток вывода. -* {% cut "Подключить сторонний логгер `go.uber.org/zap`" %} - ```go - package main - - import ( - "context" - - "go.uber.org/zap" - - ydbZap "github.com/ydb-platform/ydb-go-sdk-zap" - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/trace" - ) - - func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - var log *zap.Logger // zap-logger with init out of this scope - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydbZap.WithTraces( - log, - ydbZap.WithDetails(trace.DetailsAll), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() - } - ``` - {% endcut %} -* {% cut "Подключить сторонний логгер `github.com/rs/zerolog`" %} - ```go - package main - - import ( - "context" - "os" - - "github.com/rs/zerolog" - - ydbZerolog "github.com/ydb-platform/ydb-go-sdk-zerolog" - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/trace" - ) - - func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - var log zerolog.Logger // zap-logger with init out of this scope - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydbZerolog.WithTraces( - log, - ydbZerolog.WithDetails(trace.DetailsAll), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() - } - ``` - {% endcut %} -* {% cut "Подключить собственную имплементацию логгера `github.com/ydb-platform/ydb-go-sdk/v3/log.Logger`" %} - ```go - package main - - import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/log" - "github.com/ydb-platform/ydb-go-sdk/v3/trace" - ) - - func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - var logger log.Logger // logger implementation with init out of this scope - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithLogger( - trace.DetailsAll, - ydb.WithExternalLogger(logger), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() - } - ``` - {% endcut %} - -{% include [overlay](go_appendix.md) %} - -* Реализовать собственный пакет логирования на основе пакета трассировки `github.com/ydb-platform/ydb-go-sdk/v3/trace` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/java.md deleted file mode 100644 index 29d7708be29..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/logs/java.md +++ /dev/null @@ -1,50 +0,0 @@ -В {{ ydb-short-name }} Java SDK для логирования используется библиотека slf4j, которая позволяет использовать различные уровни логирования (`error`, `warn`, `info`, `debug`, `trace`) для одного или нескольких логгеров. В текущей реализации доступны следующие логгеры: - -* Логгер `com.yandex.ydb.core.grpc` предоставляет информацию о внутренней реализации grpc протокола - * уровень `debug` логирует все операции по протоколу grpc, рекомедуется использовать только для отладки - * уровень `info` рекомендуется использовать по умолчанию - -* Логгер `com.yandex.ydb.table.impl` на уровне `debug` позволяет отслеживать внутреннее состояние драйвера ydb, в частности работу пула сессий. - -* Логгер `com.yandex.ydb.table.SessionRetryContext` на уровне `debug` будет информировать о количестве ретраев, результатах выполненных запросов, времени выполнения отдельных ретраев и общем времени выполнения всей операции - -* Логгер `com.yandex.ydb.table.Session` на уровне `debug` предоставляет информацию о тексте запроса, статусе ответа и времени выполнения для различных операций сессии - - -Включение и настройка логгеров Java SDK зависит от используемой реализации `slf4j-api`. -Здесь приведен пример конфигурации `log4j2` для библиотеки `log4j-slf4j-impl` - -```xml -<Configuration status="WARN"> - <Appenders> - <Console name="Console" target="SYSTEM_OUT"> - <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> - </Console> - </Appenders> - - <Loggers> - <Logger name="io.netty" level="warn" additivity="false"> - <AppenderRef ref="Console"/> - </Logger> - <Logger name="io.grpc.netty" level="warn" additivity="false"> - <AppenderRef ref="Console"/> - </Logger> - <Logger name="com.yandex.ydb.core.grpc" level="info" additivity="false"> - <AppenderRef ref="Console"/> - </Logger> - <Logger name="com.yandex.ydb.table.impl" level="info" additivity="false"> - <AppenderRef ref="Console"/> - </Logger> - <Logger name="com.yandex.ydb.table.SessionRetryContext" level="debug" additivity="false"> - <AppenderRef ref="Console"/> - </Logger> - <Logger name="com.yandex.ydb.table.Session" level="debug" additivity="false"> - <AppenderRef ref="Console"/> - </Logger> - - <Root level="debug" > - <AppenderRef ref="Console"/> - </Root> - </Loggers> -</Configuration> -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/prometheus.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/prometheus.md deleted file mode 100644 index fc5cf9b7c01..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/prometheus.md +++ /dev/null @@ -1,15 +0,0 @@ -# Включение метрик в Prometheus - -{% include [work in progress message](../../_includes/addition.md) %} - -Ниже приведены примеры кода включения метрик в Prometheus в разных {{ ydb-short-name }} SDK. - -{% list tabs %} - -- Go - - - {% include [go.md](prometheus/go.md) %} - - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/prometheus/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/prometheus/go.md deleted file mode 100644 index 466bb1b8385..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/_includes/prometheus/go.md +++ /dev/null @@ -1,31 +0,0 @@ -```go -package main - -import ( - "context" - - "github.com/prometheus/client_golang/prometheus" - metrics "github.com/ydb-platform/ydb-go-sdk-prometheus" - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/trace" -) - -func main() { - ctx := context.Background() - registry := prometheus.NewRegistry() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - metrics.WithTraces( - registry, - metrics.WithDetails(trace.DetailsAll), - metrics.WithSeparator("_"), - ), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/index.md deleted file mode 100644 index e5687972c21..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/index.md +++ /dev/null @@ -1,3 +0,0 @@ - -{% include [balancing.md](_includes/index.md) %} - diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/jaeger.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/jaeger.md deleted file mode 100644 index 4941b019de1..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/jaeger.md +++ /dev/null @@ -1,2 +0,0 @@ - -{% include [index.md](_includes/jaeger.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/logs.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/logs.md deleted file mode 100644 index c37ce7b35ea..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/logs.md +++ /dev/null @@ -1,2 +0,0 @@ - -{% include [index.md](_includes/logs.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/prometheus.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/prometheus.md deleted file mode 100644 index 33c41f2c801..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/prometheus.md +++ /dev/null @@ -1,2 +0,0 @@ - -{% include [index.md](_includes/prometheus.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/toc_i.yaml b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/toc_i.yaml deleted file mode 100644 index b38626037be..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/toc_i.yaml +++ /dev/null @@ -1,9 +0,0 @@ -items: -- name: Обзор - href: index.md -- name: Включить логирование - href: logs.md -- name: Подключить метрики в Prometheus - href: prometheus.md -- name: Подключить трассировку в Jaeger - href: jaeger.md
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/toc_p.yaml b/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/toc_p.yaml deleted file mode 100644 index 5bfec4365de..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/debug/toc_p.yaml +++ /dev/null @@ -1,2 +0,0 @@ -items: -- include: { mode: link, path: toc_i.yaml }
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/index.md index bd4e95cb411..d4ec53dc57b 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/index.md @@ -1,3 +1,29 @@ +# Рецепты кода -{% include [index.md](_includes/index.md) %} +{% include [work in progress message](_includes/addition.md) %} + +В данном разделе содержатся рецепты кода на разных языках программирования для решения различных задач, часто встречающихся на практике, с использованием {{ ydb-short-name }} SDK. + +Содержание: +- [Обзор](index.md) +- [Инициализация драйвера](init.md) +- [Аутентификация](auth.md) + - [С помощью токена](auth-access-token.md) + - [Анонимная](auth-anonymous.md) + - [Файл сервисного аккаунта](auth-service-account.md) + - [Сервис метаданных](auth-metadata.md) + - [С помощью переменных окружения](auth-env.md) + - [С помощью логина и пароля](auth-static.md) +- [Балансировка](balancing.md) + - [Равномерный случайный выбор](balancing-random-choice.md) + - [Предпочитать ближайший дата-центр](balancing-prefer-local.md) + - [Предпочитать зону доступности](balancing-prefer-location.md) +- [Выполнение повторных запросов](retry.md) +- [Установить размер пула сессий](session-pool-limit.md) +- [Вставка данных](upsert.md) +- [Пакетная вставка данных](bulk-upsert.md) +- [Диагностика проблем](debug.md) + - [Включить логирование](debug-logs.md) + - [Подключить метрики в Prometheus](debug-prometheus.md) + - [Подключить трассировку в Jaeger](debug-jaeger.md) diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/init.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/init.md new file mode 100644 index 00000000000..e868a2fa8d7 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/init.md @@ -0,0 +1,96 @@ +# Инициализация драйвера + +{% include [work in progress message](_includes/addition.md) %} + +Для подключения к {{ ydb-short-name }} требуется указать обязательные параметры (подробнее читайте в разделе [Подключение к серверу {{ ydb-short-name }}](../../../concepts/connect.md)) и дополнительные, которые определяют поведение драйвера при работе. + +Ниже приведены примеры кода подлкючения к {{ ydb-short-name }} (создания драйвера) в разных {{ ydb-short-name }} SDK. + +{% list tabs %} + +- Go (native) + + ```golang + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + db, err := ydb.Open(ctx, "grpcs://localhost:2135/local") + if err != nil { + log.Fatal(err) + } + ... + } + ``` + +- Go (database/sql) + + {% cut "С помощью коннектора (рекомендуемый способ)" %} + ```golang + package main + + import ( + "context" + "database/sql" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + nativeDriver, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ) + if err != nil { + panic(err) + } + defer nativeDriver.Close(ctx) + connector, err := ydb.Connector(nativeDriver) + if err != nil { + panic(err) + } + db := sql.OpenDB(connector) + defer db.Close() + ... + } + ``` + {% endcut %} + + {% cut "С помощью строки подключения" %} + + Регистрация драйвера `database/sql` реализуется в момент импорта пакета конкретного драйвера через символ подчеркивавния: + ```golang + package main + + import ( + "context" + "database/sql" + "os" + + _ "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + db, err := ydb.Open(ctx, "grpcs://localhost:2135/local") + if err != nil { + log.Fatal(err) + } + ... + } + ``` + {% endcut %} + +- Java + + + {% include [work in progress message](_includes/addition.md) %} + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry.md new file mode 100644 index 00000000000..2e45ac1544e --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry.md @@ -0,0 +1,323 @@ +# Выполнение повторных попыток + +{% include [work in progress message](_includes/addition.md) %} + +{{ ydb-short-name }} является распределенной СУБД с автоматическим масштабированием под нагрузку. +На серверной стороне могут проводиться работы, серверные стойки или целые дата-центры могут быть временно отключены. +В связи с этим допускаются некоторые ошибки при работе с {{ ydb-short-name }}. +В зависимости от типа ошибки следует по разному реагировать на них. +{{ ydb-short-name }} SDK для обеспечения высокой доступности предоставляют встроенные средства выполнения повторных попыток, +в которых учтены типы ошибок и закреплена реакция на них. + +Ниже приведены примеры кода использования встроенных в {{ ydb-short-name }} SDK средств выполнения повторных попыток: + +{% list tabs %} + +- Go (native) + + В {{ ydb-short-name }} Go SDK корректная обработка ошибок закреплена в нескольких программных интерфейсах: + + {% cut "Функция повторов общего назначения" %} + + Основная логика обработки ошибок реализуется функцией-помощником `retry.Retry` + Подробности выполнения повторных запросов максимально скрыты. + Пользователь может влиять на логику работы функции `retry.Retry` двумя способами: + * через контекст (можно устанавливать deadline и cancel); + * через флаг идемпотентности операции `retry.WithIdempotent()`. По умолчанию операция считается неидемпотентной. + + Пользователь передает свою функцию в `retry.Retry`, которая по своей сигнатуре должна возвращать ошибку. + В случае, если из пользовательской функции вернулся `nil`, то повторные запросы прекращаются. + В случае, если из пользовательской функции вернулась ошибка, {{ ydb-short-name }} Go SDK пытается идентифицировать эту ошибку и в зависимости от нее выполняет повторные попытки. + + Пример кода, использующего функцию `retry.Retry`: + ```golang + package main + + import ( + "context" + "time" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/retry" + ) + + func main() { + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + var cancel context.CancelFunc + // fix deadline for retries + ctx, cancel := context.WithTimeout(ctx, time.Second) + err = retry.Retry( + ctx, + func(ctx context.Context) error { + whoAmI, err := db.Discovery().WhoAmI(ctx) + if err != nil { + return err + } + fmt.Println(whoAmI) + }, + retry.WithIdempotent(true), + ) + if err != nil { + panic(err) + } + } + ``` + + {% endcut %} + + {% cut "Выполнение повторных попыток при ошибках на объекте сессии {{ ydb-short-name }}" %} + + Для повторной обработки ошибок на уровне сессии сервиса таблиц {{ ydb-short-name }} есть функция `db.Table().Do(ctx, op)`, которая предоставляет подготовленную сессию для выполнения запросов. + Функция `db.Table().Do(ctx, op)` использует пакет `retry`, а также следит за временем жизни сессий {{ ydb-short-name }}. + Из пользовательской операции `op` согласно ее сигнатуре требуется возвращать ошибку или `nil`, чтобы драйвер смог по типу ошибки "понять" что нужно делать: поторять операцию или нет, с задержкой или нет, на этой же сессии или новой. + Пользователь может влиять на логику выполнения повторных запросов через контекст и признак идемпотентности, а {{ ydb-short-name }} Go SDK интерпретирует возвращаемые из `op` ошибки. + + Пример кода, использующего функцию `db.Table().Do(ctx, op)`: + ```golang + err := db.Table().Do(ctx, func(ctx context.Context, s table.Session) (err error) { + desc, err = s.DescribeTableOptions(ctx) + return + }, table.WithIdempotent()) + if err != nil { + return err + } + ``` + + {% endcut %} + + {% cut "Выполнение повторных попыток при ошибках на объекте интерактивной транзакции {{ ydb-short-name }}" %} + + Для повторной обработки ошибок на уровне интерактивной транзакции сервиса таблиц {{ ydb-short-name }} есть функция `db.Table().DoTx(ctx, txOp)`, которая предоставляет подготовленную транзакцию {{ ydb-short-name }} на сессии для выполнения запросов. + Функция `db.Table().DoTx(ctx, txOp)` использует пакет `retry`, а также следит за временем жизни сессий {{ ydb-short-name }}. + Из пользовательской операции `txOp` согласно ее сигнатуре требуется возвращать ошибку или `nil`, чтобы драйвер смог по типу ошибки "понять" что нужно делать: поторять операцию или нет, с задержкой или нет, на этой же транзакции или новой. + Пользователь может влиять на логику выполнения повторных запросов через контекст и признак идемпотентности, а {{ ydb-short-name }} Go SDK интерпретирует возвращаемые из `op` ошибки. + + Пример кода, использующего функцию `db.Table().DoTx(ctx, op)`: + ```golang + err := db.Table().DoTx(ctx, func(ctx context.Context, tx table.TransactionActor) error { + _, err := tx.Execute(ctx, + "DECLARE $id AS Int64; INSERT INTO test (id, val) VALUES($id, 'asd')", + table.NewQueryParameters(table.ValueParam("$id", types.Int64Value(100500))), + ) + return err + }, table.WithIdempotent()) + if err != nil { + return err + } + ``` + + {% endcut %} + + {% cut "Запросы к остальным сервисам {{ ydb-short-name }}" %} + + (`db.Scripting()`, `db.Scheme()`, `db.Coordination()`, `db.Ratelimiter()`, `db.Discovery()`) также используют внутри себя функцию `retry.Retry` для выполнения повторных запросов и не требуют использования внешних вспомогательных функций для повторов. + + {% endcut %} + +- Go (database/sql) + + Стандартный пакет `database/sql` использует внутреннюю логику выполнения повторов на основе тех ошибок, что возвращает конкретная реализация драйвера. + Так, в [коде](https://github.com/golang/go/tree/master/src/database/sql) пакета `database/sql` во многих местах можно встретить политику повторов из трех попыток: + - 2 попытки выполнить на существующем соединении или новом (если пул соединений `database/sql` пуст) + - 1 попытка выполнить на новом соединении. + + В большинстве случаев такой политики повторов достаточно, чтобы пережить временную недоступность нод {{ ydb-short-name }} или проблемы с сессией {{ ydb-short-name }}. + + {{ ydb-short-name }} Go SDK предоставляет специальные функции для гарантированного выполнения пользовательской операции: + + {% cut "Выполнение повторных попыток при ошибках на объекте соединения `*sql.Conn`:" %} + + Для повторной обработки ошибок на объекте соединения `*sql.Conn` есть вспомогательная функция `retry.Do(ctx, db, op)`, которая предоставляет подготовленное соединение `*sql.Conn` для выполнения запросов. + В функцию `retry.Do` требуется передать контекст, объект базы данных, а также пользовательскую операцию, которую требуется выполнить. + Из клиентского кода можно влиять на логику выполнения повторных запросов через контекст и признак идемпотентности, а {{ ydb-short-name }} Go SDK в свою очередь интерпретирует возвращаемые из `op` ошибки. + + Пользовательская операция `op` должна возвращать ошибку или `nil`: + - в случае, если из пользовательской функции вернулся `nil`, то повторные запросы прекращаются; + - в случае, если из пользовательской функции вернулась ошибка, {{ ydb-short-name }} Go SDK пытается идентифицировать эту ошибку и в зависимости от нее предпринимает повторные попытки. + + Пример кода, использующего функцию `retry.Do`: + ```golang + import ( + "context" + "database/sql" + "fmt" + "log" + + "github.com/ydb-platform/ydb-go-sdk/v3/retry" + ) + + func main() { + ... + err = retry.Do(ctx, db, func(ctx context.Context, cc *sql.Conn) (err error) { + row = cc.QueryRowContext(ctx, ` + PRAGMA TablePathPrefix("/local"); + DECLARE $seriesID AS Uint64; + DECLARE $seasonID AS Uint64; + DECLARE $episodeID AS Uint64; + SELECT views FROM episodes WHERE series_id = $seriesID AND season_id = $seasonID AND episode_id = $episodeID; + `, + sql.Named("seriesID", uint64(1)), + sql.Named("seasonID", uint64(1)), + sql.Named("episodeID", uint64(1)), + ) + var views sql.NullFloat64 + if err = row.Scan(&views); err != nil { + return fmt.Errorf("cannot scan views: %w", err) + } + if views.Valid { + return fmt.Errorf("unexpected valid views: %v", views.Float64) + } + log.Printf("views = %v", views) + return row.Err() + }, retry.WithDoRetryOptions(retry.WithIdempotent(true))) + if err != nil { + log.Printf("retry.Do failed: %v\n", err) + } + } + ``` + + {% endcut %} + + {% cut "Выполнение повторных попыток при ошибках на объекте интерактивной транзакции `*sql.Tx`:" %} + + Для повторной обработки ошибок на объекте интерактивной транзакции `*sql.Tx` есть вспомогательная функция `retry.DoTx(ctx, db, op)`, которая предоставляет подготовленную транзакцию `*sql.Tx` для выполнения запросов. + В функцию `retry.DoTx` требуется передать контекст, объект базы данных, а также пользовательскую операцию, которую требуется выполнить. + В функцию приходит подготовленная транзакция `*sql.Tx`, на которой следует выполнять запросы к {{ ydb-short-name }}. + Из клиентского кода можно влиять на логику выполнения повторных запросов через контекст и признак идемпотентности операции, а {{ ydb-short-name }} Go SDK в свою очередь интерпретирует возвращаемые из `op` ошибки. + + Пользовательская операция `op` должна возвращать ошибку или `nil`: + - в случае, если из пользовательской функции вернулся `nil`, то повторные запросы прекращаются; + - в случае, если из пользовательской функции вернулась ошибка, {{ ydb-short-name }} Go SDK пытается идентифицировать эту ошибку и в зависимости от нее предпринимает повторные попытки. + + Функция `retry.DoTx` использует режим изоляции read-write транзакции `sql.LevelDefault` по умолчанию, который можно изменить через опцию `retry.WithTxOptions`. + + Пример кода, использующего функцию `retry.Do`: + ```golang + import ( + "context" + "database/sql" + "fmt" + "log" + + "github.com/ydb-platform/ydb-go-sdk/v3/retry" + ) + + func main() { + ... + err = retry.DoTx(ctx, db, func(ctx context.Context, tx *sql.Tx) error { + row := tx.QueryRowContext(ctx,` + PRAGMA TablePathPrefix("/local"); + DECLARE $seriesID AS Uint64; + DECLARE $seasonID AS Uint64; + DECLARE $episodeID AS Uint64; + SELECT views FROM episodes WHERE series_id = $seriesID AND season_id = $seasonID AND episode_id = $episodeID; + `, + sql.Named("seriesID", uint64(1)), + sql.Named("seasonID", uint64(1)), + sql.Named("episodeID", uint64(1)), + ) + var views sql.NullFloat64 + if err = row.Scan(&views); err != nil { + return fmt.Errorf("cannot select current views: %w", err) + } + if !views.Valid { + return fmt.Errorf("unexpected invalid views: %v", views) + } + t.Logf("views = %v", views) + if views.Float64 != 1 { + return fmt.Errorf("unexpected views value: %v", views) + } + return nil + }, retry.WithDoTxRetryOptions(retry.WithIdempotent(true)), retry.WithTxOptions(&sql.TxOptions{ + Isolation: sql.LevelSnapshot, + ReadOnly: true, + })) + if err != nil { + log.Printf("do tx failed: %v\n", err) + } + } + ``` + + {% endcut %} + +- Java + + В {{ ydb-short-name }} Java SDK механизм повторных запросов реализован в виде класс хелпера `com.yandex.ydb.table.SessionRetryContext`. Данный класс конструируется с помощью метода `SessionRetryContext.create` в который требуется передать реализацию интерфейса `SessionSupplier` - как правило это экземпляр класса `TableClient`. + Дополнительно пользователь может задавать некоторые другие опции + * `maxRetries(int maxRetries)` - максимальное количество повторов операции, не включает в себя первое выполение. Значение по умолчанию `10` + * `retryNotFound(boolean retryNotFound)` - опция повтора операций, вернувших статус `NOT_FOUND`. По умолчанию включено. + * `idempotent(boolean idempotent)` - признак идемпотентности операций. Идемпотентные операции будут повторяться для более широкого списка ошибок. По умолчанию отключено. + + Для запуска операций с ретраями класс `SessionRetryContext` предоставляет два метода + * `CompletableFuture<Status> supplyStatus` - выполнение операции, возвращающей статус. В качестве аргумента принимает лямбду `Function<Session, CompletableFuture<Status>> fn` + * `CompletableFuture<Result<T>> supplyResult` - выполнение операции, возвращающей данные. В качестве аргумента принимает лямбду `Function<Session, CompletableFuture<Result<T>>> fn` + + При использовании класса `SessionRetryContext` нужно учитывать, что повторое исполнение операции будут выполнятся в следующих случаях + * Лямбда вернула [retryable](../error_handling.md) код ошибки + * В рамках исполнения лямбды была вызвано `UnexpectedResultException` c [retryable](../error_handling.md) кодом ошибки + + + + {% cut "Пример кода, использующего SessionRetryContext.supplyStatus:" %} + + ```java + private void createTable(TableClient tableClient, String database, String tableName) { + SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build(); + TableDescription pets = TableDescription.newBuilder() + .addNullableColumn("species", PrimitiveType.utf8()) + .addNullableColumn("name", PrimitiveType.utf8()) + .addNullableColumn("color", PrimitiveType.utf8()) + .addNullableColumn("price", PrimitiveType.float32()) + .setPrimaryKeys("species", "name") + .build(); + + String tablePath = database + "/" + tableName; + retryCtx.supplyStatus(session -> session.createTable(tablePath, pets)) + .join().expect("ok"); + } + ``` + + {% endcut %} + + {% cut "Пример кода, использующего SessionRetryContext.supplyResult:" %} + + ```java + private void selectData(TableClient tableClient, String tableName) { + SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build(); + String selectQuery + = "DECLARE $species AS Utf8;" + + "DECLARE $name AS Utf8;" + + "SELECT * FROM " + tableName + " " + + "WHERE species = $species AND name = $name;"; + + Params params = Params.of( + "$species", PrimitiveValue.utf8("cat"), + "$name", PrimitiveValue.utf8("Tom") + ); + + DataQueryResult data = retryCtx + .supplyResult(session -> session.executeDataQuery(selectQuery, TxControl.onlineRo(), params)) + .join().expect("ok"); + + ResultSetReader rsReader = data.getResultSet(0); + logger.info("Result of select query:"); + while (rsReader.next()) { + logger.info(" species: {}, name: {}, color: {}, price: {}", + rsReader.getColumn("species").getUtf8(), + rsReader.getColumn("name").getUtf8(), + rsReader.getColumn("color").getUtf8(), + rsReader.getColumn("price").getFloat32() + ); + } + } + ``` + + {% endcut %} + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/_includes/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/_includes/go.md deleted file mode 100644 index 68558a1a1f2..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/_includes/go.md +++ /dev/null @@ -1,61 +0,0 @@ -В {{ ydb-short-name }} Go SDK корректная обработка ошибок закреплена в нескольких программных интерфейсах: - -* Основная логика обработки ошибок реализуется функцией-помощником `retry.Retry`. - Подробности выполнения повторных запросов максимально скрыты. - Пользователь может влиять на логику работы функции `retry.Retry` двумя способами: - * через контекст (можно устанавливать deadline и cancel); - * через флаг идемпотентности операции `retry.WithIdempotent()`. По умолчанию операция считается неидемпотентной. - - Пользователь передает свою функцию в `retry.Retry`, которая по своей сигнатуре должна возвращать ошибку. - В случае, если из пользовательской функции вернулся `nil`, то повторные запросы прекращаются. - В случае, если из пользовательской функции вернулась ошибка, {{ ydb-short-name }} Go SDK пытается идентифицировать эту ошибку и в зависимости от нее выполняет повторные попытки. - - {% cut "Пример кода, использующего функцию `retry.Retry`:" %} - - ```go - package main - - import ( - "context" - "time" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/retry" - ) - - func main() { - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() - var cancel context.CancelFunc - // fix deadline for retries - ctx, cancel := context.WithTimeout(ctx, time.Second) - err = retry.Retry( - ctx, - func(ctx context.Context) error { - whoAmI, err := db.Discovery().WhoAmI(ctx) - if err != nil { - return err - } - fmt.Println(whoAmI) - }, - retry.WithIdempotent(true), - ) - if err != nil { - panic(err) - } - } - ``` - - {% endcut %} - -* Сервис для работы с табличными запросами `db.Table()` сразу предоставляет программный интерфейс `table.Client`, который использует пакет `retry`, а также следит за временем жизни сессий {{ ydb-short-name }}. - Пользователю доступны две публичных функции: `db.Table().Do(ctx, op)` (`op` предоставляет сессию) и `db.Table().DoTx(ctx, op)` (`op` предоставляет транзакцию). - Как и в предыдущем случае пользователь может влиять на логику выполнения повторных запросов через контекст и признак идемпотентности, а {{ ydb-short-name }} Go SDK интерпретирует возвращаемые из `op` ошибки. -* Запросы к остальным сервисам {{ ydb-short-name }} (`db.Scripting()`, `db.Scheme()`, `db.Coordination()`, `db.Ratelimiter()`, `db.Discovery()`) также используют внутри себя функцию `retry.Retry` для выполнения повторных запросов. diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/_includes/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/_includes/java.md deleted file mode 100644 index cd455281f10..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/_includes/java.md +++ /dev/null @@ -1,71 +0,0 @@ -В {{ ydb-short-name }} Java SDK механизм повторных запросов реализован в виде класс хелпера `com.yandex.ydb.table.SessionRetryContext`. Данный класс конструируется с помощью метода `SessionRetryContext.create` в который требуется передать реализацию интерфейса `SessionSupplier` - как правило это экземпляр класса `TableClient`. -Дополнительно пользователь может задавать некоторые другие опции -* `maxRetries(int maxRetries)` - максимальное количество повторов операции, не включает в себя первое выполение. Значение по умолчанию `10` -* `retryNotFound(boolean retryNotFound)` - опция повтора операций, вернувших статус `NOT_FOUND`. По умолчанию включено. -* `idempotent(boolean idempotent)` - признак идемпотентности операций. Идемпотентные операции будут повторяться для более широкого списка ошибок. По умолчанию отключено. - -Для запуска операций с ретраями класс `SessionRetryContext` предоставляет два метода -* `CompletableFuture<Status> supplyStatus` - выполнение операции, возвращающей статус. В качестве аргумента принимает лямбду `Function<Session, CompletableFuture<Status>> fn` -* `CompletableFuture<Result<T>> supplyResult` - выполнение операции, возвращающей данные. В качестве аргумента принимает лямбду `Function<Session, CompletableFuture<Result<T>>> fn` - -При использовании класса `SessionRetryContext` нужно учитывать, что повторое исполнение операции будут выполнятся в следующих случаях -* Лямбда вернула [retryable](../../../error_handling.md) код ошибки -* В рамках исполнения лямбды была вызвано `UnexpectedResultException` c [retryable](../../../error_handling.md) кодом ошибки - - - - {% cut "Пример кода, использующего SessionRetryContext.supplyStatus:" %} - - ```java - private void createTable(TableClient tableClient, String database, String tableName) { - SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build(); - TableDescription pets = TableDescription.newBuilder() - .addNullableColumn("species", PrimitiveType.utf8()) - .addNullableColumn("name", PrimitiveType.utf8()) - .addNullableColumn("color", PrimitiveType.utf8()) - .addNullableColumn("price", PrimitiveType.float32()) - .setPrimaryKeys("species", "name") - .build(); - - String tablePath = database + "/" + tableName; - retryCtx.supplyStatus(session -> session.createTable(tablePath, pets)) - .join().expect("ok"); - } - ``` - - {% endcut %} - - {% cut "Пример кода, использующего SessionRetryContext.supplyResult:" %} - - ```java - private void selectData(TableClient tableClient, String tableName) { - SessionRetryContext retryCtx = SessionRetryContext.create(tableClient).build(); - String selectQuery - = "DECLARE $species AS Utf8;" - + "DECLARE $name AS Utf8;" - + "SELECT * FROM " + tableName + " " - + "WHERE species = $species AND name = $name;"; - - Params params = Params.of( - "$species", PrimitiveValue.utf8("cat"), - "$name", PrimitiveValue.utf8("Tom") - ); - - DataQueryResult data = retryCtx - .supplyResult(session -> session.executeDataQuery(selectQuery, TxControl.onlineRo(), params)) - .join().expect("ok"); - - ResultSetReader rsReader = data.getResultSet(0); - logger.info("Result of select query:"); - while (rsReader.next()) { - logger.info(" species: {}, name: {}, color: {}, price: {}", - rsReader.getColumn("species").getUtf8(), - rsReader.getColumn("name").getUtf8(), - rsReader.getColumn("color").getUtf8(), - rsReader.getColumn("price").getFloat32() - ); - } - } - ``` - - {% endcut %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/index.md deleted file mode 100644 index c7a297f050e..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/retry/index.md +++ /dev/null @@ -1,26 +0,0 @@ -# Выполнение повторных попыток - -{% include [work in progress message](../_includes/addition.md) %} - -{{ ydb-short-name }} является распределенной СУБД с автоматическим масштабированием под нагрузку. -На серверной стороне могут проводиться работы, серверные стойки или целые дата-центры могут быть временно отключены. -В связи с этим допускаются некоторые ошибки при работе с {{ ydb-short-name }}. -В зависимости от типа ошибки следует по разному реагировать на них. -{{ ydb-short-name }} SDK для обеспечения высокой доступности предоставляют встроенные средства выполнения повторных попыток, -в которых учтены типы ошибок и закреплена реакция на них. - -Ниже приведены примеры кода использования встроенных в {{ ydb-short-name }} SDK средств выполнения повторных попыток: - -{% list tabs %} - -- Go - - - {% include [go.md](_includes/go.md) %} - -- Java - - - {% include [java.md](_includes/java.md) %} - -{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session-pool-limit.md index b97cabcb5df..755a28f0101 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/index.md +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session-pool-limit.md @@ -1,6 +1,6 @@ # Установить размер пула сессий -{% include [work in progress message](../_includes/addition.md) %} +{% include [work in progress message](_includes/addition.md) %} Размер пула сессий на клиенте влияет на потребление ресурсов (память, процессор) на серверной стороне {{ ydb-short-name }}. Простая математика: если `1000` клиентов одной базы данных имеют по `1000` сессий, то на серверной стороне создается `1000000` акторов (воркеров, исполнителей сессий). Если не лимитировать количество сессий на клиенте, то можно получить "задумчивый" кластер в полу-аварийном состоянии. @@ -12,14 +12,65 @@ {% list tabs %} -- Go +- Go (native) + ```golang + package main - {% include [go.md](_includes/go.md) %} + import ( + "context" -- Java + "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithSessionPoolSizeLimit(500), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + ... + } + ``` + +- Go (database/sql) + + Библиотека `database/sql` имеет свой пул соединений. Каждое соединение в `database/sql` соответствует конкретной сессии {{ ydb-short-name }}. Управлением пулом соединений в `database/sql` осуществляется с помощью функций `sql.DB.SetMaxOpenConns` и `sql.DB.SetMaxIdleConns`. Подробнее об этом написано в [документации](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns) `database/sql`. + + Пример кода, использующего размер пула соединений `database/sql`: + ```golang + package main + import ( + "context" + "database/sql" + + _ "github.com/ydb-platform/ydb-go-sdk/v3" + ) + + func main() { + db, err := ydb.Open("ydb", os.Getenv("YDB_CONNECTION_STRING")) + if err != nil { + panic(err) + } + defer db.Close(ctx) + db.SetMaxOpenConns(100) + db.SetMaxIdleConns(100) + ... + } + ``` + +- Java - {% include [java.md](_includes/java.md) %} + ```java + this.tableClient = TableClient.newClient(rpc) + // 10 - minimum number of active sessions to keep in the pool during the cleanup + // 500 - maximum number of sessions in the pool + .sessionPoolSize(10, 500) + .build(); + ``` {% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/go.md deleted file mode 100644 index 653b08c1037..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/go.md +++ /dev/null @@ -1,22 +0,0 @@ -```go -package main - -import ( - "context" - - "github.com/ydb-platform/ydb-go-sdk/v3" -) - -func main() { - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithSessionPoolSizeLimit(500), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/java.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/java.md deleted file mode 100644 index 402c5e65ba4..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/session_pool_limit/_includes/java.md +++ /dev/null @@ -1,7 +0,0 @@ -```java -this.tableClient = TableClient.newClient(rpc) - // 10 - minimum number of active sessions to keep in the pool during the cleanup - // 500 - maximum number of sessions in the pool - .sessionPoolSize(10, 500) - .build(); -```
\ No newline at end of file diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/toc_i.yaml b/ydb/docs/ru/core/reference/ydb-sdk/recipes/toc_i.yaml index ac6f587dcf2..0f6618d9910 100644 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/toc_i.yaml +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/toc_i.yaml @@ -1,17 +1,49 @@ items: - name: Обзор href: index.md +- name: Инициализация драйвера + href: init.md - name: Аутентификация - include: { mode: link, path: auth/toc_p.yaml } + items: + - name: Обзор + href: auth.md + - name: С помощью токена + href: auth-access-token.md + - name: Анонимная + href: auth-anonymous.md + - name: Файл сервисного аккаунта + href: auth-service-account.md + - name: Сервис метаданных + href: auth-metadata.md + - name: С помощью переменных окружения + href: auth-env.md + - name: С помощью логина и пароля + href: auth-static.md - name: Балансировка - include: { mode: link, path: balancing/toc_p.yaml } + items: + - name: Обзор + href: balancing.md + - name: Равномерный случайный выбор + href: balancing-random-choice.md + - name: Предпочитать ближайший дата-центр + href: balancing-prefer-local.md + - name: Предпочитать конкретную зону доступности + href: balancing-prefer-location.md - name: Выполнение повторных запросов - href: retry/index.md -- name: Диагностика проблем - include: { mode: link, path: debug/toc_p.yaml } + href: retry.md - name: Установить размер пула сессий - href: session_pool_limit/index.md + href: session-pool-limit.md - name: Вставка данных - href: upsert/index.md + href: upsert.md - name: Пакетная вставка данных - href: bulk_upsert/index.md + href: bulk-upsert.md +- name: Диагностика проблем + items: + - name: Обзор + href: debug.md + - name: Включить логирование + href: debug-logs.md + - name: Подключить метрики в Prometheus + href: debug-prometheus.md + - name: Подключить трассировку в Jaeger + href: debug-jaeger.md diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert.md new file mode 100644 index 00000000000..064ea3540cd --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert.md @@ -0,0 +1,133 @@ +# Вставка данных + +{% include [work in progress message](_includes/addition.md) %} + +Ниже приведены примеры кода использования встроенных в {{ ydb-short-name }} SDK средств выполнения вставки: + +{% list tabs %} + +- Go (native) + + ```go + package main + + import ( + "context" + "os" + + "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/table" + "github.com/ydb-platform/ydb-go-sdk/v3/table/types" + ) + + func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + db, err := ydb.Open(ctx, + os.Getenv("YDB_CONNECTION_STRING"), + ydb.WithAccessTokenCredentials(os.Getenv("YDB_TOKEN")), + ) + if err != nil { + panic(err) + } + defer db.Close(ctx) + // execute upsert with native ydb data + err = db.Table().DoTx( // Do retry operation on errors with best effort + ctx, // context manages exiting from Do + func(ctx context.Context, tx table.TransactionActor) (err error) { // retry operation + res, err = tx.Execute(ctx, ` + PRAGMA TablePathPrefix("/path/to/table"); + DECLARE $seriesID AS Uint64; + DECLARE $seasonID AS Uint64; + DECLARE $episodeID AS Uint64; + DECLARE $views AS Uint64; + UPSERT INTO episodes ( series_id, season_id, episode_id, views ) + VALUES ( $seriesID, $seasonID, $episodeID, $views ); + `, + table.NewQueryParameters( + table.ValueParam("$seriesID", types.Uint64Value(1)), + table.ValueParam("$seasonID", types.Uint64Value(1)), + table.ValueParam("$episodeID", types.Uint64Value(1)), + table.ValueParam("$views", types.Uint64Value(1)), // increment views + ), + ) + if err != nil { + return err + } + if err = res.Err(); err != nil { + return err + } + return res.Close() + }, table.WithIdempotent(), + ) + if err != nil { + fmt.Printf("unexpected error: %v", err) + } + } + ``` + +- Go (database/sql) + + ```go + package main + + import ( + "context" + "database/sql" + "os" + + _ "github.com/ydb-platform/ydb-go-sdk/v3" + "github.com/ydb-platform/ydb-go-sdk/v3/retry" + "github.com/ydb-platform/ydb-go-sdk/v3/types" + ) + + func main() { + db, err := sql.Open("ydb", os.Getenv("YDB_CONNECTION_STRING")) + if err != nil { + panic(err) + } + defer db.Close(ctx) + // execute upsert with native ydb data + err = retry.DoTx(ctx, db, func(ctx context.Context, tx *sql.Tx) error { + if _, err = tx.ExecContext(ctx,` + PRAGMA TablePathPrefix("/local"); + REPLACE INTO series + SELECT + series_id, + title, + series_info, + comment + FROM AS_TABLE($seriesData); + `, + sql.Named("seriesData", types.ListValue( + types.StructValue( + types.StructFieldValue("series_id", types.Uint64Value(1)), + types.StructFieldValue("title", types.TextValue("IT Crowd")), + types.StructFieldValue("series_info", types.TextValue( + "The IT Crowd is a British sitcom produced by Channel 4, written by Graham Linehan, produced by "+ + "Ash Atalla and starring Chris O'Dowd, Richard Ayoade, Katherine Parkinson, and Matt Berry.", + )), + types.StructFieldValue("comment", types.NullValue(types.TypeText)), + ), + types.StructValue( + types.StructFieldValue("series_id", types.Uint64Value(2)), + types.StructFieldValue("title", types.TextValue("Silicon Valley")), + types.StructFieldValue("series_info", types.TextValue( + "Silicon Valley is an American comedy television series created by Mike Judge, John Altschuler and "+ + "Dave Krinsky. The series focuses on five young men who founded a startup company in Silicon Valley.", + )), + types.StructFieldValue("comment", types.TextValue("lorem ipsum")), + ), + )), + ); err != nil { + return err + } + return nil + }, retry.WithDoTxRetryOptions(retry.WithIdempotent(true))) + if err != nil { + fmt.Printf("unexpected error: %v", err) + } + } + ``` + +{% endlist %} diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert/_includes/go.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert/_includes/go.md deleted file mode 100644 index d8c158cb4a1..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert/_includes/go.md +++ /dev/null @@ -1,59 +0,0 @@ -```go -package main - -import ( - "context" - "os" - - "github.com/ydb-platform/ydb-go-sdk/v3" - "github.com/ydb-platform/ydb-go-sdk/v3/table" - "github.com/ydb-platform/ydb-go-sdk/v3/table/types" -) - -func main() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - db, err := ydb.Open(ctx, - os.Getenv("YDB_CONNECTION_STRING"), - ydb.WithAccessTokenCredentials(os.Getenv("YDB_TOKEN")), - ) - if err != nil { - panic(err) - } - defer func() { - _ = db.Close(ctx) - }() - // execute bulk upsert with native ydb data - err = db.Table().DoTx( // Do retry operation on errors with best effort - ctx, // context manages exiting from Do - func(ctx context.Context, tx table.TransactionActor) (err error) { // retry operation - res, err = tx.Execute(ctx, ` - PRAGMA TablePathPrefix("/path/to/table"); - DECLARE $seriesID AS Uint64; - DECLARE $seasonID AS Uint64; - DECLARE $episodeID AS Uint64; - DECLARE $views AS Uint64; - UPSERT INTO episodes ( series_id, season_id, episode_id, views ) - VALUES ( $seriesID, $seasonID, $episodeID, $views ); - `, - table.NewQueryParameters( - table.ValueParam("$seriesID", types.Uint64Value(1)), - table.ValueParam("$seasonID", types.Uint64Value(1)), - table.ValueParam("$episodeID", types.Uint64Value(1)), - table.ValueParam("$views", types.Uint64Value(1)), // increment views - ), - ) - if err != nil { - return err - } - if err = res.Err(); err != nil { - return err - } - return res.Close() - }, - ) - if err != nil { - fmt.Printf("unexpected error: %v", err) - } -} -``` diff --git a/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert/index.md b/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert/index.md deleted file mode 100644 index 225e03dccd9..00000000000 --- a/ydb/docs/ru/core/reference/ydb-sdk/recipes/upsert/index.md +++ /dev/null @@ -1,14 +0,0 @@ -# Вставка данных - -{% include [work in progress message](../_includes/addition.md) %} - -Ниже приведены примеры кода использования встроенных в {{ ydb-short-name }} SDK средств выполнения вставки: - -{% list tabs %} - -- Go - - - {% include [go.md](_includes/go.md) %} - -{% endlist %} |