UPDATE:
kezd összeállni a kép. tehát, a megoldott részletek:
- cluster tag install: speciális kickstartos usb-s netinstall. már félig előkészítve érkezik meg a szerver a clusterbe.
- distributed locking PHP web alkalmazáshoz: mysql-ben a select .. set_lock és release_lock. tökéletesen működik, nem szól bele a teljesítménybe, nem kell új kapcsolatot nyitni hozzá, atomikus, és kizárólagos (amíg egy sql szervert használunk).
- passzív monitoring gráfolással: munin (marad, mert ismerem, és nem kellenek triggerek).
- config management: ansible (barátságos, megfelelő teljesítményű, mindent tud, ami kell).
- idő szinkronizálás: ntp, a fejgép valamelyik európai ntp szerverről veszi az adatokat, a cluster tagoknak pedig a fejgép az ntp forrás.
- cluster tagok menedzselése, szervízmenedzselés rajtuk: pacemaker+corosync. még nincs kész, de ez is tud mindent, ami szükséges. mondjuk rémálom a kezdeti konfigja.
- nginx konfig menedzsment: saját script, ami a pcs-ből szerzi az adatokat, és ez alapján kapcsolgat nginx konfigokat, aztán soft reload az nginxnek.
kérdéses, de jelenleg nincs jobb:
- website megosztott fájlterület: nfs4, sync, hard, nolocks. a hard ugyan megakasztja a kliens gépeket, ha a gw szerver leáll/rebootol, de amint visszajön, mennek tovább gond nélkül. mivel nem kell HA, ezért DRBD nélkül.
még megoldandó: gateway shutdown esetén a kliens gépek értesítése, hogy lőjék le az NFS-t esetleg használó cuccaikat, és unmountolják az nfs-t. jobb tippem nincs, mint egy külön init.d script, ami shutdown esetén legelőször, startup esetén legvégül fut le, és ami:
- shutdown esetén pcs-en keresztül(?) szól a cluster tagoknak, hogy a php-fpm szolgáltatást állítsák le (ez használja csak az nfs-t), majd direkt ssh-s parancson keresztül unmountolom a gépeken a /home-ot (az van NFS-en megosztva), végül pcs-el standby-ba rakom a clustergépet.
- startup esetén: /home nfs remount ssh-n keresztül, pcs-el pedig kiveszem standbyból a cluster tagokat, és ahol kell, beindítom a php-fpm-et.
==================
eredeti post:
hali mind,
kicsit hosszadalmas dolog jön, de segítség kéne, nagyon.
szóval, adott egy site, aminek eléggé nagy a forgalma, és eddig változatos módon próbáltuk a növekvő forgalmat és az egyre bonyolultabb, egyre több ajaxos megoldást tartalmazó kódbázist normális sebességgel kiszolgálhatóvá tenni. volt már olyan, hogy egy másik szerveren futott az egész adatbázis (most csak bizonyos táblák futnak egy másik szerveren), de a lényeg, hogy a fő kiszolgálást (ami LAMP alapon történik) mindig csak egyetlen szerver végezte. nemrég masszív kódrefaktoringot is csináltam, ami segített a dolgokon, de ez már csak ideig-óráig mehet így. szóval az egyetlen megoldás az, ha egy olyan mini-clustert hozok létre, amiben:
- van egy gateway szerver, a netről csak ez látszik
- e mögött egy privát switchben egy mini-hálózat van, amiben kétféle gép lesz: app server (amin a php scriptek futnak), és db szerver (jelenleg egy, ami pedig értelemszerűen a db backendet adja).
csináltam egy rakat barrage tesztet, hogy megtudjam, egy gépen futva melyik webkiszolgáló kombináció adja a legjobb eredményt, ez alapján arra jutottam, hogy a gateway gépen nginx fog futni (az nginx repoból), az app gépeken pedig php-fpm kiszolgálók fognak menni (remi repoból, mert a php 5.4 mindenképp fontos).
gondolkoztam azon is, hogy pxe boot-tal működjenek a gateway mögötti gépek, de főleg az nfs szerver terhelés-enyhítése miatt arra jutottam, hogy maradnak kis ssd-kel szerelt gépek, a frissítést yum-mal is el tudják végezni, és a /home/ partíciót (mivel itt vannak a scriptek) kötöm be nfs-en. a telepítésre pedig csináltam kickstart fájlokat, így új szervert berakni, vagy meglevőt újrahúzni gyerekjáték. a konfigok központi kezelésére pedig csináltam néhány egyszerű shell scriptet, amik nfs-ről húzzák át az egyes géptípusok konfigjait.
ami készen van:
- gateway szerver: centos, nginx, kimenő sendmail, ntp szerver, nfs szerver, iptables NAT-tal kiszolgálja a belső hálózatban levő gépek net igényét is, dhcpd a belső címkiosztások kezelésére (mac addr alapján)
- app szerverek: centos, php-fpm szerver, /home/ nfs-ről mountolva, rc.localban a konfig fájlok szinkronizációs megoldásával
- db és memcached szerver: centos, mysqld, memcached (egyrészt serverwide változók tárolására, másrészt session backendként az egyes php-fpm-es gépek részére)
- a statikus fájlokat a gateway nginx-e szolgálja ki, mivel erre külön backend gép nem lesz, ráadásul az nfs megosztás miatt úgyis csak a gatewayt terhelné, így legalább be tudja cachelni read pufferbe
amiben kéne tipp, segítség:
- kéne valami watchdog rendszer, ami figyeli, ha kiesik valamelyik app backend, vagy neadjisten a db backend. tudnék csinálni saját scriptet, de ha tudtok valami ilyesmiről, akkor inkább nem találnám fel a spanyolviaszt.
- ezzel kapcsolatos még, hogy keresek olyan tápelosztót, amit soros portról, vagy esetleg etherneten vezérelni tudnék, hogyha egy backend gép elakad, akkor tudjak távolról egy gyors ki-be kapcsolást csinálni. találtam olyan, hogy epowerswitch 4, csakhogy fogalmam sincs, azt honnan lehet rendelni. valaki tud erről valamit?
- valahogy az nginx-nek is a tudtára kéne adni, ha egy backend meghal, hogy oda ne küldjön forgalmat.
- valahogy meg kéne oldani, hogy a backend gépek ne nagyon drifteljenek el az órájukat illetően, mivel van a site-on pár olyan szolgáltatás, ami minimum másodperces egyezést, de optimális esetben millisec egyezést kívánna meg a gépek között. erre lehet megoldás az a fícsör az nginxben, hogy ugyanarról az ip-ről mindig ugyanarra az app szerverre dobja a requestet? (akkor legalább sessionön belül konzisztens lenne a timestamp kezelés.)
- a mail() funkciónál elég, ha a php.ini-ben a localhost helyett a gateway gépet adom meg, hogy tudjon leveleket is kiküldeni a rendszer?
- nagyon rossz ötlet, hogy nem PXE boottal mennek a backend gépek? tényleg nem akarom az NFS-t arra lefoglalni, hogy a rendszerfájlokat onnan vegye, lesz így is elég gondja, hogy a php-fpm scripteket végrehajtsa a gateway gépről.
- php-ban acélbiztos, atomikus locking nfs mounton? erre olvastam egy olyan tippet, ami a hardlinkes megoldást preferálja, miszerint egy meglevő fájlra csinálok egyedi néven egy hardlinket, aztán stat-olom, és megnézem, hogy az 'nlink' (hardlinkek száma) 2-e -- mert akkor csak én lockolom az adott pillanatban az adott fájlt. erről tudtok valamit, esetleg más ötlet? (állítólag az nfslock nem jó, mert nem atomikus a php szempontjából.)
előre is köszönet a tippekért! :)