Portál AbcLinuxu, 23. říjen 2017 19:18

Stavíme poštovní server – 17 (optimalizace výkonu)

19. 4. 2010 | Lukáš Jelínek
Články - Stavíme poštovní server – 17 (optimalizace výkonu)  

Pokud není poštovní server příliš zatížen, není obvykle potřeba se nějak významně zabývat tím, jak je optimalizován z hlediska výkonu. Pokud ale průtok zpráv a uživatelských přístupů stoupá, nabývá optimalizace serveru na významu.

Obsah

Silnější železo, nebo optimalizace?

link

S rostoucí zátěží serveru (nejen poštovního) se stává aktuální otázka, jak se s touto zátěží vypořádat. Nabízejí se v zásadě tři možná řešení:

Nejjednodušší řešení zátěže je posílení hardwaru, lidově řečeno „silnější železo“. Může to zahrnovat výměnu či přidání procesoru, rozšíření operační paměti, nasazení rychlejších disků či změnu konfigurace pole RAID, zvýšení rychlosti síťového připojení atd. Výhoda je, že jednoduše posílí ten prostředek, kterého se nedostává. Stojí to však určité peníze a mnohdy to nelze provést bez výměny celého serveru (například proto, že základní deska toho současného více procesorů či větší paměť neumožňuje přidat). Navíc pokud je velká zátěž jen přechodný jev (typicky při útoku), bylo by navyšování hrubé síly zbytečné.

Další možnost je změna architektury – a to jak ve smyslu serveru jako celku, tak i poštovního řešení. Server jako celek lze virtualizovat a nastavovat mu prostředky podle potřeby (takže stačí mít velmi výkonný fyzický stroj a provozovat na něm více serverů virtuálních; lze tím ušetřit za hardware). Změna architektury poštovního řešení může znamenat například oddělení rolí serveru (např. doručování a relaying), přenesení některých služeb na samostatné stroje (např. greylisting, databáze, antivirová kontrola), použití samostatného úložiště atd. Změny architektury jsou dobrá volba pro dlouhodobý horizont, ovšem pokud je potřeba najít řešení nadměrné zátěže ihned, může to být velmi nákladné a něco se může zbytečně uspěchat.

Poslední možnost je optimalizace stávajícího serveru, jeho konfigurace. Na přímých nákladech to nebude stát ani korunu, veškeré změny se odehrají jen v rámci konfigurace. Vždy je to samozřejmě něco za něco. Vylepšení některých vlastností může mít za následek zhoršení jiných.

Kdo očekává, že budou následující odstavce prošpikované kouzelnými hodnotami, které stačí někam zadat, a vše bude najednou skvělé, bude asi zklamán. Takhle jednoduché to není, ostatně kdyby bylo, vyřešili by to tvůrci programu sami a nebylo by potřeba nic konfigurovat. Další text bude tedy hodně v obecné rovině, konkrétní řešení je třeba vždy tvořit pro danou reálnou situaci.

Adaptivní změna chování

link

Verze 2.5 programu Postfix přináší jedno zásadní vylepšení, týkající se funkce při extrémní zátěži. Zavádí totiž stress-adaptive behavior čili „stresově adaptivní chování“. Funguje to tak, že pokud se server dostane do stavu přetížení (nelze obsloužit dalšího klienta), řídící proces master restartuje službu (typicky smtpd) v režimu pro vysokou zátěž. Aktuálně otevřené relace jsou obslouženy ještě v původním režimu.

Smyslem existence režimu je řešit krátkodobé stavy extrémní zátěže (masivní připojování ze spammerských botnetů, různé DoS a DDoS útoky atd.), nikoli trvalý nadměrný provoz.

Režim pro vysokou zátěž využívá samostatnou konfiguraci důležitých parametrů, které mají vliv na to, jak proběhne obsloužení připojeného klienta. Využívají se k tomu podmínkové konstrukty v konfiguračním souboru. Bude proto nejlepší podívat se nejprve na ně, protože je lze využít obecněji, nikoli jen v tomto případě.

Podmínkové konstrukty v main.cf

link

Veškeré dosud uváděné příklady konfigurace (v souboru main.cf) ukazovaly jen obyčejné přiřazování hodnot, ať již přímo, nebo přes nějaký datový zdroj. Nicméně již od verze 2.2 umožňuje Postfix vázat na to, zda je určitý parametr neprázdný nebo naopak prázdný. Obecný formát vypadá takto:

${name?value}
${name:value}

Připomíná to ternární operátor známý například z jazyka C, nicméně v tomto případě je rozdělen na dvě části. V prvním případě se uvedená hodnota použije, je-li obsah parametru neprázdný, ve druhém případě pro opačnou situaci, tedy prázdný parametr. Tady je konkrétní příklad:

relay_clientcerts = ${relayhost?hash:/etc/postfix/relay_clientcerts}

Tento zápis říká, že pokud je parametr relayhost neprázdný, nastaví se relay_clientcerts na uvedenou hodnotu (jinak bude prázdný). Oba konstrukty lze kombinovat a dosáhnout situace, jako kdyby se jednalo o ternární operátor:

smtpd_delay_reject = ${smtpd_client_restrictions?no}${smtpd_client_restrictions:yes}

V případě neprázdného parametru smtpd_client_restrictions se pro smtpd_delay_reject použije hodnota no, v opačném případě hodnota yes. Velmi se to bude hodit pro režim vysoké zátěže, jak se vzápětí ukáže.

Parametry pro režim vysoké zátěže

link

Při extrémní zátěži lze serveru odlehčit tím, že se některé parametry změní tak, aby se server se zátěží lépe vyrovnal. Týká se to hlavně následujících skupin parametrů:

Veškeré změny se však týkají jen služeb, které jsou veřejně přístupné (typicky tedy smtpd, případně včetně submission, pokud se používá). U ostatních služeb se režim vysoké zátěže nepoužívá.

Následující fragment souboru main.cf ukazuje možnou úpravu parametrů pro účely režimu vysoké zátěže:

smtpd_timeout = ${stress?10}${stress:300}s

smtpd_soft_error_limit = ${stress?1}${stress:10}
smtpd_hard_error_limit = ${stress?1}${stress:20}
smtpd_junk_command_limit = ${stress?1}${stress:100}

smtpd_client_connection_rate_limit = ${stress?10}${stress:0}
smtpd_client_message_rate_limit = ${stress?30}${stress:0}
smtpd_client_recipient_rate_limit = ${stress?300}${stress:0}
smtpd_recipient_limit = ${stress?100}${stress:0}
smtpd_recipient_overshoot_limit = ${stress?10}${stress:1000}

Takováto konfigurace znamená, že za běžných podmínek (server není příliš zatížen) se nebudou uplatňovat přísná omezení – ta nastoupí až v situaci, kdy dojde k přetížení serveru a služba smtpd bude nastartována v režimu vysoké zátěže (stress). Pak se například timeout zkrátí na 10 sekund, limit chyb a „prázdných“ příkazů klesne na 1 atd.

U Postfixu od verze 2.6 není potřeba některé z těchto parametrů nastavovat (viz manuál), protože výchozí hodnoty již s režimem vysoké zátěže počítají. Verze 2.5 však tato nastavení potřebuje.

Nastavování přísných omezení může být porušením RFC 2821 a hlavně může působit problémy některým legitimním klientům. Je proto potřeba vždy hledat rovnováhu mezi nutností aplikovat omezení a potřebou chránit před těmito omezeními legitimní provoz. Často je lepší postupovat raději konzervativně a přetěžování serveru (například ze strany botnetů) řešit i jinými prostředky.

Další ladění konfigurace

link

Na výkon má vliv řada konfiguračních parametrů. Velmi záleží na tom, kde je konkrétně problém s výkonem (ve které části serveru) a který systémový prostředek, resp. jeho nedostatek, problémy způsobuje.

Další popis se bude týkat výhradně Postfixu. V praxi se však velmi často stává, že úzké hrdlo není Postfix, nýbrž jiná součást serverového řešení, typicky třeba Spamassassin nebo ClamAV. V takových případech je potřeba soustředit se právě na tyto další programy a upravit jejich konfiguraci, případně se poohlédnout po jejich méně náročných alternativách.

Existuje více systémových prostředků, kterých se může při provozu serveru nedostávat. Je to především procesor, operační paměť, přenosové pásmo pro komunikaci s úložištěm (diskem) a přenosové pásmo pro síťovou komunikaci. V některých případech může být takový zdroj například i DNS server, vzdálená databáze nebo LDAP server.

Procesor

link

Procesor bývá pro holý Postfix (bez dalších programů) málokdy nedostatkový zdroj. Většina operací s poštou je nenáročná. Větší zátěž se objevuje jen v případech, kdy se provádí složitější analýza těla zpráv nebo při šifrování komunikace (TLS). Na tyto věci je tedy potřeba se primárně zaměřit. Není-li potřeba TLS, lze ho vypnout (přinejmenším pro směr ven, aby to nemělo dopady na klienty nastavené natvrdo tak, že ho používají) a ušetřit tím nemalé množství procesorového času.

Dále se mohou objevit problémy při velkém množství otevřených relací (jak u příchozí, tak u odchozí pošty), na kterých probíhá komunikace. Systém je tak nucen k velmi častému přepínání kontextu a roste vlastní režie systému. Velmi záleží na tom, jak se s tím vyrovná jádro systému – například u Linuxu verzí 2.4 (občas ho lze ještě na serverech potkat) to bylo dost nepříznivé, protože operační složitost plánování běhu úloh byla lineární (u jader 2.6 byl zaveden nový plánovač s konstantní složitostí; plánovač CFS, který je v Linuxu od jádra 2.6.23, má složitost přibližně logaritmickou). Dalším faktorem je počet procesorů či jejich jader.

Pokud se tedy vyskytuje situace, že má Postfix trvale problémy s nedostatkem procesorového výkonu (projevují se vytížením všech procesorů/jader procesy Postfixu, dlouhou prodlevou při příjmu zpráv apod.), je v první řadě potřeba zjistit, čím je to způsobeno. Pokud se využívají složitá pravidla pro analýzu těla zpráv, je vhodné zvážit jejich smysl a případně přesunout celou analýzu do Spamassassinu nebo jiného podobného programu, pokud se používá. Totéž se týká i analýzy hlaviček.

Je-li příčinou vysoký počet současně otevřených relací, lze jejich počet omezit. Je třeba to dělat primárně na odchozí straně (kde to způsobí jen případné zvětšení zpoždění zpráv; omezování příchozích relací má vždy za následek odmítání klientů).

Ve výchozím nastavení vytvoří řídicí proces master maximálně 100 procesů pro určitou službu. Pokud je počet procesů služby smtp nízký (výrazně nižší než uvedený limit), nemá smysl ho dále omezovat. Pokud se ale k této hodnotě blíží nebo ji případně dosahuje, lze hodnotu snížit například na 50 a sledovat, jak se chování systému změní. Změna může vypadat takto (v souboru master.cf – ostatní řádky se nemění):

smtp      unix  –       –       –       –       50       smtp

Pokud je zásah úspěšný (uvedená hodnota samozřejmě není dogma – vhodnou lze nejlépe najít testováním), je potřeba kontrolovat, zda se ve frontách nehromadí zprávy. Může se totiž stát, že je potřeba doručovat na mnoho serverů současně a proto se limit procesů vyčerpá. Pro sledování stavu fronty, zejména počtu zpráv čekajících na doručení do určité domény a časové distribuce doby čekání, lze s výhodou použít nástroj qshape – podrobné informace o jeho použití najdete v manuálu (qshape(1)) a v dokumentaci k Postfixu.

Jedno z možných řešení situací, kdy se zprávy hromadí ve frontách, je omezit počet současného doručování do téže domény. Server totiž normálně může vytvořit pro určitou doménu více relací současně (standardně až 20) a doručovat paralelně. To může zrychlit doručení, protože někdy poštu pro doménu přijímá více serverů, ale také to spotřebuje více procesů. Je-li zbytečná spotřeba procesů nežádoucí, lze souběžné doručování omezit (v main.cf):

smtp_destination_concurrency_limit = 2

Uvedený řádek zajistí, že se nebude doručovat ve více než dvou souběžných relacích pro tutéž doménu. Rychlejšímu vyprazdňování front to pomůže jen v případech, kdy se doručuje do relativně malého počtu domén, ale do každé směřuje hodně zpráv. Opět je potřeba důkladně otestovat chování a vyzkoušet více různých hodnot.

Paměť

link

Podobně jako v případě procesoru, Postfix je velmi nenáročný i na paměť. Dá se říci, že nejvíce paměti se spotřebuje pro diskovou cache, nikoli pro vlastní data nebo programový kód. Pro případy nedostatku fyzické paměti (systém se dostává do stavu, kdy je paměti málo – musí proto odkládat paměťové stránky na disk a omezovat diskovou cache) platí prakticky totéž jako pro problémy s procesory. Omezení počtu relací směrem ven sníží paměťové nároky Postfixu.

Disk

link

Pomalost disku nebo diskového pole je svízelná. Často brzdí celý zbytek serveru, který většinu času čeká na dokončení diskových operací. Řešení (bez instalace lepšího hardwaru) může situaci obvykle jen částečně zlepšit.

Pokud je problém v tom, že je diskové úložiště nejen pomalé, ale že také často dochází k odkládání paměťových stránek kvůli nedostatku fyzické paměti, je první potřebný krok snížení paměťových nároků (viz výše). Toto ovšem pomůže i v případě, že nedochání k odkládání, resp. že odkládací prostor není vůbec použit. Důvod samozřejmě je, že čím větší je disková cache v operační paměti, tím menší množství dat je třeba přenést mezi pamětí a diskem.

Síť

link

Problém s nedostatečně rychlou sítí (typicky s internetovým připojením, například s připojením firemní sítě, kde je server umístěn) není spjat přímo s konkrétním softwarem (tj. v tomto případě Postfixem), nýbrž je zcela obecný. Nicméně vhodnou konfigurací lze zátěž snížit, byť samozřejmě za cenu určitých kompromisů.

V první řadě lze vypnout kontroly podle vzdálených blacklistů – ať se již používají přímo v Postfixu (například v parametru smtpd_client_restrictions) nebo prostřednictvím Spamassassinu. Sníží to poněkud účinnost antispamové ochrany, někdy je to ale relativně malá cena za lepší propustnost síťového připojení.

Další možnost je eliminovat nadbytečné DNS dotazy. Lze si na stroji dostupném rychlým spojem (v lokální síti) spustit cachující DNS server a nastavit si DNS resolver (standardně v /etc/resolv.conf) tak, aby dotazy posílal na něj. Případně lze tento server spustit i přímo na stroji, kde běží Postfix, i když to není příliš čisté řešení.

Nelze-li použít podobné řešení, je ještě možnost vypnout DNS dotazy pro klienty. Zajistí se to tímto nastavením:

smtpd_peername_lookup = no

Tato volba bude mít za následek, že se v logu serveru a v hlavičkách Received ve zprávách objeví u klientů pouze IP adresa, místo názvu bude „unknown“. Při určitém nastavení antispamové ochrany (například při použití pravidel whitelist_from_rcvd nebo def_whitelist_from_rcvd v programu Spamassassin) to však má mírný vliv na přesnost antispamové ochrany.

Jinak pro síť platí opět totéž jako pro procesor a paměť. Snížením počtu souběžných odchozích relací se zátěž sítě sníží (projeví se to zejména na asymetrických komunikačních spojích, kde je odchozí směr výrazně pomalejší než příchozí).

Ostatní

link

Do kategorie „ostatní“ patří všechno to, co nešlo přímo zařadit do předchozích kategorií. Jedná se zejména o externí zdroje dat, které mohou být brzdou například proto, že je zatěžují (kromě poštovního serveru) i další odběratelé informací.

Nejčastěji je problém s databází uživatelů, schránek a aliasů. Cílem pak je, aby se se vzdáleným zdrojem (typicky databází nebo serverem LDAP) komunikovalo co nejúsporněji a nejefektivněji.

Značná část zde spadá do působnosti programu Dovecot, který Postfixu slouží jako autentizační rozhraní. O tom bude ale řeč až příště, proto následující odstavce budou věnovány pouze tomu, co souvisí výhradně s Postfixem.

Základem je zjišťovat ze vzdáleného zdroje co nejméně informací. Zejména není třeba zjišťovat nic, co může být přímo součást konfigurace, protože jde o údaje nedílně spjaté s instalací na konkrétním serveru. Příkladem jsou třeba identifikátory uživatele a skupiny (virtual_uid_maps, virtual_gid_maps) v klasickém případě, kdy jsou pevně dány. Podobně například cestu k domovskému adresáři lze často sestavit přímo z adresy příjemce a není nutné ji získávat databázovým dotazem.

Dále je potřeba, aby byla databáze (nebo obecně jakýkoli datový zdroj) kvalitně navržena a aby byly vhodně konstruovány i dotazy. Někdy je to problém, protože dotazy směřují do již existující databáze, ale i tam lze často udělat mnoho pro zrychlení přístupu – například vytvořením indexů.

Pokud si vzpomenete na sedmý díl seriálu, určitě vás napadne další zajímavá možnost, jak zrychlit přístup – využít službu proxymap. Tady je ale důležité to, jakým způsobem služba proxymap funguje. Zrychlí funkci jen v případě, že je problémem velký počet současných připojení (naráží se na limit nebo je problém se spotřebou paměti databázovým serverem). V opačném případě může být komunikace naopak pomalejší, protože proxymap veškeré přístupy serializuje – řadí je za sebe a tím brání lepšímu časovému využití komunikačního kanálu.

Je-li zdrojem dat databáze, lze si udržovat lokální on-line replikovanou verzi, samozřejmě pokud to databáze umožňuje (což například MySQL standardně ano). Veškeré dotazy se provádějí jen na této lokální kopii, bez nutnosti odesílat a přijímat nějaká vzdálená data. Data se přenášejí jen při změnách v hlavní databázi (master) na tuto kopii.

Optimalizace konfigurace programu Dovecot

link

To by bylo ohledně optimalizace (beze změny architektury) Postfixu téměř vše. Ne však úplně vše, protože příští díl bude věnován optimalizaci konfigurace programu Dovecot, kde se řada úprav nepřímo dotkne i programu Postfix.

Seriál Stavíme poštovní server (dílů: 17)

První díl: Stavíme poštovní server – 1 (Postfix), poslední díl: Stavíme poštovní server – 17 (optimalizace výkonu).
Předchozí díl: Stavíme poštovní server – 16 (záložní server)

Související články

SPAM – greylisting ve firmě
Mailserver s odvirováním pošty
DKIM – podepisujeme e-maily na serveru
Spam: naučte se bránit
MessageWall - kladivo nejen na spam
Jsme na dovolené - automatická odpověď

Další články z této rubriky

PowerDNS – přívětivý a jednoduchý DNS server
Bootování ze sítě: pxelinux a kořenový adresář na NFS
Těžký život Do Not Track
OpenAFS – servery
Architektura IPv6 – konfigurace adres a objevování sousedů (2)

Diskuse k tomuto článku

19.4.2010 10:54 ch-in-A
Rozbalit Rozbalit vše vyborny, clanek!
Odpovědět | Sbalit | Link | Blokovat | Admin
vyborny, clanek/serial! diky
Josef Kufner avatar 19.4.2010 15:52 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: vyborny, clanek!
+1

Chtělo by to ještě pár dílů o nějakých pěkných specialitkách. Třeba jak na virtuální imap složky v dovecotu a podobné věci (trošu jsem je oťukával, ale moc to nefungovalo).
Hello world ! Segmentation fault (core dumped)

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.