Ngagunakeun mcrouter pikeun skala memcached horisontal

Ngagunakeun mcrouter pikeun skala memcached horisontal

Ngembangkeun proyék-beban tinggi dina basa naon waé butuh pendekatan khusus sareng panggunaan alat khusus, tapi nalika aplikasi dina PHP, kaayaan tiasa janten parah sahingga anjeun kedah ngembangkeun, contona, server aplikasi sorangan. Dina catetan ieu kami bakal ngobrol ngeunaan nyeri akrab jeung neundeun sési disebarkeun sarta cache data di memcached na kumaha urang direngsekeun masalah ieu dina hiji "bangsal" proyék.

Pahlawan kasempetan nyaéta aplikasi PHP dumasar kana kerangka symfony 2.3, anu henteu kalebet dina rencana bisnis pikeun ngapdet. Salian gudang sési cukup baku, proyék ieu dijieun pinuh pamakéan kawijakan "caching sagalana". di memcached: réspon kana pamundut kana database sareng server API, rupa-rupa umbul, konci pikeun nyingkronkeun palaksanaan kode sareng seueur deui. Dina kaayaan kitu, ngarecahna memcached janten fatal kana operasi aplikasi. Sajaba ti éta, leungitna cache ngabalukarkeun konsékuansi serius: DBMS mimiti burst di seams, jasa API ngawitan larangan requests, jsb. Stabilisasi kaayaan tiasa nyandak puluhan menit, sareng salami waktos ieu jasa bakal ngalambatkeun pisan atanapi henteu sayogi.

Urang diperlukeun nyadiakeun kamampuhan pikeun skala horisontal aplikasi kalawan saeutik usaha, i.e. kalayan parobahan minimal kana kode sumber sareng fungsionalitas pinuh dilestarikan. Jieun cache teu ngan tahan ka gagal, tapi ogé coba pikeun ngaleutikan leungitna data ti dinya.

Naon anu lepat sareng memcached sorangan?

Sacara umum, ekstensi memcached pikeun PHP ngadukung data anu disebarkeun sareng neundeun sési out of the box. Mékanisme pikeun hashing konci konsisten ngidinan Anjeun pikeun merata nempatkeun data dina loba server, uniquely alamat unggal konci husus ka server husus ti grup, sarta diwangun-di parabot failover mastikeun kasadiaan tinggi tina layanan cache (tapi, hanjakalna, euweuh data).

Hal-hal anu langkung saé kalayan neundeun sési: anjeun tiasa ngonpigurasikeun memcached.sess_number_of_replicas, salaku hasil tina nu data bakal disimpen dina sababaraha server sakaligus, sarta dina acara kagagalan hiji conto memcached, data bakal ditransfer ti batur. Sanajan kitu, lamun server datang deui online tanpa data (sakumaha biasana kajadian sanggeus balikan deui a), sababaraha konci bakal redistributed dina kahadean na. Kanyataanna ieu bakal hartosna leungitna data sési, Kusabab euweuh jalan ka "buka" ka replica sejen bisi sono.

parabot perpustakaan baku anu aimed utamana di horisontal skala: aranjeunna ngidinan Anjeun pikeun ngaronjatkeun cache kana ukuran gigantic sarta nyadiakeun aksés ka dinya ti kode hosted on server béda. Sanajan kitu, dina kaayaan urang, volume data disimpen teu ngaleuwihan sababaraha gigabytes, sarta kinerja hiji atawa dua titik cukup cukup. Sasuai, hiji-hijina parabot baku bisa jadi pikeun mastikeun kasadiaan memcached bari ngajaga sahanteuna hiji conto cache dina kaayaan gawé. Sanajan kitu, ieu teu mungkin pikeun ngamangpaatkeun malah kasempetan ieu ... Di dieu eta sia recalling jaman baheula tina kerangka dipaké dina proyék éta, naha éta teu mungkin pikeun meunangkeun aplikasi pikeun digawekeun ku pool of server. Hayu urang ogé ulah poho ngeunaan leungitna data sési: panon nasabah twitched ti logout masif pamaké.

Ideally ieu diperlukeun réplikasi rékaman di memcached na bypassing réplika bisi aya kasalahan atawa kasalahan. Mantuan kami nerapkeun strategi ieu microuter.

microuter

Ieu mangrupikeun router memcached anu dikembangkeun ku Facebook pikeun ngabéréskeun masalahna. Ieu ngarojong protokol téks memcached, nu ngidinan pamasangan memcached skala kana babandingan gélo. Katerangan lengkep ngeunaan mcrouter tiasa dipendakan dina pengumuman ieu. Diantara hal séjén fungsionalitas lega éta tiasa ngalakukeun naon anu urang peryogikeun:

  • réplikasi rékaman;
  • ngalakukeun fallback ka server séjén di grup lamun aya kasalahan.

Meunang gawe!

konfigurasi microuter

Kuring bakal langsung ka config:

{
 "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"
       ]
     }
   }
 }
}

Naha tilu pools? Naha server diulang? Hayu urang terang kumaha gawéna.

  • Dina konfigurasi ieu, mcrouter milih jalur dimana pamundut bakal dikirim dumasar kana paréntah pamundut. Lalaki ngabejaan manehna ieu OperationSelectorRoute.
  • GET requests buka Handler nu RandomRoutenu acak milih kolam renang atawa jalur diantara objék Asép Sunandar Sunarya children. Unggal unsur susunan ieu dina gilirannana Handler a MissFailoverRoute, anu bakal ngaliwat unggal server di kolam renang dugi ka nampi réspon sareng data, anu bakal dipulangkeun ka klien.
  • Upami urang dianggo sacara éksklusif MissFailoverRoute kalawan kolam renang tina tilu server, lajeng sadayana requests bakal datangna munggaran ka conto memcached munggaran, sarta sésana bakal nampa requests dina dasar residual lamun euweuh data. Pendekatan sapertos kitu bakal ngakibatkeun beban kaleuleuwihan dina server munggaran dina daptar, Ku kituna ieu mutuskeun pikeun ngahasilkeun tilu pools kalawan alamat dina urutan béda tur pilih aranjeunna acak.
  • Kabéh requests séjén (jeung ieu catetan a) diolah ngagunakeun AllMajorityRoute. Pawang ieu ngirimkeun pamundut ka sadaya server di kolam renang sareng ngantosan réspon tina sahenteuna N / 2 + 1 di antarana. Tina pamakéan AllSyncRoute pikeun nulis operasi kungsi ditinggalkeun, saprak metoda ieu merlukeun respon positif ti всех server di grup - disebutkeun eta bakal balik SERVER_ERROR. Sanajan mcrouter bakal nambahkeun data kana caches sadia, fungsi PHP nelepon bakal balik kasalahan sarta bakal ngahasilkeun bewara. AllMajorityRoute teu jadi ketat tur ngamungkinkeun nepi ka satengah tina unit bisa dicokot kaluar tina layanan tanpa masalah ditétélakeun di luhur.

kalemahan utama Skéma ieu nyaéta yén upami leres-leres henteu aya data dina cache, maka pikeun tiap pamundut ti klien N anu nyuhunkeun ka memcached leres-leres bakal dieksekusi - pikeun ka sadaya server di kolam renang nu. Urang bisa ngurangan jumlah server di pools, contona, ka dua: sacrificing reliabiliti gudang, urang meunang.оspeed luhur sarta beban kirang ti requests mun leungit konci.

NB: Anjeun oge bisa manggihan tumbu mangpaat pikeun diajar mcrouter dokuméntasi dina wiki и masalah proyék (kaasup anu ditutup), ngalambangkeun sakabeh gudang rupa-rupa konfigurasi.

Ngawangun sarta ngajalankeun mcrouter

Aplikasi kami (sareng memcached sorangan) dijalankeun dina Kubernetes - sasuai, mcrouter ogé aya di dinya. Pikeun assembly wadahna urang ngagunakeun werf, config nu bakal kasampak kawas kieu:

NB: The listings dibikeun dina artikel diterbitkeun dina Repository nu flant / microuter.

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)

... jeung sketsa eta kaluar Bagan helm. Hal metot nyaeta ngan aya generator config dumasar kana jumlah réplika (Upami aya anu gaduh pilihan anu langkung laconic sareng elegan, bagikeun dina koméntar):

{{- $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)

Kami gulung kana lingkungan tés sareng pariksa:

# 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 >

Milarian téks kasalahan henteu masihan hasil, tapi pikeun pamundut "microuter php"Di payun mangrupikeun masalah pangkolotna anu teu kaungkab dina proyék - kurangna rojongan protokol binér memcached.

NB: Protokol ASCII dina memcached langkung laun tibatan binér, sareng hartosna standar hashing konci anu konsisten ngan ukur tiasa dianggo sareng protokol binér. Tapi ieu teu nyieun masalah pikeun kasus husus.

Trikna aya dina kantong: anu anjeun kedah laksanakeun nyaéta ngalih ka protokol ASCII sareng sadayana bakal jalan.... Sanajan kitu, dina hal ieu, kabiasaan néangan jawaban di dokuméntasi dina php.net maénkeun lulucon kejem. Anjeun moal manggihan jawaban nu bener aya ... iwal, tangtosna, anjeun ngagulung ka tungtungna, dimana di bagian "Catatan kontribusi pamaké" bakal satia jeung jawaban unfairly downvoted.

Leres, nami pilihan anu leres nyaéta memcached.sess_binary_protocol. Éta kedah ditumpurkeun, saatos éta sési bakal ngamimitian jalan. Sadaya anu tetep nyaéta nempatkeun wadahna nganggo mcrouter kana pod sareng PHP!

kacindekan

Ku kituna, kalawan ngan parobahan infrasturktur kami bisa ngajawab masalah: masalah toleransi sesar memcached geus direngsekeun, sarta reliabiliti gudang cache geus ngaronjat. Salian kaunggulan atra pikeun aplikasi, ieu masihan rohangan pikeun maneuver nalika digawé dina platform nu: lamun sakabeh komponen boga cadangan a, hirup administrator geus greatly disederhanakeun. Sumuhun, metoda ieu ogé boga drawbacks na, éta bisa kasampak kawas "kruk", tapi lamun eta ngaheéat duit, buries masalah na teu ngabalukarkeun anyar - naha henteu?

PS

Baca ogé dina blog urang:

sumber: www.habr.com

Tambahkeun komentar