---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ytsaurus.tech/docs/en/user-guide/dynamic-tables/resharding.md
  - https://ytsaurus.tech/docs/ru/user-guide/dynamic-tables/resharding.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ytsaurus.tech/docs/ru/llms.txt

<!-- source: ru/_includes/user-guide/dynamic-tables/resharding.md -->
# Шардирование

В данном разделе рассматриваются способы шардирования динамических таблиц. Приводится описание алгоритма автоматического шардирования.

Динамические таблицы делятся на [таблеты](https://ytsaurus.tech/docs/ru/user-guide/dynamic-tables/overview.md#tablets) (шарды), являющиеся единицей параллелизма.

#### Сортированные таблицы

Каждый таблет [сортированной таблицы](https://ytsaurus.tech/docs/ru/user-guide/dynamic-tables/sorted-dynamic-tables.md) отвечает за некоторый диапазон ключей. Граничные ключи таблетов (также называемые pivot-ключами) доступны в атрибуте `pivot_keys` таблицы. Таблет с индексом *k* отвечает за ключи, лежащие между *k*-м граничным ключом (включительно) и *k*+1-м (не включительно).

Каждый граничный ключ состоит из некоторого префикса ключевых колонок таблицы. Например, для таблицы с тремя ключевыми колонками типов int64, string, double допустимы граничные ключи `[]`, `[10]`, `[50; foo]`, `[100; bar; 1.234]`. Граничные ключи таблетов должны строго возрастать. Первый граничный ключ обязательно должен быть пустым.

При решардировании сортированной таблицы можно как явно указать желаемые граничные ключи, так и передать параметр `tablet_count`. Во втором случае система попробует самостоятельно равномерно разбить таблицу на требуемое число таблетов.

#### Упорядоченные таблицы

Каждый таблет [упорядоченной таблицы](https://ytsaurus.tech/docs/ru/user-guide/dynamic-tables/ordered-dynamic-tables.md) является независимой очередью. Решардирование упорядоченной таблицы возможно только с указанием желаемого числа таблетов. Подробнее см. в разделе [Шардирование упорядоченных таблиц](https://ytsaurus.tech/docs/ru/user-guide/dynamic-tables/ordered-dynamic-tables.md).

#### Реплицированные таблицы
Физически каждый таблет [реплицированной таблицы](https://ytsaurus.tech/docs/ru/user-guide/dynamic-tables/replicated-dynamic-tables.md) является очередью и хранит лог репликации. Несмотря на это, логически шардирование происходит так же, как и для обычных таблиц.
- Каждый таблет сортированной реплицированной таблицы отвечает за диапазон ключей и хранит лог репликации ключей из этого диапазона.
- Каждый таблет упорядоченной реплицированной таблицы является независимой очередью. Для соответствия таблетов реплицированной таблицы и реплик необходимо использовать атрибут [preserve_tablet_index](replicated-dynamic-tables#sohranenie-indeksa-tableta-pri-replikacii-uporyadochennoj-tablicy).

Шардирование сортированной реплицированной таблицы не обязано совпадать с шардированием реплик. Разные реплики одной таблицы также могут быть шардированы по-разному.

Непустую реплицированную таблицу решардировать невозможно. При необходимости это сделать нужно пересоздать таблицу с нужными граничными ключами.

## Ручное шардирование

Для решардирования таблицы используется команда [reshard-table](https://ytsaurus.tech/docs/ru/api/commands.md#reshard_table). Перед выполнением команды таблица должна быть отмонтирована.

{% list tabs %}

- CLI
  ```bash
  yt unmount-table //path --sync

  # Reshard with tablet count
  yt reshard-table //path --tablet-count 10 --sync
  # --enable-slicing is used to pick pivots more precisely in case of small tables
  yt reshard-table //path --tablet-count 100 --enable-slicing --sync
  # Reshard with pivot keys
  yt reshard-table //path '[]' '[10;foo]' '[20]' --sync

  yt mount-table //path --sync
  ```

- Python
  ```python
  yt.unmount_table("//path", sync=True)

  # Reshard with tablet count
  yt.reshard_table("//path", tablet_count=10, sync=True)

  # enable_slicing is used to pick pivots more precisely in case of small tables
  yt.reshard_table("//path", tablet_count=10, enable_slicing=True, sync=True)

  # Reshard with pivot keys
  yt.reshard_table("//path", [[], [10, "foo"], [20]], sync=True)

  yt.mount_table("//path", sync=True)
  ```

{% endlist %}

{% note info "Про параметр sync" %}

Команды unmount-table, reshard-table и mount-table асинхронные, поэтому при их использовании рекомендуется дожидаться завершения выполнения. Для этого используется флаг `--sync` или параметр `sync=True`. Unmount-table на практике может выполняться долго, поэтому ожидание для неё необходимо. Reshard-table и mount-table типично завершаются мгновенно, поэтому при ручных запусках ожидание можно опускать, однако в скриптах рекомендуется использовать sync.

{% endnote %}

При указании параметра `tablet_count` система попробует автоматически выбрать подходящие граничные ключи. Если таблица достаточно маленькая (меньше 200 МБ на таблет), итоговых таблетов может оказаться меньше, чем запрошено. В этом случае для уточнения поиска граничных ключей рекомендуется использовать опцию [enable_slicing](https://ytsaurus.tech/docs/ru/api/commands.md#reshard_table).

Узнать число таблетов можно через атрибут `@tablet_count`.

## Шардирование по хешу { #hash }

Для равномерного распределения нагрузки можно воспользоваться стандартным приёмом: добавить первой вспомогательную ключевую колонку, в которую записывать хеш от той части ключа, по которой выполнять шардирование (например, хеш от первой колонки). В результате получится таблица, ключи которой равномерно распределены в диапазоне [0, 2<sup>64</sup> – 1].

Для разбиения такой таблицы на *k* таблетов достаточно разбить диапазон [0, 2<sup>64</sup>-1] на *k* частей. Для этого можно использовать команду reshard-table с флагом `--uniform`: при указании `tablet_count` система выставит граничные ключи [], [2<sup>64</sup> / *k*], [2<sup>64</sup> * 2 / *k*] и т. д.

Значение ключевой колонки можно вычислять на клиентской стороне и передавать при записи в таблицу, но в качестве альтернативы можно использовать вычисляемые колонки.

### Вычисляемые колонки { #expression }

Система YTsaurus поддерживает возможность автоматического вычисления значения ключевой колонки по формуле. Данную формулу необходимо указать в схеме этой колонки в поле `expression`. Ключевая колонка может зависеть только от невычисляемых ключевых колонок. При записи строки или поиска строки по ключу вычисляемые колонки необходимо пропускать.

Для равномерного распределения будет лучше указать `"expression" = "farm_hash(key)"`, где `key` — префикс исходного ключа (`farm_hash` — это встроенная функция, вычисляющая [FarmHash](https://code.google.com/p/farmhash) от аргументов).

При использовании автоматически вычисляемых колонок стоит учитывать, что для оптимизации работы операция `select_rows` выводит из предиката диапазон затрагиваемых ключей. Если в предикате некоторые значения вычисляемых колонок не заданы явно, то YTsaurus попробует дополнить условие значением вычисляемых колонок. В текущей реализации результат будет успешным, только в том случае если те колонки, от которых зависит вычисляемая, в предикате определяются равенством или с помощью оператора `IN`. Вычисление явно заданных значений вычисляемых колонок в выводе диапазонов не происходит.

#### Пример использования вычисляемых колонок

Пусть имеется таблица с колонками `hash, key, value`, причём `hash` и `key` ключевые, а для `hash` в схеме указана формула `expression = "farm_hash(key)"`. Тогда для операций вставки, удаления и чтения по ключу нужно указывать только `key` и `value`. Чтобы операция `select_rows` работала эффективно, в предикате нужно точно определить `key`, тогда система YTsaurus сможет вычислить какие значения `hash` нужно рассматривать. Например, в запросе можно указать `WHERE key = key_value` или `WHERE key IN (key_value1, key_value2)`.

Если же указать `WHERE key > key_lower_bound and key < key_upper_bound`, то, диапазон для `hash` вывести нельзя. В некоторых случаях возможен перебор значений вычисляемых колонок. Перебор происходит в следующих случаях:

1. Выражение вычисляемой колонки имеет вид `expression = "f(key / divisor)"` , при этом `key` и `divisor` должны быть целочисленными. В данном случае происходит перебор всех таких значений `key`, которые порождают различные значения `expression`. Такое поведение обобщается на случай с несколькими вычисляемыми колонками и несколькими вхождениями `key`c различными делителями.
2. Выражение имеет вид `expression = "f(key) % mod"`. В данном случае происходит перебор значений `expression` в пределах значения `mod`, а также в перебор включается значение `null`.

Если существует возможность переборов обоими способами, выбирается тот, который порождает наименьшее количество значений. Общее количество ключей, порождаемых перебором, ограничено параметром `range_expansion_limit`.
<!-- endsource: ru/_includes/user-guide/dynamic-tables/resharding.md -->