Чтобы решить подобную проблему, многие шардирующие функ-ции прибегают к использованию консистентных хеш-функций . Эти хеш-функции устроены таким образом, что при количестве ключей K и увеличении количества шардов до N гарантированно окажется перенаправлено не более K / N запросов. Например, при использовании консистентной хеш-функции для шардирования 118Часть II. Паттерны проектирования обслуживающих систем
кэша из рассматриваемого примера переход с 10 шардов на 11 вы-зовет перенаправление менее 10 % запросов ( K / 11). Это гораздо лучше, чем потерять весь шардированный сервис. Практикум. Построение консистентного шардированного прокси-сервера Первый вопрос, которым стоит задаться при шардировании HTTP-запросов, — какой ключ использовать в шардиру ющей функции? Есть несколько подходов, но в общем случае не-плохо подойдет путь HTTP-запроса, совмещенный с пара-метрами запроса и всем тем, что делает запрос уникальным. И это без учета cookies и языка/страны (например, en-us). Если ваш сервис позволяет пользователю выполнять тон-кую настройку параметров, их значения также стоит сделать частью ключа.
В качестве шардирующего прокси может выступать nginx. worker_processes 5;
error_log error.log;
pid nginx.pid;
worker_rlimit_nofile 8192;
events {
worker_connections 1024;
}
http {
# Определяем именованный «обработчик», который можно будет # указать в директиве proxy ниже
upstream backend {
# Хешируем URI-адрес запроса с использованием # консистентной хеш-функции
hash $request_uri consistent
server web-shard-1.web;
server web-shard-2.web;
Глава 6. Шардированные сервисы 119
server web-shard-3.web;
}
server {
listen localhost:80;
location / {
proxy_pass http://backend;
}
}
}
Обратите внимание, что в качестве ключа мы используем пол-ный URI запроса, а также указываем ключевое слово con sistent , чтобы nginx задействовал консистентную хеш-функцию. Шардирование реплицированных сервисов
В большей части примеров в этой главе описывается шар-дирование кэша. Кэш, безусловно, не единственный сервис, которому шардирование пойдет на пользу. Шардирование подойдет для любого сервиса, в котором хранится больше данных, чем может поместиться на одной машине. В отличие от предыдущих примеров, ключ и функция шардирования являются не частью HTTP-запроса, а частью пользователь-
ского контекста.
Рассмотрим, например, реализацию крупномасштабной много-пользовательской игры. Мир такой игры, скорее всего, слиш-ком велик для хранения на одной машине. Маловероятно, что игроки, находящиеся в этом мире далеко друг от друга, будут как-то взаимодействовать. Следовательно, игровой мир может быть шардирован на несколько машин. Ключом шардирующей функции в этом случае будет местоположение пользователя на игровой карте. Таким образом, все игроки, находящиеся 120Часть II. Паттерны проектирования обслуживающих систем в одной части карты, будут обслуживаться одной и той же группой серверов.
Системы с «горячим»
шардированием
В идеале нагрузка на шардированный кэш должна быть равно-мерной, но во многих случаях это не так. За счет этого появ-ляются «горячие» шарды, поскольку естественные закономер-ности в распределении нагрузки приводят к тому, что на одни шарды приходится больше трафика, чем на другие. Рассмотрим, например, шардированный кэш пользователь-ских фотографий. Когда какая-то фотография приобретает «вирусную» популярность, на нее приходится несоразмерно больше трафика, чем на другие, и шард кэша, содержащий эту фотографию, становится «горячим». Когда в реплициро-ванном шардированном кэше возникает такая ситуация, этот шард можно масштабировать в соответствии с выросшей нагрузкой.
Если для шардов настроено автоматическое масштабирование, можно в зависимости от роста или падения нагрузки динами-чески выделять и освобождать ресурсы, предназначенные для реплицированных шардов. Данный процесс проиллюстриро-ван на рис. 6.3.
Сначала все три шарда обрабатывают одинаковое количество трафика. Затем трафик перераспределяется таким образом, что на шард А приходится в четыре раза больше трафика, чем на шарды Б и В. Система с «горячим» шардированием пере-мещает шард Б на машину с шардом В, а шард А реплицирует на вторую машину. Реплики теперь делят трафик поровну. Глава 6. Шардированные сервисы 121
Рис. 6.3. Пример системы с «горячим» шардированием. Сначала шардынагружены равномерно, но когда нагрузка на шард A увеличивается, он реплицируется на две машины, а шарды Б и B попадают на одну
Читать дальше