В кластере с мульти-мастер репликацией необходимо установить опорную точку, прежде чем другие узлы смогут присоединиться и сформировать кластер. Это называется инициализацией кластера и включает запуск одного узла как primary component. Перезапуск одного узла или повторное подключение после выключения можно выполнять в обычном режиме.
В случае полного выключения кластера сервер, который был остановлен последним, должен быть запущен первым с опцией командной строки --new-cluster или путем запуска manticore_new_cluster через systemd. Чтобы убедиться, что сервер может быть опорной точкой, файл grastate.dat, расположенный в пути кластера, должен быть обновлен значением 1 для опции safe_to_bootstrap. Должны быть выполнены оба условия: --new-cluster и safe_to_bootstrap=1. Если любой другой узел будет запущен без этих установленных опций, возникнет ошибка. Опция командной строки --new-cluster-force может быть использована для принудительного обхода этой защиты и запуска кластера с другого сервера. Альтернативно, можно запустить manticore_new_cluster --force для использования systemd.
В случае жесткого сбоя или некорректного выключения всех серверов в кластере необходимо определить наиболее продвинутый узел с наибольшим seqno в файле grastate.dat, расположенном в пути кластера, и запустить его с ключом командной строки --new-cluster-force.
В случае, если демон поиска Manticore останавливается и в кластере не остается узлов для обслуживания запросов, необходимо восстановление. Благодаря мульти-мастерной природе библиотеки Galera, используемой для репликации, кластер репликации Manticore является единой логической сущностью, которая поддерживает согласованность своих узлов и данных, а также состояние всего кластера. Это позволяет безопасно выполнять записи на нескольких узлах одновременно и обеспечивает целостность кластера.
Однако это также создает определенные сложности. Рассмотрим несколько сценариев, используя кластер из узлов A, B и C, чтобы понять, что нужно делать, когда некоторые или все узлы становятся недоступными.
Когда узел A останавливается, другие узлы получают сообщение о "нормальном завершении работы". Размер кластера уменьшается, и происходит перерасчет кворума.
При запуске узел A присоединяется к кластеру и не будет обслуживать транзакции записи, пока полностью не синхронизируется с кластером. Если кэш writeset на донорских узлах B или C (который можно контролировать с помощью параметра Galera кластера gcache.size) все еще содержит все транзакции, пропущенные узлом A, узел A получит быстрый инкрементальный перенос состояния (IST), то есть перенос только пропущенных транзакций. Если нет, произойдет перенос состояния снимка (SST), который включает передачу файлов таблиц.
В сценарии, когда узлы A и B остановлены, размер кластера уменьшается до одного, и узел C формирует основной компонент для обработки транзакций записи.
Узлы A и B затем могут быть запущены как обычно и присоединятся к кластеру после запуска. Узел C выступает в роли донора, предоставляя перенос состояния узлам A и B.
Все узлы остановлены как обычно, и кластер выключен.
Проблема теперь в том, как инициализировать кластер. Важно, чтобы при корректном завершении работы searchd узлы записывали номер последней выполненной транзакции в файл grastate.dat в каталоге кластера вместе с флагом safe_to_bootstrap. Узел, который был остановлен последним, будет иметь опцию safe_to_bootstrap: 1 и самый продвинутый номер seqno.
Важно, чтобы этот узел запускался первым для формирования кластера. Для инициализации кластера сервер должен быть запущен на этом узле с флагом --new-cluster. В Linux также можно запустить manticore_new_cluster, который запустит Manticore в режиме --new-cluster через systemd.
Если другой узел запускается первым и инициализирует кластер, тогда самый продвинутый узел присоединится к этому кластеру, выполнит полный SST и получит файл таблицы, в котором некоторые транзакции отсутствуют по сравнению с файлами таблиц, которые он имел ранее. Поэтому важно запускать первым узел, который был остановлен последним, он должен иметь флаг safe_to_bootstrap: 1 в grastate.dat.
В случае сбоя или сетевой ошибки, из-за которой узел A исчезает из кластера, узлы B и C попытаются переподключиться к узлу A. При неудаче они удалят узел A из кластера. При этом два из трех узлов продолжают работать, кластер сохраняет кворум и функционирует нормально.
При перезапуске узел A автоматически присоединится к кластеру, как описано в Случае 1.
Узлы A и B вышли из строя. Узел C не может сформировать кворум самостоятельно, так как 1 узел меньше половины от общего числа узлов (3). В результате кластер на узле C переходит в состояние non-primary и отклоняет любые транзакции записи с сообщением об ошибке.
Тем временем узел C ждет подключения других узлов и также пытается к ним подключиться. Если это происходит, и сеть восстанавливается, а узлы A и B возвращаются в онлайн, кластер автоматически восстанавливается. Если узлы A и B просто временно отключены от узла C, но могут общаться друг с другом, они продолжат работать нормально, так как все еще формируют кворум.
Однако, если оба узла A и B вышли из строя или перезапустились из-за отключения питания, кто-то должен активировать основной компонент на узле C с помощью следующей команды:
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1POST /cli -d "
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1
"Важно отметить, что перед выполнением этой команды необходимо убедиться, что другие узлы действительно недоступны. В противном случае может возникнуть ситуация "split-brain" и сформируются отдельные кластеры.
Все узлы вышли из строя. В этой ситуации файл grastate.dat в каталоге кластера не был обновлен и не содержит действительного номера последовательности seqno.
Если это произошло, необходимо найти узел с самыми свежими данными и запустить сервер на нем с использованием ключа командной строки --new-cluster-force. Все остальные узлы запустятся как обычно, как описано в Случае 3).
В Linux также можно использовать команду manticore_new_cluster --force, которая запустит Manticore в режиме --new-cluster-force через systemd.
Split-brain может привести к переходу кластера в состояние неосновного узла. Например, рассмотрим кластер, состоящий из четного числа узлов (четыре), таких как две пары узлов, расположенных в разных дата-центрах. Если сетевая ошибка прерывает соединение между дата-центрами, возникает split-brain, так как каждая группа узлов удерживает ровно половину кворума. В результате обе группы прекращают обработку транзакций записи, поскольку модель репликации Galera отдает приоритет согласованности данных, и кластер не может принимать транзакции записи без кворума. Однако узлы в обеих группах пытаются переподключиться к узлам из другой группы в попытке восстановить кластер.
Если кто-то хочет восстановить кластер до восстановления сети, следует выполнить те же шаги, описанные в Case 5, но только для одной группы узлов.
После выполнения оператора группа с узлом, на котором он был выполнен, сможет снова обрабатывать транзакции записи.
- SQL
- JSON
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1POST /cli -d "
SET CLUSTER posts GLOBAL 'pc.bootstrap' = 1
"Однако важно отметить, что если оператор будет выполнен в обеих группах, это приведет к формированию двух отдельных кластеров, и последующее восстановление сети не приведет к повторному объединению групп.
При стандартной конфигурации Manticore ожидает ваши подключения на:
- порт 9306 для клиентов MySQL
- порт 9308 для HTTP/HTTPS подключений
- порт 9312 для HTTP/HTTPS, а также подключений от других узлов Manticore и клиентов, использующих бинарный API Manticore
- SQL
- HTTP
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
- docker
mysql -h0 -P9306HTTP — это безсессионный протокол, поэтому не требует специальной фазы подключения:
curl -s "http://localhost:9308/search"require_once __DIR__ . '/vendor/autoload.php';
$config = ['host'=>'127.0.0.1','port'=>9308];
$client = new \Manticoresearch\Client($config);import manticoresearch
config = manticoresearch.Configuration(
host = "http://127.0.0.1:9308"
)
client = manticoresearch.ApiClient(config)
indexApi = manticoresearch.IndexApi(client)
searchApi = manticoresearch.searchApi(client)
utilsApi = manticoresearch.UtilsApi(client)import manticoresearch
config = manticoresearch.Configuration(
host = "http://127.0.0.1:9308"
)
async with manticoresearch.ApiClient(config) as client:
indexApi = manticoresearch.IndexApi(client)
searchApi = manticoresearch.searchApi(client)
utilsApi = manticoresearch.UtilsApi(client)var Manticoresearch = require('manticoresearch');
var client= new Manticoresearch.ApiClient()
client.basePath="http://127.0.0.1:9308";
indexApi = new Manticoresearch.IndexApi(client);
searchApi = new Manticoresearch.SearchApi(client);
utilsApi = new Manticoresearch.UtilsApi(client);import com.manticoresearch.client.ApiClient;
import com.manticoresearch.client.ApiException;
import com.manticoresearch.client.Configuration;
import com.manticoresearch.client.model.*;
import com.manticoresearch.client.api.IndexApi;
import com.manticoresearch.client.api.UtilsApi;
import com.manticoresearch.client.api.SearchApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("http://127.0.0.1:9308");
IndexApi indexApi = new IndexApi(client);
SearchApi searchApi = new UtilsApi(client);
UtilsApi utilsApi = new UtilsApi(client);using ManticoreSearch.Client;
using ManticoreSearch.Api;
using ManticoreSearch.Model;
string basePath = "http://127.0.0.1:9308";
IndexApi indexApi = new IndexApi(basePath);
SearchApi searchApi = new UtilsApi(basePath);
UtilsApi utilsApi = new UtilsApi(basePath);use std::sync::Arc;
use manticoresearch::{
apis::{
{configuration::Configuration,IndexApi,IndexApiClient,SearchApi,SearchApiClient,UtilsApi,UtilsApiClient}
},
};
async fn maticore_connect {
let configuration = Configuration {
base_path: "http://127.0.0.1:9308".to_owned(),
..Default::default(),
};
let api_config = Arc::new(configuration);
let utils_api = UtilsApiClient::new(api_config.clone());
let index_api = IndexApiClient::new(api_config.clone());
let search_api = SearchApiClient::new(api_config.clone());Запустите контейнер Manticore и используйте встроенный MySQL клиент для подключения к узлу.
docker run --name manticore -d manticoresearch/manticore && docker exec -it manticore mysqlManticore Search реализует SQL-интерфейс с использованием протокола MySQL, что позволяет использовать любую библиотеку или коннектор MySQL, а также многие клиенты MySQL для подключения к Manticore Search и работы с ним так, как если бы это был сервер MySQL, а не Manticore.
Однако диалект SQL отличается и реализует только подмножество команд или функций SQL, доступных в MySQL. Кроме того, существуют конструкции и функции, специфичные для Manticore Search, такие как конструкция MATCH() для полнотекстового поиска.
Manticore Search не поддерживает подготовленные выражения на стороне сервера, но можно использовать подготовленные выражения на стороне клиента. Важно отметить, что Manticore реализует тип данных с множественными значениями (MVA), который не имеет эквивалента в MySQL или библиотеках, реализующих подготовленные выражения. В таких случаях значения MVA должны быть сформированы в сыром запросе.
Некоторые клиенты/коннекторы MySQL требуют значения для пользователя/пароля и/или имени базы данных. Поскольку в Manticore Search нет концепции баз данных и не реализован контроль доступа пользователей, эти значения могут быть заданы произвольно, так как Manticore просто их игнорирует.
Порт по умолчанию для SQL-интерфейса — 9306, и он включён по умолчанию.
Вы можете настроить порт MySQL в разделе searchd конфигурационного файла, используя директиву listen следующим образом:
searchd {
...
listen = 127.0.0.1:9306:mysql
...
}
Имейте в виду, что в Manticore нет аутентификации пользователей, поэтому убедитесь, что порт MySQL недоступен для всех, кроме вашей сети.
Для выполнения "VIP"-подключений можно использовать отдельный порт MySQL. При подключении к этому порту пул потоков обходится, и всегда создаётся новый выделенный поток. Это полезно в случаях сильной перегрузки, когда сервер либо зависает, либо не позволяет подключиться через обычный порт.
searchd {
...
listen = 127.0.0.1:9306:mysql
listen = 127.0.0.1:9307:mysql_vip
...
}
Самый простой способ подключиться к Manticore — использовать стандартный клиент MySQL:
mysql -P9306 -h0
Протокол MySQL поддерживает шифрование SSL. Защищённые подключения могут быть выполнены на том же прослушивающем порту mysql.
Сжатие может использоваться с MySQL-подключениями и доступно клиентам по умолчанию. Клиенту нужно просто указать, что соединение должно использовать сжатие.
Пример с использованием клиента MySQL:
mysql -P9306 -h0 -C
Сжатие может использоваться как в защищённых, так и в незащищённых соединениях.
Официальные коннекторы MySQL могут использоваться для подключения к Manticore Search, однако они могут требовать определённых настроек, передаваемых в строке DSN, так как коннектор может пытаться выполнять некоторые SQL-команды, ещё не реализованные в Manticore.
JDBC Connector версии 6.x и выше требует Manticore Search версии 2.8.2 или выше, и строка DSN должна содержать следующие опции:
jdbc:mysql://IP:PORT/DB/?characterEncoding=utf8&maxAllowedPacket=512000&serverTimezone=XXX
По умолчанию Manticore Search сообщает коннектору свою версию, однако это может вызвать некоторые проблемы. Чтобы их избежать, директива mysql_version_string в разделе searchd конфигурационного файла должна быть установлена на версию ниже 5.1.1:
searchd {
...
mysql_version_string = 5.0.37
...
}
.NET MySQL коннектор по умолчанию использует пулы подключений. Чтобы корректно получать статистику SHOW META, запросы вместе с командой SHOW META должны отправляться как единый многооператорный запрос (SELECT ...;SHOW META). Если пуллинг включён, в строку подключения необходимо добавить опцию Allow Batch=True, чтобы разрешить многооператорные запросы:
Server=127.0.0.1;Port=9306;Database=somevalue;Uid=somevalue;Pwd=;Allow Batch=True;
К Manticore можно получить доступ через ODBC. Рекомендуется установить charset=UTF8 в строке ODBC. Некоторые драйверы ODBC не понравится версия, сообщаемая сервером Manticore, так как они воспримут её как очень старую версию MySQL. Это можно переопределить с помощью опции mysql_version_string.
Manticore SQL поверх MySQL поддерживает синтаксис комментариев в стиле C. Всё от открывающей последовательности /* до закрывающей */ игнорируется. Комментарии могут занимать несколько строк, не могут вкладываться и не должны логироваться. Специфичные для MySQL комментарии /*! ... */ также в настоящее время игнорируются. (Поддержка комментариев была добавлена скорее для лучшей совместимости с дампами, создаваемыми mysqldump, а не для улучшения общей совместимости запросов между Manticore и MySQL.)
SELECT /*! SQL_CALC_FOUND_ROWS */ col1 FROM table1 WHERE ...