Открыть сервис

Хеш-слоты

Хеш-слоты (англ. hash slots) — это фиксированное количество логических разделов (слотов), на которые равномерно распределяется всё ключевое пространство хэш-функции в распределённых системах, использующих алгоритм согласованного хэширования. Каждый хеш-слот однозначно сопоставляется с определённым диапазоном значений хэш-функции и закрепляется за конкретным узлом кластера. Такая схема применяется для обеспечения масштабируемости, балансировки нагрузки и минимизации перемещения данных при добавлении или удалении узлов.

История и происхождение

Концепция хеш-слотов получила широкое распространение в середине 2000-х годов в связи с развитием распределённых баз данных и систем кэширования. Ключевым импульсом стало появление алгоритма согласованного хэширования (consistent hashing), предложенного Дэвидом Каргером и его коллегами в 1997 году. В первоначальной версии согласованного хэширования использовалось кольцо хэш-значений, где каждый узел отвечал за определённый диапазон. Однако на практике такая схема приводила к неравномерному распределению данных и сложностям при репликации.

В 2007 году компания Amazon представила распределённое хранилище Dynamo, где для балансировки нагрузки применялась виртуализация узлов (vNodes). В 2013 году компания Redis представила кластерную архитектуру Redis Cluster, которая ввела чёткое понятие хеш-слотов как фиксированного набора из 16384 логических разделов. Эта реализация стала стандартом де-факто для многих современных распределённых систем.

Принцип работы

Хэш-функция и слоты

В системах, использующих хеш-слоты, для каждого ключа данных вычисляется хэш-значение. Затем это значение отображается на один из фиксированного количества слотов (например, 16384 в Redis Cluster). Формула отображения обычно выглядит как:

`` slot = CRC16(key) mod 16384 ``

где CRC16циклический избыточный код (16-битная версия), а 16384 — количество слотов. Полученный номер слота определяет, на каком узле кластера будет храниться данный ключ.

Распределение слотов по узлам

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

Репликация

Для обеспечения отказоустойчивости каждый хеш-слот может иметь несколько реплик (копий), расположенных на разных узлах. В Redis Cluster, например, каждый слот имеет одну основную (master) реплику и одну или несколько резервных (slave) реплик. Если основной узел выходит из строя, одна из резервных реплик автоматически становится основной.

Классификация систем, использующих хеш-слоты

Хеш-слоты применяются в различных типах распределённых систем:

1. Системы управления базами данных (СУБД)

  • Redis Cluster — использует 16384 хеш-слота. Каждый ключ отображается на слот, а слоты распределяются между узлами кластера. Поддерживает автоматическое перераспределение слотов при добавлении/удалении узлов.
  • Apache Cassandra — использует виртуальные узлы (vNodes), которые по сути являются аналогом хеш-слотов. Количество vNodes настраивается администратором.
  • Amazon DynamoDB — использует внутреннюю реализацию хеш-слотов для распределения данных по партициям.

2. Системы кэширования

3. Распределённые файловые системы

  • Ceph — использует CRUSH-алгоритм, который отображает объекты на хеш-слоты (PG — placement groups), а затем на OSD (объектные устройства хранения).

Характеристики и параметры

Количество слотов

В большинстве реализаций количество хеш-слотов фиксировано и не зависит от числа узлов. В Redis Cluster это 16384 (2^14), что обеспечивает хороший баланс между точностью распределения и накладными расходами на хранение метаданных. В Apache Cassandra количество vNodes может варьироваться от 256 до 4096 на узел.

Распределение слотов

Распределение может быть:

  • Равномерным — каждый узел получает примерно одинаковое количество слотов.
  • Взвешенным — узлы с большей производительностью получают больше слотов.
  • Динамическим — система автоматически перераспределяет слоты в зависимости от нагрузки.

Перемещение данных

При изменении состава кластера (добавление/удаление узла) перемещаются только данные, относящиеся к перераспределяемым слотам. В Redis Cluster, например, при добавлении нового узла перемещается примерно 1/N часть данных (где N — количество узлов), что значительно меньше, чем при полном рехэшировании.

Применение

Балансировка нагрузки

Хеш-слоты позволяют равномерно распределять запросы между узлами кластера, так как ключи равномерно распределяются по слотам, а слоты — по узлам.

Масштабирование

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

Отказоустойчивость

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

Шардирование

Хеш-слоты являются основой для шардирования (сегментирования) баз данных, позволяя распределять данные по нескольким серверам без необходимости в единой точке отказа.

Примеры реализации

Redis Cluster

В Redis Cluster каждый ключ отображается на один из 16384 хеш-слотов. Кластер может содержать до 1000 узлов. Распределение слотов хранится в метаданных кластера и обновляется при изменении топологии. Клиентские библиотеки (например, redis-py-cluster) автоматически определяют, на каком узле находится нужный слот, и направляют запрос напрямую.

Apache Cassandra

Cassandra использует виртуальные узлы (vNodes), каждый из которых соответствует хеш-слоту. Количество vNodes на узел настраивается параметром num_tokens. При добавлении нового узла система автоматически перераспределяет vNodes между всеми узлами, минимизируя перемещение данных.

Критика и ограничения

Неравномерное распределение

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

Сложность перераспределения

Хотя перемещение данных при изменении состава кластера меньше, чем при полном рехэшировании, оно всё равно требует значительных вычислительных и сетевых ресурсов, особенно при большом количестве данных.

Фиксированное количество слотов

В системах с фиксированным количеством слотов (например, 16384) невозможно изменить это число без полной остановки кластера и перераспределения всех данных. Это ограничивает гибкость при очень больших кластерах.

Зависимость от хэш-функции

Выбор хэш-функции влияет на равномерность распределения. Слабые хэш-функции могут приводить к коллизиям и неравномерному заполнению слотов.

Интересные факты

  • Число 16384 (2^14) в Redis Cluster выбрано не случайно: оно достаточно велико для равномерного распределения, но при этом укладывается в 2 байта (16 бит), что упрощает хранение метаданных.
  • В некоторых реализациях (например, в Amazon DynamoDB) хеш-слоты называются «партициями» (partitions), а их количество может автоматически увеличиваться при росте объёма данных.
  • Алгоритм CRC16, используемый в Redis Cluster, не является криптостойким, но обеспечивает хорошее распределение для большинства практических случаев.

Источники

  • Redis Cluster Specification (Redis Documentation)
  • David Karger et al. "Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web" (1997)
  • Giuseppe DeCandia et al. "Dynamo: Amazon's Highly Available Key-value Store" (2007)
  • Apache Cassandra Documentation (vNodes)
  • "Redis in Action" by Josiah L. Carlson (2013)

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →