Kõrgetasemeline replikatsioon Tarantooli DBMS-is

Tere, ma loon rakendusi DBMS-i jaoks Tarantool on Mail.ru Groupi välja töötatud platvorm, mis ühendab endas suure jõudlusega DBMS-i ja rakendusserveri Lua keeles. Tarantoolil põhinevate lahenduste suur kiirus saavutatakse eelkõige tänu DBMS-i mälusisese režiimi toele ja võimalusele täita rakenduse äriloogikat ühes andmetega aadressiruumis. Samas on andmete püsivus tagatud ACID tehingute abil (kettal peetakse WAL logi). Tarantoolil on sisseehitatud replikatsiooni ja killustamise tugi. Alates versioonist 2.1 toetatakse SQL-i keeles päringuid. Tarantool on avatud lähtekoodiga ja litsentsitud lihtsustatud BSD litsentsi alusel. Samuti on olemas kommertsversioon Enterprise.

Kõrgetasemeline replikatsioon Tarantooli DBMS-is
Tundke jõudu! (… ehk naudi etendust)

Kõik eelnev muudab Tarantooli atraktiivseks platvormiks andmebaasidega töötavate suure koormusega rakenduste loomiseks. Sellistes rakendustes on sageli vajadus andmete replikatsiooni järele.

Nagu eespool mainitud, on Tarantoolil sisseehitatud andmete replikatsioon. Selle toimimise põhimõte on sooritada koopiates järjestikku kõik põhilogis (WAL) sisalduvad tehingud. Tavaliselt selline replikatsioon (nimetame seda edasi madalal tasemel) kasutatakse rakenduse veataluvuse tagamiseks ja/või lugemiskoormuse jaotamiseks klastri sõlmede vahel.

Kõrgetasemeline replikatsioon Tarantooli DBMS-is
Riis. 1. Replikatsioon klastris

Alternatiivse stsenaariumi näide oleks ühes andmebaasis loodud andmete ülekandmine töötlemiseks/seireks teise andmebaasi. Viimasel juhul võib mugavam lahendus olla kasutamine kõrge tase replikatsioon – andmete replikatsioon rakenduse äriloogika tasemel. Need. Me ei kasuta DBMS-i sisseehitatud valmislahendust, vaid rakendame arendatava rakenduse sees replikatsiooni iseseisvalt. Sellel lähenemisviisil on nii eeliseid kui ka puudusi. Loetleme eelised.

1. Liikluse kokkuhoid:

  • Te ei saa edastada kõiki andmeid, vaid ainult osa neist (näiteks saate edastada ainult mõned tabelid, mõned nende veerud või kirjed, mis vastavad teatud kriteeriumile);
  • Erinevalt madala taseme replikatsioonist, mida teostatakse pidevalt asünkroonses (rakendatud Tarantooli praeguses versioonis - 1.10) või sünkroonses (rakendatud Tarantooli järgmistes versioonides) režiimis, saab kõrgetasemelist replikatsiooni teostada seansside kaupa (st rakendus sünkroonib esmalt andmed – vahetusseansi andmed, seejärel tekib replikatsioonis paus, mille järel toimub järgmine vahetusseanss jne);
  • kui kirjet on mitu korda muudetud, saate üle kanda ainult selle uusima versiooni (erinevalt madala taseme replikatsioonist, kus kõik põhifailis tehtud muudatused esitatakse koopiatel järjestikku).

2. HTTP-vahetuse juurutamine, mis võimaldab sünkroonida kaugandmebaase, ei tekita raskusi.

Kõrgetasemeline replikatsioon Tarantooli DBMS-is
Riis. 2. Replikatsioon HTTP kaudu

3. Andmebaasistruktuurid, mille vahel andmeid edastatakse, ei pea olema samad (pealegi on üldjuhul võimalik kasutada isegi erinevaid DBMS-e, programmeerimiskeeli, platvorme jne).

Kõrgetasemeline replikatsioon Tarantooli DBMS-is
Riis. 3. Replikatsioon heterogeensetes süsteemides

Negatiivne külg on see, et programmeerimine on keskmiselt keerulisem/kulukam kui konfigureerimine ning sisseehitatud funktsionaalsuse kohandamise asemel tuleb ise juurutada.

Kui teie olukorras on ülaltoodud eelised üliolulised (või on vajalik tingimus), siis on mõistlik kasutada kõrgetasemelist replikatsiooni. Vaatame mitmeid viise kõrgetasemelise andmete replikatsiooni rakendamiseks Tarantool DBMS-is.

Liikluse minimeerimine

Seega on üks kõrgetasemelise replikatsiooni eeliseid liikluse kokkuhoid. Selle eelise täielikuks realiseerimiseks on vaja minimeerida iga vahetusseansi jooksul edastatavate andmete hulka. Muidugi ei tasu unustada, et seansi lõpus tuleb andmevastuvõtja sünkroniseerida allikaga (vähemalt selle osa andmete puhul, mis on seotud replikatsiooniga).

Kuidas minimeerida kõrgetasemelise replikatsiooni käigus edastatavate andmete hulka? Lihtne lahendus võiks olla andmete valimine kuupäeva ja kellaaja järgi. Selleks saab kasutada tabelis juba olemasolevat kuupäeva-kellaaja välja (kui see on olemas). Näiteks võib "tellimuse" dokumendil olla väli "nõutav tellimuse täitmise aeg" - delivery_time. Selle lahenduse probleem seisneb selles, et selle välja väärtused ei pea olema järjekorras, mis vastab tellimuste loomisele. Seega me ei mäleta välja maksimaalset väärtust delivery_time, mis edastati eelmise vahetusseansi ajal, ja valige järgmise vahetusseansi ajal kõik kõrgema väljaväärtusega kirjed delivery_time. Vahetusseansside vahel võib olla lisatud madalama väljaväärtusega kirjeid delivery_time. Samuti võis järjekord läbi viia muudatusi, mis siiski väljakut ei puudutanud delivery_time. Mõlemal juhul ei kanta muudatusi allikast sihtkohta. Nende probleemide lahendamiseks peame edastama andmed "kattuvad". Need. igal vahetusseansil edastame kõik andmed koos välja väärtusega delivery_time, ületades mõnda minevikupunkti (näiteks N tundi praegusest hetkest). Siiski on ilmne, et suurte süsteemide puhul on see lähenemisviis väga üleliigne ja võib vähendada liikluse kokkuhoidu, mille poole püüdleme. Lisaks ei pruugi teisaldataval tabelis olla välja, mis on seotud kuupäeva ja kellaajaga.

Teine lahendus, mis on rakendamise poolest keerulisem, on andmete vastuvõtmise kinnitamine. Sellisel juhul edastatakse iga vahetusseansi ajal kõik andmed, mille kättesaamist ei ole saaja kinnitanud. Selle rakendamiseks peate lähtetabelisse lisama Boole'i ​​veeru (näiteks is_transferred). Kui vastuvõtja kinnitab kirje kättesaamist, võtab vastav väli väärtuse true, mille järel kanne enam vahetustega ei osale. Sellel rakendusvalikul on järgmised puudused. Esiteks tuleb iga ülekantud kirje kohta genereerida ja saata kinnitus. Jämedalt öeldes võib see olla võrreldav edastatavate andmete kahekordistamisega ja edasi-tagasi reiside arvu kahekordistamisega. Teiseks puudub võimalus saata sama kirjet mitmele vastuvõtjale (esimene vastuvõtja kinnitab kättesaamise nii endale kui ka kõigile teistele).

Meetod, millel pole ülaltoodud puudusi, on veeru lisamine ülekantud tabelisse, et jälgida selle ridade muutusi. Selline veerg võib olla kuupäeva ja kellaaja tüüpi ning seda peab rakendus seadistama/värskendama praegusele kellaajale iga kord, kui kirjeid lisatakse/muuttakse (koos lisamise/muudatusega). Näitena nimetame veergu update_time. Salvestades selle veeru maksimaalse väljaväärtuse ülekantud kirjete jaoks, saame alustada järgmist vahetusseanssi selle väärtusega (valige välja väärtusega kirjed update_time, ületades varem salvestatud väärtuse). Viimase lähenemisviisi probleem seisneb selles, et andmete muutmine võib toimuda partiidena. Veerus olevate välja väärtuste tulemusena update_time ei pruugi olla ainulaadne. Seega ei saa seda veergu kasutada jaotatud (lehekülgede kaupa) andmete väljastamiseks. Andmete kuvamiseks lehekülgede kaupa peate leiutama lisamehhanisme, millel on tõenäoliselt väga madal efektiivsus (näiteks kõigi väärtusega kirjete otsimine andmebaasist update_time kõrgem kui antud ja toodab teatud arvu kirjeid, alustades teatud nihkest valimi algusest).

Andmeedastuse tõhusust saate parandada, kui eelmist lähenemist pisut täiustada. Selleks kasutame muudatuste jälgimiseks veeruvälja väärtustena täisarvu tüüpi (pikk täisarv). Paneme veerule nime row_ver. Selle veeru välja väärtust tuleb ikkagi määrata/värskendada iga kord, kui kirje luuakse/muuttakse. Kuid sel juhul ei omistata väljale praegust kuupäeva-kellaaega, vaid mõne loenduri väärtust, mida suurendatakse ühe võrra. Selle tulemusena veerg row_ver sisaldab unikaalseid väärtusi ja seda saab kasutada mitte ainult "delta" andmete kuvamiseks (andmed on lisatud/muudetud alates eelmise vahetusseansi lõpust), vaid ka lihtsalt ja tõhusalt lehtedeks jaotamiseks.

Viimane pakutud meetod kõrgetasemelise replikatsiooni raames edastatavate andmete hulga minimeerimiseks tundub mulle kõige optimaalsem ja universaalsem. Vaatame seda üksikasjalikumalt.

Andmete edastamine reaversioonide loenduri abil

Serveri/peaosa juurutamine

MS SQL Serveris on selle lähenemisviisi rakendamiseks spetsiaalne veerutüüp - rowversion. Igal andmebaasil on loendur, mis suureneb ühe võrra iga kord, kui kirje lisatakse/muuttakse tabelis, millel on veerg nagu rowversion. Selle loenduri väärtus määratakse lisatud/muudetud kirjes automaatselt selle veeru väljale. Tarantooli DBMS-il pole sarnast sisseehitatud mehhanismi. Tarantoolis pole seda aga käsitsi keeruline rakendada. Vaatame, kuidas seda tehakse.

Esiteks natuke terminoloogiat: Tarantooli tabeleid nimetatakse tühikuteks ja kirjeid korteežideks. Tarantoolis saate luua järjestusi. Jadad pole midagi muud kui järjestatud täisarvude väärtuste nimelised generaatorid. Need. see on täpselt see, mida me oma eesmärkide saavutamiseks vajame. Allpool loome sellise jada.

Enne mis tahes andmebaasitoimingu sooritamist Tarantoolis peate käivitama järgmise käsu:

box.cfg{}

Selle tulemusena hakkab Tarantool kirjutama praegusesse kataloogi andmebaasi hetktõmmiseid ja tehingulogisid.

Loome järjestuse row_version:

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

Variant if_not_exists võimaldab luua skripti mitu korda: kui objekt on olemas, ei proovi Tarantool seda uuesti luua. Seda suvandit kasutatakse kõigis järgnevates DDL-käskudes.

Loome näitena ruumi.

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
})

Siin määrame ruumi nime (goods), väljade nimed ja tüübid.

Tarantooli automaatse suurendamise väljad luuakse ka järjestuste abil. Loome väljade kaupa automaatselt suureneva primaarvõtme 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 toetab mitut tüüpi indekseid. Enim kasutatavad indeksid on TREE ja HASH tüübid, mis põhinevad nimele vastavatel struktuuridel. PUU on kõige mitmekülgsem indeksitüüp. See võimaldab teil andmeid organiseeritud viisil hankida. Kuid võrdseks valikuks sobib HASH paremini. Sellest lähtuvalt on soovitatav kasutada primaarvõtme jaoks HASH-i (mida me ka tegime).

Veeru kasutamiseks row_ver muudetud andmete edastamiseks peate selle veeru väljadele siduma järjestuse väärtused row_ver. Kuid erinevalt primaarvõtmest on veeru välja väärtus row_ver peaks suurenema ühe võrra mitte ainult uute kirjete lisamisel, vaid ka olemasolevate muutmisel. Selleks saate kasutada käivitajaid. Tarantoolil on kahte tüüpi ruumipäästikuid: before_replace и on_replace. Päästikud käivitatakse alati, kui ruumis olevad andmed muutuvad (iga muudatustest mõjutatud korteeži jaoks käivitatakse trigeri funktsioon). Erinevalt on_replace, before_replace-triggerid võimaldavad teil muuta selle korteeži andmeid, mille jaoks triger käivitatakse. Sellest lähtuvalt sobivad meile viimast tüüpi päästikud.

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

Järgmine päästik asendab välja väärtuse row_ver salvestatud korteež jada järgmisele väärtusele row_version.

Et oleks võimalik kosmosest andmeid välja tõmmata goods veeru järgi row_ver, loome indeksi:

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

Indeksi tüüp - puu (TREE), sest peame eraldama andmed veerus olevate väärtuste kasvavas järjekorras row_ver.

Lisame ruumi mõned andmed:

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}

Sest Esimene väli on automaatselt suurenev loendur; selle asemel edastame nulli. Tarantool asendab automaatselt järgmise väärtuse. Samamoodi veeruväljade väärtusena row_ver võite jätta nulli või jätta väärtuse määramata, sest see veerg on ruumi viimasel kohal.

Kontrollime sisestamise tulemust:

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]
...

Nagu näete, täidetakse esimene ja viimane väli automaatselt. Nüüd on lihtne kirjutada funktsiooni ruumimuudatuste lehekülgede kaupa üleslaadimiseks 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

Funktsioon võtab parameetrina väärtuse row_ver, millest alates on vaja muudatused maha laadida, ja tagastab osa muudetud andmetest.

Andmeproovide võtmine Tarantoolis toimub indeksite kaudu. Funktsioon get_goods kasutab indeksi järgi iteraatorit row_ver muudetud andmete vastuvõtmiseks. Iteraatori tüüp on GT (suurem kui, suurem kui). See tähendab, et iteraator läbib järjestikku indeksi väärtusi alates edasi antud võtmest (välja väärtus row_ver).

Iteraator tagastab kordused. Selleks, et hiljem oleks võimalik andmeid HTTP kaudu edastada, on vaja kortereid teisendada järgnevaks serialiseerimiseks sobivaks struktuuriks. Näidis kasutab selleks standardfunktsiooni tomap. Kasutamise asemel tomap saate kirjutada oma funktsiooni. Näiteks võiksime välja nimetada ümber name, ärge läbige põldu code ja lisage väli 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

Väljundandmete lehekülje suurus (kirjete arv ühes osas) määratakse muutujaga page_size. Näites väärtus page_size on 5. Reaalses programmis loeb lehe suurus tavaliselt rohkem. See sõltub ruumikorpuse keskmisest suurusest. Optimaalse lehe suuruse saab määrata empiiriliselt, mõõtes andmeedastusaega. Mida suurem on lehe suurus, seda väiksem on edasi-tagasi reiside arv saatva ja vastuvõtva poole vahel. Nii saate muudatuste allalaadimiseks kuluvat üldist aega lühendada. Kui aga lehe suurus on liiga suur, kulutame liiga kaua proovi serialiseerimisele. Selle tulemusena võib esineda viivitusi muude serverisse saabuvate päringute töötlemisel. Parameeter page_size saab laadida konfiguratsioonifailist. Iga edastatava ruumi jaoks saate määrata oma väärtuse. Enamiku tühikute jaoks võib vaikeväärtus (näiteks 100) siiski sobida.

Teostame funktsiooni 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
...

Võtame välja väärtuse row_ver viimaselt realt ja kutsuge funktsioon uuesti:

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

Veel kord:

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

Nagu näete, tagastab funktsioon sel viisil kasutamisel kõik ruumikirjed lehekülgede kaupa goods. Viimasele lehele järgneb tühi valik.

Teeme ruumis muudatusi:

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

Oleme muutnud välja väärtust name ühe kirje jaoks ja lisas kaks uut kirjet.

Kordame viimast funktsioonikutset:

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

Funktsioon tagastas muudetud ja lisatud kirjed. Seega funktsioon get_goods võimaldab vastu võtta andmeid, mis on muutunud pärast viimast kõnet, mis on vaadeldava replikatsioonimeetodi aluseks.

Jätame tulemuste väljastamise HTTP kaudu JSON-vormingus käesoleva artikli reguleerimisalast välja. Selle kohta saad lugeda siit: https://habr.com/ru/company/mailru/blog/272141/

Kliendi/orja osa rakendamine

Vaatame, kuidas vastuvõtva poole rakendamine välja näeb. Loome vastuvõtvale poolele allalaaditud andmete salvestamiseks ruumi:

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
})

Ruumi struktuur sarnaneb allikas oleva ruumi struktuuriga. Aga kuna me ei kavatse saadud andmeid mujale edastada, siis veerg row_ver ei ole saaja ruumis. Põllul id allika identifikaatorid salvestatakse. Seetõttu pole vastuvõtja poolel vaja seda automaatselt suurendada.

Lisaks vajame ruumi väärtuste salvestamiseks 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
})

Iga laaditud ruumi kohta (väli space_name) salvestame siia viimati laaditud väärtuse row_ver (väli value). Veerg toimib esmase võtmena space_name.

Loome funktsiooni ruumiandmete laadimiseks goods HTTP kaudu. Selleks vajame teeki, mis rakendab HTTP-klienti. Järgmine rida laadib raamatukogu ja loob HTTP-kliendi:

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

Vajame ka jsoni deserialiseerimiseks teeki:

local json = require('json')

Sellest piisab andmete laadimise funktsiooni loomiseks:

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

Funktsioon täidab URL-i aadressile HTTP-päringu ja saadab selle row_ver parameetrina ja tagastab päringu deserialiseeritud tulemuse.

Vastuvõetud andmete salvestamise funktsioon näeb välja järgmine:

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

Andmete ruumi salvestamise tsükkel goods paigutatakse tehingusse (selleks kasutatakse funktsiooni box.atomic), et vähendada kettatoimingute arvu.

Lõpuks kohaliku ruumi sünkroonimise funktsioon goods allikaga saate seda rakendada järgmiselt:

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

Kõigepealt loeme eelnevalt salvestatud väärtuse row_ver ruumi pärast goods. Kui see puudub (esimene vahetusseanss), siis võtame seda kui row_ver null. Järgmisena laadime tsüklis muudetud andmed lehekülgede kaupa alla määratud URL-i allikast. Igal iteratsioonil salvestame saadud andmed vastavasse lokaalsesse ruumi ja värskendame väärtust row_ver (kosmoses row_ver ja muutujas row_ver) – võtke väärtus row_ver laetud andmete viimaselt realt.

Juhusliku silmuse eest kaitsmiseks (programmis esineva vea korral) loop while saab asendada for:

for _ = 1, max_req do ...

Funktsiooni täitmise tulemusena sync_goods ruumi goods vastuvõtja sisaldab kõigi kosmosekirjete uusimaid versioone goods allikas.

Ilmselgelt ei saa andmete kustutamist sel viisil edastada. Kui selline vajadus on olemas, võite kasutada kustutamismärki. Lisa ruumi goods boolean väli is_deleted ja kirje füüsilise kustutamise asemel kasutame loogilist kustutamist – määrame välja väärtuse is_deleted tähendusse true. Mõnikord Boolean välja asemel is_deleted mugavam on põldu kasutada deleted, mis salvestab kirje loogilise kustutamise kuupäeva-kellaaja. Pärast loogilise kustutamise sooritamist kantakse kustutamiseks märgitud kirje allikast sihtkohta (vastavalt ülalpool käsitletud loogikale).

Järjestus row_ver saab kasutada andmete edastamiseks teistest ruumidest: iga edastatava ruumi jaoks pole vaja luua eraldi jada.

Vaatasime tõhusat viisi kõrgetasemeliseks andmete replikatsiooniks rakendustes, mis kasutavad Tarantool DBMS-i.

Järeldused

  1. Tarantool DBMS on atraktiivne ja paljutõotav toode suure koormusega rakenduste loomiseks.
  2. Kõrgetasemelisel andmete replikatsioonil on madala tasemega võrreldes mitmeid eeliseid.
  3. Artiklis käsitletud kõrgetasemeline replikatsioonimeetod võimaldab minimeerida ülekantavate andmete hulka, edastades ainult need kirjed, mis on muutunud pärast viimast vahetusseanssi.

Allikas: www.habr.com

Lisa kommentaar