Přetížil se mi server IO požadavky. Už podruhé. Chtěl jsem po něm docela obyčejnou věc. Asi 5 paralelních IO požadavků různé povahy (4x čtení a 1x zápis). Skripty pro převod obrázků, samba nad RAID5 diskovým polem a iSCSI target nad samostatným diskem. Tedy, ne že by ty IO nevyřizoval vůbec, to zase jo. Na terminál reagoval, ovšem příkaz kill
načítal několik desítek sekund.Odpovědnost za plánování IO má kdo jiný, než plánovač (elevator). CentOS 5.5 nabízí 4:
Poslední jmenovaný je výchozím plánovačem. Postupně jsem je otestoval standardním testem pgbench
pro PostgreSQL server.
Podmínky testů
- HW: Intel(R) Core(TM)2 CPU 6320; 8GB DDR2-800; HDD SAMSUNG HD103UJ
- SW: CentOS 5.5 64b (2.6.18-194.11.1.el5.centos.plus); postgresql-8.4.4
- FS: Vyladěný XFS
- Test byl spuštěn 4x, výsledky zprůměrovány.
Testovací skript
Inicializace DB pro test a nastavení plánovače pro disk nesoucí soubory DB:
# deadline, noop, anticipatory, cfq echo "deadline" > /sys/block/sda/queue/scheduler pgbench -i -s 10; sync
Test samotný, vždy 4x:
pgbench -c 64 -M prepared -t 1000
Výsledky testů plánovačů
scheduler | tps | prumer tps | pomer vykonu % | |||
deadline | 1507 | 1598 | 1558 | 1519 | 1626.00 | 100.00 |
noop | 1549 | 1595 | 1573 | 1562 | 1569.75 | 96.54 |
anticipatory | 1498 | 1503 | 1476 | 1502 | 1494.75 | 91.93 |
cfq | 1400 | 1430 | 1446 | 1429 | 1426.25 | 87.72 |
Test tedy vyhrál plánovač deadline. Výchozí plánovač v CentOSu a dalších distribucí Linux, cfq dopadl nejhůře s výkonem o 13% nižším.
Změna výchozího plánovače
Plánovač lze změnit kdykoliv za běhu a může být pro každé blokové zařízení jiné. Změna se provede prostým zapsáním do souboru ve speciálním systému souborů /sys. Například pro disk sda a plánovač deadline:
echo "deadline" > /sys/block/sda/queue/scheduler
Aktivní plánovač a seznam dostupných lze získat jednoduše přečtením souboru scheduler:
cat /sys/block/sda/queue/scheduler noop anticipatory [deadline] cfq
Aktuální plánovač je vypsán v hranatých závorkách.
Takto provedená změna ovšem není trvalá, tu lze nastavit v parametrech jádra. V souboru /etc/grub/grub.conf, plánovač se zde uvádí jako parametr elevator:
kernel /vmlinuz-2.6.18-194.11.1.el5 ro root=/dev/system/root elevator=deadline
Pokud chceme použít pro každé blokové zařízení jiný plánovač (každý se hodí na jiný typ pracovní zátěže), je možné dát jejich nastavení např. do /etc/rc.d/rc.local.
Závěr
Ale zpět k problému. Výchozí plánovač se snaží být fér (Completely Fair Queuing — zcela spravedlivý plánovač), bohužel tak moc, že zcela zablokuje přístup k disku. Zatímco plánovač deadline přidělí každému IO požadavku určitý čas, pak se věnuje dalšímu požadavku ve frontě a tak dále (samozřejmě s optimalizací pro minimální seek). Tedy se každý požadavek nakonec dostane ke slovu a bude vyřizován poměrně dlouho (ve výchozím nastavení 500ms, za tuto dobu lze na moderním disku přečíst i několik desítek MB dat).
Systém se chová o poznání předvídatelněji. Při pěti požadavcích je práce s diskem samozřejmě pomalá, ale každý program se k němu nakonec dostane.