[image]

Тесты: производительность разных механизмов кеширования в PHP

 
+
-
edit
 

Balancer

администратор
★★★★★
Наконец, у меня накопился достаточный инструментарий для того, чтобы без особых затрат провести тестирование различных механизмов кеширования данных в PHP. Основные кандидаты, с которых начиналось тестирование:
  • Memcached
  • MySQL в виде кеш-таблицы
  • Redis
  • Файловый кеш фреймворка Zend


(список будет пополняться по мере дописания материала)

Зачем, вообще, понадобился этот тест. Традиционно считается, что из подручных инструментов лучшим является Memcache. Многие широко его используют, вроде бы, заметно разгружая им свои системы. Однако, не менее традиционны уже и тесты, показывающие чрезмерную медлительность memcache, нередко обычный файловый кеш работает много быстрее! Поскольку хранение данных в файловой системе крайне накладно для дисковой подсистемы и скорость работы может сильно падать при параллельной работе нескольких процессов, тестирование явно должно подразумевать многопоточность. Вот на этом моменте я в своё время и заткнулся, так как с многопоточностью в PHP разбираться было лениво.

Но шаг за шагом, реализуя иные вещи, мне пришлось последнее время заняться и вопросом многопоточности. Что сразу же подвело и к реализации теста.

Итак, в чём суть теста.
  • Пишутся классы кеш-бэкендов под фреймворк BORS. До последнего времени практически использовался только один такой класс, cache_smart, использующий совмещённое хранение данных в памяти процесса, memcache и mysql. Были для тестов когда-то реализованы bors_cache_zend_file для проверки эффективности разрекламированного файлового кеша Zend и bors_cache_redis для работы с популярным key-value хранилищем Redis. В дальнейшем работа была приостановлена, пока я к ней не вернулся на днях.
  • Каждый кеш заполняется некоторым набором хаотичных, но детерминированных данных, часть из которых имеет малое, часть — более долгое время хранения. Результат считывается сразу после заполнения, чтобы проверить на сохраняемость данных, затем происходит ожидание, в течении времени, гарантирующего устаревание части данных и актуальность другой части данных и ещё одна проверка на оба случая. Таким образом тест производительности автоматически становится и тестом на работоспособность.
  • Измеряется время работы и работоспособность теста как в одиночном, так и в многопоточном режимах.


Продолжение следует :)
   
+
-
edit
 

Balancer

администратор
★★★★★
Начну сразу с подстерегавших меня неожиданностей.
  • Оказалось, что в многопоточном режиме в PHP, стандартный класс Memcache не работает, вываливая Notice «MemcachePool::set(): Server localhost (tcp 11211, udp 0) failed with: Network timeout (0)». Вопрос решён пока костыльно, я вместо одного общего instance для всего процесса фреймворка стал заводить его при каждом обращении. Безусловно, это на сколько то снижает скорость, так что впоследствии этот вопрос нужно будет разрулить отдельно.
  • Пресловутый файловый кеш Zend, как оказалось, безошибочно отрабатывает в однопоточном режиме и начинает сбоить (возвращает отсутствие данных в кеше при их предварительной установке) в многопоточном режиме. В частности:
    • 1-5 потоков, работоспособность 100%
    • При 10 потоках ошибочные пустые значения считываются, в среднем, в половине случаев. Разброс от 0 до 100%.
    • При 20 потоках верное чтение практически не встречается.
  • Также пришлось переписать старый класс cache_smart, приведя его к новому (несколько лет назад :D) интерфейсу, под новым именем bors_cache_smart. Временно блокировано сохранение в памяти процесса, так как для этих данных отсутствовала проверка на истекание срока жизни кеша. Со временем нужно будет исправить, а также, сделать bors_cache_smart универсальным бэкендом, работающим не только с memcached и mysql, но и с другими кешами, в порядке приоритета, задаваемым результатами этого теста :)


Предварительные результаты. Всё тестируется на сервере Авиабазы, на живой и нагруженной машине. Напомню, Quad-Core AMD Opteron(tm) Processor 2386 SE, 16Гб RAM, SATA.

Однопоточное использование.
КешМинимальное время работы в серии, сек.Максимальное время работы в серии
memcache0,0600,066
mysql0,1300,171
smart0,1560,229
zend_file0,0951,029
redis0,1200,321

(серия - 7 запусков)

Сразу видно, что скорость работы файлового кеша очень сильно зависит от загрузки машины. Разброс значений — более чем в 10 раз. Достаточно заметный разброс у кеша smart. Очень хорошо показывает себя, вопреки критике, memcache. redis является достаточно серьёзным конкурентом mysql.

Переходим к многопоточному тестированию.
   
+
-
edit
 

Balancer

администратор
★★★★★
Многопоточное тестирование

5 потоков
Кешavg-minavg-maxmedian-minmedian-maxminmax
memcache0,1060,1330,1060,1340,1030,144
mysql0,2190,2330,2180,2320,1970,249
smart0,2640,2810,2640,2810,2560,287
zend_file0,4310,6100,3960,6340,2260,709
redis0,1480,1680,1470,1860,1200,190


avg-min — минимальное среднее время в серии из трёх запусков
avg-max — максимальное среднее время в серии из трёх запусков
median-min — минимальное медианное время в серии из трёх запусков
median-max — максимальное медианное время в серии из трёх запусков

10 потоков
Кешavg-minavg-maxmedian-minmedian-maxminmaxдоля отказов, %
memcache0,2060,2100,2040,2100,1890,2360+0+0
mysql0,3750,4930,3880,5040,3140,5160+0+0
smart0,5560,6670,5620,6680,5390,6870+20+20
zend_file1,3991,7171,4071,6220,6772,51660+50+40
redis0,2800,6030,3000,6090,2050,61730+0+0


20 потоков
Кешavg-minavg-maxmedian-minmedian-maxminmaxдоля отказов, %
memcache0,4110,4740,4150,4880,3660,5160+0+0
mysql0,8790,9300,8870,9380,7330,9620+15+5
smart1,1321,4731,1331,5051,0801,5250+5+0
zend_file1,3411,3411,3411,3411,3411,341100+95+100
redis0,6960,8240,7250,8480,5130,8930+0+0



50 потоков
Кешavg-minavg-maxmedian-minmedian-maxminmaxдоля отказов, %
mysql1,6082,3731,6082,3831,5872,4140+100+48
redis2,6934,6622,8574,7411,5014,8790+0+0


  • memcached на 50 потоках стал выдавать тонны Notce «Memcache::connect(): Server localhost (tcp 11211, udp 0) failed with: Невозможно назначить запрошенный адрес (99)»
  • Ошибки mysql на большом числе потоков, возможно, связаны с превышением лимита числа соединений. Хотя ошибки не выводились.
  • Непонятны были 30% отказов в одном из тестов с redis, при чём всего на 10 потоках. Хотя даже на 50 потоках впоследствии отрабатывает замечательно.


Выводы:
  • memcache, действительно, самый быстрый. Если только не откажет :)
  • Следующим за ним можно назвать redis.
  • Файловый кеш всерьёз можно в дальнейшем не рассматривать.


В данном тесте происходила небольшая выборка, всего на 100 значений. И одно чтение на одну запись. Для более реалистичного теста потребуется 1-2 миллиона записей и несколько чтений на одну запись. Поскольку это будет много более ресурсоёмкая задача, то это будет отдельный тест. Участвовать будут memcache (если ему хватит памяти), mysql и redis.
   
+
-
edit
 

Balancer

администратор
★★★★★
memcache также выбыл из борьбы, так как глючит с большим числом записей. Видимо, требует настройки. Буду разбираться позже.

10000 записей по тесту одна запись + 10 чтений выполняется:
  • redis — 34.5 сек
  • mysql — 39,0 сек


Запустил тест на 1 млн. записей и пойду спать :)
   
RU Balancer #18.05.2011 12:29  @Balancer#18.05.2011 04:22
+
-
edit
 

Balancer

администратор
★★★★★
Balancer> Запустил тест на 1 млн. записей и пойду спать :)

Облом жёсткий. Ночью, когда я уже спал, дома вырубили свет. А тест был запущен в обычной ssh-сессии, ни вывода лога в файл, ни screen'а. Так что чем там и с какими цифрами закончилось — не в курсе :D
   

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru