Replikazzjoni ta 'livell għoli f'Tarantool DBMS

Hello, qed noħloq applikazzjonijiet għal DBMS Tarantool hija pjattaforma żviluppata minn Mail.ru Group li tgħaqqad DBMS ta 'prestazzjoni għolja u server ta' applikazzjoni fil-lingwa Lua. Il-veloċità għolja ta 'soluzzjonijiet ibbażati fuq Tarantool tinkiseb, b'mod partikolari, minħabba l-appoġġ għall-modalità fil-memorja tad-DBMS u l-abbiltà li tesegwixxi l-loġika tan-negozju tal-applikazzjoni fi spazju tal-indirizz wieħed bid-dejta. Fl-istess ħin, il-persistenza tad-dejta hija żgurata bl-użu ta 'tranżazzjonijiet ACID (jinżamm log WAL fuq id-diska). Tarantool għandu appoġġ integrat għar-replikazzjoni u t-tqattigħ. Nibdew mill-verżjoni 2.1, mistoqsijiet fil-lingwa SQL huma appoġġjati. Tarantool huwa sors miftuħ u liċenzjat taħt il-liċenzja Simplified BSD. Hemm ukoll verżjoni kummerċjali Enterprise.

Replikazzjoni ta 'livell għoli f'Tarantool DBMS
Ħoss il-qawwa! (...magħrufa wkoll gawdi l-prestazzjoni)

Kollha ta 'hawn fuq tagħmel Tarantool pjattaforma attraenti għall-ħolqien ta' applikazzjonijiet ta 'tagħbija għolja li jaħdmu ma' databases. F'dawn l-applikazzjonijiet, ħafna drabi jkun hemm bżonn ta' replikazzjoni tad-dejta.

Kif imsemmi hawn fuq, Tarantool għandu replikazzjoni tad-dejta integrata. Il-prinċipju tat-tħaddim tiegħu huwa li tesegwixxi b'mod sekwenzjali fuq repliki t-tranżazzjonijiet kollha li jinsabu fil-ġurnal prinċipali (WAL). Normalment replikazzjoni bħal din (aħna se nsejħuha aktar livell baxx) jintuża biex jiżgura t-tolleranza tal-ħsarat tal-applikazzjoni u/jew biex jiddistribwixxi t-tagħbija tal-qari bejn in-nodi tal-cluster.

Replikazzjoni ta 'livell għoli f'Tarantool DBMS
Ross. 1. Replikazzjoni fi ħdan cluster

Eżempju ta' xenarju alternattiv ikun it-trasferiment ta' data maħluqa f'database waħda għal database oħra għall-ipproċessar/monitoraġġ. Fil-każ tal-aħħar, soluzzjoni aktar konvenjenti tista 'tkun li tuża livell għoli replikazzjoni - replikazzjoni tad-dejta fil-livell tal-loġika tan-negozju tal-applikazzjoni. Dawk. Aħna ma nużawx soluzzjoni lesta mibnija fid-DBMS, iżda nimplimentaw replikazzjoni waħedna fi ħdan l-applikazzjoni li qed niżviluppaw. Dan l-approċċ għandu kemm vantaġġi kif ukoll żvantaġġi. Ejja elenka l-vantaġġi.

1. Iffrankar tat-traffiku:

  • Ma tistax tittrasferixxi d-dejta kollha, iżda biss parti minnha (per eżempju, tista 'tittrasferixxi biss xi tabelli, xi kolonni jew rekords tagħhom li jissodisfaw ċertu kriterju);
  • B'differenza replikazzjoni ta 'livell baxx, li titwettaq kontinwament fil-modalità mhux sinkroniku (implimentat fil-verżjoni attwali ta' Tarantool - 1.10) jew sinkroniku (li għandu jiġi implimentat f'verżjonijiet sussegwenti ta 'Tarantool), replikazzjoni ta' livell għoli tista 'titwettaq f'sessjonijiet (jiġifieri, il- applikazzjoni l-ewwel tissinkronizza d-data - data ta 'sessjoni ta' skambju, imbagħad ikun hemm pawża fir-replikazzjoni, u wara sseħħ is-sessjoni ta 'skambju li jmiss, eċċ.);
  • jekk rekord inbidel diversi drabi, tista 'tittrasferixxi biss l-aħħar verżjoni tagħha (b'differenza mir-replikazzjoni ta' livell baxx, li fiha l-bidliet kollha li saru fuq il-kaptan jindaqqu lura b'mod sekwenzjali fuq ir-repliki).

2. M'hemm l-ebda diffikultajiet fl-implimentazzjoni tal-iskambju HTTP, li jippermettilek tissinkronizza databases remoti.

Replikazzjoni ta 'livell għoli f'Tarantool DBMS
Ross. 2. Replikazzjoni fuq HTTP

3. L-istrutturi tad-database li bejniethom tiġi trasferita d-dejta m'għandhomx għalfejn ikunu l-istess (barra minn hekk, fil-każ ġenerali, huwa saħansitra possibbli li jintużaw DBMSs, lingwi ta' programmar, pjattaformi, eċċ. differenti).

Replikazzjoni ta 'livell għoli f'Tarantool DBMS
Ross. 3. Replikazzjoni f'sistemi eteroġenji

L-iżvantaġġ huwa li, bħala medja, l-ipprogrammar huwa aktar diffiċli/jiswa aktar flus mill-konfigurazzjoni, u minflok ma tippersonalizza l-funzjonalità integrata, ikollok timplimenta tiegħek stess.

Jekk fis-sitwazzjoni tiegħek il-vantaġġi ta 'hawn fuq huma kruċjali (jew huma kundizzjoni meħtieġa), allura jagħmel sens li tuża replikazzjoni ta' livell għoli. Ejja nħarsu lejn diversi modi kif nimplimentaw replikazzjoni tad-dejta ta 'livell għoli fid-DBMS Tarantool.

Minimizzazzjoni tat-traffiku

Allura, wieħed mill-vantaġġi ta 'replikazzjoni ta' livell għoli huwa l-iffrankar tat-traffiku. Sabiex dan il-vantaġġ jiġi realizzat bis-sħiħ, huwa meħtieġ li jiġi minimizzat l-ammont ta 'dejta trasferita matul kull sessjoni ta' skambju. Naturalment, m'għandniex ninsew li fl-aħħar tas-sessjoni, ir-riċevitur tad-dejta għandu jkun sinkronizzat mas-sors (għall-inqas għal dik il-parti tad-dejta li hija involuta fir-replikazzjoni).

Kif timminimizza l-ammont ta 'dejta trasferita waqt replikazzjoni ta' livell għoli? Soluzzjoni sempliċi tista' tkun li tagħżel id-data skont id-data u l-ħin. Biex tagħmel dan, tista' tuża l-qasam tad-data-ħin li diġà teżisti fit-tabella (jekk teżisti). Pereżempju, dokument "ordni" jista' jkollu qasam "ħin meħtieġ ta' eżekuzzjoni tal-ordni" - delivery_time. Il-problema b'din is-soluzzjoni hija li l-valuri f'dan il-qasam m'għandhomx għalfejn ikunu fis-sekwenza li tikkorrispondi għall-ħolqien ta 'ordnijiet. Allura ma nistgħux niftakru l-valur massimu tal-qasam delivery_time, trażmessa matul is-sessjoni ta 'skambju preċedenti, u matul is-sessjoni ta' skambju li jmiss agħżel ir-rekords kollha b'valur ta 'field ogħla delivery_time. Rekords b'valur ta' kamp aktar baxx setgħu ġew miżjuda bejn sessjonijiet ta' skambju delivery_time. Ukoll, l-ordni setgħet għaddiet minn bidliet, li madankollu ma affettwawx il-qasam delivery_time. Fiż-żewġ każijiet, il-bidliet mhux se jiġu trasferiti mis-sors għad-destinazzjoni. Biex issolvi dawn il-problemi, ser ikollna bżonn li tittrasferixxi d-data "koinċidenza". Dawk. f'kull sessjoni ta 'skambju aħna se tittrasferixxi d-dejta kollha bil-valur tal-qasam delivery_time, jaqbeż xi punt fil-passat (per eżempju, N sigħat mill-mument attwali). Madankollu, huwa ovvju li għal sistemi kbar dan l-approċċ huwa superfluwi ħafna u jista 'jnaqqas l-iffrankar tat-traffiku li qed nistinkaw għalih għal xejn. Barra minn hekk, it-tabella li qed tiġi trasferita jista' ma jkollhax qasam assoċjat ma' data-ħin.

Soluzzjoni oħra, aktar kumplessa f'termini ta' implimentazzjoni, hija li tirrikonoxxi l-irċevuta tad-data. F'dan il-każ, matul kull sessjoni ta 'skambju, id-dejta kollha tiġi trażmessa, li l-wasla tagħha ma ġietx ikkonfermata mir-riċevitur. Biex timplimenta dan, ser ikollok bżonn iżżid kolonna Boolean mat-tabella tas-sors (per eżempju, is_transferred). Jekk ir-riċevitur jirrikonoxxi li rċieva r-rekord, il-qasam korrispondenti jieħu l-valur true, wara li d-dħul ma jibqax involut fi skambji. Din l-għażla ta 'implimentazzjoni għandha l-iżvantaġġi li ġejjin. L-ewwel, għal kull rekord trasferit, għandha tiġi ġġenerata u mibgħuta rikonoxximent. Bejn wieħed u ieħor, dan jista' jkun komparabbli mal-irduppjar tal-ammont ta' dejta trasferita u li jwassal għall-irduppjar tan-numru ta' vjaġġi bir-ritorn. It-tieni, m'hemm l-ebda possibbiltà li jintbagħat l-istess rekord lil diversi riċevituri (l-ewwel riċevitur li jirċievi jikkonferma l-irċevuta għalih innifsu u għall-oħrajn kollha).

Metodu li m'għandux l-iżvantaġġi mogħtija hawn fuq huwa li żżid kolonna mat-tabella trażmessa biex issegwi l-bidliet fir-ringieli tagħha. Kolonna bħal din tista' tkun tat-tip ta' data-ħin u għandha tiġi stabbilita/aġġornata mill-applikazzjoni għall-ħin kurrenti kull darba li r-rekords jiġu miżjuda/mibdula (atomikament biż-żieda/bidla). Bħala eżempju, ejja nsejħu l-kolonna update_time. Billi nsalvaw il-valur massimu tal-qasam ta' din il-kolonna għar-rekords trasferiti, nistgħu nibdew is-sessjoni ta' skambju li jmiss b'dan il-valur (agħżel ir-rekords bil-valur tal-qasam update_time, li jaqbeż il-valur maħżun qabel). Il-problema bl-approċċ tal-aħħar hija li l-bidliet fid-dejta jistgħu jseħħu f'lottijiet. Bħala riżultat tal-valuri tal-qasam fil-kolonna update_time jista 'ma jkunx uniku. Għalhekk, din il-kolonna ma tistax tintuża għall-ħruġ tad-dejta f'porzjonijiet (paġna b'paġna). Biex turi d-dejta paġna b’paġna, ser ikollok tivvinta mekkaniżmi addizzjonali li x’aktarx ikollhom effiċjenza baxxa ħafna (pereżempju, l-irkupru mid-database tar-rekords kollha bil-valur update_time ogħla minn waħda partikolari u li tipproduċi ċertu numru ta’ rekords, li jibdew minn ċertu offset mill-bidu tal-kampjun).

Tista 'ttejjeb l-effiċjenza tat-trasferiment tad-dejta billi ttejjeb kemmxejn l-approċċ preċedenti. Biex tagħmel dan, se nużaw it-tip ta 'numru sħiħ (numru sħiħ twil) bħala l-valuri tal-qasam tal-kolonna għat-traċċar tal-bidliet. Ejja nsemmu l-kolonna row_ver. Il-valur tal-field ta' din il-kolonna xorta jrid jiġi ssettjat/aġġornat kull darba li jinħoloq/immodifika rekord. Iżda f'dan il-każ, il-qasam mhux se jiġi assenjat id-data-ħin attwali, iżda l-valur ta 'xi counter, miżjud b'wieħed. Bħala riżultat, il-kolonna row_ver se jkun fih valuri uniċi u jista 'jintuża mhux biss biex juri dejta "delta" (dejta miżjuda/mibdula mit-tmiem tas-sessjoni ta' skambju preċedenti), iżda wkoll biex tinqasam f'paġni b'mod sempliċi u effettiv.

L-aħħar metodu propost biex jiġi minimizzat l-ammont ta 'dejta trasferita fil-qafas ta' replikazzjoni ta 'livell għoli jidhirli l-aktar ottimali u universali. Ejja nħarsu lejha f'aktar dettall.

Tgħaddi Dejta Bl-Użu ta' Kontr tal-Verżjoni ta' Ringiela

Implimentazzjoni tas-server/parti prinċipali

Fl-MS SQL Server, hemm tip ta 'kolonna speċjali biex timplimenta dan l-approċċ - rowversion. Kull database għandha counter li jiżdied b'wieħed kull darba li rekord jiġi miżjud/mibdul f'tabella li għandha kolonna simili rowversion. Il-valur ta' dan il-counter huwa awtomatikament assenjat lill-qasam ta' din il-kolonna fir-rekord miżjud/mibdul. It-Tarantool DBMS m'għandux mekkaniżmu simili inkorporat. Madankollu, f'Tarantool mhuwiex diffiċli li timplimentaha manwalment. Ejja nħarsu lejn kif dan isir.

L-ewwel, ftit terminoloġija: it-tabelli f'Tarantool jissejħu spazji, u r-rekords jissejħu tuples. F'Tarantool tista' toħloq sekwenzi. Is-sekwenzi huma xejn aktar minn ġeneraturi msemmija ta' valuri interi ordnati. Dawk. dan huwa eżattament dak li għandna bżonn għall-iskopijiet tagħna. Hawn taħt se noħolqu sekwenza bħal din.

Qabel ma twettaq kwalunkwe operazzjoni ta 'database f'Tarantool, għandek bżonn tmexxi l-kmand li ġej:

box.cfg{}

Bħala riżultat, Tarantool se jibda jikteb snapshots tad-database u reġistri tat-tranżazzjonijiet fid-direttorju attwali.

Ejja noħolqu sekwenza row_version:

box.schema.sequence.create('row_version',
    { if_not_exists = true })

Għażla if_not_exists jippermetti li l-iskript tal-ħolqien jiġi esegwit diversi drabi: jekk l-oġġett jeżisti, Tarantool mhux se jipprova jerġa' joħloq. Din l-għażla se tintuża fil-kmandi DDL sussegwenti kollha.

Ejja noħolqu spazju bħala eżempju.

box.schema.space.create('goods', {
    format = {
        {
            name = 'id',
            type = 'unsigned'

        },
        {
            name = 'name',
            type = 'string'

        },
        {
            name = 'code',
            type = 'unsigned'

        },
        {
            name = 'row_ver',
            type = 'unsigned'

        }
    },
    if_not_exists = true
})

Hawnhekk nissettjaw l-isem tal-ispazju (goods), ismijiet ta' oqsma u t-tipi tagħhom.

Oqsma awto-inkrementali f'Tarantool huma maħluqa wkoll bl-użu ta 'sekwenzi. Ejja noħolqu ċavetta primarja awto-inkrementata b'qasam id:

box.schema.sequence.create('goods_id',
    { if_not_exists = true })
box.space.goods:create_index('primary', {
    parts = { 'id' },
    sequence = 'goods_id',
    unique = true,
    type = 'HASH',
    if_not_exists = true
})

Tarantool jappoġġja diversi tipi ta 'indiċi. L-indiċijiet l-aktar użati huma tipi TREE u HASH, li huma bbażati fuq strutturi li jikkorrispondu għall-isem. TREE hija t-tip ta 'indiċi l-aktar versatili. Jippermettilek li tirkupra data b'mod organizzat. Iżda għall-għażla ta 'ugwaljanza, HASH huwa aktar adattat. Għaldaqstant, huwa rakkomandabbli li tuża HASH għaċ-ċavetta primarja (li huwa dak li għamilna).

Biex tuża l-kolonna row_ver biex tittrasferixxi dejta mibdula, għandek bżonn torbot il-valuri tas-sekwenza mal-oqsma ta 'din il-kolonna row_ver. Iżda b'differenza mill-ċavetta primarja, il-valur tal-qasam tal-kolonna row_ver għandha tiżdied b'wieħed mhux biss meta żżid rekords ġodda, iżda wkoll meta jinbidlu dawk eżistenti. Tista 'tuża triggers għal dan. Tarantool għandu żewġ tipi ta’ triggers spazjali: before_replace и on_replace. Triggers huma sparati kull meta d-dejta fl-ispazju tinbidel (għal kull tuple affettwat mill-bidliet, titnieda funzjoni ta 'grillu). B'differenza on_replace, before_replace-triggers jippermettulek timmodifika d-dejta tat-tuple li għaliha jiġi esegwit il-grillu. Għaldaqstant, l-aħħar tip ta’ triggers jixraq lilna.

box.space.goods:before_replace(function(old, new)
    return box.tuple.new({new[1], new[2], new[3],
        box.sequence.row_version:next()})
end)

Il-grillu li ġej jissostitwixxi l-valur tal-qasam row_ver tuple maħżun għall-valur li jmiss tas-sekwenza row_version.

Sabiex tkun tista 'tiġbed data mill-ispazju goods bil-kolonna row_ver, ejja noħolqu indiċi:

box.space.goods:create_index('row_ver', {
    parts = { 'row_ver' },
    unique = true,
    type = 'TREE',
    if_not_exists = true
})

Tip ta' indiċi - siġra (TREE), għax ikollna bżonn niġbdu d-dejta f'ordni axxendenti tal-valuri fil-kolonna row_ver.

Ejja nżidu xi dejta fl-ispazju:

box.space.goods:insert{nil, 'pen', 123}
box.space.goods:insert{nil, 'pencil', 321}
box.space.goods:insert{nil, 'brush', 100}
box.space.goods:insert{nil, 'watercolour', 456}
box.space.goods:insert{nil, 'album', 101}
box.space.goods:insert{nil, 'notebook', 800}
box.space.goods:insert{nil, 'rubber', 531}
box.space.goods:insert{nil, 'ruler', 135}

Għax L-ewwel qasam huwa kontro-inkrementazzjoni awtomatika; aħna ngħaddu nil minflok. Tarantool awtomatikament jissostitwixxi l-valur li jmiss. Bl-istess mod, bħala l-valur tal-oqsma tal-kolonna row_ver inti tista 'tgħaddi nil - jew ma tispeċifika l-valur fil-livelli kollha, għaliex din il-kolonna tokkupa l-aħħar pożizzjoni fl-ispazju.

Ejja niċċekkja r-riżultat tal-inserzjoni:

tarantool> box.space.goods:select()
---
- - [1, 'pen', 123, 1]
  - [2, 'pencil', 321, 2]
  - [3, 'brush', 100, 3]
  - [4, 'watercolour', 456, 4]
  - [5, 'album', 101, 5]
  - [6, 'notebook', 800, 6]
  - [7, 'rubber', 531, 7]
  - [8, 'ruler', 135, 8]
...

Kif tistgħu taraw, l-ewwel u l-aħħar oqsma jimtlew awtomatikament. Issa se jkun faċli li tikteb funzjoni għal uploading paġna b'paġna ta 'bidliet fl-ispazju goods:

local page_size = 5
local function get_goods(row_ver)
    local index = box.space.goods.index.row_ver
    local goods = {}
    local counter = 0
    for _, tuple in index:pairs(row_ver, {
        iterator = 'GT' }) do
        local obj = tuple:tomap({ names_only = true })
        table.insert(goods, obj)
        counter = counter + 1
        if counter >= page_size then
            break
        end
    end
    return goods
end

Il-funzjoni tieħu bħala parametru l-valur row_ver, li jibda minnu huwa meħtieġ li jinħatt il-bidliet, u jirritorna porzjon tad-dejta mibdula.

It-teħid ta' kampjuni tad-dejta f'Tarantool isir permezz ta' indiċi. Funzjoni get_goods juża iteratur bl-indiċi row_ver biex tirċievi data mibdula. It-tip iteratur huwa GT (Greater Than, akbar minn). Dan ifisser li l-iteratur se jaqsam b'mod sekwenzjali l-valuri tal-indiċi billi jibda miċ-ċavetta mgħoddija (valur tal-qasam row_ver).

L-iteratur jirritorna tuples. Sabiex sussegwentement tkun tista 'tittrasferixxi d-dejta permezz ta' HTTP, huwa meħtieġ li t-tuples jiġu kkonvertiti għal struttura konvenjenti għal serialization sussegwenti. L-eżempju juża l-funzjoni standard għal dan tomap. Minflok tuża tomap tista 'tikteb il-funzjoni tiegħek. Pereżempju, nistgħu rridu nbiddlu isem qasam name, tgħaddix l-għalqa code u żid qasam comment:

local function unflatten_goods(tuple)
    local obj = {}
    obj.id = tuple.id
    obj.goods_name = tuple.name
    obj.comment = 'some comment'
    obj.row_ver = tuple.row_ver
    return obj
end

Id-daqs tal-paġna tad-dejta tal-ħruġ (in-numru ta 'rekords f'porzjon wieħed) huwa determinat mill-varjabbli page_size. Fl-eżempju l-valur page_size huwa 5. Fi programm reali, id-daqs tal-paġna ġeneralment ikun importanti aktar. Jiddependi fuq id-daqs medju tat-tuple spazjali. Id-daqs ottimali tal-paġna jista' jiġi determinat empirikament billi jitkejjel il-ħin tat-trasferiment tad-dejta. Iktar ma jkun kbir id-daqs tal-paġna, iżgħar in-numru ta 'roundtrips bejn in-naħat li jibgħat u dak li jirċievi. Dan il-mod tista 'tnaqqas il-ħin ġenerali għat-tniżżil tal-bidliet. Madankollu, jekk id-daqs tal-paġna huwa kbir wisq, aħna se nqattgħu wisq żmien fuq is-server serializing il-kampjun. Bħala riżultat, jista 'jkun hemm dewmien fl-ipproċessar ta' talbiet oħra li jaslu lis-server. Parametru page_size jistgħu jitgħabbew mill-fajl tal-konfigurazzjoni. Għal kull spazju trażmess, tista 'tissettja l-valur tagħha stess. Madankollu, għall-biċċa l-kbira tal-ispazji l-valur default (per eżempju, 100) jista 'jkun adattat.

Ejja tesegwixxi l-funzjoni get_goods:

tarantool> get_goods(0)

---
- - row_ver: 1
    code: 123
    name: pen
    id: 1
  - row_ver: 2
    code: 321
    name: pencil
    id: 2
  - row_ver: 3
    code: 100
    name: brush
    id: 3
  - row_ver: 4
    code: 456
    name: watercolour
    id: 4
  - row_ver: 5
    code: 101
    name: album
    id: 5
...

Ejja nieħdu l-valur tal-qasam row_ver mill-aħħar linja u sejjaħ il-funzjoni mill-ġdid:

tarantool> get_goods(5)

---
- - row_ver: 6
    code: 800
    name: notebook
    id: 6
  - row_ver: 7
    code: 531
    name: rubber
    id: 7
  - row_ver: 8
    code: 135
    name: ruler
    id: 8
...

Għal darb'oħra:

tarantool> get_goods(8)
---
- []
...

Kif tistgħu taraw, meta tintuża b'dan il-mod, il-funzjoni tirritorna r-rekords tal-ispazju kollha paġna b'paġna goods. L-aħħar paġna hija segwita minn għażla vojta.

Ejja nagħmlu bidliet fl-ispazju:

box.space.goods:update(4, {{'=', 6, 'copybook'}})
box.space.goods:insert{nil, 'clip', 234}
box.space.goods:insert{nil, 'folder', 432}

Bdilna l-valur tal-qasam name għal daħla waħda u żied żewġ entrati ġodda.

Ejja nirrepetu l-aħħar sejħa tal-funzjoni:

tarantool> get_goods(8)
---



- - row_ver: 9
    code: 800
    name: copybook
    id: 6
  - row_ver: 10
    code: 234
    name: clip
    id: 9
  - row_ver: 11
    code: 432
    name: folder
    id: 10
...

Il-funzjoni rritornat ir-rekords mibdula u miżjuda. Allura l-funzjoni get_goods jippermettilek tirċievi data li nbidlet mill-aħħar sejħa tagħha, li hija l-bażi tal-metodu ta 'replikazzjoni li qed jiġi kkunsidrat.

Aħna se nħallu l-ħruġ ta 'riżultati permezz HTTP fil-forma ta' JSON barra mill-ambitu ta 'dan l-artikolu. Tista' taqra dwar dan hawn: https://habr.com/ru/company/mailru/blog/272141/

Implimentazzjoni tal-parti klijent/slave

Ejja nħarsu lejn kif tidher l-implimentazzjoni tan-naħa li tirċievi. Ejja noħolqu spazju fuq in-naħa li tirċievi biex taħżen id-dejta mniżżla:

box.schema.space.create('goods', {
    format = {
        {
            name = 'id',
            type = 'unsigned'

        },
        {
            name = 'name',
            type = 'string'

        },
        {
            name = 'code',
            type = 'unsigned'

        }
    },
    if_not_exists = true
})

box.space.goods:create_index('primary', {
    parts = { 'id' },
    sequence = 'goods_id',
    unique = true,
    type = 'HASH',
    if_not_exists = true
})

L-istruttura tal-ispazju tixbaħ l-istruttura tal-ispazju fis-sors. Imma peress li m'aħniex se ngħaddu d-data riċevuta imkien ieħor, il-kolonna row_ver mhix fl-ispazju tar-riċevitur. Fil-għalqa id se jiġu rreġistrati l-identifikaturi tas-sors. Għalhekk, min-naħa tar-riċevitur m'hemmx bżonn li tagħmilha awto-inkrementali.

Barra minn hekk, għandna bżonn spazju biex insalvaw il-valuri row_ver:

box.schema.space.create('row_ver', {
    format = {
        {
            name = 'space_name',
            type = 'string'

        },
        {
            name = 'value',
            type = 'string'

        }
    },
    if_not_exists = true
})

box.space.row_ver:create_index('primary', {
    parts = { 'space_name' },
    unique = true,
    type = 'HASH',
    if_not_exists = true
})

Għal kull spazju mgħobbi (field space_name) aħna se nissejvja l-aħħar valur mgħobbi hawn row_ver (qasam value). Il-kolonna taġixxi bħala ċ-ċavetta primarja space_name.

Ejja noħolqu funzjoni biex tagħbija data tal-ispazju goods permezz HTTP. Biex nagħmlu dan, għandna bżonn librerija li timplimenta klijent HTTP. Il-linja li ġejja tgħabbi l-librerija u tagħti istanzija lill-klijent HTTP:

local http_client = require('http.client').new()

Għandna bżonn ukoll librerija għad-deserialization json:

local json = require('json')

Dan huwa biżżejjed biex tinħoloq funzjoni tat-tagħbija tad-dejta:

local function load_data(url, row_ver)
    local url = ('%s?rowVer=%s'):format(url,
        tostring(row_ver))
    local body = nil
    local data = http_client:request('GET', url, body, {
        keepalive_idle =  1,
        keepalive_interval = 1
    })
    return json.decode(data.body)
end

Il-funzjoni tesegwixxi talba HTTP lill-indirizz url u tibgħatha row_ver bħala parametru u jirritorna r-riżultat deserialized tat-talba.

Il-funzjoni biex tissejvja d-dejta riċevuta tidher bħal din:

local function save_goods(goods)
    local n = #goods
    box.atomic(function()
        for i = 1, n do
            local obj = goods[i]
            box.space.goods:put(
                obj.id, obj.name, obj.code)
        end
    end)
end

Ċiklu ta 'ffrankar ta' data fl-ispazju goods jitqiegħed fi tranżazzjoni (il-funzjoni tintuża għal dan box.atomic) biex jitnaqqas in-numru ta 'operazzjonijiet tad-disk.

Fl-aħħarnett, il-funzjoni tas-sinkronizzazzjoni tal-ispazju lokali goods b'sors tista' timplimentah hekk:

local function sync_goods()
    local tuple = box.space.row_ver:get('goods')
    local row_ver = tuple and tuple.value or 0

    —— set your url here:
    local url = 'http://127.0.0.1:81/test/goods/list'

    while true do
        local goods = load_goods(url, row_ver)

        local count = #goods
        if count == 0 then
            return
        end

        save_goods(goods)

        row_ver = goods[count].rowVer
        box.space.row_ver:put({'goods', row_ver})
    end
end

L-ewwel naqraw il-valur salvat qabel row_ver għall-ispazju goods. Jekk tkun nieqsa (l-ewwel sessjoni ta 'skambju), allura nieħduha bħala row_ver żero. Sussegwentement fiċ-ċiklu nagħmlu download paġna b'paġna tad-dejta mibdula mis-sors fl-url speċifikat. F'kull iterazzjoni, aħna nissejvjaw id-dejta riċevuta fl-ispazju lokali xieraq u naġġornaw il-valur row_ver (fl-ispazju row_ver u fil-varjabbli row_ver) - ħu l-valur row_ver mill-aħħar linja tad-dejta mgħobbija.

Biex tipproteġi kontra looping aċċidentali (f'każ ta 'żball fil-programm), il-linja while jistgħu jiġu sostitwiti minn for:

for _ = 1, max_req do ...

Bħala riżultat ta 'eżekuzzjoni tal-funzjoni sync_goods spazju goods ir-riċevitur ikun fih l-aħħar verżjonijiet tar-rekords spazjali kollha goods fis-sors.

Ovvjament, it-tħassir tad-dejta ma jistax jixxandar b'dan il-mod. Jekk teżisti tali ħtieġa, tista' tuża marka ta' tħassir. Żid mal-ispazju goods qasam boolean is_deleted u minflok ma nħassru fiżikament rekord, nużaw tħassir loġiku - nissettjaw il-valur tal-qasam is_deleted fis-sens true. Xi drabi minflok qasam boolean is_deleted huwa aktar konvenjenti li tuża l-qasam deleted, li jaħżen id-data-ħin tat-tħassir loġiku tar-rekord. Wara li twettaq tħassir loġiku, ir-rekord immarkat għat-tħassir jiġi trasferit mis-sors għad-destinazzjoni (skond il-loġika diskussa hawn fuq).

Sekwenza row_ver jistgħu jintużaw biex jittrasmettu data minn spazji oħra: m'hemmx bżonn li tinħoloq sekwenza separata għal kull spazju trażmess.

Ħarsa lejn mod effettiv ta 'replikazzjoni ta' dejta ta 'livell għoli f'applikazzjonijiet li jużaw it-Tarantool DBMS.

Sejbiet

  1. Tarantool DBMS huwa prodott attraenti u promettenti għall-ħolqien ta 'applikazzjonijiet ta' tagħbija għolja.
  2. Replikazzjoni tad-dejta ta 'livell għoli għandha numru ta' vantaġġi fuq replikazzjoni ta 'livell baxx.
  3. Il-metodu ta 'replikazzjoni ta' livell għoli diskuss fl-artikolu jippermettilek li timminimizza l-ammont ta 'dejta trasferita billi tittrasferixxi biss dawk ir-rekords li nbidlu mill-aħħar sessjoni ta' skambju.

Sors: www.habr.com

Żid kumment