В этой статье я расскажу о собственном опыте настройки кластера MySQL, вернее почему это не получилось сделать, а также о недостатках кластерного решения, предлагаемого MySQL и вообще о том, что желающим работать с кластером MySQL стоит сильно подумать - стоит ли это вообще делать! Несмотря на обилие статей о настройке кластера MySQL на русском языке, о недостатках и ограничениях кластера, авторы этих статей предпочитают умалчивать, что наводит на мыль о том, что либо они просто переводили английский оригинал документации по кластеру MySQL, либо запускали свой кластер на такой базе данных, которая может называться лишь тестовой, а не используемой в продуктивных системах с большим объёмом данных, разнообразной структурой и высокой нагрузкой. Автор: Виктор Вислобоков Итак, дано: существует БД, дамп которой, выполненный через mysqldump, составляет 2.5Gb. В общем довольно крупная БД, хотя и не сказать, чтобы очень. Нагрузка на MySQL сервер довольно велика, в связи с чем необходимо создать кластер и распределить эту нагрузку на вычислительную мощность двух серверов. Установка пакетов для кластера MySQLИтак, здесь вроде бы всё просто. У меня на серверах стоит CentOS 5.x, но вот незадача - пакета mysql-cluster ни в одном репозитарии для CentOS 5.x нет! Воспользовавшись поисковиками, я понял, что здесь удачи мне не видать - все занимались самосбором, версии какие-то древние, половина ссылок идёт в никуда. Разумеется первым делом, я зашёл на сайт MySQL, где раздаются как уже собранные пакеты под разные дистрибутивы, так и пакеты с исходными текстами. Собранного пакета под CentOS разумеется не было, был только пакет с исходными текстами для Red Hat Enterprise Linux 5 (почему? читайте маленькое пояснение ниже). Я взял эти исходники, но собираться под CentOS они не захотели с чем я поздравляю компанию Sun, которая теперь владеет MySQL! Поэтому я сделал так, как обычно делаю в случаях, когда мне чего-либо не хватает в CentOS и когда нужных мне пакетов нигде не найти - я просто попытался собрать готовый пакет из исходных текстов для дистрибутива Fedora. Если кто не знает, то поясню, что CentOS - это свободный клон Red Hat Enterprise Linux (RHEL), собирается из тех же исходников, с удалением логотипов Red Hat и коммерческих инструментов. В свою очередь, дистрибутив Fedora по факту является тестовой площадкой для будущих версий RHEL. Именно поэтому, в большинстве случаев, пакеты для Fedora прекрасно собираются в дистрибутивах RHEL и CentOS без каких-либо доводок и исправлений. Итак, на одном из зекал Fedora я нашёл исходник пакета mysql-5.0.77-1.fc10.src.rpm. И что характерно, что качество создания пакета в свободном дистрибутиве оказалось много выше, чем у коммерческой компании Sun - пакет для Fedora собрался в CentOS без каких-либо проблем, за что отдельное спасибо как сопровождающему данный пакет, так и всей команде Fedora. Сборка пакета из исходных текстов осуществляется командой: rpmbuild --rebuild mysql-5.0.77-1.fc10.src.rpm Разумеется, у вас должны быть установлены при этом все пакеты, которые необходимы для собственно сборки пакетов (rpmbuild, rpm-devel, компиляторы, auto* и т.д.), а также и те пакеты, сообщение о необходимости установке которых, вы получите при запуске сборки. После сборки вы получите следующие бинарные пакеты: mysql-5.0.77-1.i386.rpm mysql-bench-5.0.77-1.i386.rpm mysql-cluster-5.0.77-1.i386.rpm mysql-debuginfo-5.0.77-1.i386.rpm mysql-devel-5.0.77-1.i386.rpm mysql-embedded-5.0.77-1.i386.rpm mysql-embedded-devel-5.0.77-1.i386.rpm mysql-libs-5.0.77-1.i386.rpm mysql-server-5.0.77-1.i386.rpm mysql-test-5.0.77-1.i386.rpm Насколько я понял документацию, очень рекомендуется, чтобы все элементы кластера MySQL были одной версии. Более того, для организации устойчивой работы кластера в MySQL 5.0.x, необходимо ТРИ сервера: два кластерных узла и арбитр. Вы, конечно, можете использовать в качестве арбитра один из узлов кластера MySQL, но в случае отказа этого узла (содержащего также и арбитр), весь кластер рушится. Это одно из ограничений кластера MySQL 5.0.x. Как опять же было прочитано в документации на сайте MySQL: в версиях 6.x, можно будет создавать кластер и без арбитра, но к сожалению ветка 6.x - это даже не бета, а крайне экспериментальная альфа и ни о каком продуктивном использоваии этой версии и речи идти не может! Оцените комичность ситуации: для кластера из двух серверов нам надо три! К счастью, нужное количество серверов нашлось, учитывая, к тому же, что для арбитр - это фактически просто процесс, который не оказывает никакого влияния на MySQL, установленный на той же машине, т.е. вы можете смело запускать арбитр на машине, где уже настроен и работает какой-либо другой MySQL сервер - конфликтовать они друг с другом не будут как и зависеть друг от друга. Итак, на все три сервера ставим, получившиеся после сборки пакеты: mysql, mysql-cluster, mysql-libs, а на два сервера, которые будут узлами ставим ещё и пакет mysql-server. Установка пакетов как вы помните выполняется командой rpm -i <имя пакета>. Если же у вас уже был установлен mysql, то вместо ключа -i, воспользуйтесь ключём -U, чтобы обновить существующую версию. На этом этап установки закончен! Переходим к настройке... Настройка кластера MySQLИтак, сервер, на котором я устанавливаю арбитр имеет IP адрес: 10.1.1.2, узлы кластера, где будут работать экземпляры сервера MySQL имеют IP адреса: 10.1.1.13 и 10.1.1.3. Создаём файлы конфигурации. Файл конфигурации для арбитра вы должны создать сами. По умолчанию, после установки пакета у вас будет создан каталог /var/lib/mysql-cluster. Вот в этом каталоге вы и создаёте файл config.ini следующего содержания: [NDBD DEFAULT] NoOfReplicas=2 DataMemory=702M IndexMemory=160M RedoBuffer=32M MaxNoOfOrderedIndexes=8196 MaxNoOfUniqueHashIndexes=2048 MaxNoOfAttributes=9600 TimeBetweenLocalCheckpoints=10 [MYSQLD DEFAULT] [NDB_MGMD DEFAULT] [TCP DEFAULT] [NDB_MGMD] # IP этого сервера (арбитра) HostName=10.1.1.2 # Узлы кластера [NDBD] # IP первого сервера HostName=10.1.1.3 DataDir= /var/lib/mysql-cluster [NDBD] # IP второго сервера HostName=10.1.1.13 DataDir=/var/lib/mysql-cluster # Здесь можно задать некие параметры для клиентов MySQL (тех двух узлов кластера) # Но лучше этого не делать и задавать параметры непосредственно на самих серверах [MYSQLD] [MYSQLD] Некоторые пояснения по конфигу. На самом деле, вы можете пока смело закомментировать все директивы в секции [NDBD DEFAULT] кроме первых трёх. Остальные параметры по тонкой настроке кластера, даны тут скорее для примера - в реальности их намного больше, чем в этом конфигурационном файле и я оставил их, чтобы показать, что они вообще-то есть, потому что в упоминаемых мной статьях приводятся только именно первые три и больше ничего. За подробными пояснениями по данным параметрам, вам нужно сходить на сайт MySQL и почитать документацию по развёртыванию кластера, но краткие пояснения я дам NoOfReplicas=2 говорит, что в нашем кластере два узла DataMemory=702M и IndexMemory=160M два самых гадских параметра. Гадских потому, что нехватка памяти там или там может привести к ошибкам в работе кластера и к появлению разных (порой совершенно непонятных) сообщений при импорте БД на кластер. Значения, которые я поставил в этих переменных чисто условные, но советую начинать не менее чем с 400M и 100M соответственно. Забегая вперёд, могу сказать, что для моей БД этого не хватило! В документации MySQL приводится даже какая-то методика расчёта этих параметров, только вот эта методика больно уж неточная и непонятная, хотя вы можете и попробовать. RedoBuffer=32M значение размера буфера наката данных. Вроде бы как написано, что по умолчанию оно как раз 32M составляет. Поясню, что это такое. При закачивании данных в БД, которая размещена на кластере, порции данных передаются по сети на другой узел кластера для синхронизации и передаются именно в этот буфер, который затем записывается на диск. Если скорость данных записи на диск будет медленее, чем скорость поступления данных в буфер, то буфер переполнится, о чём вы получите так называемую "Temporality error" (временную ошибку). То-то вас это утешит, что ошибка временная, ведь ваша операция-то тем не менее обломается! MaxNoOfOrderedIndexes=8196 это количество индексов, которые может обслуживать кластер. Сюда входят все индексы, в том числе и первичные ключи. Если индексов в вашей БД будет больше, чем значение этого паметра, вы получите ошибку и ваш кластер работать не будет!MaxNoOfUniqueHashIndexes=2048 это количество индексов, созданных с ключевым словом HASH. В остальном всё аналогично предыдущему параметру. MaxNoOfAttributes=9600 это общее количество атрибутов, которые может обслуживать кластер. Что рассматривать как атрибут, я несколько не понял до конца. Совершенно точно, что любое поле (столбец) таблицы является атрибутом, но вот является ли атрибутом любой именованый объект в БД (например функция, триггер, индекс) я затрудняюсь сказать. TimeBetweenLocalCheckpoints=10 это очень хитрый параметр, который управляет частотой сброса на диск буферов узлов кластера, т.е. по сути частотой синхронизации данных между узлами. Для более нагруженных кластеров (в плане новых данных) рекомендуется меньшие значения, для менее нагруженных большие. Итак, с настройкой арбитра мы закончили, переходим к настройками самих узлов кластера. Собственно вы просто дописываете тот конфиг /etc/my.cnf, который у вас уже есть с вашими излюбленными параметрами. Надо начать секцию [mysqld] вот так: [mysqld] ndbcluster ndb-connectstring=10.1.1.2:1186 ... далее ваши любимые параметры настройки MySQL сервера и дополнительная [mysql_cluster] ndb-connectstring=10.1.1.2:1186 Вот собственно и всё. Все необходимые параметры для функционирования кластера, узлы возьмут из конфига арбитра. Переходим к старту кластера... Старт кластера MySQLСперва запускаем арбитр, для чего на сервере с арбитром запускаем service ndb_mgmd start Затем на каждом из узлов кластера запускаем собственно сам MySQL-сервер и кластерную составляющую: service mysqld start service ndbd start Разумеется, в случае если всё настроено везде верно, вам должно выдать ОК на все эти операции. Теперь идёт в консоль управления кластером. Для этого на сервере с арбитром запускаем: ndb_mgmи видим -- NDB Cluster -- Management Client -- ndb_mgm> Значит подключение к арбитру прошло успешно, он функционирует нормально. Теперь смотрим состояние кластера: ndb_mgm> show Cluster Configuration --------------------- [ndbd(NDB)] 2 node(s) id=2 @10.1.1.3 (Version: 5.0.77, Nodegroup: 0, Master) id=3 @10.1.1.13 (Version: 5.0.77, starting, Nodegroup: 0) [ndb_mgmd(MGM)] 1 node(s) id=1 @10.1.1.2 (Version: 5.0.77) [mysqld(API)] 2 node(s) id=4 @10.1.1.13 (Version: 5.0.77) id=5 @10.1.1.3 (Version: 5.0.77) Как видим, оба узла запущены, узел 10.1.1.3 считается мастером. Если же картина например такая: ndb_mgm> show Connected to Management Server at: localhost:1186 Cluster Configuration --------------------- [ndbd(NDB)] 2 node(s) id=2 @10.1.1.3 (Version: 5.0.77, Nodegroup: 0, Master) id=3 (not connected, accepting connect from 10.1.1.13) [ndb_mgmd(MGM)] 1 node(s) id=1 @10.1.1.2 (Version: 5.0.77) [mysqld(API)] 2 node(s) id=4 @10.1.1.13 (Version: 5.0.77) id=5 @10.1.1.3 (Version: 5.0.77) то понятное дело, что узел 10.1.1.13 не запущен и соответственно надо принимать меры (например повторно его запустить) Необходимо ещё написать как вы можете изменить конфигурационные параметры, которые мы указывали в конфиге арбитра. Для этого вы должны, исправить config.ini на сервере с арбитром, после чего зайти в консоль управления nbd_mgm, остановить кластер командой shutdown, а затем выполнить снова все операции по старту кластера. В отдельных случаях, мной замечено, что после запуска ndbd на узлах кластера, должно пройти довольно продолжительное время, прежде чем по команде show в консоли вы увидите, что всё поднялось как надо. По всей видимости это связано с синхронизацией недосинхронизированных данных с последнего запуска кластера. Это был собственно старт кластера, а теперь начинается самое весёлое! Нам нужно импортировать существующую БД в кластер... Импорт существующей БД в кластерИтак, вы думаете, что теперь вам достаточно создать БД на любом из узлов кластера и она тут же появится на другом? Нет! Вы очень глубоко заблуждаетесь! Суперкластер от MySQL работает не так! Вы должны создать БД с одним и тем же именем на обоих узлах кластера. Далее, вам следует уяснить, что кластера как такового у вас нет! Вы в шоке? В недоумении? Поясняю. Всё что даёт вам кластер - это новый так называемый Storage Engine или говоря по простому - способ хранения данных в БД MySQL. В первых версиях MySQL был только один Storage Engine - MyISAM. Он до сих пор широко используется потому что наиболее просто, содержит наименьшее количество ограничений и хранится на файловой системе в виде множества отдельных файлов (как правило по 3 файла на таблицу). Далее появился более прогрессивный, поддерживающий транзакции Storage Engine под название InnoDB. Правда вот незадача, прогрессивный InnoDB не позволял в отличие от MyISAM использовать полнотекстовые индексы. Со временем появились и другие Storage Engine, например Archive, который позволяет хранить данные в БД в сжатом виде. Так вот, единственное, что делает кластер MySQL - это предоставляет вам новый Storage Engine, который называет NDB или ndbcluster. Как вы понимаете, в Storage Engine хранятся только таблицы и связанные с ними данные. А вот все остальные объекты БД (например, хранимые процедуры) вам придётся создавать (и при необходимости менять) ручками на обоих узлах кластера самим - правда здорово? То же самое касается пользователей, групп, прав и прочего, всего что не относится к таблицам. Всё веселее не правда ли? Но леший с этим, давайте вернёмся к импорту. Допустим на 1-м узле кластера у нас есть БД с именем mydb. По идее можно воспользоваться специальной утилитой, входящей в состав MySQL, чтобы изменить в данной БД Storage Engine для всех таблиц: mysql_convert_table_format --type=NDB mydb По идее она должна отработать и будет вам счастье (ну за исключением вышеописанных хранимых процедур, пользователей, групп и прочего). Но это по идее. На самом деле, если у вас большая БД с большой структурой, вы будете получать самые разныее сообщения об ошибках и невозможности импорта. Например: ERROR 157 (HY000): Could not connect to storage engine.. нет подключения к арбитру, а возможно просто зависание последней сессии (или сессий). Зайдите в консоль управления кластером на сервере с арбитром (nbd_mgm), убедитесь что оба узла кластера запущены, а также нелишним будет выполнить команду: "purge stale sessions" для сброса зависших сессий. error 1296 HY000 at line 1392; got error 902, out of memory in NDB kernal, orderd index data ( increase dataMemory) from NDB cluster. что будет означать, что вы выделили недостаточно памяти в параметре DataMemory error чего-то там #sql-XXX опять может не хватать памяти как в DataMemory так и в IndexMemory. Если не помогает, попробуйте прогнать код ошибки через: perror КОДили perror --nbd КОД возможно и получите какое-то осмысленное сообщение, а может и нет! ERROR 1297 (HY000): Got temporary error 233 'Out of operation records in transaction coordinator (increase MaxNoOfConcurrentOperations)' from ndbcluster тут понятное дело, что надо в config.ini на сервере с арбитром завести параметр MaxNoOfConcurrentOperations и увеличить его от значения по умолчанию, которое смотрите в доках по кластеру на сайте MySQL ERROR 1297 (HY000): Got temporary error 410 'REDO log files overloaded, consult online manual (decrease TimeBetweenLocalCheckpoints, and|or incre' from ndbcluster что означает ошибку переполнения буфера наката, о которой я говорил в параграфе о настройках арбитра Ну что, вам хватит? Вы уже поняли, что такое кластер MySQL и всё ещё желаете с ним работать, несмотря на то, что тут подпорка на подпорке? Тогда вот вам ещё ошибка: ERROR 1005 (HY000): Can't create table './mydb/table.frm' (errno: 4318) прогнав через perror получаем "application error". Тут уж без google не разобраться! В итоге оказывается, что кластерный Storage Engine имеет ещё и (перечисляю не все):
Вот тут собственно и сказки конец! Для моей БД эти ограничения оказались критичными. А вам решать самим - стоит ли пользоваться этим сплошным недоразумением или всё-таки жить спокойно. Мой вывод - такой кластер будет работать только на небольших таблицах при небольшом размере БД, но тогда зачем вообще нужен кластер? На нагруженных и тяжёлых БД всё это работать не будет! В продолжении выводов - оптимизируйте структуру БД и запросы, создавайте индексы. Если же несмотря на всё это мощность MySQL вам не хватает и вы думаете о кластере, то лучше посмотрите в сторону PostgreSQL или Oracle.
|
|||
