Участник:Rain/Заметки/Onyx: различия между версиями
Rain (обсуждение | вклад) |
Rain (обсуждение | вклад) |
||
Строка 83: | Строка 83: | ||
== Разное == | == Разное == | ||
== Что сделано == | |||
На данный момент из полезного сделано: | |||
* inotify-based синхронизация контента между 6 (master -> web{1,3}/import/backup) серверами. Практически не вызывает нагрузки, контент копируется в реальном времени. |
Версия 13:48, 27 февраля 2012
Заметки по серверам для carid.com:
Что хотелось бы сделать
Кодировки MySQL
Навести порядок с кодировками базы. Сейчас в настройках на большинстве серверов указан (или не указан, а используется старое дефолтное значение) latin1. При этом в коде явно указывается использовать юникод через
SET NAMES 'utf8'
(иначе бы не получалось сохранять всякие там "®" и прочие юникодные символы) - хотя кое-где стоит
SET NAMES 'latin1'
(но такие места не должны вызвать проблем, в дальнейшем их можно поправить). Т.е., реально настройки указываются одни, база в свойствах таблиц указывает latin1, а реально данные хранятся другие; как следствие - имеем проблемы при работе с дампами.
По-идее, в настройках сервера можно сходу указать правильные параметры подключения - это не должно сломать текущую логику работы (нужна проверка на тестовом сервере); кодировка все равно задается через set names (но не уверен, что происходит при репликации). Для перехода на правильные настройки можно использовать следующий алгоритм:
- Прописать правильные настройки на Master-сервере
- Перевести slave-алиасы на мастер-сервер
- STOP SLAVE; на слейв-сервере
- Одновременно перезапускаем Master-сервер
- Заливаем дамп напрямую с Slave-сервера на Master-сервер, заменяя в потоке charset в дампе на юникодный и проверив, что льется юникодный поток.
- Снимаем уже правильный дамп с Master-сервера
- Настраиваем Slave-сервера на работу с юникодом
- Восстанавливаем работу Slave'ов
- Переключаем slave сайта на восстановленные слейвы.
По-идее, основная часть работы (и downtime сайта) займет время однопоточной заливки дампа (т.е., минут 30). Как вариант - написать скрипт, который будет дампить и заливать базы впараллель, тогда downtime уменьшится минут до 10.
InnoDB
Перевод базы на InnoDB. Считаю, что это решит текущую проблему с локами базы при смешной нагрузке. На данный момент сменить тип движка нельзя для следующих таблиц:
Используется FULLTEXT: xcart_categories_index xcart_extra_field_values xcart_make_model xcart_order_details xcart_order_messages xcart_products xcart_users_map Ошибка при конвертации: "ERROR 1075 (42000) at line 1: Incorrect table definition; there can be only one auto column and it must be defined as a key" в xcart_counters
- с ошибкой разобраться, для остальных таблиц потенциально можно вынести поиск в отдельную маленькую таблицу, оставив ее в MyISAM (требует правки кода, так что в крайнем случае можно оставить их как есть - все же лучше иметь 8 лочащихся таблиц, чем 300).
- Само по себе изменение остальных таблиц должно пройти гладко; на время конвертации можно переключить Slave-сервера на мастер (т.к. мастер мощный, а слейв могут долго работать с таблицей; как следствие - отставание репликации). Помимо ликвидации табличных локов, это позволит держать всю базу в оперативной памяти, т.е., будет не особо важно, насколько быстрый диск (остальные параметры на тему сброса данных на диск можно потюнить).
- Момент, необходимый для рассмотрения - держать ли все таблицы в одном ibdata-файле или нет. С одной стороны работа с таблицами, разделенными по файлам проще (нагляднее, проще для восстановления, наглядно видно занимаемое и свободное место, можно мигрировать с диска на диск на ходу (а надо ли, если замена диска все равно подразумевает отключение сервера?) и т.п.), с другой - в случае использования одного файла можно указать в качестве файла полностью FIO Drive - без таблицы разделов (привет выравниванию) и без файловой системы (привет фрагментации).
- До этого момента рассматривать варианты, вроде перехода на MySQL-кластер или Percona-сервер - бред, так как первое, фактически - мультимастер-сервер с синхронной репликацией (и не самым хорошим движком), второе хорошо прежде всего XtraDB.
- После решения проблем подобных миграций при недостатке производительности (но не ранее) можно рассматривать переход на другие базы - на данный момент это MariaDB+XtraDB или Percona Server.
Оптимизация использования MySQL-серверов, отказоустойчивость
Потенциально можно раскидывать запросы чтения с Master на Slave-сервер для разгрузки мастер-сервера. Подобные оптимизации можно делать только после ликвидации локов (что даст ускорение репликации и большую синхронность между серверами - как следствие - более корректную вычитку данных приложением).
Варианты реализации:
- На уровне приложения. Объявить новую переменную с подключением к слейву, подключения на вычитку данных цеплять на эту переменную. Требует правки кода и знания того, как работает сайт, поэтому пока труднореализуемо.
- Как подпункт: в дальнейшем в таком варианте можно сделать балансировку на уровне DNS'a - объявить для алиаса несколько IP-адресов и он в round robin-режиме будет отдавать разные сервера.
- На уровне подключений:
- mysql-proxy. Без наведения порядка с кодировками не взлетит, так как раскидывает подключения на уровне запросов (т.е., set names может уйти на один сервер, а запрос - на другой и получим кашу). Прост в настройке, может раскидывать запросы на запись и чтения по разным серверам (в т.ч. несколько серверов чтения)
- haproxy. Рулит подключениями на уровне TCP-соединений. Более навороченный вариант, требует больше настройки.
Еще оптимизация - сделать Master-Master-репликацию. Тут есть 2 момента:
- Можно вынести админку, с которой работают импортеры/апдейтеры и прочие, на другой мастер-сервер при условии малого пересечения таблиц, в которые пишет админка и сайт (подразумевается, например, что посетитель не пишет в таблицу с перечнем товаров, в которую пишет сотрудник и т.п. Как подвариант - пересекающиеся таблицы писать только на один сервер для исключения ситуации split brain'a)
- HA-кластер. Умирает один мастер - переключаемся каким-то средством балансировки на другой (через haproxy/mysql-proxy/heartbeat и т.п.). Пока второй мастер живой - используется для админки (1-й пункт) или как слейв. Плюс как слейв можно завести 3-й сервер (освободившийся от memcached, например).
Memcached
Убрать единый сервер Memcached и создать собственный Memcached на каждом веб-сервере. Плюсы:
- Убираем единую точку отказа
- Убираем оверхед при перегонке мелких данных по сети.
- Не держим лишний мощный, но практически не используемый сервер
Недостаток такого варианта - выделение памяти на каждом сервере. На деле из 36 Гб на веб-серверах используется 2-3 Гб. Memcached за долгое время набрал данных лишь на 8 Гб (на данный момент - 13), из них многое - из-за постоянных тестов. Эффективность кэша на момент 8 Гб - порядка 80 процентов, что мало. Итого, если выделить даже по 16 Гб под memcached на каждом сервере - этого с головой хватит и для нужд веб-сервера, и для memcached. По процессору - даже единый memcached практически не нагружает процессор (нагрузка на уровне пары процентов для одного ядра сервера). При разделении нагрузка на каждый отдельный memcached уменьшится до 3 раз на текущий момент. Когда начнем упираться в процессор на веб-сервере - наличие на нем memcached будет далеко не самой большой проблемой (иначе говоря, мы скорее заведем новый сервер впараллель к трем существующим, чем упремся в процессор).
Варианты реализации:
- Репликация данных: не затрагивает приложение, но repcached на данный момент умеет работать только в режиме master<->master или мастер с несколькими клиентами (кстати, пробовал репликацию цепочкой - не взлетело, да и не является отказоустойчивым). Для наших трех серверов не подходит. Из того, что протестировал между двумя серверами - плюс в том, что при восстановлении сервера реплицируются все данные, т.е., снова разогревать кэш не придется.
- Redis. Проблемы с репликацией те же, что и в первом пункте, в остальном вроде как является более быстрой альтернативой memcached (что пока не требуется).
- Использовать средства приложения: Богдан говорит, что приложение при легкой правке кода может принимать массив серверов, при этом можно указывать их вес (т.е., для 127.0.0.1 указать максимальный приоритет, для других узлов - меньший).
Безопасность
Разное
Что сделано
На данный момент из полезного сделано:
- inotify-based синхронизация контента между 6 (master -> web{1,3}/import/backup) серверами. Практически не вызывает нагрузки, контент копируется в реальном времени.