воскресенье, 10 января 2016 г.

postgres бенчмарки. часть 3. железо

Т.к. постгрес каждый запрос выполняем на отдельном цпу (без распараллеливания) то очень важно для системы, работающей с постгрес, чтобы эффективность каждого ядра + работа с памятью была максимальной.

Есть хороший бенчмарк, написанный для этих целей - http://github.com/gregs1104/stream-scaling

Чтобы бенчмарк был более достверный - надо отключить пониженное энергопотребление процессора и динамическую частоту.

На системе с Intel(R) Core(TM) i3-4030U CPU @ 1.90GHz - 4 ядра:

Function    Best Rate MB/s  Avg time     Min time     Max time
Copy:           11128.2     0.015148     0.014378     0.016843
Scale:           9838.3     0.017435     0.016263     0.022605
Add:             9520.8     0.026703     0.025208     0.031915
Triad:           8808.9     0.028463     0.027245     0.029689

Number of Threads requested = 2
Function    Best Rate MB/s  Avg time     Min time     Max time
Triad:          10690.4     0.026216     0.022450     0.030911

Number of Threads requested = 3
Function    Best Rate MB/s  Avg time     Min time     Max time
Triad:           9466.7     0.026791     0.025352     0.030185

Number of Threads requested = 4
Function    Best Rate MB/s  Avg time     Min time     Max time
Triad:          10119.8     0.024579     0.023716     0.027354



Вот данные с системы на которой основные бенчмарки проверяются:

Intel(R) Core(TM) i5 CPU         750  @ 2.67GHz
Function    Best Rate MB/s  Avg time     Min time     Max time
Copy:            6894.2     0.037242     0.036641     0.038797
Scale:           8803.7     0.028890     0.028694     0.029372
Add:             8344.5     0.045766     0.045409     0.047154
Triad:           7644.4     0.050011     0.049568     0.052200

Number of Threads requested = 2
Function    Best Rate MB/s  Avg time     Min time     Max time
Triad:           8180.4     0.047172     0.046320     0.049512

Number of Threads requested = 3
Function    Best Rate MB/s  Avg time     Min time     Max time
Triad:           7354.3     0.055346     0.051523     0.060877

Number of Threads requested = 4
Function    Best Rate MB/s  Avg time     Min time     Max time
Triad:           7282.7     0.054480     0.052030     0.059323



Современные системы работают с памятью лучше.


В первом случае частота памяти 1600 MHz, во втором - 1333 MHz


Диски
Т.к. постгрес работает с блоками по 8кб - замерим работу диск с данными, которые вдвое превышают оперативу
blocks = 250,000 * (gigabytes of RAM) = 1750000  (для 7gb)
time sh -c "dd if=/dev/zero of=bigfile bs=8k count=1750000 && sync"
time dd if=bigfile of=/dev/null bs=8k

hdd
time sh -c "dd if=/dev/zero of=bigfile bs=8k count=1750000 && sync"
1750000+0 записей получено
1750000+0 записей отправлено
скопировано 14336000000 байт (14 GB), 254,593 c, 56,3 MB/c

real 4m29.297s
user 0m0.284s
sys 0m10.948s

На чтение
time dd if=bigfile of=/dev/null bs=8k
1750000+0 записей получено
1750000+0 записей отправлено
скопировано 14336000000 байт (14 GB), 262,622 c, 54,6 MB/c

real 4m22.634s
user 0m0.592s
sys 0m15.396s

sudo hdparm -tT /dev/sda
/dev/sda:
 Timing cached reads:   19278 MB in  2.00 seconds = 9647.50 MB/sec
 Timing buffered disk reads: 272 MB in  3.01 seconds =  90.22 MB/sec

Скорость памяти можно измерять с помощью memtest86+

postgres бенчмарки. часть 2

Создадим таблицу помощнее
pgbench -i -s 30 -h 192.168.1.103 -U postgres tmp

На этот раз она занимает 456М

И пройдёмся теми же тестами
110тпс для одного клиента

pgbench -c 80 -U postgres -T 30 -h 192.168.1.103 tmp
При 80 клиентах получается 320тпс

Уже заметна нагрузка на базу в лице checkpoint process - база нахватывается транзакций, исполняет их и сохраняет, создавая нагрузку на диск. (в конце статьи поборем эту беду)

Локально получалось и до 420тпс разгонять. Возможно было удачное попадание в чекпойнт.

Таблица таже. Попробуем добавить --foreign-keys
300-320 tps

И без них или чуть хуже (?) или столько же

 -j 4 - в 4 потока. В пределах погрешности - 427
pgbench -c 80 -j4 -U postgres -T 30 -h 192.168.1.103 tmp
scaling factor: 30
query mode: simple
number of clients: 80
number of threads: 4
duration: 30 s
number of transactions actually processed: 12812
latency average: 187.324 ms
tps = 425.185222 (including connections establishing)
tps = 427.432431 (excluding connections establishing)


Если делать в одного клиента - нагрузка на сеть получается равномерной
Нашел интересную вещь - протокол

Теперь нужна нормальная (большая база) для тестов похожи на среднюю нагрузку
pgbench -i -s 200 -h 192.168.1.103 -U postgres tmp

Это база на 3гб
Классический тест
pgbench -c 80 -U postgres -T 30 -h 192.168.1.103 tmp
Делает большой разброс от 180 до 280 тпс.

В один коннект
93тпс. Видно что нагрузка просела.

Протестим увеличение work_mem
Непонятно. Всё также
200-270тпс

Самое время увеличить shared_buffers. 2гб в самый раз!
И сразу 200-290тпс

Всё упирается в чекпойнты. С 3 поднимем до 10
И сразу 290-337. Т.е. когда часто идёт запись есть смысл увеличивать число сегментов.

А теперь всё увеличим!
500! 500! Карл!
Повторно - 300.
Соло - 113-115 что несколько выше

Если при тестах видно что упирается всё в сегменты, то надо увеличивать число. При этом логи постгреса сами подскажут что нужно это число увеличить! Грепайте по HINT
После увеличения сегментов много пользовательский тест показал
pgbench -c 100 -U postgres -T 30 -h 192.168.1.103 tmp
starting vacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 200
query mode: simple
number of clients: 100
number of threads: 1
duration: 30 s
number of transactions actually processed: 48504
latency average: 61.851 ms
tps = 1597.936361 (including connections establishing)
tps = 1638.000089 (excluding connections establishing)

Огонь!

Проверим только селекты
pgbench -S -c 100 -U postgres -T 30 -h 192.168.1.103 tmp
starting vacuum...end.
transaction type: SELECT only
scaling factor: 200
query mode: simple
number of clients: 100
number of threads: 1
duration: 30 s
number of transactions actually processed: 93766
latency average: 31.995 ms
tps = 3100.100112 (including connections establishing)
tps = 3179.048805 (excluding connections establishing)

Это при 100 клиентах. Для одного клиента нам тоже важно
 pgbench -S -U postgres -T 30 -h 192.168.1.103 tmp
starting vacuum...end.
transaction type: SELECT only
scaling factor: 200
query mode: simple
number of clients: 1
number of threads: 1
duration: 30 s
number of transactions actually processed: 48013
latency average: 0.625 ms
tps = 1600.395937 (including connections establishing)
tps = 1600.801624 (excluding connections establishing)

1600 записей можно читать для одного клиента