Использование ProxySQL для маршрутизации INSERT в распределённом индексе RealTime

В этой статье мы обсудим, как использовать ProxySQL для маршрутизации вставок в распределённый RT индекс, используя Sphinx/Manticore Search.

Распределённый индекс в Manticore позволяет выполнять UPDATE по нескольким индексам RealTime, так как UPDATE отправляется во все индексы, но изменения происходят только в одном индексе (при условии, что у вас уникальные ID по всем индексам).

Для вставок распределённый индекс не знает, какой индекс следует выбрать, это означает, что нам нужно отправить вставку в один из подиндексов RealTime, что должно быть реализовано в коде приложения. Это имеет недостаток в том, что внесение изменений в распределённый индекс (например, добавление нового подиндекса RT) требует внесения изменений в код приложения.
ProxySQL — это прокси-сервер, осведомлённый о SQL, для MySQL. Поскольку Sphinx и Manticore Search имеют совместимый с mysql протокол, ProxySQL можно использовать для простого балансирования серверов Manticore. Но ProxySQL имеет отличную функцию: движок маршрутизации запросов на основе regexp, который позволяет не только маршрутизировать запросы, но и переписывать их.

Что мы собираемся сделать дальше, так это отправить вставку в распределённый индекс, и с помощью ProxySQL мы перепишем запрос, изменив целевой индекс вставки на основе выбранного критерия. Таким образом, нам не нужно вносить изменения в код приложения, если мы добавляем новые шардов в распределённый индекс или изменяем, как документы распределяются по шардов.

Рассмотрим распределённый индекс, состоящий из двух подиндексов RT. Мы хотим распределить вставку документов на основе четности идентификаторов документов.

index myrt {
     type  = distrubuted
     local = myrt1
     local = myrt2
}

Добавление сервера Manticore Search в качестве бэкенда

В этом примере мы будем рассматривать группу хостов с id 2 для нашего сервера Manticore.

Admin> INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES(2,'192.168.1.224',9306);

Admin> LOAD MYSQL SERVERS TO RUNTIME;

Добавление правил переписывания в ProxySQL

Мы хотим вставлять документы с нечётными идентификаторами в myrt1 и документы с чётными идентификаторами в myrt2. Мы определяем 2 правила, которые захватывают идентификаторы и в зависимости от четности идентификатора изменяют имя индекса перед отправкой запроса в Manticore.

Admin> INSERT INTO mysql_query_rules(rule_id,match_pattern,replace_pattern,destination_hostgroup,active)
VALUES(32,
'^INSERT INTO (\w+)\(id,content,title,user_id,group_id\) VALUES\(([0-9]*)([02468])',
'INSERT INTO \12(id,content,title,user_id,group_id)  VALUES(\2\3',2,1);

Admin> INSERT INTO mysql_query_rules(rule_id,match_pattern,replace_pattern,destination_hostgroup,active)
VALUES(33,
'INSERT INTO (\w+)\(id,content,title,user_id,group_id\) VALUES\(([0-9]*)([13579])',
'INSERT INTO \11(id,content,title,user_id,group_id)  VALUES(\2\3',2,1);

Admin> LOAD MYSQL QUERY RULES TO RUNTIME;

Обратите особое внимание при создании шаблонов regexp, а также на то, как вы строите запросы из вашего кода приложения, чтобы убедиться, что запросы будут захвачены.

Запуск SphinxQL через ProxySQL

Прежде чем мы запустим наши первые запросы, нам нужно создать пользователя в ProxySQL, который по умолчанию будет использовать группу хостов с id 2, чтобы запросы, выполняемые им, направлялись на наш сервер Manticore.

Admin> INSERT INTO mysql_users(username,password,active,default_hostgroup) VALUES('test','pass',1,2);

Admin> LOAD MYSQL USERS TO RUNTIME;

И давайте запустим несколько вставок (используя соединение ProxySQL):

mysql> INSERT INTO myrt(id,content,title,user_id,group_id) VALUES(1,'test1','test1',1,1);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO myrt(id,content,title,user_id,group_id) VALUES(2,'test2','test2',1,1);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO myrt(id,content,title,user_id,group_id) VALUES(20,'test20','test20',1,1);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO myrt(id,content,title,user_id,group_id) VALUES(11,'test11','test11',1,1);
mysql> select * from myrt;
+------+---------+----------+--------+
| id   | user_id | group_id | title  |
+------+---------+----------+--------+
|    1 |       1 |        1 | test1  |
|    2 |       1 |        1 | test2  |
|   11 |       1 |        1 | test11 |
|   20 |       1 |        1 | test20 |
+------+---------+----------+--------+
4 rows in set (0.00 sec)
mysql> select * from myrt1;
+------+---------+----------+--------+
| id   | user_id | group_id | title  |
+------+---------+----------+--------+
|    1 |       1 |        1 | test1  |
|   11 |       1 |        1 | test11 |
+------+---------+----------+--------+
2 rows in set (0.00 sec)

mysql> select * from myrt2;
+------+---------+----------+--------+
| id   | user_id | group_id | title  |
+------+---------+----------+--------+
|    2 |       1 |        1 | test2  |
|   20 |       1 |        1 | test20 |
+------+---------+----------+--------+
2 rows in set (0.00 sec)

Наконец, не забудьте сохранить изменения, внесённые в ProxySQL, на диск для сохранения:

Admin> SAVE MYSQL QUERY RULES TO DISK; SAVE MYSQL SERVERS TO DISK; SAVE MYSQL USERS TO DISK;

Установить Manticore Search

Установить Manticore Search