research: работа пула с мастерами/репликами
на текущий момент пул работает следующим образом
изначальное построение коннектов:
- для discovery режима пул устанавливает коннекты ко всем нодам кластера (если возможно), независимо от реплика/мастер
- для bootstrap режима пул устанавливает коннекты ко всем указанным в DSN нодам (независимо от реплика/мастер)
перестройка состава пула по топологии:
- для discovery режима пул периодически закрывает/открывает новые соединения в соответствии с изменениями топологии (ноды умерли/ожили) независимо от реплика/мастер начиная с 2.0
- для bootstrap режима
не поддерживаетсяподдерживается начиная с 3.0
роутинг запросов:
- для DQL, DDL, DML* запросов пул использует соединение в соответствии со своей политикой балансировки (по умолчанию rr). таким образом, могут использоваться как мастера, так и реплики
- для DML: insert (parametrized query) пул вычисляет по метаданным от пикодаты (если возможно) необходимый репликасет и направляет запрос на мастер нужного репликасета. если сделать этого не удалось (вычислить репликасет или мастера нет в пуле и тп), пул направляет запрос по тому же принципу, как написано выше
Предмет задачи
Необходимо изучить и составить решение, каким образом наполнять пул (к каким нодам) и каким образом использовать для запросов
Является предпочтительным использовать всегда мастера (тогда, возможно, и наполнять пул стоит только мастерами)
Опции Picodata
-FORWARD (pico 26.2) опция дает ошибки при неверном роутинге (например если при forward=off пикодате необходимо запрос переадресовать внутри себя, будет ошибка). в целом forward вынесен в отдельную задачу #114
READ_PREFERENCE(pico 26.1) опция имеет три значения:leader(по умолчанию) выполняет чтение только на лидерах репликасетов,replicaтолько на репликах,anyна любом узле репликасета
не дает ошибки при неверном роутинге, но может влиять на производительность. например, если при read_preference=replica послать запрос на мастер, то пикодата перешлет его на реплику для чтение и потом отдаст ответ. получаем дополнительный сетевой хоп, но в то же время разгружаем роутер (координатор)
при этом опции можем задать несколькими способами:
OPTION (READ_PREFERENCE = ...)в тексте запроса -- драйвер не распознает;- startup-параметр сессии
options=read_preference=<v>в доп аргументах или прямо в DSN?options=read_preference%3D<v>в DSN -- драйвер может распознать и это не дорого для пула, так как делается один раз ALTER SYSTEM SET read_preference = '<v>'-- драйвер может распознать через запрос к системной таблице, но смысла не имеет, т.к. может меняться в системе постоянно
Ограничения и ошибки:
- если в запроса DML/DDL задать
OPTION (READ_PREFERENCE = ...), то ошибкаread_preference option is supported only for DQL queries - DML всегда диспатчится как
leader, еслиREAD_PREFERENCEуказан на уровне сессии, то есть нет ошибки - если значение
replicaи в репликасете нет реплик, то вероятно ошибка таумаута - для unlogged-таблиц только одно значение валидно:
read_preference must be set to 'leader' when querying unlogged tables - при режиме
sql_preemptionтолько одно значение валидно:read_preference must be set to 'leader' when sql_preemption is enabled
Надо как-то предупредить пользователя или сослаться на предупреждение от Picodata, что чтение с реплик допустимо, если пишущая нагрузка не пересекается с читающей и топология не меняется во время чтения, иначе возможны неконсистентные результаты
Предлагаемое решение
Новая настройка пула
Добавить настройку instance_role с значениями ["any" (default), "leader", "replica"]. Эта настройка доп фильтр на создание пользовательских соединений к узлам, как forbidden tiers. Предположительно, доработка минимальна, т.к. reconcile и rebalance алгоритм умеют работать с топологией с доп ограничениями (forbidden tiers, DSN при bootstrap режиме). Доработка в основном понадобится только для старта пула, т.к. на старте мы пользуемся на топологией, а системными таблицами. У нас есть TODO на ресерч данной темы (не стоит ли перейти на топологию и тут)
При выключенной топологии также можно задавать instance_role, но тогда список узлов фиксируется один раз на старте и драйвер не будет реагировать на изменения топологии, в тч смену лидера. Надо проговорить в доке
Поддержка startup опций
Если опции настроены через аргументы/DSN, на нашей стороне необходимо:
- проверить, что нет конфликта с
instance_role(если есть => явная ошибка) - использовать режим на основе переданной настройки.
read_preference=leader=>instance_role=leader,read_preference=any=>instance_role=any,read_preference=replica=>instance_role=any. Последнее связано с тем, что replica будет использоваться пикодатой только на чтение. Если мы откроем пул только из реплик (без прямого указания от пользователя), мы получим значительное ухудшение записи.
Остальные способы настройки read_preference драйвером не обрабатываются из-за отсутствия возможности или целесообразности
Definition of done
- изучение новых опций пикодата и их работы, по ним составить описание
- составленные кейсы использования
- дизайн на стороне драйвера: новая конфигурация, дефолтное поведение, фиксация инструкции для пользователя (
пусть разработчик сам ищет баги в своем коде-- тоже вариант) - заведенные задачи на разработку/баги по принятым решениям