NewSQL = NoSQL+ACID

NewSQL = NoSQL+ACID
Hadi hivi majuzi, Odnoklassniki ilihifadhi takriban TB 50 ya data iliyochakatwa kwa wakati halisi katika Seva ya SQL. Kwa kiasi kama hicho, karibu haiwezekani kutoa ufikiaji wa haraka na wa kuaminika, na hata ufikiaji wa kutofaulu kwa kituo cha data kwa kutumia DBMS ya SQL. Kwa kawaida, katika hali hiyo, moja ya hifadhi za NoSQL hutumiwa, lakini si kila kitu kinaweza kuhamishiwa kwa NoSQL: baadhi ya vyombo vinahitaji dhamana za shughuli za ACID.

Hii ilituongoza kwenye utumiaji wa hifadhi ya NewSQL, ambayo ni, DBMS ambayo hutoa uvumilivu wa makosa, usawazishaji na utendaji wa mifumo ya NoSQL, lakini wakati huo huo kudumisha dhamana ya ACID inayojulikana kwa mifumo ya zamani. Kuna mifumo michache ya kiviwanda inayofanya kazi ya tabaka hili jipya, kwa hivyo tulitekeleza mfumo kama huu sisi wenyewe na kuuweka katika uendeshaji wa kibiashara.

Jinsi inavyofanya kazi na kilichotokea - soma chini ya kata.

Leo, watazamaji wa kila mwezi wa Odnoklassniki ni zaidi ya wageni milioni 70 wa kipekee. Sisi Tuko kwenye tano bora mitandao mikubwa zaidi ya kijamii ulimwenguni, na kati ya tovuti ishirini ambazo watumiaji hutumia wakati mwingi. Miundombinu ya OK hushughulikia mizigo ya juu sana: zaidi ya maombi milioni ya HTTP/sekunde kwa kila mbele. Sehemu za meli za seva za vipande zaidi ya 8000 ziko karibu na kila mmoja - katika vituo vinne vya data vya Moscow, ambayo inafanya uwezekano wa kuhakikisha latency ya mtandao ya chini ya 1 ms kati yao.

Tumekuwa tukitumia Cassandra tangu 2010, kuanzia toleo la 0.6. Leo kuna vikundi kadhaa vya kufanya kazi. Nguzo za kasi zaidi huchakata zaidi ya shughuli milioni 4 kwa sekunde, na maduka makubwa zaidi 260 TB.

Walakini, hizi zote ni nguzo za kawaida za NoSQL zinazotumiwa kuhifadhi uratibu hafifu data. Tulitaka kuchukua nafasi ya hifadhi kuu thabiti, Microsoft SQL Server, ambayo imetumika tangu kuanzishwa kwa Odnoklassniki. Hifadhi hiyo ilijumuisha zaidi ya mashine 300 za Toleo la Kawaida la SQL Server, ambazo zilikuwa na TB 50 za data - vyombo vya biashara. Data hii inarekebishwa kama sehemu ya miamala ya ACID na inahitaji uthabiti wa juu.

Ili kusambaza data kwenye nodi za Seva ya SQL, tulitumia wima na mlalo kugawa (kugawanyika). Kihistoria, tulitumia mpango rahisi wa kushiriki data: kila huluki ilihusishwa na tokeni - kazi ya kitambulisho cha huluki. Huluki zilizo na tokeni sawa ziliwekwa kwenye seva sawa ya SQL. Uhusiano wa bwana-maelezo ulitekelezwa ili ishara za rekodi kuu na za watoto zifanane kila wakati na ziko kwenye seva moja. Katika mtandao wa kijamii, karibu rekodi zote hutolewa kwa niaba ya mtumiaji - ambayo ina maana kwamba data zote za mtumiaji ndani ya mfumo mdogo wa kazi huhifadhiwa kwenye seva moja. Hiyo ni, shughuli ya biashara karibu kila wakati ilihusisha meza kutoka kwa seva moja ya SQL, ambayo ilifanya iwezekane kuhakikisha uthabiti wa data kwa kutumia miamala ya ACID ya ndani, bila hitaji la kutumia. polepole na isiyoaminika shughuli za ACID zilizosambazwa.

Shukrani kwa kushiriki na kuharakisha SQL:

  • Hatutumii vizuizi vya vitufe vya Kigeni, kwani wakati wa kugawa kitambulisho cha huluki kinaweza kupatikana kwenye seva nyingine.
  • Hatutumii taratibu na vichochezi vilivyohifadhiwa kutokana na mzigo wa ziada kwenye DBMS CPU.
  • Hatutumii JOIN kwa sababu ya yote yaliyo hapo juu na usomaji mwingi wa nasibu kutoka kwa diski.
  • Nje ya muamala, tunatumia kiwango cha kujitenga cha Kusoma Bila Kujitolea ili kupunguza vikwazo.
  • Tunafanya shughuli fupi tu (kwa wastani mfupi kuliko ms 100).
  • Hatutumii UPDATE na FUTA za safu mlalo nyingi kwa sababu ya idadi kubwa ya mikwamo - tunasasisha rekodi moja tu kwa wakati mmoja.
  • Kila mara sisi huuliza maswali kwenye faharasa - hoja iliyo na mpango kamili wa kuchanganua jedwali inamaanisha kupakia hifadhidata kupita kiasi na kuifanya ishindwe.

Hatua hizi zilituruhusu kubana karibu utendaji wa juu zaidi kutoka kwa seva za SQL. Hata hivyo, matatizo yalizidi kuwa mengi. Hebu tuwaangalie.

Matatizo na SQL

  • Kwa kuwa tulitumia sharding ya kibinafsi, kuongeza shards mpya kulifanywa na wasimamizi. Wakati huu wote, nakala za data zinazoweza kupanuka hazikuwa zikitoa maombi.
  • Kadiri idadi ya rekodi kwenye jedwali inavyokua, kasi ya kuingizwa na urekebishaji inapungua; wakati wa kuongeza fahirisi kwenye jedwali lililopo, kasi hushuka kwa sababu fulani; uundaji na uundaji upya wa faharisi hufanyika na wakati wa kupumzika.
  • Kuwa na kiasi kidogo cha Windows kwa Seva ya SQL katika uzalishaji hufanya usimamizi wa miundombinu kuwa mgumu

Lakini shida kuu ni

uvumilivu wa makosa

Seva ya kawaida ya SQL ina uvumilivu duni wa makosa. Wacha tuseme una seva moja tu ya hifadhidata, na inashindwa mara moja kila baada ya miaka mitatu. Wakati huu tovuti iko chini kwa dakika 20, ambayo inakubalika. Ikiwa una seva 64, basi tovuti iko chini mara moja kila wiki tatu. Na ikiwa una seva 200, basi tovuti haifanyi kazi kila wiki. Hili ni tatizo.

Nini kifanyike ili kuboresha uvumilivu wa makosa ya seva ya SQL? Wikipedia inatualika kujenga nguzo inayopatikana sana: ambapo katika kesi ya kushindwa kwa kipengele chochote kuna chelezo.

Hii inahitaji kundi la vifaa vya gharama kubwa: marudio mengi, nyuzinyuzi za macho, uhifadhi wa pamoja, na ujumuishaji wa hifadhi haufanyi kazi kwa uhakika: karibu 10% ya swichi huisha kwa kushindwa kwa nodi ya chelezo kama treni nyuma ya nodi kuu.

Lakini hasara kuu ya nguzo hiyo inayopatikana sana ni upatikanaji wa sifuri ikiwa kituo cha data ambacho iko kinashindwa. Odnoklassniki ina vituo vinne vya data, na tunahitaji kuhakikisha uendeshaji katika tukio la kushindwa kabisa katika mojawapo yao.

Kwa hili tunaweza kutumia Multi-Master replication iliyojengwa ndani ya Seva ya SQL. Suluhisho hili ni ghali zaidi kwa sababu ya gharama ya programu na inakabiliwa na shida zinazojulikana na kurudiwa - ucheleweshaji wa shughuli usiotabirika na urudiaji wa synchronous na ucheleweshaji wa kutumia majibu (na, kwa sababu hiyo, marekebisho yaliyopotea) na urudiaji wa asynchronous. Inamaanisha utatuzi wa migogoro kwa mikono hufanya chaguo hili kutotumika kabisa kwetu.

Shida hizi zote zilihitaji suluhisho kali, na tukaanza kuzichambua kwa undani. Hapa tunahitaji kufahamiana na kile SQL Server hufanya - shughuli.

Shughuli rahisi

Hebu tuchunguze shughuli rahisi zaidi, kutoka kwa mtazamo wa programu ya SQL iliyotumiwa: kuongeza picha kwenye albamu. Albamu na picha huhifadhiwa katika sahani tofauti. Albamu ina kaunta ya picha ya umma. Kisha shughuli kama hiyo imegawanywa katika hatua zifuatazo:

  1. Tunafunga albamu kwa ufunguo.
  2. Unda kiingilio kwenye jedwali la picha.
  3. Ikiwa picha ina hadhi ya umma, basi ongeza kihesabu cha picha ya umma kwenye albamu, sasisha rekodi na ufanye muamala.

Au katika pseudocode:

TX.start("Albums", id);
Album album = albums.lock(id);
Photo photo = photos.create(…);

if (photo.status == PUBLIC ) {
    album.incPublicPhotosCount();
}
album.update();

TX.commit();

Tunaona kuwa hali ya kawaida ya shughuli ya biashara ni kusoma data kutoka kwa hifadhidata hadi kwenye kumbukumbu ya seva ya programu, kubadilisha kitu na kuhifadhi maadili mapya kwenye hifadhidata. Kawaida katika shughuli kama hiyo tunasasisha vyombo kadhaa, meza kadhaa.

Wakati wa kutekeleza shughuli, marekebisho ya wakati mmoja ya data sawa kutoka kwa mfumo mwingine yanaweza kutokea. Kwa mfano, Antispam inaweza kuamua kuwa mtumiaji anashuku kwa namna fulani na kwa hivyo picha zote za mtumiaji zisiwe hadharani tena, zinahitaji kutumwa ili kukaguliwa, kumaanisha kubadilisha picha.hadhi hadi thamani nyingine na kuzima vihesabio vinavyolingana. Ni wazi, ikiwa operesheni hii itatokea bila dhamana ya atomicity ya maombi na kutengwa kwa marekebisho yanayoshindana, kama vile katika ACID, basi matokeo hayatakuwa kile kinachohitajika - ama counter ya picha itaonyesha thamani isiyo sahihi, au sio picha zote zitatumwa kwa kiasi.

Nambari nyingi zinazofanana, kudhibiti mashirika anuwai ya biashara ndani ya shughuli moja, zimeandikwa katika uwepo wote wa Odnoklassniki. Kulingana na uzoefu wa uhamiaji hadi NoSQL kutoka Uthabiti wa Hatimaye Tunajua kwamba changamoto kubwa (na uwekezaji wa muda) hutokana na kutengeneza msimbo ili kudumisha uwiano wa data. Kwa hivyo, tulizingatia hitaji kuu la hifadhi mpya kuwa utoaji wa miamala halisi ya ACID kwa mantiki ya programu.

Mahitaji mengine, sio muhimu sana, yalikuwa:

  • Ikiwa kituo cha data kitashindwa, kusoma na kuandika kwa hifadhi mpya lazima iwepo.
  • Kudumisha kasi ya maendeleo ya sasa. Hiyo ni, wakati wa kufanya kazi na hazina mpya, idadi ya nambari inapaswa kuwa takriban sawa; haipaswi kuwa na haja ya kuongeza chochote kwenye hazina, kukuza algorithms ya kusuluhisha mizozo, kudumisha faharisi za sekondari, nk.
  • Kasi ya hifadhi mpya ilipaswa kuwa ya juu kabisa, wakati wa kusoma data na wakati wa usindikaji wa shughuli, ambayo ilimaanisha kwa ufanisi kwamba ufumbuzi wa kitaaluma, wa ulimwengu wote, lakini wa polepole, kama vile, kwa mfano, haukutumika. ahadi za awamu mbili.
  • Kuongeza kasi kiotomatiki popote ulipo.
  • Kutumia seva za bei nafuu za kawaida, bila hitaji la kununua vifaa vya kigeni.
  • Uwezekano wa maendeleo ya uhifadhi na watengenezaji wa kampuni. Kwa maneno mengine, kipaumbele kilipewa suluhisho za wamiliki au wazi, ikiwezekana katika Java.

Maamuzi, maamuzi

Kuchambua suluhisho zinazowezekana, tulikuja kwa chaguzi mbili zinazowezekana za usanifu:

Ya kwanza ni kuchukua seva yoyote ya SQL na kutekeleza uvumilivu wa makosa unaohitajika, utaratibu wa kuongeza kiwango, nguzo ya kushindwa, utatuzi wa migogoro na shughuli zilizosambazwa, za kuaminika na za haraka za ACID. Tulikadiria chaguo hili kuwa lisilo la maana sana na la nguvu kazi kubwa.

Chaguo la pili ni kuchukua hifadhi iliyotengenezwa tayari ya NoSQL na kuongeza kutekelezwa, nguzo ya kushindwa, utatuzi wa migogoro, na kutekeleza shughuli na SQL mwenyewe. Kwa mtazamo wa kwanza, hata kazi ya kutekeleza SQL, bila kutaja shughuli za ACID, inaonekana kama kazi ambayo itachukua miaka. Lakini basi tuligundua kuwa seti ya kipengele cha SQL tunachotumia katika mazoezi ni mbali na ANSI SQL kama Cassandra CQL mbali na ANSI SQL. Kuangalia kwa karibu zaidi CQL, tuligundua kuwa ilikuwa karibu kabisa na kile tulichohitaji.

Cassandra na CQL

Kwa hivyo, ni nini kinachovutia kuhusu Cassandra, ina uwezo gani?

Kwanza, hapa unaweza kuunda majedwali ambayo yanaauni aina mbalimbali za data; unaweza kufanya CHAGUA au KUSASISHA kwenye ufunguo msingi.

CREATE TABLE photos (id bigint KEY, owner bigint,…);
SELECT * FROM photos WHERE id=?;
UPDATE photos SET … WHERE id=?;

Ili kuhakikisha uthabiti wa data ya nakala, Cassandra hutumia mbinu ya akidi. Katika hali rahisi, hii inamaanisha kwamba wakati nakala tatu za safu moja zimewekwa kwenye nodi tofauti za nguzo, uandishi unachukuliwa kuwa umefanikiwa ikiwa nodi nyingi (ambayo ni mbili kati ya tatu) zimethibitisha kufaulu kwa operesheni hii ya uandishi. . Data ya safu mlalo inachukuliwa kuwa sawa ikiwa, wakati wa kusoma, nodi nyingi zilipigwa kura na kuzithibitisha. Kwa hivyo, na nakala tatu, uthabiti kamili na wa papo hapo wa data unahakikishwa ikiwa nodi moja itashindwa. Mbinu hii ilituruhusu kutekeleza mpango unaotegemewa zaidi: kila mara tuma maombi kwa nakala zote tatu, ukingoja jibu kutoka kwa zile mbili za haraka sana. Jibu la marehemu la nakala ya tatu hutupwa katika kesi hii. Node ambayo imechelewa kujibu inaweza kuwa na matatizo makubwa - breki, ukusanyaji wa takataka katika JVM, kurejesha kumbukumbu ya moja kwa moja kwenye kernel ya Linux, kushindwa kwa vifaa, kukatwa kutoka kwa mtandao. Hata hivyo, hii haiathiri shughuli za mteja au data kwa njia yoyote.

Njia tunapowasiliana na nodes tatu na kupokea jibu kutoka kwa mbili inaitwa uvumi: ombi la nakala za ziada hutumwa hata kabla ya "kuanguka".

Faida nyingine ya Cassandra ni Batchlog, utaratibu unaohakikisha kwamba kundi la mabadiliko unayofanya yanatekelezwa kikamilifu au hayatumiki kabisa. Hii huturuhusu kutatua A katika ACID - atomiki nje ya kisanduku.

Jambo la karibu zaidi kwa shughuli huko Cassandra ni ile inayoitwa "shughuli nyepesi". Lakini wao ni mbali na shughuli za "halisi" za ACID: kwa kweli, hii ni fursa ya kufanya CAS kwenye data kutoka kwa rekodi moja tu, kwa kutumia makubaliano kwa kutumia itifaki ya Paxos yenye uzani mzito. Kwa hiyo, kasi ya shughuli hizo ni ya chini.

Tulichokuwa tunakosa huko Cassandra

Kwa hivyo, tulilazimika kutekeleza miamala halisi ya ACID huko Cassandra. Kwa kutumia ambayo tunaweza kutekeleza kwa urahisi vipengele vingine viwili vinavyofaa vya DBMS ya kawaida: faharasa za haraka zisizobadilika, ambazo zingeturuhusu kufanya uteuzi wa data sio tu kwa ufunguo msingi, na jenereta ya kawaida ya vitambulisho vya kuongeza kiotomatiki vya monotoni.

C*Moja

Kwa hivyo DBMS mpya ilizaliwa C*Moja, inayojumuisha aina tatu za nodi za seva:

  • Hifadhi - (karibu) seva za kawaida za Cassandra zinazohusika na kuhifadhi data kwenye diski za ndani. Kadiri mzigo na ujazo wa data unavyoongezeka, idadi yao inaweza kuongezwa kwa makumi na mamia kwa urahisi.
  • Waratibu wa shughuli - hakikisha utekelezaji wa shughuli.
  • Wateja ni seva za maombi zinazotekeleza shughuli za biashara na kuanzisha shughuli. Kunaweza kuwa na maelfu ya wateja kama hao.

NewSQL = NoSQL+ACID

Seva za aina zote ni sehemu ya nguzo ya kawaida, tumia itifaki ya ndani ya ujumbe wa Cassandra kuwasiliana na kila mmoja na mwingine. uvumi kwa kubadilishana habari za nguzo. Kwa Mapigo ya Moyo, seva hujifunza kuhusu kushindwa kwa pande zote, kudumisha schema moja ya data - meza, muundo wao na urudufishaji; mpango wa kugawanya, topolojia ya nguzo, nk.

Wateja

NewSQL = NoSQL+ACID

Badala ya madereva ya kawaida, hali ya Mteja wa Mafuta hutumiwa. Nodi kama hiyo haihifadhi data, lakini inaweza kufanya kama mratibu wa utekelezaji wa ombi, ambayo ni kwamba, Mteja mwenyewe hufanya kama mratibu wa maombi yake: huuliza nakala za uhifadhi na kusuluhisha mizozo. Hii sio tu ya kuaminika zaidi na ya haraka zaidi kuliko dereva wa kawaida, ambayo inahitaji mawasiliano na mratibu wa kijijini, lakini pia inakuwezesha kudhibiti maambukizi ya maombi. Nje ya shughuli iliyofunguliwa kwa mteja, maombi hutumwa kwa hazina. Ikiwa mteja amefungua shughuli, basi maombi yote ndani ya shughuli yanatumwa kwa mratibu wa shughuli.
NewSQL = NoSQL+ACID

C*Mratibu wa Muamala Mmoja

Mratibu ni jambo tulilotekeleza kwa C*One kuanzia mwanzo. Ina jukumu la kudhibiti miamala, kufuli, na mpangilio ambao miamala inatumika.

Kwa kila shughuli inayohudumiwa, mratibu hutengeneza muhuri wa muda: kila muamala unaofuata ni mkubwa kuliko shughuli ya awali. Kwa kuwa mfumo wa utatuzi wa mizozo wa Cassandra unategemea muhuri wa muda (wa rekodi mbili zinazokinzana, ule ulio na muhuri wa muda wa hivi punde unachukuliwa kuwa wa sasa), mzozo huo utasuluhishwa kila mara kwa manufaa ya shughuli inayofuata. Hivyo tulitekeleza Saa ya Lamport - njia ya bei nafuu ya kutatua migogoro katika mfumo uliosambazwa.

Kufuli

Ili kuhakikisha kutengwa, tuliamua kutumia njia rahisi - kufuli zisizo na matumaini kulingana na ufunguo wa msingi wa rekodi. Kwa maneno mengine, katika shughuli, rekodi lazima kwanza imefungwa, kisha tu kusoma, kurekebishwa na kuhifadhiwa. Ni baada tu ya ahadi iliyofanikiwa ndipo rekodi inaweza kufunguliwa ili miamala shindani iweze kuitumia.

Utekelezaji wa kufunga vile ni rahisi katika mazingira yasiyo ya kusambazwa. Katika mfumo uliosambazwa, kuna chaguo kuu mbili: ama tekeleza kufuli kwa kusambazwa kwenye nguzo, au usambaze miamala ili shughuli zinazohusisha rekodi sawa zihudumiwe na mratibu huyo huyo kila mara.

Kwa kuwa kwa upande wetu data tayari imesambazwa kati ya vikundi vya shughuli za ndani katika SQL, iliamuliwa kugawa vikundi vya shughuli za ndani kwa waratibu: mratibu mmoja hufanya shughuli zote na ishara kutoka 0 hadi 9, pili - na ishara kutoka 10 hadi 19, Nakadhalika. Matokeo yake, kila moja ya matukio ya mratibu inakuwa bwana wa kikundi cha shughuli.

Kisha kufuli kunaweza kutekelezwa kwa njia ya banal HashMap katika kumbukumbu ya mratibu.

Kushindwa kwa mratibu

Kwa kuwa mratibu mmoja hutumikia kikundi cha shughuli pekee, ni muhimu sana kuamua haraka ukweli wa kutofaulu kwake ili jaribio la pili la kutekeleza shughuli litaisha. Ili kufanya hili kuwa la haraka na la kuaminika, tulitumia itifaki iliyounganishwa kikamilifu ya mapigo ya sauti:

Kila kituo cha data hupangisha angalau nodi mbili za kuratibu. Mara kwa mara, kila mratibu hutuma ujumbe wa mapigo ya moyo kwa waratibu wengine na kuwajulisha kuhusu utendakazi wake, na pia ni jumbe zipi za mapigo ya moyo alizopokea kutoka kwa waratibu katika nguzo mara ya mwisho.

NewSQL = NoSQL+ACID

Kupokea taarifa kama hizo kutoka kwa wengine kama sehemu ya jumbe zao za mapigo ya moyo, kila mratibu anaamua mwenyewe ni nodi zipi za nguzo zinazofanya kazi na zipi hazifanyi kazi, kwa kuongozwa na kanuni ya akidi: ikiwa nodi X imepokea taarifa kutoka kwa nodi nyingi kwenye nguzo kuhusu kawaida. upokeaji wa ujumbe kutoka kwa nodi Y, kisha , Y inafanya kazi. Na kinyume chake, mara tu wengi wanaporipoti kukosa ujumbe kutoka kwa nodi Y, basi Y imekataa. Inashangaza kwamba ikiwa akidi itafahamisha nodi X kwamba haipokei tena ujumbe kutoka kwake, basi nodi X yenyewe itajiona kuwa imeshindwa.

Ujumbe wa mapigo ya moyo hutumwa kwa masafa ya juu, takriban mara 20 kwa sekunde, na muda wa 50 ms. Katika Java, ni vigumu kuhakikisha jibu la maombi ndani ya 50 ms kutokana na urefu wa kulinganishwa wa pause unaosababishwa na mtoza takataka. Tuliweza kufikia wakati huu wa majibu kwa kutumia kikusanya taka cha G1, ambacho huturuhusu kubainisha lengo kwa muda wa kusitisha GC. Hata hivyo, wakati mwingine, mara chache kabisa, mtoza anasimama huzidi 50 ms, ambayo inaweza kusababisha kugundua kosa la uwongo. Ili kuzuia hili kutokea, mratibu haitoi ripoti ya kushindwa kwa node ya mbali wakati ujumbe wa kwanza wa moyo kutoka kwake hupotea, tu ikiwa kadhaa wamepotea mfululizo.Hivi ndivyo tulivyoweza kugundua kushindwa kwa node ya mratibu mwaka 200. ms.

Lakini haitoshi kuelewa haraka ni nodi gani imeacha kufanya kazi. Tunahitaji kufanya kitu kuhusu hili.

Uhifadhi

Mpango wa kawaida unahusisha, katika tukio la kushindwa kwa bwana, kuanza uchaguzi mpya kwa kutumia moja ya mtindo zima algorithms. Hata hivyo, algoriti kama hizo zina matatizo yanayojulikana na muunganiko wa wakati na urefu wa mchakato wa uchaguzi wenyewe. Tuliweza kuzuia ucheleweshaji kama huo wa ziada kwa kutumia mpango wa kubadilisha wa mratibu katika mtandao uliounganishwa kikamilifu:

NewSQL = NoSQL+ACID

Hebu sema tunataka kutekeleza shughuli katika kikundi cha 50. Hebu tuamua mapema mpango wa uingizwaji, yaani, ni nodes gani zitafanya shughuli katika kikundi cha 50 katika tukio la kushindwa kwa mratibu mkuu. Lengo letu ni kudumisha utendakazi wa mfumo iwapo kituo cha data kitashindwa. Hebu tuamua kwamba hifadhi ya kwanza itakuwa node kutoka kituo kingine cha data, na hifadhi ya pili itakuwa node kutoka kwa tatu. Mpango huu umechaguliwa mara moja na haubadilika mpaka topolojia ya nguzo inabadilika, yaani, mpaka nodes mpya ziingie (ambayo hutokea mara chache sana). Utaratibu wa kuchagua bwana mpya anayefanya kazi ikiwa wa zamani atashindwa daima utakuwa kama ifuatavyo: hifadhi ya kwanza itakuwa bwana anayefanya kazi, na ikiwa imeacha kufanya kazi, hifadhi ya pili itakuwa bwana anayefanya kazi.

Mpango huu ni wa kuaminika zaidi kuliko algorithm ya ulimwengu wote, kwani kuamsha bwana mpya ni wa kutosha kuamua kutofaulu kwa wa zamani.

Lakini wateja wataelewaje ni bwana gani anayefanya kazi sasa? Haiwezekani kutuma habari kwa maelfu ya wateja katika 50 ms. Hali inawezekana wakati mteja anatuma ombi la kufungua shughuli, bila kujua kuwa bwana huyu hafanyi kazi tena, na ombi litaisha. Ili kuzuia hili kutokea, wateja kwa kubahatisha hutuma ombi la kufungua shughuli kwa bwana wa kikundi na akiba zake zote mbili mara moja, lakini ni yule tu ambaye ndiye bwana anayefanya kazi kwa sasa atajibu ombi hili. Mteja atafanya mawasiliano yote yanayofuata ndani ya shughuli tu na bwana anayefanya kazi.

Mabwana wa chelezo huweka maombi yaliyopokelewa ya miamala ambayo si yao kwenye foleni ya miamala ambayo haijazaliwa, ambapo huhifadhiwa kwa muda. Ikiwa bwana anayefanya kazi atakufa, bwana mpya huchakata maombi ya kufungua miamala kutoka kwa foleni yake na kujibu mteja. Ikiwa mteja tayari amefungua shughuli na bwana wa zamani, basi jibu la pili linapuuzwa (na, kwa wazi, shughuli hiyo haitakamilika na itarudiwa na mteja).

Jinsi shughuli inavyofanya kazi

Wacha tuseme mteja alituma ombi kwa mratibu ili afungue shughuli kwa shirika kama hilo na ufunguo wa msingi kama huo. Mratibu hufunga huluki hii na kuiweka kwenye jedwali la kufuli kwenye kumbukumbu. Ikiwa ni lazima, mratibu anasoma huluki hii kutoka kwa hifadhi na kuhifadhi data inayotokana katika hali ya shughuli katika kumbukumbu ya mratibu.

NewSQL = NoSQL+ACID

Wakati mteja anataka kubadilisha data katika muamala, hutuma ombi kwa mratibu ili kurekebisha huluki, na mratibu huweka data mpya katika jedwali la hali ya muamala kwenye kumbukumbu. Hii inakamilisha kurekodi - hakuna rekodi inayofanywa kwenye hifadhi.

NewSQL = NoSQL+ACID

Wakati mteja anaomba data yake iliyobadilishwa kama sehemu ya shughuli inayoendelea, mratibu hufanya kama ifuatavyo:

  • ikiwa kitambulisho tayari iko kwenye shughuli, basi data inachukuliwa kutoka kwa kumbukumbu;
  • ikiwa hakuna kitambulisho kwenye kumbukumbu, basi data iliyopotea inasomwa kutoka kwa nodes za hifadhi, pamoja na wale ambao tayari wako kwenye kumbukumbu, na matokeo hutolewa kwa mteja.

Kwa hivyo, mteja anaweza kusoma mabadiliko yake mwenyewe, lakini wateja wengine hawaoni mabadiliko haya, kwa sababu yanahifadhiwa tu kwenye kumbukumbu ya mratibu; bado hawako kwenye nodi za Cassandra.

NewSQL = NoSQL+ACID

Wakati mteja anatuma ahadi, hali iliyokuwa kwenye kumbukumbu ya huduma huhifadhiwa na mratibu katika kundi lililoingia, na hutumwa kama kundi lililoingia kwenye hifadhi ya Cassandra. Duka hufanya kila kitu muhimu ili kuhakikisha kuwa kifurushi hiki kinatumika kwa atomi (kabisa), na kurudisha jibu kwa mratibu, ambaye hutoa kufuli na kuthibitisha mafanikio ya shughuli kwa mteja.

NewSQL = NoSQL+ACID

Na ili kurejesha, mratibu anahitaji tu kuachilia kumbukumbu iliyochukuliwa na hali ya muamala.

Kama matokeo ya maboresho yaliyo hapo juu, tulitekeleza kanuni za ACID:

  • Atomiki. Hii ni hakikisho kwamba hakuna muamala utakaorekodiwa kiasi katika mfumo; ama shughuli zake zote ndogo zitakamilika, au hakuna kitakachokamilika. Tunafuata kanuni hii kupitia bechi iliyoingia katika Cassandra.
  • Uthabiti. Kila shughuli iliyofanikiwa, kwa ufafanuzi, inarekodi matokeo halali tu. Ikiwa, baada ya kufungua shughuli na kufanya sehemu ya shughuli, imegunduliwa kuwa matokeo ni batili, kurudi nyuma kunafanywa.
  • Kujitenga. Wakati muamala unatekelezwa, miamala ya pamoja haipaswi kuathiri matokeo yake. Shughuli zinazoshindana zimetengwa kwa kutumia kufuli zisizo na matumaini kwa mratibu. Kwa usomaji wa nje ya muamala, kanuni ya kujitenga inazingatiwa katika kiwango cha Umejitolea Kusoma.
  • Kudumu. Bila kujali matatizo katika viwango vya chiniβ€”kuzima kwa mfumo, kushindwa kwa maunziβ€”mabadiliko yaliyofanywa na shughuli iliyokamilishwa kwa mafanikio yanapaswa kuhifadhiwa wakati shughuli zinapoanza tena.

Kusoma kwa faharasa

Wacha tuchukue meza rahisi:

CREATE TABLE photos (
id bigint primary key,
owner bigint,
modified timestamp,
…)

Ina kitambulisho (ufunguo msingi), mmiliki na tarehe ya marekebisho. Unahitaji kufanya ombi rahisi sana - chagua data juu ya mmiliki na tarehe ya mabadiliko "siku ya mwisho".

SELECT *
WHERE owner=?
AND modified>?

Ili swala kama hilo lishughulikiwe haraka, katika DBMS ya kawaida ya SQL unahitaji kuunda faharisi kwa safu (mmiliki, iliyorekebishwa). Tunaweza kufanya hivi kwa urahisi kabisa, kwa kuwa sasa tuna dhamana ya ACID!

Fahirisi katika C*One

Kuna jedwali la chanzo lenye picha ambamo kitambulisho cha rekodi ndio ufunguo msingi.

NewSQL = NoSQL+ACID

Kwa faharasa, C*One huunda jedwali jipya ambalo ni nakala ya la asili. Ufunguo ni sawa na usemi wa faharisi, na pia inajumuisha ufunguo wa msingi wa rekodi kutoka kwa jedwali la chanzo:

NewSQL = NoSQL+ACID

Sasa swali la "mmiliki wa siku ya mwisho" linaweza kuandikwa upya kama chaguo kutoka kwa jedwali lingine:

SELECT * FROM i1_test
WHERE owner=?
AND modified>?

Uwiano wa data katika picha za jedwali la chanzo na jedwali la faharasa i1 hudumishwa kiotomatiki na mratibu. Kulingana na schema ya data peke yake, wakati mabadiliko yanapokelewa, mratibu huzalisha na kuhifadhi mabadiliko sio tu kwenye meza kuu, bali pia katika nakala. Hakuna vitendo vya ziada vinavyofanywa kwenye meza ya index, magogo hayajasomwa, na hakuna kufuli hutumiwa. Hiyo ni, kuongeza faharisi hutumia rasilimali karibu hakuna na haina athari kwa kasi ya utumiaji wa marekebisho.

Kwa kutumia ACID, tuliweza kutekeleza faharasa zinazofanana na SQL. Zinafanana, zinaweza kupanuka, kwa haraka, zinaweza kutungwa, na zimejumuishwa katika lugha ya uulizaji ya CQL. Hakuna mabadiliko ya msimbo wa programu yanayohitajika ili kusaidia faharasa. Kila kitu ni rahisi kama katika SQL. Na muhimu zaidi, faharisi haziathiri kasi ya utekelezaji wa marekebisho kwenye jedwali la awali la shughuli.

Nini kimetokea

Tulitengeneza C*One miaka mitatu iliyopita na kuizindua katika uendeshaji wa kibiashara.

Tulipata nini mwisho? Hebu tutathmini hili kwa kutumia mfano wa mfumo mdogo wa usindikaji wa picha na hifadhi, mojawapo ya aina muhimu zaidi za data katika mtandao wa kijamii. Hatuzungumzii juu ya miili ya picha zenyewe, lakini juu ya kila aina ya habari ya meta. Sasa Odnoklassniki ina rekodi kama hizo bilioni 20, mfumo unashughulikia maombi elfu 80 ya kusoma kwa sekunde, hadi shughuli elfu 8 za ACID kwa sekunde inayohusishwa na urekebishaji wa data.

Tulipotumia SQL iliyo na replication factor = 1 (lakini katika RAID 10), maelezo mafupi ya picha yalihifadhiwa kwenye kundi linalopatikana sana la mashine 32 zinazotumia Microsoft SQL Server (pamoja na nakala rudufu 11). Seva 10 pia zilitengwa kwa ajili ya kuhifadhi nakala rudufu. Jumla ya magari 50 ya gharama kubwa. Wakati huo huo, mfumo ulifanya kazi kwa mzigo uliopimwa, bila hifadhi.

Baada ya kuhamia mfumo mpya, tulipokea replication factor = 3 - nakala katika kila kituo cha data. Mfumo huo una nodi 63 za kuhifadhi za Cassandra na mashine 6 za kuratibu, kwa jumla ya seva 69. Lakini mashine hizi ni nafuu zaidi, gharama yao ya jumla ni karibu 30% ya gharama ya mfumo wa SQL. Wakati huo huo, mzigo huhifadhiwa kwa 30%.

Kwa kuanzishwa kwa C*One, latency pia ilipungua: katika SQL, operesheni ya kuandika ilichukua takriban 4,5 ms. Katika C * One - kuhusu 1,6 ms. Muda wa ununuzi kwa wastani ni chini ya 40 ms, ahadi imekamilika kwa 2 ms, muda wa kusoma na kuandika ni wastani wa 2 ms. Asilimia ya 99 - tu 3-3,1 ms, idadi ya muda umepungua kwa mara 100 - yote kutokana na kuenea kwa matumizi ya uvumi.

Kufikia sasa, nodi nyingi za Seva ya SQL zimekatishwa kazi; bidhaa mpya zinatengenezwa kwa kutumia C*One pekee. Tulibadilisha C*One kufanya kazi katika wingu letu wingu moja, ambayo ilifanya iwezekanavyo kuharakisha kupelekwa kwa makundi mapya, kurahisisha usanidi na uendeshaji wa otomatiki. Bila nambari ya chanzo, kufanya hivi itakuwa ngumu zaidi na ngumu.

Sasa tunashughulikia kuhamisha vifaa vyetu vingine vya kuhifadhi hadi kwenye wingu - lakini hiyo ni hadithi tofauti kabisa.

Chanzo: mapenzi.com

Kuongeza maoni