В итоге получим связку из двух серверов, подключенных между собой по гигабиту. На одном i386 и крутятся основные компоненты биллинга (ядро, радиус, веб-морда), а на другом исключительно FreeBSD 7.X + Mysql. Ничем лишнем этот сервер не занимаем. Вместо фаервола просто грамотная настройка сервисов.
Теперь переходим к самому главному. Как выжать максимум из дорогого выделенного сервера СУБД?
Скажу сразу, что оптимизация из соседних веток, которая у нас использовалась на мускуле с i386 / 4G RAM не проканала. Сервис mysqld было невозможно остановить.
http://forum.sysadmins.su/index.php?showtopic=32120
Пришлось на этот раз не тупо воровать чужие конфиги, а вкурить каждую опцию и понять, что она значит. На данный момент make.conf выглядит вот так:
Код: Выделить всё
CPUTYPE=opteron
.if ${.CURDIR:N*/usr/ports/databases/mysql50-server} == ""
WITH_CHARSET=cp1251
WITH_XCHARSET=all
WITH_COLLATION=cp1251_general_ci
WITH_PROC_SCOPE_PTH=yes
BUILD_OPTIMIZED=yes
BUILD_STATIC=yes
CONFIGURE_ARGS+= \
--with-innodb \
--enable-assembler \
--enable-community-features \
--enable-profiling \
--enable-static \
--without-debug
.endif
Теперь пару слов о sysctl и параметрах ядра.
sysctl.conf:
Код: Выделить всё
vfs.read_max=128 # должно повысить sequential read performance
kern.maxfiles=65536 # На всякий случай, но должно хватить и дефолта
kern.maxfilesperproc=32768 # Чтобы не получать "Too many open files..." но с нашей базой должно хватить дефолта
kern.timecounter.hardware=TSC # Советуют ставить, может дать прирост
kern.threads.max_threads_per_proc=15000 # Повышает планку для максимального числа тредов в libthr
kern.threads.max_groups_per_proc=15000 # Повышает планку для максимального числа тредов в libthr
Раздел с /var/db/mysql маунтим вот таким образом:
Код: Выделить всё
/dev/da0s2d /var/db ufs rw,async,noatime 0 0
noatime: перестает маркировать время последнего обращения к файлам на ФС, дает незначительный прирост I/O
[0 0] Первый 0 дизейблит FS dump, второй убирает fsck и quoacheck
Также рекомендуется делать newfs с максимальным размером блока, чего я сразу не сделал при установки, а потом было уже влом переносить данные раздела чтобы его правильно проформатить.
Переходим к самому главному - mysql. Нетап вроде рекомендует юзать ветку 5.0, и к томуже в современных бенчах пишут, что 5.1 часто сливает 5.0. По этому экспериментировать не стали, установили из портов 5.0.90. На старом сервере была 5.0.45 - не обновляли, ибо "работает - не трогай".
my.cnf (напротив некоторых парамов оставлю коменты):
Код: Выделить всё
[mysqld]
port = 3306
socket = /tmp/mysql.sock
back_log = 100
max_connections = 32
max_connect_errors = 4294967295 #ноль здесь не означает "дизейбл", по этому гуглирование предложило установить максимально возможное значение connect error
table_cache = 5526
max_allowed_packet = 128M
max_heap_table_size = 256M
sort_buffer_size = 512M
join_buffer_size = 8M
thread_cache_size = 18
thread_concurrency = 18 # Число конкурентных тредов рекомендуют ставить число ядер * 2. Я поставил 18 имея 6 ядер
query_cache_size = 256M
query_cache_limit = 4M
ft_min_word_len = 4
thread_stack = 256K
transaction_isolation = REPEATABLE-READ # repeatable-read выигрывает у read-committed по тестам
tmp_table_size = 4G # Обязательно выделяем больше места из памяти для tmp-таблиц. Временные таблицы будут создаваться в групповых отчетах по трафику
long_query_time = 3
tmpdir = /var/db/tmp
innodb_file_per_table # Об этом много писали на этом форуме. Однозначно стоит ставить
log_warnings
skip-name-resolve # На всякий случай отрубили резолвинг, настроили гранты по IP. Всё равно пара учеток всего.
#*** MyISAM Specific options
key_buffer_size = 1G
read_buffer_size = 2M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_max_extra_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover
skip-federated
# *** INNODB Specific options ***
innodb_additional_mem_pool_size = 2G
innodb_buffer_pool_size = 8G
innodb_file_io_threads = 4 # Написано тут: http://mysqlha.blogspot.com/2008/10/more-background-io-threads-for-innodb.html
#innodb_force_recovery=1 # Придется включать если посыпется база
innodb_thread_concurrency = 18
innodb_log_buffer_size = 32M
innodb_log_file_size = 512M
innodb_log_files_in_group = 4
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
Также неожиданностью стал расход полосы канала. Средняя скорость передачи данных 11 килобайт, а мы готовились к каким-то бОльшим объемам.
Ниже приведу графики загрузок с комментариями:
LAN. Пик в 120кб хз откуда взялся.

Всплеск lavg вызван генерацией группового отчета по трафику за апрель

Памяти в запасе всегда остается около гига

Активность буферного пула около 10 операций записи. Чтение иногда подскакивает до 40.

Буферный пул постоянно растет

Чекпоинт ейдж полезен для подбора размеров лога

ИОпсы для InnoDB

InnoDB Raw-риды

Ну и счетчики основных команд

PS:
Забыл сказать про ядро. Кернел GENERIC. Ничего в нем не меняли. В версии 7.3 шедуллер используется ULE, который лучше всего подходит для mysql. Гонял sysbanch, все ядра загружаются равномерно. К SMP подсистеме претензий нет.