Mem(Rep)cache és Couchbase

Fórumok

Sziasztok,

Néhány gondolat, tapasztalat a Repcache, Couchbase kapcsán.

A webszervereink működése során eljutottunk arra a pontra, hogy szükségessé vált a PHP sessionok alternatív módon történő kezelése.
Alapesetben fontos, hogy a jelenlegi két szerver közötti PHP sessionok mindkét szerver által "láthatóak" legyenek, ezt OCFS2-vel oldottuk meg.
Majd jött egy érdekes probléma, a sessionok nagy száma miatt az OCFS2 elérése finoman szólva is problémás volt, 200+ os load-ról beszélünk és álló
szolgáltatásokról, mivel szerencsétlen nem tudta elérni a session fileokat, jobban mondva elérte egy idő után, de ki akarja ezt kivárni?!

Szóval volt vala ez

Tudni kell, hogy a szerverek egy haproxy mögött helyezkednek el, a fenti problémára az ideiglenes megoldás a saját EXT4-es filerendszer használatával
küszöböltük ki, na bumm oda a session redundancia.

Majd lett belőle ez

Sebaj, van egy csodálatos szolgáltatás...Memcache, beállítottuk (persze a tesztrendsezren :) ) - igazából a repcache-t - boldogok voltunk, odasüss, szinkronizál, működik!

A sok transzformáció után lett belőle ez

Aztán jöttek a tesztek és az anomáliák, szerverek közötti váltásoknál nem minden esetben volt sikeres a session file-ok használata, ott volt, de mégsem tudta/akarta olvasni, esetleg a kliens oldalon tűnt el a sessionID, így már esélytelen volt, hogy bármilyen szolgáltatás működjön újbóli bejelentkezés nélkül.
És egy apró, de nem elhanyagolható probléma, ServerA meghal, nem baj, hiszen ServerB tartalmazza az elhalásig szinkronizált összes adatot, de mint fentebb írtam ez nem volt 100%-osan működőképes.
De a fő probléma ott van, hogy ServerA egyszer csak beleordít az éterbe, hogy "DRÁGÁM, MEGJÖTTEM", ServerB erre annyit mond, hogy "ÉS?", nesze itt van 1-2 session, most generálták nálam őket. Na mármost itt van egy kis probléma, ServerB rendelkezik mondjuk 6000 sessional, ServerA pedig 1-2-vel, és nem, nem fogják szinkronizálni, hiszen a repcache ezt nem tudja, ő azt tudja, hogy ha keletkezik egy session ServerA-n vagy ServerB-n azt leszinkronizálja oda-vissza.
Sebaj, erre is van megoldás, egy gyönyörű phpscript amit mondjuk induláskor lefuttatva leszinkronizálhatja az éppen feléledő szerverre a párja tartalmát. Kicsit buhera, nemde?
Aztán képbe került, hogy lesz egy harmadik szerver is, na ekkor vetettük el a repcache-t, egyszerűen erre totálisan alkalmatlan.

Képbe került a Couchbase.
Akkor ugorjunk neki felkiáltással ment is fel a tesztrendszerre, itt már a majdani három szerveres megoldással futottunk neki a beállításnak.
Első körben csináltunk egy Clustert (memcached bucket-el, de ezt hamar elvetettük és a Couchbase bucket-et használjuk), amelyben benne volt mindhárom szerver, be lett állítva a replikáció, csodás ServerA tartalma replikálódik ServerB-re és ServerC-re és ServerB pedig ServerA-ra és ServerC-re és így tovább.
Aztán jött a fekete leves, szerencsétlen PHP ha így van beállítva:

 
session.save_handler = memcached
session.save_path = '172.18.99.1:11211, 172.18.99.2:11211, 172.18.99.3:11211'

minden gyönyörűen működik amíg az összes szerver elérhető, de a szerverek közötti mozgás továbbra sem tökéletes, megy is meg nem is, leginkább nem.
A másik probléma, hogy a PHP nem igazán tolerálja, ha valamelyik megadott save_path nem elérhető, ha kiesett akkor az eredmény, oldal nem működik, mindenféle config problémákkal dobálózik a logokban, hogy ő bizony nem éri el ServerB-t pedig ez van beállítva.
Itt jogosan kérdezed, hogy akkor miért nem localhost?
Igazából az, de nem a fenti megoldással, emlékszel, replikálódik de az átjárás a szerverek között nem működik rendesen, álló szolgáltatások, ismételt bejelentkezés...nightmare.

A másik megoldás pedig a Couchbase XDCR (Cross DataCenter Replication) szolgáltatása a php.ini localhost-os beállításásval.
Ebben az esetben nem húzod be az összes szerveredet egy Clusterbe ahol ugye egy bazinagy vödörbe kerül a szervereken beállított memóriamennyiség, hanem mindenki a saját kis kiosztott memóriájával gazdálkodhat.
Ha mindegyik kis clusteredet (valójában egy nyamvadt szerver fut a clusterban, de ha a Couchbase clusternek hívja, legyen az) felkonfiguráltad, elindultak mehet a replikáció beállítása az XDCR fülön, itt is a hasonlóan kell beállítani, mint ahogy az egy clusterben történt, csak ez nem automatikus, hanem kézzel történik.

Tehát valahogy így néz ki a kapcsolati ábra most

Tehát fogjuk ServerA-t és felvisszük ServerB-t és ServerC-t az XDCR Remote Clusterek közé, majd a Create Replication gombbal beállítjuk, hogy ezen a szerveren melyik "bucket-et" fogja szinkronizálni a másik cluster melyik bucketjébe. Pl: ServerA default bucket megy ServerB default bucket-be és ServerC default bucket-be. A többi szerveren hasonló séma szerint kell beállítani.
Csak azért default, mert ezt nem lehet változtatni, egyébként is, nekünk tökéletesen megfelel.

Maga a szinkronizálás változásra történik meg, és ami csodálatos, ha bármelyik szerver nem elérhető...nem történik semmi, megy minden tovább a maga útján, a haproxy nem fog odadobni kérést, hiszen azt mondja, hogy hohóó, nálad nem működik a Couchbase, nem kapsz semmit, majd odaadom ServerX-nek a session-t.
De mi történik, ha teszem azt, - maradva az előző példánál - ServerA feladja a harcot és eltűnik az éterből? Semmi, majd ServerB és ServerC dolgozik helyette, a HAProxy megoldja.
Majd később eljön a várva várt pillanat: ServerA egyszer csak azt mondja: "DRÁGÁM, MEGJÖTTEM", erre azt kiáltja ServerB és ServerC, hogy "ÖRÜLÖK, HOGY ITTHON VAGY" nesze itt vannak az adatok, cserélgessünk egymás között, majd kis idő múlva tadaaa az összes session megjelenik ServerA-n is, mindenki boldog, leginkább a felhasználó, nincs kiesés, gyors.

Jelenleg itt állunk, a rendszer tesztelési fázisban van, de a tapasztalatok eddig biztatóak, remélem segítettem, hogy ne kelljen másnak is végigjárnia ezeket a hosszadalmas tesztelési köröket. És ofc szívesen várom az építő jellegű hozzászólásokat :)

A végére néhány unalmas beállítás:

(Rep)Memcache esetében:

php.ini
Memcached: (php5-memecached)


session.save_handler = memcached
session.save_path = '172.18.99.1:11211, 172.18.99.2:11211, 172.18.99.3:11211'

Memcache (php5-memcache)


session.save_handler = memcache
session.save_path = 'tcp://172.18.99.1:11211, tcp://172.18.99.2:11211, tcp://172.18.99.3:11211'" 

memcached.ini, letölthető innen: http://sourceforge.net/projects/repcached/files/


extension=memcached.so
[memcached]
memcached.sess_locking = 1
memcached.sess_consistent_hash = 1
memcached.sess_binary = 1
memcached.sess_lock_wait = 150000
memcached.sess_prefix = "memc.sess.key."
memcached.sess_number_of_replicas = 2
memcached.sess_randomize_replica_read = 0
memcached.sess_remove_failed = 0
memcached.compression_type = fastlz
memcached.compression_factor = 1.3
memcached.compression_threshold = 2000
memcached.serializer = php
memcached.use_sasl = 0

memcache.ini:


extension=memcache.so
[memcache]
memcache.dbpath="/var/lib/memcache"
memcache.maxreclevel=0
memcache.maxfiles=0
memcache.archivememlim=0
memcache.maxfilesize=0
memcache.maxratio=0
memcache.allow_failover=1
memcache.max_failover_attempts=2
memcache.session_redundancy=2
memcache.default_timeout_ms=1000
memcache.hash_strategy=consistent

A couchbase esetében, nem tudok config file-okkal szolgálni, lényegében a webes felületen beállíthatóak a szükséges dolgok.
Letölthető innen: http://www.couchbase.com/nosql-databases/downloads
Az install tulajdonképpen next -> next -> finish


dpkg -i couchbase-server-community_3.0.1-ubuntu12.04_amd64.deb

Majd a http://server_ip:8091 -es porton lehet elérni a böngészőben.

Üdv, Thunder

Hozzászólások

Mi ezt nagyon egyszerűen oldottuk meg, mindenféle szívás nélkül:
- saját session driver-t használunk
- ami Redis-ben tárolja a session adatokat

Eredmény:
- gyors
- stabil
- megbízható
- skálázható

Egyébként a CouchBase használata erre kicsit ágyúval verébre eset, Repcache pedig fel sem merült volna, lévén, hogy évek óta nem fejlesztik már.

Alapvetoen igaz, amit irtal, de amikor ott tartottatok az elejen, h nem megy es nezzuk a memcache-t es nem mukodik a replikacio, akkor azt miert nem egyszeruen csak felraktatok a haproxy melle es orom-bodotta?

Persze vegeredmenyben az jobb, amit most irtal, csak valoszinuleg el sem jutottal volna idaig egy jo ideig:)

TBH most is. Mivel meg mindig egy szem HAProxy van, ha az kidol, a userek igy se - ugyse erik el a webszervereket, vagyis nagyjabol tokeletesen irrelevans, hogy eppen a session szolgaltatas az pont elerheto-e - senki sem akarja majd hasznalni azt.

Ilyen esetben en azt gondolom, hogy mivel egy role, egy helyen kell lennie, meg ha valojaban tobb szerviz is. Aztan persze lehet HAproxy-t duplikalni...
--
Ki oda vágyik, hol száll a galamb, elszalasztja a kincset itt alant:


()=() 
('Y') Blog | @hron84
C . C Üzemeltető macik
()_()

a Couchbase sajat syncje miert nem mukodott?

amugy meg a szerver elvesztes mokanal 1 sec a timeout, es csak utana lep tovabb egy masik memcache-re. mi a php5-memcache-t meghaxoltuk, es az int tipusu timeout parameter helyett double lett. igy tcp://1.2.3.4:11211?timeout=0.1 beallitassal szepen megy memcachekbe a session, ha egyik elhal akkor php 100ms utan ugrik a masik szerverre.

--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

Ha arra gondolsz, hogy egy clusterben a három couchbase szerver, akkor azért, mert annak ellenére, hogy szinkronizálja az adatokat, különbséget tesz aktív és (ha jól rémlik) replikált adatok között.

Egyébként érdekes, mert ha elvesztette az egyik szervert akkor nekem nem ugrott tovább a következőre, hanem elkezdett anyázni, hogy nem jó a php.ini-ben lévő save_path.

hali,

"De a fő probléma ott van, hogy ServerA egyszer csak beleordít az éterbe, hogy "DRÁGÁM, MEGJÖTTEM", ServerB erre annyit mond, hogy "ÉS?", nesze itt van 1-2 session, most generálták nálam őket. Na mármost itt van egy kis probléma, ServerB rendelkezik mondjuk 6000 sessional, ServerA pedig 1-2-vel, és nem, nem fogják szinkronizálni, hiszen a repcache ezt nem tudja, ő azt tudja, hogy ha keletkezik egy session ServerA-n vagy ServerB-n azt leszinkronizálja oda-vissza."

De fogják szinkronizálni. Nem egészen érthető, hogy miféle repcache-ről beszélsz, hiszen az egy elég halott dolog - én is egy saját repoban patchelgetem, de amit hiányolsz, az nekem működik.

A másik, ami feltűnt, hogy úgy beszélsz a "szerver meghalásról", mintha az egy mindennapos dolog lenne. Ha ez tényleg így van, az sajnálatos, de alapvetően a lehetőségek függvényében kellene meghatározni, hogy mit is vársz el a rendszertől. Olyan, hogy bárhol, bármikor beírod, hogy "reboot", és nem veszik el valamennyi session, tranzakció, request, olyat néha nem lehet, néha nem érdemes, máskor meg nagyon nehéz csinálni. Szerintem külön kell választani azt a képességet is, hogy miként tolerálja a rendszer a tervezett karbantartást és miként a meghibásodást, mert az két külön dolog. (tervezett karbantartásban lehetnek plusz lépések, átterhelés stb).
Mondok egy példát, adott rendszernél én döntöttem úgy, hogy kritikus session adatok egyszerű memcache-be menjenek (ESX-en, vrrp pár, drs separation, és külön storage azért), überszuper technológiák ellenében (galera, infini, couchbase, ndb stb), megmondom miért: üzleti igény az volt, hogy napközben a perc leállás is gáz, de éjszaka lehet karbantartani. A memcache faék egyszerű, a keepalived check scriptje is két sor, csak ez van a gépeken, be merem írni, hogy:
at 04:00
reboot
Az alternatív technológiákkal ezt nem biztos, hogy mindig meg merném tenni, ráadásul gyakran jönnek hozzájuk frissítések, több idő kell a tesztelésre, nem elég a junior, ha gáz van. (de azokat a technológiákat is nagyon szeretjük)

Szia,

Sorry, ha úgy tűnt, mintha a szerver meghalás mindennapos dolog, nem így van, én a legrosszabb esetből indultam ki, előfordulhat, Murphy nem alszik :)

Tervezett karbantartás esetén ugye kitudod venni a forgalomból az érintett szervert, semmi probléma.
Más esetben, nem a hiba oldaláról megközelítve a session problémát, egy adott user az esetek nagy százalékában egy adott szerveren fog dolgozni kijelentkezésig, tehát ebből a szempontból nem is lenne szükség a session-ok redundanciájára.
Viszont vannak olyan szolgáltatások amelyek nem feltétlenül kapcsolódnak vissza mindig ugyanarra a szerverre, itt viszont már nagyon fontos, hogy a session elérhető legyen bármelyiken.