Немного теории. В операционных системах UNIX существует раздел файловой системы, который физически находится в оперативной памяти, но позволяет работать с ним как с обычным дисковым накопителем. Скорость доступа к блоку жесткого диска приблизительно равна 1 мс. Скорость доступа к памяти — 0.001 мс. Попробуем применить это к БД MySQL, чтобы выжать максимум из операций insert/update.
Сперва проверим скорость случайной записи на жесткий диск:
time sysbench --test=fileio --file-total-size=100M --file-num=1000 prepare 1000 files, 102Kb each, 99Mb total real 0m47.682s
Теперь то же самое для shared memory (/run/shm или /dev/shm):
time sysbench --test=fileio --file-total-size=100M --file-num=1000 prepare 1000 files, 102Kb each, 99Mb total real 0m0.083s
Сравним результаты и увидим, что время создания 1000 файлов уменьшилось в 574 раза. Хорошо. Значит, следует ожидать прирост скорости записи в БД.
Выполняем следующее:
1) Проверяем размер и свободное место для /run/shm
df -h | grep -P "Filesystem|shm" Filesystem Size Used Avail Use% Mounted on none 16G 782M 15,2G 4.8% /run/shm
2) Проверяем сколько места занимает БД
sudo ls -lh /var/lib/mysql/ | grep ibdata1 -rw-rw---- 1 mysql mysql 4.5G июня 14 05:21 ibdata1
Значит, что базу мы можем перенести в /run/shm
3) Останавливаем MySQL:
sudo service mysql stop
4) Создаем директории и копируем данные:
sudo mkdir /run/shm/mysql-lib sudo chown mysql:mysql /run/shm/mysql-lib sudo cp -rp /var/lib/mysql/* /run/shm/mysql-lib/
5) Правим конфиг:
sudo nano /etc/mysql/my.cnf [mysqld] #datadir = /var/lib/mysql datadir = /run/shm/mysql-lib
6) Правим AppArmor:
sudo nano /etc/apparmor.d/usr.sbin.mysqld #/var/lib/mysql/ r, #/var/lib/mysql/** rwk, /run/shm/mysql-lib/ r, /run/shm/mysql-lib/** rwk,
7) Запускаем MySQL
sudo service mysql start
* Если сервис не стартует — смотрим /var/log/mysql/error.log
Теперь самое интересное. Проверяем, что получилось.
Тест на жестком диске я провел заранее, поэтому сразу привожу результаты.
HDD Shared mem Insert 10 000 000 строк 202 сек 66 сек (bulk = 1000) Update 100 000 раз 122 сек 16 сек (id = rnd)
Update выполнялся по случайному интервалу [1 000 000 — 9 000 000] для первичного ключа (id). Крайние значения отброшены, чтобы движок «копался» внутри таблицы.
Существенный прирост скорости на INSERT и еще больший на UPDATE.
Меньше для вставки, т.к. MySQL производит пересчет индексов и организацию данных.
В настройках MySQL выставлено:
innodb_buffer_pool_size = 1024M
Если ставить меньше, то скорость UPDATE для HDD естественно падает.
innodb_flush_log_at_trx_commit = 2
Как таковых транзакций здесь у нас нет и на скорость это не влияет. Тем не менее, оставляем это значение равным 2.
При такой схеме критически важно писать бинарный лог и регулярно делать бэкап. Максимально снизить издержки записи мы можем только указав для бинарника отдельный жесткий диск. Последовательная скорость записи на винчестер намного выше случайной. Поэтому ставим в систему дополнительный жесткий диск, монтируем его, например, в /mnt/hddbin/, и указываем в my.ini путь для бинарного лога: log_bin = /mnt/hddbin/mysql-bin.log
Не забываем добавить скрипты для перезагрузки и останова системы. Смотрим папку /etc/rc*. Обычно это 0 (отключение системы) и 6 (перезагрузка). Мануал, как добавить скрипты легко найти в гугле. Скрипт перед перезагрузкой или выключением системы останавливает MySQL, затем копирует папку /run/shm/mysql-lib на жесткий диск. При включении системы скрипт восстанавливает данные с жесткого диска в папку /run/shm/mysql-lib и после запускает MySQL.
Так же добавляем простенький bash или perl скрипт для мониторинга свободной памяти в /run/shm. Можно подключить Zabbix.
ссылка на оригинал статьи http://habrahabr.ru/post/260297/
Добавить комментарий