Bakit maaaring kailanganin mo ang semi-synchronous na pagtitiklop?

Kamusta kayong lahat. Si Vladislav Rodin ay nakikipag-ugnayan. Kasalukuyan akong nagtuturo ng mga kurso sa Software Architecture at High-Stress Software Architecture sa OTUS. Sa pag-asa sa pagsisimula ng isang bagong daloy ng kurso "Arkitekto ng Mataas na Pagkarga" Nagpasya akong magsulat ng isang maikling piraso ng orihinal na materyal na gusto kong ibahagi sa iyo.

Bakit maaaring kailanganin mo ang semi-synchronous na pagtitiklop?

Pagpapakilala

Dahil sa katotohanan na ang HDD ay maaari lamang magsagawa ng mga 400-700 na operasyon sa bawat segundo (na hindi maihahambing sa tipikal na rps para sa isang high-load system), ang klasikong database ng disk ay ang bottleneck ng arkitektura. Samakatuwid, kinakailangang bigyang-pansin ang mga pattern ng scaling ng imbakan na ito.

Sa kasalukuyan, mayroong 2 database scaling pattern: replication at sharding. Binibigyang-daan ka ng Sharding na sukatin ang pagpapatakbo ng pagsulat at, bilang resulta, bawasan ang rps bawat pagsusulat bawat server sa iyong cluster. Ang pagtitiklop ay nagpapahintulot sa iyo na gawin ang parehong bagay, ngunit may mga operasyon sa pagbabasa. Ito ang pattern na ito ay nakatuon sa artikulong ito.

Pagtitiklop

Kung titingnan mo ang pagtitiklop sa isang napakataas na antas, ito ay isang simpleng bagay: mayroon kang isang server, mayroong data dito, at pagkatapos ay hindi na makayanan ng server na ito ang pagkarga ng pagbabasa ng data na ito. Magdaragdag ka ng ilang server, mag-synchronize ng data sa lahat ng server, at makakabasa ang user mula sa anumang server sa iyong cluster.

Sa kabila ng maliwanag na pagiging simple nito, mayroong ilang mga pagpipilian para sa pag-uuri ng iba't ibang mga pagpapatupad ng scheme na ito:

  • Sa pamamagitan ng mga tungkulin sa cluster (master-master o master-slave)
  • Sa pamamagitan ng mga bagay na ipinadala (batay sa hilera, batay sa pahayag o halo-halong)
  • Ayon sa mekanismo ng pag-synchronize ng node

Ngayon ay haharapin natin ang punto 3.

Paano nagaganap ang isang transaction commit?

Ang paksang ito ay hindi direktang nauugnay sa pagtitiklop; ang isang hiwalay na artikulo ay maaaring isulat dito, ngunit dahil ang karagdagang pagbabasa ay walang silbi nang hindi nauunawaan ang mekanismo ng paggawa ng transaksyon, hayaan mong ipaalala ko sa iyo ang mga pinakapangunahing bagay. Nagaganap ang isang transaksyon sa 3 yugto:

  1. Pag-log ng isang transaksyon sa log ng database.
  2. Paggamit ng isang transaksyon sa isang database engine.
  3. Ibinabalik ang kumpirmasyon sa kliyente na matagumpay na nailapat ang transaksyon.

Sa iba't ibang mga database, ang algorithm na ito ay maaaring may mga nuances: halimbawa, sa InnoDB engine ng MySQL database mayroong 2 log: isa para sa pagtitiklop (binary log), at ang isa para sa pagpapanatili ng ACID (undo/redo log), habang sa PostgreSQL mayroong isang log na gumaganap ng parehong mga function (magsulat ng maagang log = WAL). Ngunit kung ano ang ipinakita sa itaas ay tiyak ang pangkalahatang konsepto, na nagpapahintulot sa mga naturang nuances na hindi isinasaalang-alang.

Kasabay (sync) pagtitiklop

Magdagdag tayo ng lohika upang gayahin ang mga natanggap na pagbabago sa algorithm ng commit ng transaksyon:

  1. Pag-log ng isang transaksyon sa log ng database.
  2. Paggamit ng isang transaksyon sa isang database engine.
  3. Nagpapadala ng data sa lahat ng mga replika.
  4. Pagtanggap ng kumpirmasyon mula sa lahat ng mga replika na ang isang transaksyon ay nakumpleto sa kanila.
  5. Ibinabalik ang kumpirmasyon sa kliyente na matagumpay na nailapat ang transaksyon.

Sa diskarteng ito nakakakuha kami ng ilang mga kawalan:

  • hinihintay ng kliyente na mailapat ang mga pagbabago sa lahat ng mga replika.
  • habang tumataas ang bilang ng mga node sa cluster, binabawasan namin ang posibilidad na maging matagumpay ang write operation.

Kung ang lahat ay higit pa o hindi gaanong malinaw sa 1st point, kung gayon ang mga dahilan para sa 2nd point ay nagkakahalaga ng pagpapaliwanag. Kung sa panahon ng kasabay na pagtitiklop ay hindi kami nakatanggap ng tugon mula sa kahit isang node, ibabalik namin ang transaksyon. Kaya, sa pamamagitan ng pagtaas ng bilang ng mga node sa cluster, pinapataas mo ang posibilidad na mabigo ang isang write operation.

Maaari ba tayong maghintay ng kumpirmasyon mula lamang sa isang tiyak na porsyento ng mga node, halimbawa, mula sa 51% (quorum)? Oo, magagawa namin, ngunit sa klasikong bersyon, kinakailangan ang kumpirmasyon mula sa lahat ng mga node, dahil ito ay kung paano namin masisiguro ang kumpletong pagkakapare-pareho ng data sa cluster, na isang walang alinlangan na bentahe ng ganitong uri ng pagtitiklop.

Asynchronous (async) replication

Baguhin natin ang nakaraang algorithm. Magpapadala kami ng data sa mga replika "mamaya", at "mamaya" ang mga pagbabago ay ilalapat sa mga replika:

  1. Pag-log ng isang transaksyon sa log ng database.
  2. Paggamit ng isang transaksyon sa isang database engine.
  3. Ibinabalik ang kumpirmasyon sa kliyente na matagumpay na nailapat ang transaksyon.
  4. Pagpapadala ng data sa mga replika at paglalapat ng mga pagbabago sa mga ito.

Ang diskarte na ito ay humahantong sa katotohanan na ang cluster ay gumagana nang mabilis, dahil hindi namin pinapanatili ang kliyente na naghihintay para sa data na maabot ang mga replika at maging nakatuon.

Ngunit ang kondisyon ng paglalaglag ng data sa mga replika "sa ibang pagkakataon" ay maaaring humantong sa pagkawala ng isang transaksyon, at sa pagkawala ng isang transaksyon na kinumpirma ng user, dahil kung ang data ay walang oras upang kopyahin, isang kumpirmasyon sa kliyente tungkol sa tagumpay ng operasyon ay ipinadala, at ang node kung saan dumating ang mga pagbabago ay nag-crash sa HDD, nawala namin ang transaksyon, na maaaring humantong sa napaka hindi kasiya-siyang mga kahihinatnan.

Semisync replication

Sa wakas makarating tayo sa semi-synchronous na pagtitiklop. Ang ganitong uri ng pagtitiklop ay hindi masyadong kilala o napakakaraniwan, ngunit ito ay may malaking interes dahil maaari nitong pagsamahin ang mga pakinabang ng parehong kasabay at asynchronous na pagtitiklop.

Subukan nating pagsamahin ang 2 naunang diskarte. Hindi namin papanatilihin ang kliyente nang matagal, ngunit kakailanganin naming kopyahin ang data:

  1. Pag-log ng isang transaksyon sa log ng database.
  2. Paggamit ng isang transaksyon sa isang database engine.
  3. Nagpapadala ng data sa mga replika.
  4. Pagtanggap ng kumpirmasyon mula sa replica na natanggap na ang mga pagbabago (ilalapat ang mga ito "sa ibang pagkakataon").
  5. Ibinabalik ang kumpirmasyon sa kliyente na matagumpay na nailapat ang transaksyon.

Pakitandaan na sa algorithm na ito, ang pagkawala ng transaksyon ay nangyayari lamang kung pareho ang node na tumatanggap ng mga pagbabago at ang replica node ay nabigo. Ang posibilidad ng naturang pagkabigo ay itinuturing na mababa, at ang mga panganib na ito ay tinatanggap.

Ngunit sa diskarteng ito ay may posibleng panganib ng phantom reads. Isipin natin ang sumusunod na senaryo: sa hakbang 4, hindi kami nakatanggap ng kumpirmasyon mula sa anumang replika. Dapat nating ibalik ang transaksyong ito at huwag magbalik ng kumpirmasyon sa kliyente. Dahil inilapat ang data sa hakbang 2, mayroong agwat ng oras sa pagitan ng pagtatapos ng hakbang 2 at ang rollback ng transaksyon, kung saan makikita ng mga magkakatulad na transaksyon ang mga pagbabagong hindi dapat nasa database.

Lose-less semisync replication

Kung mag-isip ka ng kaunti, maaari mo lamang i-reverse ang mga hakbang ng algorithm at ayusin ang problema ng phantom reads sa sitwasyong ito:

  1. Pag-log ng isang transaksyon sa log ng database.
  2. Nagpapadala ng replica data.
  3. Pagtanggap ng kumpirmasyon mula sa replica na natanggap na ang mga pagbabago (ilalapat ang mga ito "sa ibang pagkakataon").
  4. Paggamit ng isang transaksyon sa isang database engine.
  5. Ibinabalik ang kumpirmasyon sa kliyente na matagumpay na nailapat ang transaksyon.

Ngayon, gumawa lang kami ng mga pagbabago kung na-replicate ang mga ito.

Pagbubuhos

Gaya ng dati, walang perpektong solusyon; mayroong isang hanay ng mga solusyon, na ang bawat isa ay may sariling mga pakinabang at disadvantages at angkop para sa paglutas ng iba't ibang klase ng mga problema. Ito ay ganap na totoo para sa pagpili ng isang mekanismo para sa pag-synchronize ng data sa isang replicated database. Ang hanay ng mga pakinabang na mayroon ang semi-synchronous na pagtitiklop ay sapat na matatag at kawili-wili na maaari itong ituring na karapat-dapat na pansin, sa kabila ng mababang pagkalat nito.

Iyon lang. Magkita-kita tayo sa kurso!

Pinagmulan: www.habr.com

Magdagdag ng komento