aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormzinal <mzinal@yandex-team.com>2022-08-10 16:22:26 +0300
committermzinal <mzinal@yandex-team.com>2022-08-10 16:22:26 +0300
commit8c70d6f947c5f278c665b548cd583e9844e6d7ad (patch)
tree1b08665160d2b87ea413306f31ef1164fffb5b26
parent0acde0be21b007e0b0da0f728085afa7bc7e4e34 (diff)
downloadydb-8c70d6f947c5f278c665b548cd583e9844e6d7ad.tar.gz
[YDB] scalability best practices updated for readability
-rw-r--r--ydb/docs/ru/core/best_practices/_includes/pk_scalability.md18
1 files changed, 11 insertions, 7 deletions
diff --git a/ydb/docs/ru/core/best_practices/_includes/pk_scalability.md b/ydb/docs/ru/core/best_practices/_includes/pk_scalability.md
index 9b22d1415e..5d6f938c6a 100644
--- a/ydb/docs/ru/core/best_practices/_includes/pk_scalability.md
+++ b/ydb/docs/ru/core/best_practices/_includes/pk_scalability.md
@@ -10,29 +10,33 @@
Все таблицы в {{ ydb-short-name }} отсортированы по возрастанию первичного ключа. Это означает, что запись в таблицу данных с монотонно возрастающим первичным ключом приведет к добавлению новых данные в конец таблицы. Так как {{ ydb-short-name }} разделяет таблицы на партиции по диапазонам ключей, вставки будут обрабатываться одним конкретным сервером, отвечающим за "последнюю" партицию. Сосредоточение нагрузки на одном сервере приведет к медленной загрузке данных и неэффективному использованию распределенной системы.
В качестве примера рассмотрим запись лога пользовательских событий в таблицу со схемой ```( timestamp, userid, userevent, PRIMARY KEY (timestamp, userid) )```.
-```timestamp``` монотонно возрастает, как следствие, все записи будут записываться в конец таблицы и "последняя" партиция, которая отвечает за данный диапазон ключей, будет обслуживать все записи в таблицу. Это приведет к невозможности масштабирования нагрузки на запись, производительность будет ограничена одним процессом обслуживания этой партиции, и не будет расти с добавлением серверов в кластер.
+Значения колонки ```timestamp``` монотонно возрастают; как следствие, все новые записи будут добавляться в конец таблицы, и "последняя" партиция, которая отвечает за данный диапазон ключей, будет обслуживать все операции вставки в таблицу. Это приведет к невозможности масштабирования нагрузки на вставку, производительность будет ограничена одним процессом обслуживания этой партиции, и не будет расти с добавлением серверов в кластер.
-В {{ ydb-short-name }} поддерживается автоматическое разделение партиции при достижении порогового размера или нагрузки. Но в рассматриваемом случае после разделения новая партиция начнет опять принимать всю нагрузку на запись, и ситуация повторится.
+В {{ ydb-short-name }} поддерживается автоматическое разделение партиции при достижении порогового размера или нагрузки. Но в рассматриваемом случае после разделения новая партиция начнет опять принимать всю нагрузку на вставку, и ситуация повторится.
## Приемы, позволяющие равномерно распределить нагрузку по партициям таблицы {#balance-shard-load}
### Изменение порядка следования компонент ключа {#key-order}
-Запись данных в таблицу со схемой ```( timestamp, userid, userevent, PRIMARY KEY (timestamp, userid) )``` приводит к неравномерной нагрузке на партиции таблицы из-за монотонно возрастающего первичного ключа. Изменение порядка следования компонент ключа таким образом, чтобы монотонно возрастающая часть не была первой компонентой, может помочь более равномерно распределить нагрузку. Если изменить схему таблицы на ```( timestamp, userid, userevent, PRIMARY KEY (userid, timestamp) )```, то при достаточном количестве пользователей, генерирующих события, запись в БД будет распределена по партициям более равномерно.
+Запись данных в таблицу со схемой ```( timestamp, userid, userevent, PRIMARY KEY (timestamp, userid) )``` приводит к неравномерной нагрузке на партиции таблицы из-за монотонно возрастающего первичного ключа. Изменение порядка следования компонент ключа таким образом, чтобы монотонно возрастающая часть не была первой компонентой, может помочь более равномерно распределить нагрузку. Если изменить определение первичного ключа таблицы на ```PRIMARY KEY (userid, timestamp)```, то при достаточном количестве пользователей, генерирующих события, запись в БД будет распределена по партициям более равномерно.
### Использование хеша от значений ключевых колонок в качестве первичного ключа {#key-hash}
-Рассмотрим таблицу со схемой ```( timestamp, userid, userevent, PRIMARY KEY (userid, timestamp) )```. В качестве всего первичного ключа или его первой компоненты можно использовать хеш от исходного ключа, например так:
+Для получения более равномерного распределения операций вставки между партициями таблицы необходимо увеличить разнообразие значений "префикса" (начальной части) первичного ключа. Для этого можно включить в первичный ключ значение хеш-кода от всего первичного ключа или его части.
+
+Например, в рассматриваемую таблицу со схемой ```( timestamp, userid, userevent, PRIMARY KEY (userid, timestamp) )``` можно включить дополнительное поле, рассчитываемое как хеш-код: ```userhash = HASH(userid)```. В результате схема таблицы преобразуется к следующему виду:
```
-( HASH(timestamp, userid), timestamp, userid, userevent, PRIMARY KEY (HASH(userid), userid, timestamp) )
+( userhash, userid, timestamp, userevent, PRIMARY KEY (userhash, userid, timestamp) )
```
-При правильном выборе функции хеширования строки будут распределены достаточно равномерно по всему пространству ключей, что в приведет к равномерной нагрузке на систему. При этом, наличие полей ```userid, timestamp``` в составе ключа после ```HASH(userid)``` сохраняет локальность и сортировку данных по времени для конкретного пользователя.
+При правильном выборе функции хеширования строки будут распределены достаточно равномерно по всему пространству ключей, что в приведет к более равномерной нагрузке на систему. При этом наличие полей ```userid, timestamp``` в составе ключа после поля ```userhash``` сохраняет локальность и сортировку данных по времени для конкретного пользователя.
+
+Расчёт значения поля ```userhash``` в описанном выше примере должен осуществляться приложением, и явно указываться как при вставке новых записей таблицы, так и при доступе к записям по первичному ключу.
### Уменьшение количества партиций, затрагиваемых в одном запросе {#decrease-shards}
-Предположим, что основной сценарий работы с данными таблицы — прочитать все события по конкретному ```userid```. Тогда при использовании схемы таблицы ```( timestamp, userid, userevent, PRIMARY KEY (timestamp, userid) )``` каждое чтение будет затрагивать все партиции таблицы. При этом, каждая партиция будет просканирована полностью, так как строки, относящиеся к конкретному ```userid```, расположены в заранее неизвестном порядке. Изменение порядка следования компонент ключа ```( timestamp, userid, userevent, PRIMARY KEY (userid, timestamp) )``` приведет к тому, что все строки, относящиеся к конкретному ```userid```, будут следовать друг за другом. Такое расположение строк положительно повлияет на скорость чтения информации по конкретному ```userid```.
+Предположим, что основной сценарий работы с данными таблицы — прочитать все события по конкретному ```userid```. Тогда при использовании схемы таблицы ```( timestamp, userid, userevent, PRIMARY KEY (timestamp, userid) )``` каждое чтение будет затрагивать все партиции таблицы. При этом, каждая партиция будет просканирована полностью, так как строки, относящиеся к конкретному ```userid```, расположены в заранее неизвестном порядке. Изменение порядка следования компонент ключа ```( timestamp, userid, userevent, PRIMARY KEY (userid, timestamp) )``` приведет к тому, что все строки, относящиеся к конкретному ```userid```, будут следовать друг за другом. Такое расположение строк положительно повлияет на скорость чтения информации по конкретному ```userid```, и сократит нагрузку.
## Значение NULL в ключевой колонке {#key-null}