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

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

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

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

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

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

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

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

В этом примере мы будем использовать идентификатор группы хостов 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

Мы хотим вставлять документы с нечетными ID в myrt1 и документы с четными ID в myrt2. Мы определим 2 правила, которые захватывают ID и, в зависимости от четности, изменяют имя индекса перед отправкой запроса в 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;

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

Выполнение SphinxQL через ProxySQL

Перед выполнением первых запросов нам нужно создать пользователя в ProxySQL, который по умолчанию будет использовать идентификатор группы хостов 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