Высоконагруженные системы. Глава 6. Секционирование.
Tags: высоконагруженныеприложения, клеппман, книги
Published: 2024-02-06 22:14:20

## Основное

Секционирование - это разбиение данных на секции, чтобы каждый элемент данных был в каждой секции (в отличиее от репликации, где каждый элемент данных хранится в каждом узле). Основная цель секционирования - масштабируемость, так как увеличивается пропускная способность на кол-во запросов, так как секции независимы. 

При этом секционирование и репликация используются чаще всего вместе, так как первое дает масштабирумость и второе - отказоустойчивость. На каждом узле хранится несколько секций (но не обязтельно все). И для одних секций один и тот же узел может быть ведущим, а для других секций - ведомым (что лишний раз показывает независимость секций).


## Подходы к секционированию

### Секционирование по диапазону ключей

Этот подход заключается в том, чтобы закрепить за каждой секций диапазон значению ключа. Например, за секцией 1 - значения от А до В, за секций 2 - от Г до Е и т.д. При этом внутри самой секции используются SS-таблицы (под капотом самобалансирующиеся структуры данных - AVL дерево, например), благодаря которым значения отсортированы и становися просто искать по диапазону.

Однако такой подход имеет недостаток - вероятность "горячей точки". Это значение, по которому осуществлено секционирование, по которому слишком много данных (например, в декабре кол-во транзакций гораздо больше, чем в другие месяцы). В результате секция может быть перегружена данными.

### Секциоинирование по хэшу ключа

Этот подход решает проблему "горячих точек". Хорошая хэш-функция возвращает равномерно распределенные значения для разных ключей. Можно каждоый секции сопоставить диапазон значения хэш функции. Однако теряется возможность быстрого поиска по диапазону, так как близкие по значению ключи лежат теперь уже в разных секциях. Также стоит иметь в виду, что данный подход не защищает от крайнего случая "горячей точки", когда все операции происходит по одному и тому же ключю.



## Секционирование и вторичные индексы

Вторичные индексы в отличие от ключей не идентифицируют однозначно запись - а значит, нельзя им поставить в соответствие определенную секцию. Но есть 2 варианта, как использовать вторичный индекс.


### Секционирование вторичных индексов по документам

Этот подход заключается в том, что внутри каждой секции строится свой независимый индекс. Поэтому при добавлении/изменении данных в секции меняется только этот индекс. Поэтому его еще называют локальным.

Минусом такого подхода является то, что при поиске приходится делать запросы во все секции и объединять полученные результаты, что весьма затратно по времени.


### Секционирование вторичных индексов по термам

Этот подход заключается в том, что индекс секционирован по нескольким узлам. Например, поле color - значениям цвета, начинаяющимся с буквы a до r, соответствует секция 1. А цветам от s до z - секция 2.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqowdlmpeyuhoyhcsxex.png)


Благодаря такому подходу скоросить поиска сильно возрастает по сравнению с индексом по документу. Однако скорость записи наоборот, падает, так как при этом подходе секции становятся связанными, ведь индекс по термам может содержать ссылку на данные из другой секции.



## Маршрутизация запросов

Когда клиент делает запрос, откуда он знает, к какому узлу обратиться (какие секции какому узлу соответствуют)? Есть несколько вариантов:

* сами узлы могут знать - тогда при обращении на узел, он может отправить на другой, если у него нет требуемой секции

* использование gateway, у которого есть эта информация

* хранить эту информацию на самом клиенте