Модуль директоров VMOD — Varnish Directors
СИНOPSIS
import directors [as name] [from "path"] new xround_robin = directors.round_robin() VOID xround_robin.add_backend(BACKEND) VOID xround_robin.remove_backend(BACKEND) BACKEND xround_robin.backend() new xfallback = directors.fallback(BOOL sticky=0) VOID xfallback.add_backend(BACKEND) VOID xfallback.remove_backend(BACKEND) BACKEND xfallback.backend() new xrandom = directors.random() VOID xrandom.add_backend(BACKEND, REAL) VOID xrandom.remove_backend(BACKEND) BACKEND xrandom.backend() new xhash = directors.hash() VOID xhash.add_backend(BACKEND, REAL weight=1.0) VOID xhash.remove_backend(BACKEND) BACKEND xhash.backend(STRING) new xshard = directors.shard() VOID xshard.set_warmup(REAL probability=0.0) VOID xshard.set_rampup(DURATION duration=0) VOID xshard.associate(BLOB param=0) BOOL xshard.add_backend(BACKEND backend, [STRING ident], [DURATION rampup], [REAL weight]) BOOL xshard.remove_backend([BACKEND backend], [STRING ident]) BOOL xshard.clear() BOOL xshard.reconfigure(INT replicas=67) INT xshard.key(STRING) BACKEND xshard.backend([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy], [BLOB param], [ENUM resolve]) VOID xshard.debug(INT) new xshard_param = directors.shard_param() VOID xshard_param.clear() VOID xshard_param.set([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy]) STRING xshard_param.get_by() INT xshard_param.get_key() INT xshard_param.get_alt() REAL xshard_param.get_warmup() BOOL xshard_param.get_rampup() STRING xshard_param.get_healthy() BLOB xshard_param.use() BACKEND lookup(STRING)
ОПИСАНИЕ
vmod_directors обеспечивает балансировку нагрузки бэкендов в Varnish.
Модуль реализует методы балансировки нагрузки и служит примером того, как можно расширить возможности балансировки нагрузки в Varnish.
Для включения балансировки нагрузки необходимо импортировать этот vmod (directors).
Затем нужно определить ваши бэкенды. После объявления бэкендов вы можете добавить их в директор. Это происходит в выполняемом коде VCL. Если вы хотите эмулировать предыдущее поведение Varnish 3.0, вы можете просто инициализировать директоров в vcl_init{}, как показано ниже:
sub vcl_init {
new vdir = directors.round_robin();
vdir.add_backend(backend1);
vdir.add_backend(backend2);
}
Как видите, ничего не мешает вам манипулировать директорами в других частях VCL. Таким образом, у вас может быть код VCL, который будет добавлять дополнительные бэкенды в директор при запросе определённого URL.
Обратите внимание, что директора могут использовать другие директора в качестве бэкендов.
new xround_robin = directors.round_robin()
Создаёт директор с циклическим выбором бэкендов.
Этот директор будет выбирать бэкенды в циклическом порядке.
Пример:
new vdir = directors.round_robin();
VOID xround_robin.add_backend(BACKEND)
Добавляет бэкенд в директор с циклическим выбором.
Пример:
vdir.add_backend(backend1);
VOID xround_robin.remove_backend(BACKEND)
Удаляет бэкенд из директора с циклическим выбором.
Пример:
vdir.remove_backend(backend1);
BACKEND xround_robin.backend()
Выбирает бэкенд из директора.
Пример:
set req.backend_hint = vdir.backend();
new xfallback = directors.fallback(BOOL sticky=0)
Создаёт директор с выбором по умолчанию.
Директор с выбором по умолчанию будет по очереди проверять каждый добавленный бэкенд и возвращать первый, который работает.
Если sticky установлено в значение true, директор будет продолжать использовать работающий бэкенд, даже если доступен бэкенд с более высоким приоритетом. После исчерпания всего списка бэкендов, он начнёт заново с начала.
Пример:
new vdir = directors.fallback();
VOID xfallback.add_backend(BACKEND)
Добавляет бэкенд в директор.
Обратите внимание, что порядок добавления имеет значение для директора с выбором по умолчанию.
Пример:
vdir.add_backend(backend1);
VOID xfallback.remove_backend(BACKEND)
Удаляет бэкенд из директора.
Пример:
vdir.remove_backend(backend1);
BACKEND xfallback.backend()
Выбирает бэкенд из директора.
Пример:
set req.backend_hint = vdir.backend();
new xrandom = directors.random()
Создаёт директор с случайным выбором бэкенда.
Директор случайного выбора распределяет нагрузку по бэкендам, используя взвешенное распределение случайной вероятности.
Используется «тестируемый» генератор случайных чисел в varnishd, что позволяет проводить детерминированные тесты (См.: d00004.vtc).
Пример:
new vdir = directors.random();
VOID xrandom.add_backend(BACKEND, REAL)
Добавляет бэкенд в директор с заданным весом.
Каждый бэкенд получит приблизительно 100 * (вес / (сумма_всех_весов)) процентов трафика, отправленного в этот директор.
Пример:
# 2/3 to backend1, 1/3 to backend2. vdir.add_backend(backend1, 10.0); vdir.add_backend(backend2, 5.0);
VOID xrandom.remove_backend(BACKEND)
Удаляет бэкенд из директора.
Пример:
vdir.remove_backend(backend1);
BACKEND xrandom.backend()
Выбирает бэкенд из директора.
Пример:
set req.backend_hint = vdir.backend();
new xhash = directors.hash()
Создаёт директор с выбором бэкенда по хэшу.
Директор выбирает сервер бэкенда, вычисляя хэш/хеш-сумму строки, переданной в xhash.backend().
Обычно используется с client.ip или куки сессии для сохранения состояния сессий.
Пример:
new vdir = directors.hash();
VOID xhash.add_backend(BACKEND, REAL weight=1.0)
Добавляет бэкенд в директор с определённым весом.
Вес используется так же, как и в директоре случайного выбора. Рекомендуемое и значение по умолчанию — 1.0, если нет особых потребностей.
Пример:
vdir.add_backend(normal_backend); vdir.add_backend(larger_backend, 1.5);
VOID xhash.remove_backend(BACKEND)
Удаляет бэкенд из директора.
- Пример:
-
vdir.remove_backend(larger_backend);
BACKEND xhash.backend(STRING)
Выбирает бэкенд из хэш-директора.
Используйте предоставленную строку или список строк для выбора бэкенда.
- Пример:
-
# выбрать бэкенд на основе заголовка куки клиента set req.backend_hint = vdir.backend(req.http.cookie);
new xshard = directors.shard()
Создать директора фрагментации.
Введение
Директор фрагментации выбирает бэкенды по ключу, который может быть предоставлен непосредственно или получен из строк. Для одного и того же ключа директор фрагментации всегда будет возвращать один и тот же бэкенд, если только конфигурация или состояние здоровья бэкенда не изменятся. Напротив, для разных ключей директор фрагментации, скорее всего, выберет разные бэкенды. По умолчанию нездоровые бэкенды не выбираются.
Директор фрагментации похож на директора хэширования, но его основное преимущество заключается в том, что при изменении конфигурации или состояния здоровья бэкендов связь ключей с бэкендами остается максимально стабильной.
Кроме того, функции плавного включения и предварительной подготовки могут помочь дополнительно улучшить время отклика, воспринимаемое пользователем.
Метод
Когда xshard.reconfigure() вызывается явно (или неявно в конце любой задачи, содержащей переконфигурации, как xshard.add_backend()), из последних 32 бит значений хэша SHA256 идентификаторов <ident><n> (по умолчанию ident — имя бэкенда) для каждого бэкенда и для числа n от 1 до аргумента replicas для xshard.reconfigure() создаётся циклическая структура данных с консистентным хэшированием. Хэширование создаёт кажущийся случайный порядок размещения бэкендов по кольцу консистентного хэширования. Когда xshard.add_backend() вызывался с аргументом weight, replicas масштабируется с этим весом, чтобы добавить пропорционально больше копий этого бэкенда в кольцо.
Когда вызывается xshard.backend(), генерируется ключ балансировки нагрузки, если он не предоставлен. Ищется наименьшее значение хэша в круге, которое больше ключа (поиск по часовой стрелке и обход, если необходимо). Бэкенд для этого значения хэша является предпочтительным бэкендом для данного ключа.
Если запрашивается здоровый бэкенд, поиск продолжается линейно по кольцу, пока не найдутся здоровые бэкенды или пока все бэкенды не будут проверены. Порядок этих «альтернативных бэкендов» в кольце, вероятно, будет отличаться для разных ключей. Альтернативные бэкенды также могут быть выбраны явно.
О консистентном хэшировании см.:
- http://www8.org/w8-papers/2a-webserver/caching/paper2.html
- http://www.audioscrobbler.net/development/ketama/
- svn://svn.audioscrobbler.net/misc/ketama
- http://en.wikipedia.org/wiki/Consistent_hashing
Отчёт об ошибках
Ошибочные методы должны сообщать об ошибках VSL с тегом ошибки, поэтому при настройке директора фрагментации рекомендуется проверить:
varnishlog -I Error:^vmod_directors.shard
Дополнительная информация может быть предоставлена в виде сообщений, которые можно проверить с помощью
varnishlog -I Notice:^vmod_directors.shard
VOID xshard.set_warmup(REAL probability=0.0)
Установить вероятность предварительной подготовки по умолчанию. См. параметр warmup в xshard.backend(). Если probability равен 0.0 (по умолчанию), предварительная подготовка отключена.
VOID xshard.set_rampup(DURATION duration=0)
Установить продолжительность плавного включения по умолчанию. См. параметр rampup в xshard.backend(). Если duration равен 0 (по умолчанию), плавное включение отключено.
VOID xshard.associate(BLOB param=0)
Связать объект по умолчанию directors.shard_param() или очистить связь.
Значение аргумента param должно быть вызовом метода xshard_param.use(). Отсутствие аргумента очищает связь.
Связь может быть изменена для каждого запроса бэкенда с помощью аргумента param в xshard.backend().
BOOL xshard.add_backend(BACKEND backend, [STRING ident], [DURATION rampup], [REAL weight])
BOOL xshard.add_backend(
BACKEND backend,
[STRING ident],
[DURATION rampup],
[REAL weight]
)
Добавить бэкенд backend в директора.
ident: Необязательно укажите строку идентификации для этого бэкенда, которая будет хэшироваться методом xshard.reconfigure() для построения кольца консистентного хэширования. Строка идентификации по умолчанию — имя бэкенда.
ident позволяет добавить несколько экземпляров одного и того же бэкенда.
rampup: Необязательно укажите определённое время плавного включения для этого бэкенда. В противном случае используется время плавного включения для директора (см. xshard.set_rampup()).
weight: Необязательно укажите вес для масштабирования параметра replicas в методе xshard.reconfigure(). weight ограничен значением не менее 1. Значения выше 10, вероятно, не имеют большого смысла. Эффект weight также ограничен таким образом, что общее количество реплик не превышает UINT32_MAX.
BOOL xshard.remove_backend([BACKEND backend], [STRING ident])
BOOL xshard.remove_backend(
[BACKEND backend=0],
[STRING ident=0]
)
Удалить бэкенд(ы) из директора. Должен быть указан либо backend, либо ident. ident удаляет определённый экземпляр. Если backend задан без ident, удаляются все экземпляры этого бэкенда.
BOOL xshard.clear()
Удалить все бэкенды из директора.
BOOL xshard.reconfigure(INT replicas=67)
Явно переконфигурировать кольцо консистентного хэширования, чтобы отразить изменения бэкенда, которые станут эффективными немедленно.
Если этот метод не вызывается явно, переконфигурация происходит в конце текущей задачи (после vcl_init {} или по завершении текущей задачи клиента или бэкенда).
INT xshard.key(STRING)
Метод удобства для генерации ключа фрагментации для использования с аргументом key в методе xshard.backend() путём хэширования заданной строки с помощью SHA256.
Для генерации ключей фрагментации с использованием других хэшей используйте пользовательский vmod, как vmod blobdigest с аргументом key_blob в методе xshard.backend().
BACKEND xshard.backend([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy], [BLOB param], [ENUM resolve])
BACKEND xshard.backend(
[ENUM {HASH, URL, KEY, BLOB} by=HASH],
[INT key],
[BLOB key_blob],
[INT alt=0],
[REAL warmup=-1],
[BOOL rampup=1],
[ENUM {CHOSEN, IGNORE, ALL} healthy=CHOSEN],
[BLOB param],
[ENUM {NOW, LAZY} resolve]
)
Выполнить поиск бэкенда на кольце консистентного хэширования.
В данной документации используется понятие порядка бэкендов для определенного ключа фрагментации. Этот порядок детерминирован, но, по-видимому, случайный, как определено алгоритмом консистентного хэширования, и, скорее всего, будет отличаться для разных ключей, в зависимости от количества бэкендов и реплик. В частности, порядок бэкендов, о котором здесь говорится, — _не_ порядок, в котором бэкенды добавляются.
-
by способ определения ключа фрагментации
-
HASH:- при вызове в контексте бэкенда и в
vcl_pipe {}: Используйте значение хэша varnish, установленноеvcl_hash{} - при вызове в контексте клиента, отличном от
vcl_pipe {}: хэшируйтеreq.url
- при вызове в контексте бэкенда и в
-
URL: хэширование req.url / bereq.url -
KEY: использовать аргумент key -
BLOB: использовать аргумент key_blob
-
-
key ключ поиска с
by=KEYметод xshard.key() может оказаться полезным для генерации ключа фрагментации из пользовательских строк.
-
key_blob ключ поиска с
by=BLOBВ настоящее время используется первые 4 байта из заданного двоичного блока в сетевом порядке байтов (big endian), дополненные нулями слева для блоков размером меньше 4 байтов.
-
alt альтернативный выбор бэкенда
Выберите alt-й альтернативный бэкенд для данного key.
Это особенно полезно для повторных попыток/перезапусков из-за ошибок бэкенда: установив
alt=req.restartsилиalt=bereq.retriesс healthy=ALL, выбирается другой сервер.Функции rampup и warmup активны только для
alt==0 -
rampup медленный старт для серверов, которые только что стали доступными
Если
alt==0и выбранный бэкенд находится в период rampup, с вероятностью, пропорциональной доле времени с момента, когда резервный бэкенд стал доступным, до периода rampup, возвращается следующий альтернативный бэкенд, если он также не находится в периоде rampup.Значение по умолчанию для интервала rampup может быть установлено для каждого управляющего фрагмента директории с помощью метода xshard.set_rampup() или конкретно для каждого бэкенда с помощью метода xshard.add_backend().
-
warmup вероятностный выбор альтернативного сервера
возможные значения: -1, 0..1
-1: используйте вероятность warmup из определения директораИспользуется только для
alt==0: Устанавливает отношение запросов (от 0,0 до 1,0), направляемых на следующий альтернативный бэкенд для его разогрева, когда предпочтительный бэкенд доступен. Неактивно, если любой из предпочтительного или альтернативного бэкендов находится в режиме rampup.warmup=0.5— удобный способ распределения нагрузки для каждого ключа между двумя бэкендами в обычных условиях работы. -
healthy
-
CHOSEN: Возвратить доступный бэкенд, если это возможно.
Для
alt==0, возвращается первый доступный бэкенд или ничего.Для
alt > 0, игнорируется состояние здоровья бэкендов, пропущенных при выборе альтернативного бэкенда, затем возвращается следующий доступный бэкенд. Если такого нет, возвращается последний доступный бэкенд из тех, что были пропущены, или ничего. -
IGNORE: Полностью игнорировать состояние здоровья бэкенда
Просто вернуть первый или alt-й альтернативный бэкенд, игнорируя состояние здоровья, rampup и warmup.
-
ALL: Проверять состояние здоровья также для альтернативного выбора бэкенда
Для
alt > 0, возвращается alt-й альтернативный бэкенд из всех доступных, последний доступный бэкенд, который был найден, или ничего.
-
-
resolve
по умолчанию:
LAZYвvcl_init{},NOWв противном случае-
NOW: выполнить поиск бэкенда и вернуть его.Не может быть использовано в
vcl_init{}. -
LAZY: вернуть экземпляр этого директора для последующего разрешения бэкенда.LAZYрежим необходим для ссылки на экземпляры управляющих фрагментов директорий, например, как бэкенды для других директоров (слоение директоров).В
vcl_init{}и на стороне клиента,LAZYрежим не может быть использован ни с каким другим аргументом.На стороне бэкенда и в
vcl_pipe {}, параметры из аргументов или связанного набора параметров влияют на экземпляр управляющего фрагмента директории для запроса бэкенда независимо от того, где он ссылается.
-
-
param
Использовать или связать набор параметров. Значение аргумента param должно быть вызовом метода xshard_param.use().
по умолчанию: как установлено методом xshard.associate() или не задано.
- для
resolve=NOWвзять параметры по умолчанию из набора параметров directors.shard_param() -
для
resolve=LAZYсвязать набор параметров directors.shard_param() для этого запроса бэкендаПримечания по реализации использования наборов параметров с
resolve=LAZY:- Аргумент param остается связанным, и любые изменения связанного набора параметров влияют на решение фрагментации, как только директор определит фактический бэкенд.
- Если также заданы другие аргументы параметров, они имеют приоритет и сохраняются, даже если набор параметров, заданный аргументом param, впоследствии изменяется в рамках одного запроса бэкенда.
- Каждый вызов xshard.backend() переопределяет любой предыдущий вызов.
- для
VOID xshard.debug(INT)
намеренно не документировано
new xshard_param = directors.shard_param()
Создать набор параметров фрагментации.
Набор параметров позволяет повторно использовать аргументы xshard.backend() в нескольких экземплярах управляющих фрагментов директорий и упрощает сложные случаи использования (например, управляющий фрагмент директории с пользовательскими параметрами, расположенный ниже других директоров).
Наборы параметров имеют два раздела:
- область VCL, определенная в
vcl_init{} - область запроса бэкенда
Область VCL определяет значения по умолчанию для области запроса бэкенда. Любые изменения набора параметров в контексте бэкенда и в vcl_pipe {} влияют только на соответствующий запрос бэкенда.
Наборы параметров не могут использоваться в контексте клиента, за исключением vcl_pipe {}.
Следующий пример — типичный случай использования: набор параметров связан с несколькими директорами. Выбор директора происходит на стороне клиента, а параметры изменяются на стороне бэкенда для реализации повторных попыток на альтернативных бэкендах:
sub vcl_init {
new shard_param = directors.shard_param();
new dir_A = directors.shard();
dir_A.add_backend(...);
dir_A.reconfigure();
dir_A.associate(shard_param.use()); # <-- !
new dir_B = directors.shard();
dir_B.add_backend(...);
dir_B.reconfigure();
dir_B.associate(shard_param.use()); # <-- !
}
sub vcl_recv {
if (...) {
set req.backend_hint = dir_A.backend(resolve=LAZY);
} else {
set req.backend_hint = dir_B.backend(resolve=LAZY);
}
}
sub vcl_backend_fetch {
# changes dir_A and dir_B behaviour
shard_param.set(alt=bereq.retries, by=URL);
}
VOID xshard_param.clear()
Сбросить набор параметров до значений по умолчанию, как документировано для xshard.backend().
- в
vcl_init{}, сбрасывает значения параметров по умолчанию для этой VCL - в контексте бэкенда и в
vcl_pipe {}, сбрасывает набор параметров для этого запроса бэкенда до значений по умолчанию VCL
Ограничено для: vcl_pipe, backend, housekeeping.
VOID xshard_param.set([ENUM by], [INT key], [BLOB key_blob], [INT alt], [REAL warmup], [BOOL rampup], [ENUM healthy])
VOID xshard_param.set(
[ENUM {HASH, URL, KEY, BLOB} by],
[INT key],
[BLOB key_blob],
[INT alt],
[REAL warmup],
[BOOL rampup],
[ENUM {CHOSEN, IGNORE, ALL} healthy]
)
Изменить заданные параметры набора параметров, как описано для xshard.backend().
- в
vcl_init{}, изменить значения параметров по умолчанию для этой VCL - в контексте бэкенда и в
vcl_pipe {}, изменить набор параметров для этого запроса бэкенда, сохраняя значения по умолчанию для этой VCL для не указанных аргументов.
Ограничено для: vcl_pipe, backend, housekeeping.
STRING xshard_param.get_by()
Получить строковое представление аргумента by перечисления, которое определяет, как управляющий фрагмент фрагментации, использующий этот объект параметра, выведет ключ фрагментации. См. xshard.backend().
INT xshard_param.get_key()
Получить ключ, который управляющий фрагмент фрагментации, использующий этот объект параметра, будет использовать. См. xshard.backend().
INT xshard_param.get_alt()
Получить параметр alt, который управляющий фрагмент фрагментации, использующий этот объект параметра, будет использовать. См. xshard.backend().
REAL xshard_param.get_warmup()
Получить параметр warmup, который управляющий фрагмент фрагментации, использующий этот объект параметра, будет использовать. См. xshard.backend().
BOOL xshard_param.get_rampup()
Получить параметр rampup, который управляющий фрагмент фрагментации, использующий этот объект параметра, будет использовать. См. xshard.backend().
STRING xshard_param.get_healthy()
Получить строковое представление аргумента healthy перечисления, которое будет использоваться управляющим фрагментом фрагментации, использующим этот объект параметра. См. xshard.backend().
BLOB xshard_param.use()
Для использования с аргументом param метода xshard.backend() для связывания этого набора параметров фрагментации с управляющим фрагментом фрагментации.
Ограничено для: vcl_pipe, backend, housekeeping.
BACKEND lookup(STRING)
Поиск бэкенда по его имени.
Ограничено для: housekeeping.
БЛАГОДАРНОСТИ
Разработка предыдущей версии директора фрагментов частично спонсировалась компанией Deutsche Telekom AG - Products & Innovation.
Разработка предыдущей версии директора фрагментов частично спонсировалась компанией BILD GmbH & Co KG.
АВТОРСКИЕ ПРАВА
This document is licensed under the same licence as Varnish
itself. See LICENCE for details.
SPDX-License-Identifier: BSD-2-Clause
Copyright (c) 2013-2015 Varnish Software AS
Copyright 2009-2020 UPLEX - Nils Goroll Systemoptimierung
All rights reserved.
Authors: Poul-Henning Kamp <phk@FreeBSD.org>
Julian Wiesener <jw@uplex.de>
Nils Goroll <slink@uplex.de>
Geoffrey Simmons <geoff@uplex.de>
SPDX-License-Identifier: BSD-2-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Copyright © 2006 Verdens Gang AS
Copyright © 2006–2020 Varnish Software AS
Licensed under the BSD-2-Clause License.
https://varnish-cache.org/docs/7.4/reference/vmod_directors.html