Введение

Техника хеширования
В информатике, согласованное хеширование. Статья впоследствии была адаптирована для решения технической задачи отслеживания файлов в одноранговых сетях, таких как распределенная хеш-таблица. Teradata использовала эту технику в своей распределенной базе данных, выпущенной в 1986 году, хотя и не использовала этот термин. Teradata до сих пор использует концепцию хеш-таблицы для решения именно этой задачи. Akamai Technologies была основана в 1998 году учеными Дэниелом Левином и Ф. Томсоном Лейтоном (соавторами статьи, вводящей термин "согласованное хеширование"). В сети доставки контента Akamai согласованное хеширование используется для балансировки нагрузки внутри кластера серверов, а стабильный алгоритм поиска пары – для балансировки нагрузки между кластерами. Согласованное хеширование также используется для снижения влияния частичных сбоев системы в крупных веб-приложениях, обеспечивая надежное кэширование без повсеместных последствий сбоя. Согласованное хеширование также является основой распределенных хеш-таблиц (DHT), которые используют хеш-значения для разделения пространства ключей между распределенным набором узлов, а затем создают накладную сеть связанных узлов, обеспечивающую эффективный поиск узлов по ключу. Rendezvous hashing, разработанный в 1996 году, представляет собой более простой и универсальный метод. Он достигает целей согласованного хеширования, используя существенно отличающийся алгоритм HRW (highest random weight) – алгоритм наибольшего случайного веса.

Основная техника

В задаче балансировки нагрузки, например, когда BLOB необходимо назначить одному из серверов в кластере, можно использовать стандартную хеш-функцию следующим образом: мы вычисляем хеш-значение для этого BLOB, и, предположив, что полученное значение хеша равно *h*, выполняем операцию взятия по модулю с количеством серверов (в данном случае *N*), чтобы определить сервер, на котором можно разместить BLOB: *h mod N*; следовательно, BLOB будет помещен на сервер, чей идентификатор является преемником *h* на единичном круге. Однако, при добавлении или удалении сервера во время сбоя или масштабирования (при изменении *N*), все BLOB на каждом сервере должны быть переназначены и перемещены из-за перехеширования, что является дорогостоящей операцией. Последовательное хеширование было разработано для решения проблемы переназначения каждого BLOB при добавлении или удалении сервера в кластере. Основная идея заключается в использовании хеш-функции, которая отображает как BLOB, так и серверы на единичный круг, обычно в радианах. Например, *hash(x)* (где *hash(x)* – хеш BLOB или идентификатор сервера, например IP-адрес или UUID). Затем каждый BLOB назначается следующему серверу, который встречается на круге по часовой стрелке. Обычно для поиска "позиции" или сервера для размещения конкретного BLOB используется алгоритм двоичного поиска или линейного поиска со сложностью *O(log N)* или *O(N)* соответственно; и на каждой итерации, выполняемой по часовой стрелке, производится операция *server_id(h)* (где *server_id(h)* – идентификатор сервера в кластере), чтобы найти сервер для размещения BLOB. Это обеспечивает равномерное распределение BLOB по серверам. Но, что более важно, если сервер выходит из строя и удаляется из круга, переназначению подлежат только те BLOB, которые были отображены на этот сервер, – следующему серверу по часовой стрелке. Аналогично, при добавлении нового сервера он добавляется на единичный круг, и перераспределению подлежат только BLOB, отображенные на этот сервер. Важно отметить, что при добавлении или удалении сервера подавляющее большинство BLOB сохраняют свои прежние назначения, а добавление одного сервера приводит к перемещению лишь небольшой доли BLOB. Хотя процесс перемещения BLOB между кэш-серверами в кластере зависит от контекста, обычно, вновь добавленный кэш-сервер определяет своего "преемника" и перемещает все BLOB, чье отображение принадлежит этому преемнику (то есть чье хеш-значение меньше, чем у нового сервера), с него. Однако, в случае кэша веб-страниц, в большинстве реализаций перемещение или копирование не требуется, если кэшированный BLOB достаточно мал. Когда запрос попадает на вновь добавленный кэш-сервер, происходит промах кэша, выполняется запрос к фактическому веб-серверу, и BLOB кэшируется локально для последующих запросов. Избыточные BLOB на ранее использовавшихся кэш-серверах удаляются в соответствии с политикой вытеснения кэша.

Уменьшение отклонения

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