Я установил Galera Cluster на 3 узлах. Он отлично работает для чтения данных. Я сделал простое приложение, чтобы протестировать кластер. К сожалению, я вынужден сказать, что кластер полностью терпит неудачу, когда я пытаюсь что-то написать. Может, его можно настроить по другому или я что-то не так делаю?
У меня есть простая хранимая процедура:
CREATE PROCEDURE testproc(IN p_idWorker INTEGER)
BEGIN
DECLARE t_id INT DEFAULT -1;
DECLARE t_counter INT ;
UPDATE test SET idWorker = p_idWorker WHERE counter = 0 AND idWorker IS NULL limit 1;
SELECT id FROM test WHERE idWorker = p_idWorker LIMIT 1 INTO t_id;
SELECT ABS(MAX(counter)/MIN(counter)) FROM TEST INTO t_counter;
SELECT COUNT(*) FROM test WHERE counter = 0 INTO t_counter;
IF t_id >= 0 THEN
UPDATE test SET counter = counter + 1 WHERE id = t_id;
UPDATE test SET idWorker = NULL WHERE id = t_id;
SELECT t_counter AS res;
ELSE
SELECT 'end' AS res;
END IF;
END $$
Теперь мое простое приложение на C # создает, например, 3 клиента MySQL в отдельных потоках, и каждый из них выполняет процедуру каждые 100 мс, пока не будет записи, в которой столбец counter = 0.
К сожалению, примерно через 10 секунд что-то пошло не так. На серверах есть процесс query_end, который никогда не заканчивается. После этого - обновить тестовую таблицу нельзя, MySQL возвращает:
ОШИБКА 1205 (HY000): Превышен тайм-аут ожидания блокировки; попробуйте перезапустить транзакцию
. Вы даже не можете перезапустить mysql. Что вы можете сделать, так это перезапустить сервер, а иногда и весь кластер. Неужели Galera Cluster настолько ненадежен, когда вы делаете массовые параллельные записи / обновления? Сложно поверить.
У нас была почти такая же проблема - когда мы обновляли его, не удалось с тайм-аутом блокировки. Наша текущая стратегия состоит в том, чтобы использовать 1 сервер для фоновых процессов и массовых операций записи, а другие 2 сервера использовать для живых веб-серверов.
Это довольно просто, если вы используете HAProxy, но нам также пришлось внести некоторые изменения в наш код.
Пока кажется, что он работает намного лучше, но мы обязательно посмотрим, будет ли он работать нормально через несколько недель (когда мы не столкнемся с теми же проблемами, что и были).
Некоторые заметки из нашего опыта:
Спустя несколько недель я могу сказать, что изменения действительно сильно изменились. Я думаю, что самым важным изменением был анализ фоновых процессов и их планирование, чтобы они не перекрывались (или не перекрывались так сильно).
Изменение сервера, так что только один сервер в основном используется для записи, а два других сервера используются для чтения, улучшило наш пользовательский опыт во время тяжелых фоновых процессов.
Третий шаг, который мы сделали, - это улучшение фоновых процессов. Во время одной транзакции программист уронил таблицу и перестроил ее с нуля. Мы изменили это, чтобы сначала проверить, необходимо ли изменение, а затем обновить строку. Это значительно улучшило производительность этого процесса.
Наш опыт показывает, что чтение в кластере Galera происходит очень быстро, но запись может быть довольно медленной, особенно если вы выполняете множество операций записи. Вначале у нас были проблемы, и нам пришлось повторно импортировать всю таблицу - это было большим убийством для базы данных. Еще одна вещь, которая дважды приводила к сбою нашего сервера, заключалась в том, что binlog заполнил диски сервера, что привело к сбою сервера. Также не забудьте изменить все базы данных на таблицы Innodb, иначе возможна потеря данных. Один из наших программистов установил все таблицы журналов в MyISAM - допустим, мы потеряли некоторые из наших журналов в этом процессе.
Но все-таки могу сказать, что Galera сейчас неплохо работает. Это особенно хорошо, если вам нужно обновить сервер БД или выполнить какое-либо другое обслуживание, поскольку это не большая проблема, если вы закрываете один узел для обслуживания.
Я знаю, что уже поздно, но я оставлю здесь немного своего опыта работы с кластером Galera. Наше приложение выполняет около 160-200 вставок в секунду, и мы делаем столько же операций чтения. Ночью это намного меньше, но днем это наше среднее значение, и оно может достигать максимальной ставки аренды. Мы, вероятно, находимся в другом контексте вашего приложения, но то, что помогло нам во время перехода со стандартного MySQL на Galera, - это настроить наше приложение на автоматическую фиксацию каждой транзакции, что мгновенно удалило поведение, которое вы описываете в этом вопросе.
В Python с использованием библиотеки PySQLPool нам пришлось добавить такую строку в нашу оболочку запроса:
PySQLPool.getNewQuery(self.connection, commitOnEnd=True)
Затем мы столкнулись с другой проблемой: он недостаточно быстро записывал данные в таблицы. Один из способов сделать это достаточно быстро - использовать innodb_flush_log_at_trx_commit вариант. Поскольку мы можем позволить себе потерю транзакции в 1 секунду, мы установили настройку в нашем my.cnf следующим образом:
innodb_flush_log_at_trx_commit = 0
С этими двумя простыми настройками мы уже более года работаем с Galera, и 3 сервера хорошо работают с нашим приложением.
Лучший.