aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkruall <kruall@yandex-team.ru>2022-02-16 16:03:12 +0300
committerkruall <kruall@yandex-team.ru>2022-02-16 16:03:12 +0300
commitebd2f9f01e92438dc623385dddf267d104cf2984 (patch)
treea18708356fe8db0c1de6bd26b7faf5d7adddf2f9
parentb95ffa12c2d7a36459f4317bd68e9b77451c5993 (diff)
downloadydb-ebd2f9f01e92438dc623385dddf267d104cf2984.tar.gz
Split concept/distributed_storage.md, KIKIMR-13082
ref:65cd40b8781ff5e99c13b9aec880e336ce97435b
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_assets/BS_overview.svg (renamed from ydb/docs/ru/core/concepts/_assets/BS_overview.svg)0
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_assets/Slide3_group_layout.svg (renamed from ydb/docs/ru/core/concepts/_assets/Slide3_group_layout.svg)0
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_assets/Slide_blob.svg (renamed from ydb/docs/ru/core/concepts/_assets/Slide_blob.svg)0
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_assets/Slide_group_content.svg (renamed from ydb/docs/ru/core/concepts/_assets/Slide_group_content.svg)0
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/intro.md5
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/nodes.md11
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/tablets.md38
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/detailed_distributed_storage.md (renamed from ydb/docs/ru/core/concepts/_includes/distributed_storage/detailed_distributed_storage.md)1
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/distributed_storage_interface.md (renamed from ydb/docs/ru/core/concepts/_includes/distributed_storage/common_scheme_ydb.md)63
-rw-r--r--ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/intro.md (renamed from ydb/docs/ru/core/concepts/_includes/distributed_storage/intro.md)2
-rw-r--r--ydb/docs/ru/core/concepts/cluster/common_scheme_ydb.md5
-rw-r--r--ydb/docs/ru/core/concepts/cluster/distributed_storage.md (renamed from ydb/docs/ru/core/concepts/distributed_storage.md)2
-rw-r--r--ydb/docs/ru/core/concepts/cluster/index.md7
-rw-r--r--ydb/docs/ru/core/concepts/toc_i.yaml10
14 files changed, 84 insertions, 60 deletions
diff --git a/ydb/docs/ru/core/concepts/_assets/BS_overview.svg b/ydb/docs/ru/core/concepts/cluster/_assets/BS_overview.svg
index eb08e1cb2e..eb08e1cb2e 100644
--- a/ydb/docs/ru/core/concepts/_assets/BS_overview.svg
+++ b/ydb/docs/ru/core/concepts/cluster/_assets/BS_overview.svg
diff --git a/ydb/docs/ru/core/concepts/_assets/Slide3_group_layout.svg b/ydb/docs/ru/core/concepts/cluster/_assets/Slide3_group_layout.svg
index 3d6bf588a8..3d6bf588a8 100644
--- a/ydb/docs/ru/core/concepts/_assets/Slide3_group_layout.svg
+++ b/ydb/docs/ru/core/concepts/cluster/_assets/Slide3_group_layout.svg
diff --git a/ydb/docs/ru/core/concepts/_assets/Slide_blob.svg b/ydb/docs/ru/core/concepts/cluster/_assets/Slide_blob.svg
index b0ff8b6a77..b0ff8b6a77 100644
--- a/ydb/docs/ru/core/concepts/_assets/Slide_blob.svg
+++ b/ydb/docs/ru/core/concepts/cluster/_assets/Slide_blob.svg
diff --git a/ydb/docs/ru/core/concepts/_assets/Slide_group_content.svg b/ydb/docs/ru/core/concepts/cluster/_assets/Slide_group_content.svg
index 5e5796fae0..5e5796fae0 100644
--- a/ydb/docs/ru/core/concepts/_assets/Slide_group_content.svg
+++ b/ydb/docs/ru/core/concepts/cluster/_assets/Slide_group_content.svg
diff --git a/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/intro.md b/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/intro.md
new file mode 100644
index 0000000000..b941184345
--- /dev/null
+++ b/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/intro.md
@@ -0,0 +1,5 @@
+# Общая схема YDB
+
+Примерная общая схема YDB показана ниже.
+
+![Общая схема](../../_assets/BS_overview.svg)
diff --git a/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/nodes.md b/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/nodes.md
new file mode 100644
index 0000000000..64fa37d335
--- /dev/null
+++ b/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/nodes.md
@@ -0,0 +1,11 @@
+## Узлы
+
+Одна инсталляция YDB состоит из *кластера*, который разбит на *узлы*. Узел -- это один процесс в системе, как правило kikimr. Это узел входит в кластер и может обмениваться данными с другими узлами в этом кластере через *Interconnect*. Каждый *узел* имеет свой идентификатор, который обычно называется NodeId. NodeId -- целое число от 1, состоит из 20 бит. NodeId 0 зарезервирован для внутренних нужд и как правило обозначает текущий узел, либо отсутствие узла.
+
+На каждом узле выполняется ряд сервисов, реализованных через *акторы*.
+
+Узлы могут быть статическими и динамическими.
+
+Конфигурация статических узлов, то есть их полный перечень с указанием адреса для подключения по Interconnect, хранится в конфигурационном файле и вычитывается единожды при запуске процесса. Набор статических узлов меняется очень редко. Как правило, это происходит при расширении кластеров или при переезде узлов с одних физических машин на другие. Для того, чтобы изменить набор статических узлов, нужно разложить на **всех** узлах обновлённую конфигурацию, после чего выполнить rolling restart всего кластера.
+
+Динамические узлы заранее неизвестны и добавляются в систему по мере запуска новых процессов. Это может быть связано, например, с созданием новых тенантов в инсталляциях YDB как БД. При регистрации динамического узла его процесс сначала подключается к одному из статических узлов через gRPC и через специальный сервис, который называется Node Broker, передаёт информацию о себе, получая в ответ NodeId, под которым ему можно будет войти в систему. Механизм назначения узлов во многом похож на DHCP в контексте раздачи IP-адресов.
diff --git a/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/tablets.md b/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/tablets.md
new file mode 100644
index 0000000000..4de586d864
--- /dev/null
+++ b/ydb/docs/ru/core/concepts/cluster/_includes/common_scheme_ydb/tablets.md
@@ -0,0 +1,38 @@
+
+## Таблетки
+
+На каждом узле выполняются специальные микросервисы, которые называются *таблетками*. Каждая таблетка имеет определённый тип и идентификатор и является singleton'ом, что означает, что в каждый момент времени во всём кластере может работать только одна таблетка с конкретным идентификатором. Таблетка может запускаться на любом из подходящих для неё узлов. Важной характеристикой таблетки является её поколение -- *Generation* -- которое увеличивается при каждом следующем запуске. Стоит отметить, что в силу распределённости системы и наличии различного рода проблем, например, сетевого партиционирования, может сложиться ситуация, когда одна и та же таблетка будет фактически выполняться на двух разных узлах одновременно. Но BlobStorage гарантирует, что только одна из них сможет успешно завершить операции, изменяющие её состояние, и при этом поколение, в котором выполнена каждая успешная операция, не будет убывать со временем.
+
+Узнать, на каком узле выполняется таблетка в актуальном поколении, можно через сервис *StateStorage*. Для отправки сообщений в таблетку существует специальный набор библиотек, который называется *tablet pipe*. При помощи него, зная идентификатор целевой таблетки, можно легко послать ей нужное сообщение.
+
+Таблетку можно условно разделить на две части: базовая таблетка и пользовательская логика.
+
+Базовая таблетка представляет собой набор таблиц, каждая из которых может состоять из одной или нескольких колонок ключа произвольного типа, а также произвольного набора колонок данных. Каждая таблица может иметь свою схему, кроме того, таблицы можно создавать и удалять в ходе работы таблетки. Интерфейс базовой таблетки позволяет выполнять операции чтения и изменения этих таблиц.
+
+Пользовательская логика находится между базовой таблеткой и пользователем и позволяет обрабатывать специфические запросы для данного типа таблеток, надёжно сохраняя изменения в BlobStorage. Часто используемый шаблон работы таблетки -- хранение всех данных в памяти, вычитка их только на старте и синхронное изменение данных в памяти и в хранилище после успешного коммита.
+
+### Как таблетка хранит данные и какие они?
+
+Базовая таблетка представляет собой LSM-дерево, в котором находятся все данные её таблиц. Уровнем ниже базовой таблетки находится BlobStorage, который, грубо говоря, является KeyValue-хранилищем, в котором лежат блобы. *Блоб* -- это бинарный фрагмент размером от 1 байта до 10 мегабайт, который имеет идентификатор фиксированной структуры (обычно он называется *BlobId* и имеет тип TLogoBlobID) и связанные с ним данные. Хранилище иммутабельное, то есть каждому идентификатору соответствует только одно значение, которое не может меняться со временем. Блоб можно записать, прочитать и затем удалить, когда он станет не нужен.
+
+Подробнее о блобах и распределенном хранилище можно прочитать [здесь](../../distributed_storage.md).
+
+Для BlobStorage блобы являются непрозрачной сущностью. Таблетка может хранить несколько типов блобов. Наиболее часто записываемый блоб -- блоб лога (имеется в виду recovery log, журнал восстановления). Лог таблетки устроен в списка блобов, в каждом из которых содержится информация о вносимом изменении в таблицы. При запуске таблетка находит последний блоб лога, и затем рекурсивно по ссылкам вычитывает все связанные с ним блобы. В логе могут также упоминаться блобы снимков (snapshot) -- это разновидность блобов, которые содержат данные нескольких блобов лога после слияния (операция merge в LSM-дереве).
+
+Блобы разных типов таблетка пишет в разные *каналы*. Канал указывает ветвь хранилища, в которой следует хранить блобы, и выполняет несколько функций, а именно:
+1. Выбор типа хранилища (разные каналы могут быть привязаны к разным типам устройств -- SSD, HDD, NVME).
+2. Балансировка нагрузки, т.к. каждый канал имеет лимит от IOPS, доступному месту и пропускной способности.
+3. Указание типа данных. При восстановлении лога читаются только блобы из нулевого канала, что позволяет отделить их от прочих блобов.
+
+
+### История каналов в таблетке
+
+Как уже говорилось, каждая группа имеет фиксированный объём данных, которые в неё могут помещаться, а также делит полосу по пропускной способности и числу операций в секунду между всеми потребителями. Нагрузка на таблетки может меняться, в результате может сложиться так, что группа станет перегруженной. Для этого вводится понятие истории, которое позволяет для каждой таблетки, зная Channel и Generation блоба, определить, в какую группу записан данный блоб.
+
+Иллюстрация работы этого механизма ниже:
+
+![История каналов](../../_assets/Slide_blob.svg)
+
+Для каждого канала в структуре TTabletStorageInfo содержится подструктура TTabletChannelInfo, которая содержит диапазоны поколений и номер группы, соответствующий каждому диапазону. Диапазоны строго примыкают друг к другу, последний диапазон открыт. Номера групп могут пересекаться в разных диапазонах и даже между разными каналами -- это не запрещено и достаточно часто встречается.
+
+При выполнении записи блоба таблетка выбирает самый последний диапазон для соответствующего канала, т.к. запись всегда идёт от имени текущего поколения таблетки. При выполнении чтения номер группы извлекается исходя из BlobId.Generation читаемого блоба.
diff --git a/ydb/docs/ru/core/concepts/_includes/distributed_storage/detailed_distributed_storage.md b/ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/detailed_distributed_storage.md
index 5e3787feef..c344ecc47a 100644
--- a/ydb/docs/ru/core/concepts/_includes/distributed_storage/detailed_distributed_storage.md
+++ b/ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/detailed_distributed_storage.md
@@ -26,7 +26,6 @@
## BS_CONTROLLER
-
### Связь с NodeWarden
### Box и Storage Pool
diff --git a/ydb/docs/ru/core/concepts/_includes/distributed_storage/common_scheme_ydb.md b/ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/distributed_storage_interface.md
index 52e367fd79..839976066f 100644
--- a/ydb/docs/ru/core/concepts/_includes/distributed_storage/common_scheme_ydb.md
+++ b/ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/distributed_storage_interface.md
@@ -1,45 +1,6 @@
-## Общая схема YDB
+## Описание интерфейса BlobStorage
-Примерная общая схема YDB показана ниже.
-
-![Общая схема](../../_assets/BS_overview.svg)
-
-### Узлы
-
-Одна инсталляция YDB состоит из *кластера*, который разбит на *узлы*. Узел -- это один процесс в системе, как правило kikimr. Это узел входит в кластер и может обмениваться данными с другими узлами в этом кластере через *Interconnect*. Каждый *узел* имеет свой идентификатор, который обычно называется NodeId. NodeId -- целое число от 1, состоит из 20 бит. NodeId 0 зарезервирован для внутренних нужд и как правило обозначает текущий узел, либо отсутствие узла.
-
-На каждом узле выполняется ряд сервисов, реализованных через *акторы*.
-
-Узлы могут быть статическими и динамическими.
-
-Конфигурация статических узлов, то есть их полный перечень с указанием адреса для подключения по Interconnect, хранится в конфигурационном файле и вычитывается единожды при запуске процесса. Набор статических узлов меняется очень редко. Как правило, это происходит при расширении кластеров или при переезде узлов с одних физических машин на другие. Для того, чтобы изменить набор статических узлов, нужно разложить на **всех** узлах обновлённую конфигурацию, после чего выполнить rolling restart всего кластера.
-
-Динамические узлы заранее неизвестны и добавляются в систему по мере запуска новых процессов. Это может быть связано, например, с созданием новых тенантов в инсталляциях YDB как БД. При регистрации динамического узла его процесс сначала подключается к одному из статических узлов через gRPC и через специальный сервис, который называется Node Broker, передаёт информацию о себе, получая в ответ NodeId, под которым ему можно будет войти в систему. Механизм назначения узлов во многом похож на DHCP в контексте раздачи IP-адресов.
-
-### Таблетки
-
-На каждом узле выполняются специальные микросервисы, которые называются *таблетками*. Каждая таблетка имеет определённый тип и идентификатор и является singleton'ом, что означает, что в каждый момент времени во всём кластере может работать только одна таблетка с конкретным идентификатором. Таблетка может запускаться на любом из подходящих для неё узлов. Важной характеристикой таблетки является её поколение -- *Generation* -- которое увеличивается при каждом следующем запуске. Стоит отметить, что в силу распределённости системы и наличии различного рода проблем, например, сетевого партиционирования, может сложиться ситуация, когда одна и та же таблетка будет фактически выполняться на двух разных узлах одновременно. Но BlobStorage гарантирует, что только одна из них сможет успешно завершить операции, изменяющие её состояние, и при этом поколение, в котором выполнена каждая успешная операция, не будет убывать со временем.
-
-Узнать, на каком узле выполняется таблетка в актуальном поколении, можно через сервис *StateStorage*. Для отправки сообщений в таблетку существует специальный набор библиотек, который называется *tablet pipe*. При помощи него, зная идентификатор целевой таблетки, можно легко послать ей нужное сообщение.
-
-Таблетку можно условно разделить на две части: базовая таблетка и пользовательская логика.
-
-Базовая таблетка представляет собой набор таблиц, каждая из которых может состоять из одной или нескольких колонок ключа произвольного типа, а также произвольного набора колонок данных. Каждая таблица может иметь свою схему, кроме того, таблицы можно создавать и удалять в ходе работы таблетки. Интерфейс базовой таблетки позволяет выполнять операции чтения и изменения этих таблиц.
-
-Пользовательская логика находится между базовой таблеткой и пользователем и позволяет обрабатывать специфические запросы для данного типа таблеток, надёжно сохраняя изменения в BlobStorage. Часто используемый шаблон работы таблетки -- хранение всех данных в памяти, вычитка их только на старте и синхронное изменение данных в памяти и в хранилище после успешного коммита.
-
-#### Как таблетка хранит данные и какие они?
-
-Базовая таблетка представляет собой LSM-дерево, в котором находятся все данные её таблиц. Уровнем ниже базовой таблетки находится BlobStorage, который, грубо говоря, является KeyValue-хранилищем, в котором лежат блобы. *Блоб* -- это бинарный фрагмент размером от 1 байта до 10 мегабайт, который имеет идентификатор фиксированной структуры (обычно он называется *BlobId* и имеет тип TLogoBlobID) и связанные с ним данные. Хранилище иммутабельное, то есть каждому идентификатору соответствует только одно значение, которое не может меняться со временем. Блоб можно записать, прочитать и затем удалить, когда он станет не нужен.
-
-Для BlobStorage блобы являются непрозрачной сущностью. Таблетка может хранить несколько типов блобов. Наиболее часто записываемый блоб -- блоб лога (имеется в виду recovery log, журнал восстановления). Лог таблетки устроен в списка блобов, в каждом из которых содержится информация о вносимом изменении в таблицы. При запуске таблетка находит последний блоб лога, и затем рекурсивно по ссылкам вычитывает все связанные с ним блобы. В логе могут также упоминаться блобы снимков (snapshot) -- это разновидность блобов, которые содержат данные нескольких блобов лога после слияния (операция merge в LSM-дереве).
-
-Блобы разных типов таблетка пишет в разные *каналы*. Канал указывает ветвь хранилища, в которой следует хранить блобы, и выполняет несколько функций, а именно:
-1. Выбор типа хранилища (разные каналы могут быть привязаны к разным типам устройств -- SSD, HDD, NVME).
-2. Балансировка нагрузки, т.к. каждый канал имеет лимит от IOPS, доступному месту и пропускной способности.
-3. Указание типа данных. При восстановлении лога читаются только блобы из нулевого канала, что позволяет отделить их от прочих блобов.
-
-#### Формат идентификатора блоба
+### Формат идентификатора блоба
Каждый блоб имеет 192-битный идентификатор, состоящий из следующих полей (в порядке, используемом для сортировки):
@@ -60,7 +21,7 @@
При чтении указывается идентификатор блоба, который может быть произвольным, но желательно ранее записанным.
-#### Группы
+### Группы
Запись блобов производится в логическую сущность, называемую *группой*. На каждом узле для каждой группы, в которую осуществляется запись, создаётся специальный актор, который называется DS proxy. Этот актор отвечает за выполнение всех операций, связанных с группой. Создание этого актора производится автоматически через сервис NodeWarden, о котором речь пойдёт ниже.
@@ -90,7 +51,7 @@
Как правило, группы двух соседних поколений различаются не более, чем на один слот.
-#### Подгруппы
+### Подгруппы
Для каждого блоба вводится специальное понятие *подгруппы* -- это упорядоченное подмножество дисков группы, которое имеет строго фиксированное число элементов, зависящее от типа кодирования (в группе число элементов должно быть не меньше), на котором будут храниться данные этого блоба. Для однодатацентровых групп с обычным кодированием подмножество выбирается как первые N элементов циклической перестановки дисков в группе; перестановка зависит от хэша BlobId.
@@ -112,18 +73,6 @@
На практике при выполнении записи система пытается положить 6 фрагментов на первые 6 дисков подгруппы и в подавляющем большинстве случаев это проходит успешно. Однако если один из этих дисков недоступен, то операция записи не может завершиться успешно, тогда в работу вступают handoff-диски -- на них отправляются парты тех дисков, которые не ответили вовремя. Может случиться так, что в результате хитрых тормозов и гонок на один handoff уйдёт несколько фрагментов одного блоба. Это допустимо, хотя с точки зрения хранения бессмысленно -- каждый фрагмент должен иметь свой уникальный диск.
-#### История каналов в таблетке
-
-Как уже говорилось, каждая группа имеет фиксированный объём данных, которые в неё могут помещаться, а также делит полосу по пропускной способности и числу операций в секунду между всеми потребителями. Нагрузка на таблетки может меняться, в результате может сложиться так, что группа станет перегруженной. Для этого вводится понятие истории, которое позволяет для каждой таблетки, зная Channel и Generation блоба, определить, в какую группу записан данный блоб.
-
-Иллюстрация работы этого механизма ниже:
-
-![История каналов](../../_assets/Slide_blob.svg)
-
-Для каждого канала в структуре TTabletStorageInfo содержится подструктура TTabletChannelInfo, которая содержит диапазоны поколений и номер группы, соответствующий каждому диапазону. Диапазоны строго примыкают друг к другу, последний диапазон открыт. Номера групп могут пересекаться в разных диапазонах и даже между разными каналами -- это не запрещено и достаточно часто встречается.
-
-При выполнении записи блоба таблетка выбирает самый последний диапазон для соответствующего канала, т.к. запись всегда идёт от имени текущего поколения таблетки. При выполнении чтения номер группы извлекается исходя из BlobId.Generation читаемого блоба.
-
-#### Сборка мусора
+### Сборка мусора
-#### Блокировки таблеток \ No newline at end of file
+### Блокировки таблеток
diff --git a/ydb/docs/ru/core/concepts/_includes/distributed_storage/intro.md b/ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/intro.md
index 9827c89335..0889736365 100644
--- a/ydb/docs/ru/core/concepts/_includes/distributed_storage/intro.md
+++ b/ydb/docs/ru/core/concepts/cluster/_includes/distributed_storage/intro.md
@@ -1,3 +1,5 @@
# Дисковая подсистема кластера aka YDB BlobStorage
YDB BlobStorage -- подсистема YDB, которая отвечает за надёжное хранение данных.
+
+Позволяет хранить *блобы* (бинарный фрагмент размером от 1 байта до 10 мегабайт) c уникальным индитификатором.
diff --git a/ydb/docs/ru/core/concepts/cluster/common_scheme_ydb.md b/ydb/docs/ru/core/concepts/cluster/common_scheme_ydb.md
new file mode 100644
index 0000000000..1d03e7af51
--- /dev/null
+++ b/ydb/docs/ru/core/concepts/cluster/common_scheme_ydb.md
@@ -0,0 +1,5 @@
+{% include [concepts/index/intro.md](_includes/common_scheme_ydb/intro.md) %}
+
+{% include [concepts/index/when_use.md](_includes/common_scheme_ydb/nodes.md) %}
+
+{% include [concepts/index/when_use.md](_includes/common_scheme_ydb/tablets.md) %}
diff --git a/ydb/docs/ru/core/concepts/distributed_storage.md b/ydb/docs/ru/core/concepts/cluster/distributed_storage.md
index 8288ec7f92..d5b7ba6358 100644
--- a/ydb/docs/ru/core/concepts/distributed_storage.md
+++ b/ydb/docs/ru/core/concepts/cluster/distributed_storage.md
@@ -1,5 +1,5 @@
{% include [concepts/index/intro.md](_includes/distributed_storage/intro.md) %}
-{% include [concepts/index/when_use.md](_includes/distributed_storage/common_scheme_ydb.md) %}
+{% include [concepts/index/when_use.md](_includes/distributed_storage/distributed_storage_interface.md) %}
{% include [concepts/index/when_use.md](_includes/distributed_storage/detailed_distributed_storage.md) %}
diff --git a/ydb/docs/ru/core/concepts/cluster/index.md b/ydb/docs/ru/core/concepts/cluster/index.md
new file mode 100644
index 0000000000..13c681d0e8
--- /dev/null
+++ b/ydb/docs/ru/core/concepts/cluster/index.md
@@ -0,0 +1,7 @@
+# Кластер YDB
+
+Информация в данном разделе в основном предназначена для администраторов и разработчиков YDB.
+
+В статье ["Общая схема YDB"](common_scheme_ydb.md) представлена общая информация об узлах и таблетках.
+
+В статье ["Дисковая подсистема кластера"](distributed_storage.md) можно подробнее ознакомиться с особенностями распределенной системы хранения YDB.
diff --git a/ydb/docs/ru/core/concepts/toc_i.yaml b/ydb/docs/ru/core/concepts/toc_i.yaml
index 8b5552a40a..3f69864284 100644
--- a/ydb/docs/ru/core/concepts/toc_i.yaml
+++ b/ydb/docs/ru/core/concepts/toc_i.yaml
@@ -10,4 +10,12 @@ items:
- { name: Time to Live (TTL), href: ttl.md }
- { name: Скан запросы, href: scan_query.md }
- { name: Ограничения базы данных, href: limits-ydb.md }
-- { name: Дисковая подсистема кластера, href: distributed_storage.md, when: audience == "tech" }
+- name: Кластер YDB
+ when: audience == "tech"
+ items:
+ - name: Обзор
+ href: cluster/index.md
+ - name: Общая схема YDB
+ href: cluster/common_scheme_ydb.md
+ - name: Дисковая подсистема кластера
+ href: cluster/distributed_storage.md