Uża mcrouter biex tiskala memcached orizzontalment

Uża mcrouter biex tiskala memcached orizzontalment

L-iżvilupp ta 'proġetti ta' tagħbija għolja fi kwalunkwe lingwa jeħtieġ approċċ speċjali u l-użu ta 'għodod speċjali, iżda meta niġu għall-applikazzjonijiet fil-PHP, is-sitwazzjoni tista' ssir tant aggravata li trid tiżviluppa, pereżempju, server tal-applikazzjoni proprju. F'din in-nota se nitkellmu dwar l-uġigħ familjari mal-ħażna ta 'sessjoni mqassma u l-caching tad-dejta f'memcached u kif solvejna dawn il-problemi fi proġett wieħed "ward".

L-eroj tal-okkażjoni hija applikazzjoni PHP bbażata fuq il-qafas symfony 2.3, li xejn mhu inkluż fil-pjanijiet tan-negozju biex taġġorna. Minbarra l-ħażna ta 'sessjoni pjuttost standard, dan il-proġett għamel użu sħiħ minn politika ta’ “caching everything”. f'memcached: tweġibiet għal talbiet għad-database u s-servers tal-API, diversi bnadar, serraturi għas-sinkronizzazzjoni tal-eżekuzzjoni tal-kodiċi u ħafna aktar. F'sitwazzjoni bħal din, tqassim ta' memcached isir fatali għat-tħaddim tal-applikazzjoni. Barra minn hekk, it-telf tal-cache iwassal għal konsegwenzi serji: id-DBMS jibda jinfaqa 'fil-ħjatat, is-servizzi tal-API jibdew jipprojbixxu t-talbiet, eċċ. L-istabbilizzazzjoni tas-sitwazzjoni tista 'tieħu għexieren ta' minuti, u matul dan iż-żmien is-servizz se jkun bil-mod terriblement jew kompletament mhux disponibbli.

Kellna nipprovdu l-abbiltà li tiskala orizzontalment l-applikazzjoni bi ftit sforz, i.e. b'bidliet minimi fil-kodiċi tas-sors u l-funzjonalità sħiħa ppreservata. Agħmel il-cache mhux biss reżistenti għall-fallimenti, iżda wkoll tipprova timminimizza t-telf tad-dejta minnha.

X'hemm ħażin ma memcached innifsu?

B'mod ġenerali, l-estensjoni memcached għal PHP tappoġġja data mqassma u ħażna ta 'sessjoni barra mill-kaxxa. Il-mekkaniżmu għal hashing konsistenti taċ-ċavetta jippermettilek li tpoġġi d-dejta b'mod uniformi fuq bosta servers, u tindirizza b'mod uniku kull ċavetta speċifika għal server speċifiku mill-grupp, u għodod ta' failover integrati jiżguraw disponibbiltà għolja tas-servizz ta' caching (iżda, sfortunatament, ebda data).

L-affarijiet huma ftit aħjar bil-ħażna tas-sessjoni: tista 'tikkonfigura memcached.sess_number_of_replicas, bħala riżultat ta 'dan id-dejta se tkun maħżuna fuq diversi servers f'daqqa, u fil-każ ta' falliment ta 'istanza waħda memcached, id-dejta tiġi trasferita minn oħrajn. Madankollu, jekk is-server jerġa 'jiġi onlajn mingħajr dejta (kif normalment jiġri wara bidu mill-ġdid), xi wħud mill-ċwievet jiġu mqassma mill-ġdid favur tiegħu. Fil-fatt dan se jfisser telf ta' data tas-sessjoni, peress li m'hemm l-ebda mod kif "jmorru" għal replika oħra f'każ ta' miss.

Għodod tal-librerija standard huma mmirati prinċipalment lejn orizzontali skalar: jippermettulek iżżid il-cache għal daqsijiet ġiganteski u tipprovdi aċċess għaliha minn kodiċi ospitat fuq servers differenti. Madankollu, fis-sitwazzjoni tagħna, il-volum ta 'data maħżuna ma jaqbiżx diversi gigabytes, u l-prestazzjoni ta' wieħed jew żewġ nodi hija pjuttost biżżejjed. Għaldaqstant, l-uniċi għodod standard utli jistgħu jkunu li tiġi żgurata d-disponibbiltà ta 'memcached filwaqt li tinżamm mill-inqas istanza ta' cache waħda f'kondizzjoni ta 'ħidma. Madankollu, ma kienx possibbli li tieħu vantaġġ anki minn din l-opportunità... Hawnhekk ta 'min ifakkar l-antikità tal-qafas użat fil-proġett, u huwa għalhekk li kien impossibbli li l-applikazzjoni taħdem ma' grupp ta 'servers. Ejja ma ninsewx ukoll dwar it-telf tad-dejta tas-sessjoni: l-għajnejn tal-klijent twitched mill-logout massiv tal-utenti.

Idealment kien meħtieġ replikazzjoni ta' rekords f'repliki memcached u bypassing f’każ ta’ żball jew żball. Għinna nimplimentaw din l-istrateġija mcrouter.

mcrouter

Dan huwa router memcached żviluppat minn Facebook biex isolvi l-problemi tiegħu. Jappoġġja l-protokoll tat-test memcached, li jippermetti installazzjonijiet fuq skala memcached għal proporzjonijiet tal-ġenn. Deskrizzjoni dettaljata ta 'mcrouter tista' tinstab fi din it-tħabbira. Fost affarijiet oħra funzjonalità wiesgħa jista 'jagħmel dak li għandna bżonn:

  • rekord replikat;
  • do fallback għal servers oħra fil-grupp jekk iseħħ żball.

Ikseb ix-xogħol!

konfigurazzjoni mcrouter

Immur dritt għall-konfigurazzjoni:

{
 "pools": {
   "pool00": {
     "servers": [
       "mc-0.mc:11211",
       "mc-1.mc:11211",
       "mc-2.mc:11211"
   },
   "pool01": {
     "servers": [
       "mc-1.mc:11211",
       "mc-2.mc:11211",
       "mc-0.mc:11211"
   },
   "pool02": {
     "servers": [
       "mc-2.mc:11211",
       "mc-0.mc:11211",
       "mc-1.mc:11211"
 },
 "route": {
   "type": "OperationSelectorRoute",
   "default_policy": "AllMajorityRoute|Pool|pool00",
   "operation_policies": {
     "get": {
       "type": "RandomRoute",
       "children": [
         "MissFailoverRoute|Pool|pool02",
         "MissFailoverRoute|Pool|pool00",
         "MissFailoverRoute|Pool|pool01"
       ]
     }
   }
 }
}

Għaliex tliet pools? Għaliex is-servers huma ripetuti? Ejja nsemmu kif taħdem.

  • F'din il-konfigurazzjoni, mcrouter jagħżel il-mogħdija li għaliha tintbagħat it-talba abbażi tal-kmand tat-talba. Il-bniedem jgħidlu dan OperationSelectorRoute.
  • It-talbiet GET imorru għand il-handler RandomRouteli tagħżel b'mod każwali ġabra jew rotta fost oġġetti ta' firxa children. Kull element ta 'din l-array huwa min-naħa tiegħu handler MissFailoverRoute, li se jgħaddi minn kull server fil-pool sakemm jirċievi tweġiba bid-dejta, li se tiġi rritornata lill-klijent.
  • Jekk użajna esklussivament MissFailoverRoute b'grupp ta 'tliet servers, allura t-talbiet kollha jiġu l-ewwel għall-ewwel istanza memcached, u l-bqija jirċievu talbiet fuq bażi residwa meta ma jkunx hemm dejta. Approċċ bħal dan iwassal għal tagħbija eċċessiva fuq l-ewwel server fil-lista, għalhekk ġie deċiż li jiġu ġġenerati tliet pools b'indirizzi f'sekwenzi differenti u tagħżelhom b'mod każwali.
  • It-talbiet l-oħra kollha (u dan huwa rekord) jiġu pproċessati bl-użu AllMajorityRoute. Dan il-handler jibgħat talbiet lis-servers kollha fil-pool u jistenna tweġibiet minn mill-inqas N/2 + 1 minnhom. Mill-użu AllSyncRoute għal operazzjonijiet ta 'kitba kellhom jiġu abbandunati, peress li dan il-metodu jeħtieġ rispons pożittiv minn Kollha servers fil-grupp - inkella se terġa 'lura SERVER_ERROR. Għalkemm mcrouter se jżid id-dejta mal-caches disponibbli, is-sejħa PHP funzjoni se jirritorna żball u se jiġġenera avviż. AllMajorityRoute mhix daqshekk stretta u tippermetti li sa nofs l-unitajiet jitneħħew mis-servizz mingħajr il-problemi deskritti hawn fuq.

Żvantaġġ ewlieni Din l-iskema hija li jekk verament ma jkun hemm l-ebda data fil-cache, allura għal kull talba mill-klijent N talbiet għal memcached fil-fatt jiġu eżegwiti - biex għal kulħadd servers fil-pool. Nistgħu nnaqqsu n-numru ta 'servers f'pools, pereżempju, għal tnejn: nissagrifikaw l-affidabbiltà tal-ħażna, nikbruоveloċità ogħla u inqas tagħbija minn talbiet għal ċwievet nieqsa.

NB: Tista' ssib ukoll links utli għat-tagħlim tal-mcrouter dokumentazzjoni fuq wiki и kwistjonijiet tal-proġett (inklużi dawk magħluqa), li jirrappreżentaw maħżen sħiħ ta 'konfigurazzjonijiet varji.

Bini u tmexxija ta' mcrouter

L-applikazzjoni tagħna (u memcached innifsu) taħdem f'Kubernetes - għalhekk, mcrouter jinsab hemm ukoll. Għal assemblaġġ tal-kontenitur nużaw werf, li l-konfigurazzjoni tagħha tidher bħal din:

NB: Il-listi mogħtija fl-artiklu huma ppubblikati fir-repożitorju flant/mcrouter.

configVersion: 1
project: mcrouter
deploy:
 namespace: '[[ env ]]'
 helmRelease: '[[ project ]]-[[ env ]]'
---
image: mcrouter
from: ubuntu:16.04
mount:
- from: tmp_dir
 to: /var/lib/apt/lists
- from: build_dir
 to: /var/cache/apt
ansible:
 beforeInstall:
 - name: Install prerequisites
   apt:
     name: [ 'apt-transport-https', 'tzdata', 'locales' ]
     update_cache: yes
 - name: Add mcrouter APT key
   apt_key:
     url: https://facebook.github.io/mcrouter/debrepo/xenial/PUBLIC.KEY
 - name: Add mcrouter Repo
   apt_repository:
     repo: deb https://facebook.github.io/mcrouter/debrepo/xenial xenial contrib
     filename: mcrouter
     update_cache: yes
 - name: Set timezone
   timezone:
     name: "Europe/Moscow"
 - name: Ensure a locale exists
   locale_gen:
     name: en_US.UTF-8
     state: present
 install:
 - name: Install mcrouter
   apt:
     name: [ 'mcrouter' ]

(werf.yaml)

... u abbozzaha Tabella tat-Tmun. Il-ħaġa interessanti hija li hemm biss ġeneratur tal-konfigurazzjoni bbażat fuq in-numru ta 'repliki (jekk xi ħadd għandu għażla aktar lakonika u eleganti, jaqsamha fil-kummenti):

{{- $count := (pluck .Values.global.env .Values.memcached.replicas | first | default .Values.memcached.replicas._default | int) -}}
{{- $pools := dict -}}
{{- $servers := list -}}
{{- /* Заполняем  массив двумя копиями серверов: "0 1 2 0 1 2" */ -}}
{{- range until 2 -}}
 {{- range $i, $_ := until $count -}}
   {{- $servers = append $servers (printf "mc-%d.mc:11211" $i) -}}
 {{- end -}}
{{- end -}}
{{- /* Смещаясь по массиву, получаем N срезов: "[0 1 2] [1 2 0] [2 0 1]" */ -}}
{{- range $i, $_ := until $count -}}
 {{- $pool := dict "servers" (slice $servers $i (add $i $count)) -}}
 {{- $_ := set $pools (printf "MissFailoverRoute|Pool|pool%02d" $i) $pool -}}
{{- end -}}
---
apiVersion: v1
kind: ConfigMap
metadata:
 name: mcrouter
data:
 config.json: |
   {
     "pools": {{- $pools | toJson | replace "MissFailoverRoute|Pool|" "" -}},
     "route": {
       "type": "OperationSelectorRoute",
       "default_policy": "AllMajorityRoute|Pool|pool00",
       "operation_policies": {
         "get": {
           "type": "RandomRoute",
           "children": {{- keys $pools | toJson }}
         }
       }
     }
   }

(10-mcrouter.yaml)

Aħna noħorġuha fl-ambjent tat-test u niċċekkjaw:

# php -a
Interactive mode enabled

php > # Проверяем запись и чтение
php > $m = new Memcached();
php > $m->addServer('mcrouter', 11211);
php > var_dump($m->set('test', 'value'));
bool(true)
php > var_dump($m->get('test'));
string(5) "value"
php > # Работает! Тестируем работу сессий:
php > ini_set('session.save_handler', 'memcached');
php > ini_set('session.save_path', 'mcrouter:11211');
php > var_dump(session_start());
PHP Warning:  Uncaught Error: Failed to create session ID: memcached (path: mcrouter:11211) in php shell code:1
Stack trace:
#0 php shell code(1): session_start()
#1 {main}
  thrown in php shell code on line 1
php > # Не заводится… Попробуем задать session_id:
php > session_id("zzz");
php > var_dump(session_start());
PHP Warning:  session_start(): Cannot send session cookie - headers already sent by (output started at php shell code:1) in php shell code on line 1
PHP Warning:  session_start(): Failed to write session lock: UNKNOWN READ FAILURE in php shell code on line 1
PHP Warning:  session_start(): Failed to write session lock: UNKNOWN READ FAILURE in php shell code on line 1
PHP Warning:  session_start(): Failed to write session lock: UNKNOWN READ FAILURE in php shell code on line 1
PHP Warning:  session_start(): Failed to write session lock: UNKNOWN READ FAILURE in php shell code on line 1
PHP Warning:  session_start(): Failed to write session lock: UNKNOWN READ FAILURE in php shell code on line 1
PHP Warning:  session_start(): Failed to write session lock: UNKNOWN READ FAILURE in php shell code on line 1
PHP Warning:  session_start(): Unable to clear session lock record in php shell code on line 1
PHP Warning:  session_start(): Failed to read session data: memcached (path: mcrouter:11211) in php shell code on line 1
bool(false)
php >

It-tfittxija għat-test tal-iżball ma ta l-ebda riżultat, iżda għall-mistoqsija "mikrouter php"Fuq ta' quddiem kien hemm l-eqdem problema mhux solvuta tal-proġett - nuqqas ta’ appoġġ protokoll binarju memcached.

NB: Il-protokoll ASCII f'memcached huwa aktar bil-mod minn dak binarju, u l-mezzi standard ta 'hashing konsistenti taċ-ċavetta jaħdmu biss mal-protokoll binarju. Iżda dan ma joħloqx problemi għal każ speċifiku.

It-trick jinsab fil-borża: kull ma trid tagħmel hu li taqleb għall-protokoll ASCII u kollox jaħdem.... Madankollu, f'dan il-każ, id-drawwa li tfittex tweġibiet fil dokumentazzjoni fuq php.net lagħab ċajta krudili. Mhux se ssib it-tweġiba t-tajba hemmhekk... sakemm, ovvjament, ma tiskrolljax sal-aħħar, fejn fit-taqsima "Noti kkontribwew mill-utent" se tkun fidila u tweġiba inġustament ikkontestata.

Iva, l-isem korrett tal-għażla huwa memcached.sess_binary_protocol. Għandu jkun diżattivat, u wara s-sessjonijiet jibdew jaħdmu. Li jibqa 'huwa li tpoġġi l-kontenitur b'mcrouter ġo pod bil-PHP!

Konklużjoni

Għalhekk, b'bidliet infrastrutturali biss stajna nsolvu l-problema: il-kwistjoni bit-tolleranza tal-ħsarat memcached ġiet solvuta, u l-affidabilità tal-ħażna tal-cache żdiedet. Minbarra l-vantaġġi ovvji għall-applikazzjoni, dan ta spazju għall-manuvra meta taħdem fuq il-pjattaforma: meta l-komponenti kollha għandhom riżerva, il-ħajja tal-amministratur hija ssimplifikata ħafna. Iva, dan il-metodu għandu wkoll l-iżvantaġġi tiegħu, jista 'jidher qisu "crutch", imma jekk jiffranka l-flus, jidfen il-problema u ma jikkawżax oħrajn ġodda - għaliex le?

PS

Aqra wkoll fuq il-blog tagħna:

Sors: www.habr.com

Żid kumment