Сер 182013
 

Дисковая оптимизация операций, снижение iops на лету

Столкнулся с проблемой большого iowait. Решил, поискать в яндексе, и найти все возможные трюки. По итогу, набрал хороший запас знаний, который помог снизить iops.

1) Отключаем логирование. Причем, если система стабильная, то можно отключить не только access logs в nginx, apache, но и errors_log.

Логирование очень сильно грузит диски, особенно при большом количестве сайтов.

2) Монтируем файловую систему в режиме defaults,noatime. Этот набор позволит снизить нагрузку от nginx.

Для этого в /etc/fstab добавляем эти строки, если их нету.

Чтобы не перезагружаться, можно просто сделать быстрый ремоунт даже с корневой директорией:

mount -o remount /

3) В sysctl добавляем параметры:

sysctl -w vm.dirty_writeback_centisecs = 6000 (можно увеличить до 15000, но я не рекомендую)

sysctl -w vm.swappiness = 10

sysctl -p

Первое, если честно сложный для понятия показатель. Грубо говоря, запись грязных частей файлов на диск

Второе, соотношение использования swap от ram. Т.к. swap нам не нужен, то почти отказываемся от него.

4) Также можно смонтировать папку /tmp как tmpfs

Описано здесь

Это что касается, основных параметров оси.

Как минимум система станет отзывчивее на 50%, а это показатель.

Кві 172013
 

Мониторинг диска с помощью smartmontools

Следить за дисками необходимо так же тщательно, как и за температурой, пылью в сервере. Даже если вы используете супер надежный Raid массив, контроль за сервером показывает уровень Системного Администратора.
Для мониторинга и диагностики состояния HDD существует технология smart – технология оценки состояния жесткого диска с помощью встроенной аппаратной диагностики.

Специально для систем мониторинга в Unix системах разработана утилита smartmontools. Данный софт присутствует во всех известных мне Unix системах.

Сейчас мы настроим smartd который находится в пакете smartmontools для непрерывного мониторинга HDD штатными средствами smartmontools, устанавливаем smartmontools: (или из Backports)

Устанавливаем пакет в Debian или Ubuntu:

# apt-get install -y smartmontools

Устанавливаем пакет в CentOS или RedHat:

# yum install -y smartmontools

Устанавливаем пакет в FreeBSD

# cd /usr/ports/sysutils/smartmontools
# make install clean

smartctl — просмотр текущих значений S.M.A.R.T., запуск тестов диагностики диска вручную;
smartd — демон для записи в системный журнал изменений в значениях S.M.A.R.T, уведомления по электронной почте об ошибках, запуска тестов диагностики по расписанию;

Проверяем установлен ли S.M.A.R.T., с помощью команды:

# smartctl -i /dev/sda

Если S.M.A.R.T. отключен, то включаем:

# smartctl -s on /dev/sda

Настраиваем S.M.A.R.T. как демон в /etc/default/smartmontools, для примера добавляем два диска:

enable_smart=”/dev/sda /dev/sdb”
start_smartd=yes
smartd_opts=”–interval=1800″

Автоматизируем мониторинг для для дисков.

В файл /etc/smartd.conf (записываем email для получения уведомлений, о состоянии HDD)

/dev/sda -S on -o on -a -I 194 -W 4,38,45 -R 5 -H -l error -l selffortest -m sistemadmin@mail.ru -s (S/../.././02|L/../../6/03)
/dev/sdb -S on -o on -a -I 194 -W 4,38,45 -R 5 -H -l error -l selffortest -m sistemadmin@mail.ru -s (S/../.././02|L/../../6/03)
или
/dev/sda -S on -o on -a -I 194 -m sistemadmin@mail.ru

-a заставляет smartd наблюдать за всеми доступными SMART-параметрами дисков
-I 194 указывает smartd игнорировать изменения значения атрибута #194
-m указывает на необходимость отправки email-уведомлений.

Внимание! В файле smartd.conf вы сможете увидеть уже готовые примеры с описанием! Воспользуйтесь ими.

Запускаем сервис:

# /etc/init.d/smartmontools start

Можно проверить пишутся ли логи:

cat /var/log/syslog | grep smartd

Ключи программы взятые из MAn:

-d TYPE Тип устройства: ata, scsi, marvell, removable, 3ware,N, hpt,L/M/N
-T TYPE допустимое отклонение: normal, permissive
-o VAL Включает/выключает автоматические оффлайн тесты (on/off)
-S VAL Включает/выключает автосохранение атрибутов (on/off)
-n MODE Не проверять. Один из режимов: never, sleep, standby, idle
-H Мониторить SMART статус, уведомлять только при ошибках.
-l TYPE Мониторить SMART логи. Режимы: error, selftest
-f Монитор отказа для любых атрибутов ‘Usage’
-m ADD Письмо с варнингами на ADD для -H, -l error, -l selftest, and -f
-M TYPE Изменение поведения отсыла е-майлов (см. ман)
-s REGE Запустить тест когда дата совпадает с регулярным выражением (см. ман)
-p Сообщать о изменениях в ‘Prefailure’ атрибутах
-u ообщать о изменениях в ‘Usage’ атрибутах
-t Эквивалентно -p и -u директивам
-r ID Также сообщать ‘RAW’ значения атрибутов ID с -p, -u или -t
-R ID Следить за изменениями в атрибуте ID ‘Raw’ значения -p, -u or -t
-i ID Игнорировать атрибут ID для -f директивы
-I ID Игнорировать атрибут ID для -p, -u или -t директивы
-C ID Рапортовать если счётчик `ждущих` секторов не равен нулю
-U ID Рапортовать если счётчик `некорректируемых` секторов не равен нулю
-W D,I,C Monitor Temperature D)ifference, I)nformal limit, C)ritical limit
-v N,ST Mодифицировать метку для атрибута N (для нестандартных атрибутов)
-a Дефолт: эквивалентно -H -f -t -l error -l selftest -C 197 -U 198
-F TYPE Для ошибок в прошивке. Значения: none, samsung
-P TYPE Предустановки для диска: use, ignore, show, showall
# Комментарии: текст после него игнорируется
\ Продолжения строки

Гру 272011
 

Короткие переменные не более 7 символов – ускорение 15%

Как влияет длина имен переменных на скорость программы? Если использовать очень длинные переменные – очевидно, что весьма сильно. Однако и с короткими именеми не все просто:

  1. {$x=1;}
  2. {$x2=1;}
  3. {$x03=1;}
  4. {$x004=1;}
  5. {$x0005=1;}
  6. {$x00006=1;}
  7. {$x000007=1;}
  8. {$x0000008=1;}
  9. {$x000000010=1;}
  10. {$x00000000012=1;}
  11. {$x0000000000014=1;}
  12. {$x000000000000016=1;}
  13. {$x0000000000000000000000000000032=1;}

выдает предсказуемый результат:

 

 

счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min % от max
test N1 1 1.7000 1.7000 00.0% 68.5%
test N2 1 1.7028 1.7028 00.2% 68.6%
test N3 1 1.7182 1.7182 01.1% 69.2%
test N4 1 1.7228 1.7228 01.3% 69.4%
test N5 1 1.7536 1.7536 03.2% 70.6%
test N6 1 1.7504 1.7504 03.0% 70.5%
test N7 1 1.7799 1.7799 04.7% 71.7%
test N8 1 1.9604 1.9604 15.3% 78.9%
test N9 1 1.9865 1.9865 16.9% 80.0%
test N10 1 2.0119 2.0119 18.3% 81.0%
test N11 1 2.0302 2.0302 19.4% 81.7%
test N12 1 2.1288 2.1288 25.2% 85.7%
test N13 1 2.4835 2.4835 46.1% 100.0%

Переменные от 32 символов могут тормознуть программу почти на половину.

Но если заполнять пробелами (" "), чтобы все строки “$x=1; ...” по длине занимали одно и тоже расстояние, то получается вот что:

 

  1. {$x=1;                                   }
  2. {$x2=1;                                  }
  3. {$x03=1;                                 }
  4. {$x004=1;                                }
  5. {$x0005=1;                               }
  6. {$x00006=1;                              }
  7. {$x000007=1;                             }
  8. {$x0000008=1;                            }
  9. {$x000000010=1;                          }
  10. {$x00000000012=1;                        }
  11. {$x0000000000014=1;                      }
  12. {$x000000000000016=1;                    }
  13. {$x0000000000000000000000000000032=1;    }

 

счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min % от max
test N1 1 2.1167 2.1167 01.9% 83.3%
test N2 1 2.0766 2.0766 00.0% 81.7%
test N3 1 2.0937 2.0937 00.8% 82.4%
test N4 1 2.0821 2.0821 00.3% 81.9%
test N5 1 2.1145 2.1145 01.8% 83.2%
test N6 1 2.0921 2.0921 00.7% 82.3%
test N7 1 2.1076 2.1076 01.5% 82.9%
test N8 1 2.3058 2.3058 11.0% 90.7%
test N9 1 2.3046 2.3046 11.0% 90.7%
test N10 1 2.3107 2.3107 11.3% 90.9%
test N11 1 2.3111 2.3111 11.3% 90.9%
test N12 1 2.3680 2.3680 14.0% 93.2%
test N13 1 2.5418 2.5418 22.4% 100.0%

Уж как комментировать тест переменной из одного символа (на 2% медленне самого быстрого) – не знаю… Наверно, тесты имеют большую погрешность. Предлагаю кому-нибудь запустить тест на час (исходники теста внизу страницы).

Одно ясно – при длине переменных в 8 и более символов происходит резкое снижение производительности, до 15%! А команд, включающих названия переменных, очень много. Еще один менее резкий скачек на переменных с именем 16 символов в длину и более. А в остальных случаях – чем больше, тем дольше, весьма линейная зависимость.

Вывод – не используйте переменны из 8 и более символов, выиграете 15% скорости (вернее, сэкономите).

Гру 272011
 

Выносите $переменные из “текстовых строк” – ускорение 25-40%

Одна и таже операция присваивания (либо echo/print для вывода на экран) в зависимости от того, заключены ли переменные в кавычеки или нет, сильно влияет на скорость. В первом и втором вариантах добавлены пробелы, чтобы выравнять размер общего кода для парсинга.

  1. {$x="test".$test;    }
  2. {$x="test $test";    }
  3. {$x="test";$x.=$test;}

Переменная $test содержит строку “1234567890”.

 

 

 

счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min % от max
test N1 1 3.5911 3.5911 00.0% 70.9%
test N2 1 5.0616 5.0616 40.9% 100.0%
test N3 1 4.9870 4.9870 38.9% 98.5%

Итак, никогда не пишите $a="$b", ибо это затормозит программу (в этой строке) на 40%.

Однако, если у вас большая строка, где много текста и переменных, различия в скорости уменьшаются, т.к. общие затраты на парсинг становятся намного больше, чем разные по эффективности команды. Но почему бы и не увеличить скорость программы (строк присваивания) почти на четверть таким простым методом?

  1. {$x="test ".$test." test ".$test." test ".$test;}
  2. {$x="test $test test $test test $test";}
  3. {$x="test ";$x.=$test;$x="test ";$x.=$test;$x="test ";$x.=$test;}

счетчик кол-во
вызовов
общее
вpемя
сpеднее
вpемя
% от min % от max
test N1 1 7.6894 7.6894 00.0% 66.0%
test N2 1 9.5515 9.5515 24.2% 82.0%
test N3 1 11.6506 11.6506 51.5% 100.0%
Гру 252011
 

В чем разница между одинарной кавычкой (‘) и двойной кавычкой (“)?

Эту синтаксическую особенность можно продемонстрировать на примере

<?php
$var=10;
echo ‘1) Значение переменной: $var’;
echo ‘<br>’;
echo “2) Значение переменной: $var”;
?>

Даст результат:

1) Значение переменной: $var
2) Значение переменной: 10

 

Как видите, в первом случае PHP воспринял $var как текст, во втором – как имя переменной. Соответственно, на месте $var во втором случае мы увидели значение переменной $var, при чем если между двойными кавычками встречается символ $, обозначающий переменную, то PHP воcпримет следующий за ним набор символов (вплоть до первого символа, который не разрешен для имени переменной), как имя переменной. Если эта переменная не была объявлена, PHP сгенерирует ошибку.

Важная деталь: при двойных кавычках интерпретер не «всего-лишь» заменяет переменные и спецсимволы на их значение, а сначала ищет их во всём наборе символов от начала до конца. Так как при одинарных кавычках этого не происходит, то и обработка, соответственно, быстрей. При объёмных проектах разница во времени выполнения скрипта становится ощутимой.