пятница, 19 февраля 2016 г.

Бенчмарк базы без баунсера. Только селекты. Начало

Идём по плану. Создали таблицу на 100к записей. Для pgbench

  1. Тестим в 1/4/8/16/32 селектов.
    • 1 - 1600 (-10) тпс - 1680
    • 4 - 7300 (-100) тпс - 7300
    • 8 - 17250 (-100) тпс - 17300
    • 16 - 26500 (-300) тпс - 26700
    • 32 - 28000 (-500) тпс - 28000
  2. Тестим в 1/4/8/16/32 селектов с новым коннектом
    • 1 - 120 / 940 тпс - 120 / 945
    • 4 - 133 / 11200 тпс - 133 / 11220
    • 8 - 135 / 11200 тпс - 134 / 11300
    • 16 - 133 / 10700 тпс - 133 / 11270
    • 32 - 133 / 10500 тпс - 132 / 10660
  3. Тестим в 1/4/8/16/32 селектов prepared statements
    • 1 - 1714 (-10) тпс - 1680
    • 4 - 7400 (-100) тпс - 7600
    • 8 - 18000 (-100) тпс - 18000
    • 16 - 27500 (-300) тпс - 27500
    • 32 - 28500 (-500) тпс - 27800
  4. Тестим в 1/4/8/16/32 селектов prepared statements с новым коннектом.
    • Не работает 

Выводы

На что можно обратить внимание?
  • prepared statements - ни разу не медленные! Может тут решает то, что всё делается не из скрипта (задержки между вызовами минимальны)
  • Новые коннекты создавать реально очень дорого - лишь 133 селекта в секунду на всех.
  • Теперь подключим баунсер и ожидаем получить что в групп 1 и 3 результаты немного упадут, а в группе 2 - вырастут!

вторник, 16 февраля 2016 г.

Системные вызовы при коннекте к БД Postgres из PHP

Symfony

1455554851.464383 sendto(6, "P\0\0\0z\0SELECT t0.name AS name_1, t0.number AS number_2, t0.id AS id_3 FROM bench_data t0 WHERE t0.num"..., 168, MSG_NOSIGNAL, NULL, 0) = 168 <0.000023>
1455554851.464435 poll([{fd=6, events=POLLIN|POLLERR}], 1, 4294967295) = 1 ([{fd=6, revents=POLLIN}]) <0.000278>
1455554851.464744 recvfrom(6, "1\0\0\0\0042\0\0\0\4T\0\0\0Q\0\3name_1\0\0\0bB\0\2\0\0\4\23\377\377\0\0\1\3\0\0number_2\0\0\0bB\0\3\0\0\0\27\0\4\377\377\377\377\0\0id_3\0\0\0bB\0\1\0\0\0\27\0\4\377\377\377\377\0\0D\0\0\0006\0\3\0"..., 16384, 0, NULL, NULL) = 167 <0.000010>

Yii

1455554340.049263 sendto(6, "P\0\0\0Ipdo_stmt_00000001\0SELECT * FROM \"bench_data\" WHERE \"number\"=$1\0\0\1\0\0\0\0S\0\0\0\4", 79, MSG_NOSIGNAL, NULL, 0) = 79 <0.000040>
1455554340.049454 poll([{fd=6, events=POLLIN|POLLERR}], 1, 4294967295) = 1 ([{fd=6, revents=POLLIN}]) <0.000061>
1455554340.049617 recvfrom(6, "1\0\0\0\4Z\0\0\0\5I", 16384, 0, NULL, NULL) = 11 <0.000087>

pgbench

1455559601.087593 sendto(12, "T\0\0\0!\0\1abalance\0\0\0b\240\0\3\0\0\0\27\0\4\377\377\377\377\0\0D\0\0\0\v\0\1\0\0\0\0010C\0\0\0\rSELECT 1\0Z\0\0\0\5I", 66, 0, NULL, 0) = 66 <0.000104>
1455559601.087742 recvfrom(12, "Q\0\0\0\20DISCARD ALL\0", 8192, 0, NULL, NULL) = 17 <0.000375>

Выводы

В пых коннекте вставлен системный вызов poll для ожидания завершения работы сокета. Наверно поэтому PDO коннекторы работают хуже чистого подключения. И еще у pgbench используется другой сокет (id = 12), в то время как yii и symfony используют один и тот же (id = 6)

понедельник, 15 февраля 2016 г.

Низкоуровневая отладка процесса в Linux с помощью strace

Начал читать статью http://www.speedemy.com/troubleshooting-web-application-performance-issues/ и уже буря эмоций!

Новый ключ к пониманию работы приложения и производительности!

Например подключаюсь к php-fpm и стартую процесс

ps aux | grep php
www-data  1900  0.0  0.5 340476 32840 ?    S    февр.14   0:00 php-fpm: pool www                                                           
www-data  1901  0.0  0.6 340492 36104 ?    S    февр.14   0:00 php-fpm: pool www


sudo strace -p 1900 -tttT -s200

И вуаля!

recvfrom(9, "VALUE NotOwlnewPermissionsUser64"..., 8196, MSG_NOSIGNAL, NULL, NULL) = 531
sendto(9, "get NotOwlnewPermissionsUser6452"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
recvfrom(9, "VALUE NotOwlnewPermissionsUser64"..., 8196, MSG_NOSIGNAL, NULL, NULL) = 531
sendto(9, "get NotOwlnewPermissionsUser6452"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
recvfrom(9, "VALUE NotOwlnewPermissionsUser64"..., 8196, MSG_NOSIGNAL, NULL, NULL) = 531
sendto(9, "get NotOwlnewPermissionsUser6452"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
recvfrom(9, "VALUE NotOwlnewPermissionsUser64"..., 8196, MSG_NOSIGNAL, NULL, NULL) = 531


recvfrom(5, "\1\5\0\1\0\0\0\0", 8, 0, NULL, NULL) = 8
close(5)                                = 0
munmap(0x7f5816a00000, 2097152)         = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
accept(0, ^CProcess 1900 detached
 <detached ...>

Все системные вызовы на ладони!