1 of 116

2 of 116

План

  • что такое шардирование
  • какие есть инструменты
  • как на практике их применить

3 of 116

Что такое шардирование

4 of 116

Деление на части

5 of 116

Shard - осколок, фрагмент

6 of 116

Происхождение термина шард, 1997, Ultima Online

7 of 116

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

8 of 116

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

9 of 116

Ключ шардирования

Признак по которому объект сопоставляется с шардом

10 of 116

Функция шардирования

f(key, shardsNumber) => shardIndex

11 of 116

Функции шардирования

12 of 116

Функции шардирования

Чистые функции

  • остаток от деления
  • consistent hash
  • rendevouz hash

Функции с состоянием

  • таблица “ключ -> шард”
  • hash slot в redis:�shardingKey -> node -> shard

13 of 116

Чистые функции шардирования

Остаток от деления или modular hash

shardIndex = key % shardsNumber

При смене количества шардов, меняются все значения.

14 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

15 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

  • представим область значения hash() как кольцо

16 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

  • представим область значения hash() как кольцо
  • распределяем ноды по кольцу hash($nodeName)

17 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

  • представим область значения hash() как кольцо
  • распределяем ноды по кольцу hash($nodeName)
  • рассчитываем hash($shardingKey)

18 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

  • представим область значения hash() как кольцо
  • распределяем ноды по кольцу hash($nodeName)
  • рассчитываем hash($shardingKey)
  • выбираем ближайшую ноду по часовой стрелке

19 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

Что будет, если добавить шрад?

20 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

Что будет, если добавить шрад?

Значение функции шардирования меняется только для части ключей

21 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

Расположение нод случайно, поэтому требует балансировки.

22 of 116

Чистые функции шардирования

Consistent hash или стабильное хеширование

Расположение нод случайно, поэтому требует балансировки

Равномерность достигается увеличением числа нод (алиасами)

23 of 116

Чистые функции шардирования

Rendezvous Hash�или Highest Random Weight

24 of 116

Чистые функции шардирования

Rendezvous Hash�или Highest Random Weight

HRW как алгоритм вычисления rendezvous points в мультикаст маршрутизации

25 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

26 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

  • для каждой пары (ключ, нода) считаем хеш

27 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

  • для каждой пары (ключ, нода) считаем хеш�
  • выбираем максимальный хеш

28 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

  • для каждой пары (ключ, нода) считаем хеш�
  • выбираем максимальный хеш�
  • используем ноду давшую максимальный хеш

29 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

Минимальное перераспределение

30 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

Минимальное перераспределение

31 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

Минимальное перераспределение

32 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

Минимальное перераспределение

33 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

Минимальное перераспределение

34 of 116

Чистые функции шардирования

Rendezvous hash�или Highest Random Weight

  • простой
  • сбалансирован из коробки
  • минимальное перераспределение
  • consistent hash - частный случай HRW

35 of 116

Функции шардирования с состоянием

Таблицы маппинга hashKey => shard

36 of 116

Функции шардирования с состоянием

Hash slot в Redis:

  • hashKey => hashSlot => shard

  • пространство hash() поделено на 16384 слотов
  • каждая нода отвечает за свой диапазон слотов
  • при смене количества нод перераспределяется только часть слотов

37 of 116

Функции шардирования с состоянием

  • можно вручную точно управлять нагрузкой
  • идеальное перераспределение ключей при смене количества узлов
  • но нужно уметь координировать состояние

38 of 116

Какую проблему решает шардирование очередей

39 of 116

Ускорение разбора очереди…

40 of 116

41 of 116

...c сохранением локального порядка

42 of 116

Пример приложения в котором шардирование нужно и возможно

43 of 116

Сервис рассылки писем

44 of 116

  • Разбирать в один поток - долго

45 of 116

  • Разбирать в один поток - долго
  • Порядок имеет значение

46 of 116

  • Разбирать в один поток - долго
  • Порядок имеет значение
  • Порядок важен только в рамках одного email

47 of 116

  • Разбирать в один поток - долго
  • Порядок имеет значение
  • Порядок важен только в рамках одного email

subscribe a@example.com

subscribe b@example.com

email to a@example.com

email to b@example.com

unsubscribe b@example.com

subscribe a@example.com

email to a@example.com

subscribe b@example.com

email to b@example.com

unsubscribe b@example.com

48 of 116

Варианты реализации

49 of 116

Ручное шардирование через direct или topic exchange

50 of 116

Ручное шардирование через direct или topic exchange

  • direct exchange
  • создать очереди
  • bind по имени шарда
  • alternate exchange как фэйловер

51 of 116

Ручное шардирование через direct или topic exchange

  • в продюсер протекает деталь топологии (генерация routing key)
  • понадобиться механизм дефолтного роутинга
  • есть вероятность нарушения порядка

52 of 116

Ручное шардирование через direct или topic exchange

дает представление о идеальном варианте:

  • почти прозрачный для продюсера (требуется только sharding key)
  • нет дефолтного роутинга
  • нет нарушения порядка

53 of 116

Специальные механизмы RabbitMQ

54 of 116

RabbitMQ Sharding Plugin

55 of 116

RabbitMQ Sharding Plugin

  • exchange типа x-modulus-hash�
  • задаем в policy имя очереди и количество шардов�
  • функция modulus hash�
  • консюмим из псевдо-очереди�
  • плагин сам распределяет консюмеров по шардам

56 of 116

RabbitMQ Sharding Plugin

  • распределяет только в рамках одной ноды�
  • конкурентные basic.consume распределяются неравномерно�
  • может быть больше одного консюмера в очереди�
  • шарды добавляются при добавлении нод

57 of 116

RabbitMQ Sharding Plugin

Не подходит для целей шардирования с сохранением порядка

58 of 116

Consistent Hash Exchange

59 of 116

Consistent Hash Exchange

  • тип x-consistent-hash�
  • сами создаем очереди и биндим очереди�
  • функция consistent hash�
  • сами подключаемся к нужному шарду

60 of 116

Consistent Hash Exchange

  • во время привязки/отвязки очереди необходимо перестроить маршрутизацию�
  • перезапуск ноды меняет маршрутизацию (если нет кластера)

61 of 116

Consistent Hash Exchange

  • плагин делает ровно, то что нужно�
  • не делает лишнего�
  • можем построить идеальную схему

62 of 116

Почему этого недостаточно

63 of 116

Добавление шарда ведет к нарушению порядка

64 of 116

Решардинг - повторное распределение по шардам

65 of 116

В БД повторное распределение - очень дорогая операция

66 of 116

Перемещение минимизируют стабильным хешированием

67 of 116

В случае кролика нам не достаточно минимизации - локальный порядок должен сохраниться полностью

68 of 116

В кролике нет проблем с объемами

69 of 116

Добавление шарда

70 of 116

Добавление шарда

71 of 116

Добавление шарда

72 of 116

Добавление шарда

?

?

?

73 of 116

Топология, пригодная для решардинга

74 of 116

Топология, пригодная для решардинга

75 of 116

Топология, пригодная для решардинга

76 of 116

Топология, пригодная для решардинга

77 of 116

Механизм миграции

78 of 116

Предварительные условия

  • ваше приложение должно управлять топологией очередей
  • понадобиться коннектор к HTTP API кролика
  • применять миграции будем во время деплоя

79 of 116

Топология в запущенном приложении

80 of 116

Деплой

81 of 116

Деплой

82 of 116

Деплой

83 of 116

Деплой

84 of 116

Деплой

85 of 116

Деплой

86 of 116

Миграция

87 of 116

Миграция

88 of 116

Миграция

89 of 116

Миграция

90 of 116

Миграция

91 of 116

Миграция

92 of 116

Миграция

93 of 116

Миграция

94 of 116

Миграция

95 of 116

Миграция

96 of 116

Миграция

97 of 116

Миграция

98 of 116

Миграция

99 of 116

Миграция

100 of 116

Миграция

101 of 116

Миграция

102 of 116

Миграция

103 of 116

Миграция

104 of 116

Миграция

105 of 116

Миграция

106 of 116

Миграция

107 of 116

Миграция

108 of 116

Миграция

109 of 116

Миграция

110 of 116

Миграция

111 of 116

Миграция

112 of 116

Миграция

113 of 116

Миграция

114 of 116

Вот теперь достаточно

115 of 116

Возможности топологии

  • можем менять количество шардов на лету�
  • можем менять аргументы очередей (например приоритет)�
  • можно перестроить топологию без остановки продюсеров

116 of 116

Итоги

  • параллельную обработку сообщений можно организовать с помощю шардирования�
  • для этого подходит плагин consitent hash exchange�
  • для решардинга можно использовать буфферную очередь и shovel