Недавно была поставлена задача оптимизировать сервер для Open X (баннерная система), сервер сильный, а баннеры раздает медленно .
Ниже я расскажу о основных направлениях, в сторону которых нужно копать при оптимизации веб сервера на примере оптимизации баннерной системы OpenX.
В моем случае оптимизировалось все на следующем железе:
OS : CentOS Enterprise Linux — OS ES 5.0
CPU: Intel \ 2.0 GHz 1333FSB — Harpertown \ Xeon 5405 (Quad Core)
RAM: 4 GB
HDD: IDE 250GB
Итак, начнем.
- Канал передачи данных
Стоит понимать, что самое важное при передаче данных — это канал на сервере и канал на потенциальном клиенте. Скорость передачи данных прежде всего зависит от этих двух показателей.
Например, если мы имеем канал передачи данных в 100 Мбит\сек, мы сможем передавать 12 800 килобайт = 12,50 Мб\сек в идеальных условиях . В нашем случае баннер в среднем весит около 98Кбайт, значит в этих условиях мы сможем передавать 130 банеров в секунду, что означает — мы обслуживаем в среднем ~130 одновременных закачек баннера в секунду, каким бы не был канал у клиента, так как у нас ограничение 100 Мбит\сек.
Поэтому, следует обязательно учитывать ограничения канала при решении поставленной задачи ; в определённых ситуациях можно добиться куда большего выигрыша в производительности системы увеличением канала передачи данных.
Итак, как же посмотреть, какой канал обеспечивает наш NIC (network interface controller) ? …
Для этого используем команду :
ethtool eth0
eth0 — это ваш сетевой адаптер , у вас может отличатся (например eth1, eth2 и так далее)
получаем примерно следующий вывод
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
…
видим возможности нашей NIC
далее проверяем текущее подключение
mii-tool -v
>>
eth0: negotiated 100baseTx-FD, link ok
это говорит о том что скорость соединения с интернет 100Mb/s
- I/O жесткого диска
Если ожидается большое количество запросов к серверу, то, следовательно, будет высокая частота обращений к жесткому диску.
Что можно сделать в этом случае?
1) Установить SAS (Serial Attached SCSI ) жесткие диски — обеспечивают высокую скорость чтения\записи данных.
2) Отключить функцию записи времени последнего доступа к данным(access time), это можно сделать на этапе монтирования файловой системы в /etc/fstab опцией noatime
например : /dev/sda4 /var ext3 defaults,usrquota,noatime 1 2
желательно, чтобы у вас был отдельный раздел под вебы, чтобы можно было отключить запись времени последнего доступа к файлу только для раздела где находятся файлы веба.
После изменений нет необходимости рестартить весь сервер , просто воспользуйтесь опцией команды mount
mount -o remount /var
- Sysctl
Итак, мы подошли к самому интересному в нашей статье… SysCtl — это интерфейс для получения и изменения состояния(изменения некоторых параметров) ядра . Эти параметры доступны через /proc/sys/ (proc- это псевдо-файловая система, которая используется в качестве интерфейса к структуре данных ядра).
Ну хватит теории; стало ясно, что с помощью sysctl можно менять некоторые параметры ядра, и есть параметры, которые нам помогут улучшить производительность веб-сервера в целом.
Для того, чтобы вывести все установленные параметры, используйте команду: sysctl -a
Для того, чтобы изменить параметр, используйте следующую команду : sysctl -w <имя_параметра>=<значение_параметра>
Для того, чтобы параметры которые вы установили не приходилось каждый раз устанавливать после перезагрузки, существует файл /etc/sysctl.conf . Параметры, занесенные в этот файл, каждый раз устанавливаются во время загрузки ОС.
Нужно учесть что в BSD системах и Linux системах эти параметры сильно отличаются , так что для оптимизации следует самому подробно изучить параметры, прежде чем менять. В моем случае — в качестве ОС используется CentOS GNU\Linux, поэтому я использовал следующие параметры :
# Controls whether core dumps will append the PID to the core filename
# Useful for debugging multi-threaded applications
kernel.core_uses_pid = 1
# Controls the maximum size of a message, in bytes
kernel.msgmnb = 65536
# Controls the default maxmimum size of a mesage queue
kernel.msgmax = 65536
# Controls the maximum shared segment size, in bytes
kernel.shmmax = 4294967295
# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 268435456
# Disables packet forwarding
net.ipv4.ip_forward=0
# Disables IP source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Enable IP spoofing protection, turn on source route verification
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP Redirect Acceptance
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Enable Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 0
net.ipv4.conf.lo.log_martians = 0
net.ipv4.conf.eth0.log_martians = 0
# Disables IP source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Enable IP spoofing protection, turn on source route verification
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP Redirect Acceptance
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Disables the magic-sysrq key
kernel.sysrq = 0
# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 15
# Decrease the time default value for tcp_keepalive_time connection
net.ipv4.tcp_keepalive_time = 1800
# Turn off the tcp_window_scaling
net.ipv4.tcp_window_scaling = 0
# Turn off the tcp_sack
net.ipv4.tcp_sack = 0
# Turn off the tcp_timestamps
net.ipv4.tcp_timestamps = 0
# Enable TCP SYN Cookie Protection
net.ipv4.tcp_syncookies = 1
# Enable ignoring broadcasts request
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Enable bad error message Protection
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 1
# Increases the size of the socket queue (effectively, q0).
net.ipv4.tcp_max_syn_backlog = 1024
# Increase the tcp-time-wait buckets pool size
net.ipv4.tcp_max_tw_buckets = 1440000
# Allowed local port range
net.ipv4.ip_local_port_range = 16384 65536
- Веб-сервер
В качестве веб-сервера используется apache 2. Основные настройки, которые нужно учесть при настройке веб-сервера. Напоминаю что они будут отличаться в зависимости от поставленной задачи.
все настройки веб-сервера можно поправить в /etc/httpd/conf/httpd.conf
#уменьшить таймаут45 сек вполне хватит особенно для баннеров
Timeout 45
#в моем случае мне KeepAlive не нужен так как будет только один запрос у клиента — отдача баннера , в других случаях целесообразно его включить
KeepAlive Off
обязательно следует включить в сборку Apache prefork MPM (модуль многопоточной обработки)
# prefork MPM
<IfModule prefork.c>
#кол-во процессов при старте
StartServers 30
#минимальное кол-во запасных процессов сервера
MinSpareServers 5
#максимальное кол-во запасных процессов сервера
MaxSpareServers 50
#максимальное значение для MaxClients
ServerLimit 2000
#максимальное кол-во процессов
MaxClients 1800
#максимальное кол-во запросов на процесс
MaxRequestsPerChild 0
</IfModule>
эти значения оправданы только в случае отдачи баннеров; если у вас обычный веб-сервер, вам следует уменьшить MaxClients
и увеличить MaxRequestsPerChild.
- База Данных
в моем случае использовалась база данных на MySQL. При оптимизации следует обратить внимание на следующие параметры:
# макс. кол-во соединений сервера баз данных
max_connections = 1024
#макс. кол-во пользовательских соединений
max_user_connections = 1024
# область в памяти, которая выделяется для кеширования индексов
key_buffer_size = 1024M
myisam_sort_buffer_size = 64M
# размер буфера для объединений
join_buffer_size = 1M
# размер буфера для чтения
read_buffer_size = 1M
# размер буфера для сортировки
sort_buffer_size = 2M
# кеш таблиц
table_cache = 4000
# размер кеша потока
thread_cache_size = 384
wait_timeout = 20
# время, через которое прибиваются соединения
connect_timeout = 10
tmp_table_size = 128M
max_heap_table_size = 512M
max_allowed_packet = 16M
max_connect_errors = 10
thread_concurrency = 16
# обработка одновременных вставок, при заданном значении все вставки записываются в конец таблицы
concurrent_insert = 2
table_lock_wait_timeout = 30
read_rnd_buffer_size = 786432
#
max_write_lock_count = 16
# Если время выполнения запроса — заданное значение, то счетчик slow_queries будет увеличен на 1
long_query_time = 5
# Имена хостов не преобразовывать вообще. Все столбцы Host
в таблицах должны иметь значение IP-адреса или localhost
.
skip-name-resolve
# Не использовать блокировку системы.
skip-locking
- PHP
если вы используете php , вам следует обратить внимание на следующие параметры :
memory_limit = 128M ; Максимальный объем памяти, который может использовать скрипт
max_execution_time = 30 ; Максимальное время выполнения скрипта
register_globals = Off ; Отключить глобальные переменные в целях безопасности
mysql.allow_persistent = On ; Разрешать постоянное подключение
mysql.trace_mode = Off ; отключить режим трассировки
их можно найти в /etc/php.ini
Надеюсь, статья поможет вам идти в верном направлени при оптимизации своего сервера, удачи .
З.Ы
Хочу добавить.
Столкнулся с проблемой расчёта статистики на сервере. Дело в том что все просмотры баннеров в Open X версии 2.6 пишутся в отдельную таблицу(ox_data_raw_ad_impression) и по майнтейнсу происходит расчёт статистики . Когда мало посишений ну примерно 10k в сутки все хорошо, но когда 9000000 посищений в сутки при расчете статистики mysql уходит в swap и вешает весь сервер . Для решения данной проблемы первым делом я сменил тип таблицы с myisam на innodb , чтобы снять блокировку с таблицы при выполнении запроса рассчета статистики так как myisam таблица лочится при инсере а в innodb блокировка на уровне строк… Так же увеличил оперативную память до 8 GB. Но мою проблему это не решило… Я уже думал что нужно будет переписывать Open X чтобы все просмотры сохранять в лог файл а затем парсить файл и постить данные большими порциями через заданный интервал времени , чтобы снизить нагрузку коннекшенов на mysql …. Но к счастью девелоперы позоботилиьс о этой проблеме и выпустили новую версию Open X 2.8.1 в которой решили данную проблему переписав систему учета статистики на бакеты (https://developer.openx.org/wiki/display/COMM/Buckets ) что полность решило проблему с расчетом статистики и увеличило производительность системы за что им большое спасибо …
в данный момент у меня на одном сервере крутится 9000000 в сутки показов баннеров средний лоад тайм баннера весом 48893 байт 369 msec
… и все гуд
Просмотров: 1017