Быстрый старт с YDB
В этом руководстве вы установите одноузловой локальный кластер YDB и выполните простые запросы к вашей базе данных.
Обычно YDB хранит данные напрямую на нескольких дисковых устройствах SSD/NVMe или HDD без использования файловой системы. Однако для простоты данное руководство эмулирует диски в оперативной памяти или с использованием файла в обычной файловой системе. Таким образом, эта конфигурация не подходит для использования в промышленном окружении и даже для проведения тестов производительности. Ознакомьтесь с документацией для DevOps-инженеров для запуска YDB в production окружении.
Установите и запустите YDB
Примечание
Рекомендуемая среда для запуска YDB - это x86_64 Linux. Если у вас нет доступа к такой системе, можете переключиться на инструкции во вкладке "Docker".
-
Создайте каталог для тестирования YDB и используйте его в качестве текущего рабочего каталога:
mkdir ~/ydbd && cd ~/ydbd
-
Загрузите и запустите скрипт установки:
curl https://install.ydb.tech | bash
Это действие загрузит и распакует архив с исполняемым файлом
ydbd
, библиотеками, файлами конфигурации и скриптами, необходимыми для запуска и остановки локального кластера.Скрипт выполняется с текущими привилегиями пользователя (обратите внимание на отсутствие
sudo
). Таким образом, он не может сделать многого в системе. Чтобы проверить какие именно команды он выполняет — откройте этот же URL в вашем браузере. -
Запустите кластер в одном из следующих режимов хранения данных:
-
Данные в оперативной памяти:
./start.sh ram
В этом случае все данные хранятся только в оперативной памяти, и они будут потеряны при остановке кластера.
-
Данные в файле на диске:
./start.sh disk
При первом запуске скрипта будет создан файл
ydb.data
размером 80 ГБ в рабочем каталоге. Убедитесь, что у вас достаточно свободного места на диске для его создания. Этот файл будет использоваться для эмуляции дискового устройства, которое использовалось бы в промышленном окружении. -
Данные на дисковом устройстве:
./start.sh drive "/dev/$DRIVE_NAME"
Замените
/dev/$DRIVE_NAME
на настоящее имя устройства, которое не используется для других целей, например/dev/sdb
. В первый раз при запуске этой команды указанный дисковый накопитель будет полностью очищен, а затем будет подключен для хранения данных YDB. Рекомендуется использовать NVMe или SSD-диск с объемом не менее 800 Гб. Такая конфигурация может быть использована для тестирования производительности на одном узле или других сред, которые не имеют каких-либо требований к отказоустойчивости.
Результат:
Starting storage process... Initializing storage ... Registering database ... Starting database process... Database started. Connection options for YDB CLI: -e grpc://localhost:2136 -d /Root/test
-
-
Создайте каталог для тестирования YDB и используйте его в качестве текущего рабочего каталога:
mkdir ~/ydbd && cd ~/ydbd mkdir ydb_data mkdir ydb_certs
-
Запустите Docker контейнер:
docker run -d --rm --name ydb-local -h localhost \ --platform linux/amd64 \ -p 2135:2135 -p 2136:2136 -p 8765:8765 \ -v $(pwd)/ydb_certs:/ydb_certs -v $(pwd)/ydb_data:/ydb_data \ -e GRPC_TLS_PORT=2135 -e GRPC_PORT=2136 -e MON_PORT=8765 \ -e YDB_USE_IN_MEMORY_PDISKS=true \ cr.yandex/yc/yandex-docker-local-ydb:latest
Если контейнер успешно запустился, вы увидите его идентификатор. Контейнеру может потребоваться несколько минут для инициализации. База данных будет недоступна до окончания инициализации.
Настройка
YDB_USE_IN_MEMORY_PDISKS
делает все данные волатильными, хранящимися только в оперативной памяти. В настоящее время сохранение данных путем её отключения поддерживается только на x86_64 процессорах.
-
Установите интерфейс командной строки Kubernetes kubectl и менеджер пакетов Helm 3.
-
Установите и запустите Minikube.
-
Склонируйте репозиторий с YDB Kubernetes Operator:
git clone https://github.com/ydb-platform/ydb-kubernetes-operator && cd ydb-kubernetes-operator
-
Установите на кластер контроллер YDB:
helm upgrade --install ydb-operator deploy/ydb-operator --set metrics.enabled=false
-
Примените манифест для создания кластера YDB:
kubectl apply -f samples/minikube/storage.yaml
-
Подождите, пока
kubectl get storages.ydb.tech
станетReady
. -
Примените манифест для создания базы данных:
kubectl apply -f samples/minikube/database.yaml
-
Подождите, пока
kubectl get databases.ydb.tech
станетReady
. -
После обработки манифеста создаётся объект StatefulSet, описывающий набор динамических узлов. Созданная база данных будет доступна изнутри кластера Kubernetes по DNS-имени
database-minikube-sample
на портах 2135 и 8765. -
Получите доступ к порту 8765 снаружи Kubernetes через
kubectl port-forward database-minikube-sample-0 8765
для продолжения.
-
Установите интерфейс командной строки Kubernetes kubectl и менеджер пакетов Helm 3.
-
Установите Kind.
-
Склонируйте репозиторий с YDB Kubernetes Operator:
git clone https://github.com/ydb-platform/ydb-kubernetes-operator && cd ydb-kubernetes-operator
-
Создайте Kind кластер и дождитесь его готовности:
kind create cluster --config=samples/kind/kind-config.yaml --wait 5m
-
Установите на кластер контроллер YDB:
helm upgrade --install ydb-operator deploy/ydb-operator --set metrics.enabled=false
-
Примените манифест для создания хранилища данных YDB:
kubectl apply -f samples/kind/storage.yaml
-
Подождите, пока
kubectl get storages.ydb.tech
станетReady
. -
Примените манифест для создания базы данных:
kubectl apply -f samples/kind/database.yaml
-
Подождите, пока
kubectl get databases.ydb.tech
станетReady
. -
После обработки манифеста создаётся объект StatefulSet, описывающий набор динамических узлов. Созданная база данных будет доступна изнутри кластера Kubernetes по DNS-имени
database-kind-sample
на портах 2135 и 8765. -
Получите доступ к порту 8765 снаружи Kubernetes через
kubectl port-forward database-kind-sample-0 8765
для продолжения.
Запустите первый запрос "Hello, world!"
Самый простой способ выполнить свой первый запрос к YDB - это встроенный веб-интерфейс. Он запускается по умолчанию на порту 8765 сервера YDB, поэтому, если вы запустили его локально, вам нужно открыть localhost:8765 в вашем веб-браузере. Если нет, замените localhost
на имя хоста вашего сервера в этом URL, либо используйте ssh -L 8765:localhost:8765 my-server-hostname-or-ip.example.com
для настройки проброса порта и все равно откройте localhost:8765. Вы увидите страницу подобного вида:
YDB спроектирован как многопользовательская система с возможностью одновременной работы тысяч пользователей с одним кластером. Как следствие, большинство логических сущностей внутри кластера YDB находятся в гибкой иерархической структуре, больше похожей на виртуальную файловую систему Unix, чем на схему с фиксированной глубиной, с которой вы, возможно, знакомы из других систем управления базами данных. Как видите, первый уровень иерархии состоит из баз данных, работающих в одном процессе YDB, которые могут принадлежать разным пользователям. /Root
предназначена для системных целей, а /Root/test
или /local
(имя зависит от выбранного способа установки) - это «игровая площадка», созданная в процессе установки на предыдущем шаге. Давайте нажмём на последнюю, /Root/test
или /local
, затем введем наш первый запрос и нажмем кнопку запуска:
SELECT "Hello, world!"u;
Запрос возвращает приветствие, как и задумано:
Примечание
Заметили странный суффикс u
? YDB и её язык запросов YQL являются строго типизированными. Обычные строки в YDB могут содержать любые двоичные данные, в то время как этот суффикс указывает, что этот литерал имеет тип данных Utf8
, который может содержать только валидные последовательности UTF-8. Узнайте больше о системе типов YDB.
Второй по простоте способ выполнения SQL-запроса с использованием YDB - это интерфейс командной строки (CLI). Большинство реальных приложений же, скорее всего, будут работать с YDB через один из доступных наборов инструментов для разработчиков программного обеспечения (SDK). Если вы чувствуете себя уверенно — можете продолжить прохождение данного руководства с помощью одного из этих методов вместо веб-интерфейса.
Создайте свою первую таблицу
Основная цель существования систем управления базами данных - сохранение данных для последующего извлечения. Как система, базирующаяся на SQL, основной абстракцией YDB для хранения данных является таблица. Чтобы создать нашу первую таблицу, выполните следующий запрос:
CREATE TABLE example
(
key UInt64,
value String,
PRIMARY KEY (key)
);
Как видите, это простая таблица ключ-значение. Давайте пройдемся по ней пошагово:
- Каждый тип оператора SQL вроде
CREATE TABLE
имеет подробное описание в справке по YQL. example
- это идентификатор имени таблицы, аkey
иvalue
- идентификаторы имен столбцов. Рекомендуется использовать простые имена для таких идентификаторов, но если вам нужно использовать имя с необычными символами, оберните его в обратные кавычки.UInt64
иString
- это названия типов данных.String
представляет собой двоичную строку, аUInt64
- 64-разрядное беззнаковое целое число. Таким образом, наша таблица-пример хранит строковые значения, идентифицируемые беззнаковыми целочисленными ключами. Подробнее о типах данных.PRIMARY KEY
- одно из основных понятий SQL, которое оказывает огромное влияние на логику приложения и производительность. В соответствии со стандартом SQL, первичный ключ также подразумевает ограничение уникальности, поэтому таблица не может иметь несколько строк с одинаковыми первичными ключами. В этой примерной таблице довольно просто определить, какой столбец пользователь должен выбрать в качестве первичного ключа, и мы указываем его как(key)
в круглых скобках после соответствующего ключевого слова. В реальных сценариях таблицы часто содержат десятки столбцов, и первичные ключи могут быть составными (состоять из нескольких столбцов в указанном порядке), поэтому выбор правильного первичного ключа становится больше похожим на искусство. Если вас интересует эта тема, есть руководство по выбору первичного ключа для максимизации производительности. YDB таблицы обязаны иметь первичный ключ.
Добавление тестовых данных
Теперь давайте заполним нашу таблицу первыми данными. Самый простой способ - использовать литералы:
INSERT INTO example (key, value)
VALUES (123, "hello"),
(321, "world");
Пошаговое описание:
INSERT INTO
- это классический оператор SQL для добавления новых строк в таблицу. Однако он не является наиболее производительным, так как согласно стандарту SQL он должен проверить, существуют ли в таблице строки с заданными значениями первичного ключа, и выдать ошибку, если они уже есть. Таким образом, если вы запустите этот запрос несколько раз, все попытки, кроме первой, вернут ошибку. Если логика вашего приложения не требует такого поведения, лучше использоватьUPSERT INTO
вместоINSERT INTO
. Upsert (от "update or insert") будет безусловно записывать предоставленные значения, перезаписывая существующие строки, если они есть. Остальной синтаксис будет таким же.(key, value)
указывает имена столбцов, которые мы вставляем, и их порядок. Предоставленные значения должны соответствовать этому описанию как по количеству столбцов, так и по их типам данных.- После ключевого слова
VALUES
следует список кортежей, каждый из которых представляет собой строку таблицы. В этом примере у нас есть две строки, идентифицируемые числами 123 и 321 в столбцеkey
, и значениями "hello" и "world" в столбцеvalue
соответственно.
Чтобы убедиться, что строки были действительно добавлены в таблицу, существует распространённый запрос, который в данном случае должен вернуть 2
:
SELECT COUNT(*) FROM example;
Несколько деталей в этом запросе:
- Во
FROM
указывают таблицу, из которой извлекаются данные. COUNT
- это агрегатная функция, подсчитывающая количество значений. По умолчанию, когда нет других специальных выражений вокруг, наличие любой агрегатной функции приводит к сворачиванию результата в одну строку, содержащую агрегаты по всему входным данным (таблицеexample
в данном случае).- Астериск
*
является спецсимволом, который обычно означает "все столбцы"; таким образом,COUNT
вернет общее количество число строк.
Еще один распространённый способ заполнить таблицу данными - это объединить операции INSERT INTO
(или UPSERT INTO
) и SELECT
. В этом случае значения для сохранения вычисляются внутри базы данных, а не предоставляются клиентом в виде литералов. Для демонстрации этого подхода мы используем немного более реалистичный запрос:
$subquery = SELECT ListFromRange(1000, 10000) AS keys;
UPSERT INTO example
SELECT
key,
CAST(RandomUuid(key) AS String) AS value
FROM $subquery
FLATTEN LIST BY keys AS key
В этом запросе происходит немало интересного, давайте рассмотрим его подробнее:
-
$subquery
- это именованное выражение. Этот синтаксис является расширением YQL по сравнению со стандартным SQL и позволяет делать более читаемые сложные запросы. Он работает так же, как если бы вы написали первыйSELECT
по месту, где$subquery
используется в последней строке. Однако, использование именованных выражений позволяет легче понять, что происходит шаг за шагом, подобно переменным в обычных языках программирования. -
ListFromRange
- это функция, которая создает список последовательных целых чисел, начиная с значения, указанного в первом аргументе, и заканчивая значением, указанным во втором аргументе. Также есть третий необязательный аргумент, который позволяет пропускать числа с указанным шагом, но мы не используем его в нашем примере — по умолчанию возвращаются все целые числа в указанном диапазоне.List
является одним из наиболее распространенных контейнерных типов данных. -
AS
- это ключевое слово, используемое для задания имени значения, которое мы возвращаем изSELECT
; в данном примере -keys
. -
В части
FROM ... FLATTEN LIST BY ... AS ...
есть несколько значимых моментов:- Другой
SELECT
, использованный в выраженииFROM
, называется подзапросом. Поэтому мы выбрали это имя для нашего именованного выражения$subquery
, но мы могли бы выбрать что-то более значимое, чтобы объяснить, что это такое. Подзапросы обычно не материализуются; они просто передают вывод одногоSELECT
вводу другого на лету. Они могут использоваться в качестве средства для создания произвольно сложных графов выполнения, особенно в сочетании с другими возможностями YQL. - Ключевая фраза
FLATTEN LIST BY
изменяет входные данные, передаваемые черезFROM
, следующим образом: для каждой строки во входных данных она берет столбец типа данныхList
и создает несколько строк в соответствии с количеством элементов в этом списке. Обычно этот столбец списка заменяется столбцом с текущим одиночным элементом, но ключевое словоAS
в данном контексте позволяет получить доступ и ко всему списку (по исходному имени) и текущему элементу (по имени послеAS
).
- Другой
-
RandomUuid
- это функция, которая возвращает псевдослучайный UUID версии 4. В отличие от большинства других функций, она не использует значение своего аргумента (столбецkey
); вместо этого этот аргумент указывает на то, что нам нужно вызывать функцию для каждой строки. Смотрите ссылку с дополнительными примерами работы этой функции. -
CAST(... AS ...)
- это часто используемая функция для преобразования значений в указанный тип данных. В этом контексте послеAS
ожидается указание типа данных (в данном случаеString
), а не произвольного имени. -
UPSERT INTO
слепо записывает значения в указанные таблицы, как мы обсуждали ранее. При использовании в сочетании сSELECT
он не требует явного указания имен столбцов(key, value)
, так как столбцы теперь могут быть просто сопоставлены по именам, возвращённым изSELECT
.
Короткий вопрос!
Что теперь вернёт запрос SELECT COUNT(*) FROM example;
?
Остановка кластера
Остановите локальный кластер YDB после завершения экспериментов:
Чтобы остановить локальный кластер, выполните следующую команду:
~/ydbd/stop.sh
При желании вы можете удалить вашу рабочую директорию с помощью команды rm -rf ~/ydbd
для очистки файловой системы. Все данные внутри локального кластера YDB будут потеряны.
Чтобы остановить Docker контейнер с локальным кластером, выполните следующую команду:
docker kill ydb-local
При желании вы можете удалить вашу рабочую директорию с помощью команды rm -rf ~/ydbd
для очистки файловой системы. Все данные внутри локального кластера YDB будут потеряны.
Чтобы удалить базу данных YDB, достаточно удалить сопоставленный с ней ресурс Database:
kubectl delete database.ydb.tech database-minikube-sample
Чтобы удалить кластерYDB, выполните следующие команды (все данные будут потеряны):
kubectl delete storage.ydb.tech storage-minikube-sample
Чтобы удалить контроллер YDB из кластера Kubernetes, удалите релиз, созданный Helm:
helm delete ydb-operator
Чтобы удалить базу данных YDB, достаточно удалить сопоставленный с ней ресурс Database:
kubectl delete database.ydb.tech database-kind-sample
Чтобы удалить кластер YDB, выполните следующие команды (все данные будут потеряны):
kubectl delete storage.ydb.tech storage-kind-sample
Чтобы удалить контроллер YDB из кластера Kubernetes, удалите релиз, созданный Helm:
helm delete ydb-operator
Чтобы удалить кластер Kind целиком, выполните следующую команду:
kind delete cluster
Готово! Что дальше?
После освоения базовых операций из этого руководства, пора переходить перейти к более глубоким темам. Выберите то, что кажется наиболее актуальным в зависимости от вашего сценария использования и роли:
- Пройдите более подробный курс по YQL, который сосредоточен на написании запросов.
- Попробуйте создать свое первое приложение для хранения данных в YDB с использованием одного из SDK.
- Узнайте, как настроить развертывание YDB в готовую к промышленной эксплуатации среду.
- Почитайте об используемых в YDB концепциях.