Решения Rails для MySQL Cluster (NDB)?

Я настраиваю среду высокой доступности для клиента. Существует пара хостов с балансировкой нагрузки, обслуживающих http-запросы к нашему приложению Rails, которое параллельно разворачивается на обоих хостах.

Кроме того, доступно два хоста MySQL. Я хочу запустить MySQL Cluster (NDB) на обоих хостах (т. Е. Multi-master), чтобы иметь полностью избыточную конфигурацию. Я специально пытаюсь избежать конфигурации главный-подчиненный на основе репликации базы данных; Я чувствую, что это делает записываемый узел единственной точкой отказа.

Я ищу несколько советов о том, как лучше всего связать наше приложение Rails с кластером MySQL с несколькими мастерами, как это. Почти все адаптеры базы данных, которые я могу найти, предназначены для установок "главный-подчиненный". Failover_adapter звучит очень многообещающе, но очень устарело. Мне не удалось найти ничего похожего, разработанного за последние пять лет.

Кто-нибудь знает о каких-либо драгоценных камнях или подходах, которые они могут использовать в качестве адаптера между приложением Rails и кластером MySQL с несколькими мастерами, как я описал?

2 ответа

Решение

В итоге я не смог найти решение для адаптера, которое бы делало то, что я хотел.

Я остановился на использовании адаптера mysql2 и наведении его на обратный прокси-сервер (я использовал haproxy) перед кластером базы данных, который мог обрабатывать балансировку нагрузки и аварийное переключение между главными узлами.

Я только недавно настроил это. Там не должно быть много работы, которую нужно сделать.

В геме mysqladapter он определяет движок как InnoDB, который явно не подходит для кластеризации. Вам нужно добавить это в файл инициализации:

ActiveRecord::ConnectionAdapters::Mysql2Adapter
class ActiveRecord::ConnectionAdapters::Mysql2Adapter
  def create_table(table_name, options = {})
    super(table_name, options.reverse_merge(:options => "ENGINE=NDB"))
  end
end

Это оригинал в адаптере.

def create_table(table_name, options = {})
  super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB"))
end

Другим ключевым аспектом является то, что вы не хотите, чтобы миграции происходили одновременно, поэтому в файле deploy.rb:

task :migrate, :max_hosts => 1 do
  # sleep 0.5
  run "cd #{release_path} && bundle exec rake db:migrate RAILS_ENV=#{rails_env}"
end

Max hosts предотвращает параллельное выполнение миграций с помощью cap. Это важно, так как вы не хотите, чтобы кластер одновременно выполнял создание таблиц. Возможно, даже стоит добавить задержку, которую я прокомментировал выше, просто для дополнительной безопасности.

Еще один ключевой аспект. Не забудьте установить:

DataMemory = 
IndexMemory =

Значения по умолчанию являются чрезвычайно низкими. Обычно размер индекса составляет DataMemory/5-10

Еще одна ловушка, которую я видел до сих пор, в ваших узлах mysqld, убедитесь, что вы установили:

ndb_autoincrement_prefetch_sz

по крайней мере до 100. В противном случае объемные вставки будут длиться вечно. По умолчанию это 1.

РЕДАКТИРОВАТЬ:

ndb_autoincrement_prefetch_sz

Оставьте эту переменную полностью в покое. Не устанавливайте это. Это может привести к тому, что индексы с автоинкрементом станут не синхронизированы в кластере. Что является кошмаром для отладки.

Кроме того, убедитесь, что ваши узлы NDB не работают на том же сервере, что и узлы MGM NDB.

Удачного кодирования.

Объявление

Другие вопросы по тегам