Hallo, ek bou toepassings vir DBMS is 'n platform wat ontwikkel is deur Mail.ru Group wat 'n hoëprestasie-DBMS en 'n toepassingsbediener in die Lua-taal kombineer. Die hoë spoed van Tarantool-gebaseerde oplossings word veral bereik deur die in-geheue DBMS-modus te ondersteun en die vermoë om die toepassing se besigheidslogika in 'n enkele adresruimte met die data uit te voer. Terselfdertyd word databestendigheid verseker deur gebruik te maak van ACID-transaksies ('n WAL-log word op die skyf gehou). Tarantool het ingeboude ondersteuning vir replikasie en versplintering. Vanaf weergawe 2.1 word SQL-navrae ondersteun. Tarantool is oopbron en versprei onder die Simplified BSD-lisensie. Daar is ook 'n kommersiële Enterprise weergawe.

Voel die krag! (…oftewel geniet die optrede)
Al die bogenoemde maak Tarantool 'n aantreklike platform vir die skep van hoëlading databasistoepassings. In sulke toepassings is daar dikwels 'n behoefte om data te repliseer.
Soos hierbo genoem, het Tarantool ingeboude data-replikasie. Die beginsel van die werking daarvan is die opeenvolgende uitvoering van alle transaksies vervat in die meesterlogboek (WAL) op replikas. Tipies, so 'n replikasie (ons sal daarna verwys as lae vlak) word gebruik om fouttoleransie vir die toepassing te verskaf en/of om die leeslading tussen die nodusse van die groepie te versprei.

Rys. 1. Replikasie binne 'n groepering
'n Voorbeeld van 'n alternatiewe scenario sou wees om data wat in een databasis geskep is na 'n ander databasis oor te dra vir verwerking/monitering. In laasgenoemde geval kan 'n geriefliker oplossing wees om te gebruik hoë vlak replikasie - data replikasie op die vlak van toepassing besigheid logika. Dié. ons gebruik nie 'n klaargemaakte oplossing wat in die DBBS ingebou is nie, maar implementeer replikasie binne die toepassing wat ons op ons eie ontwikkel. Hierdie benadering het beide voordele en nadele. Kom ons lys die voordele.
1. Verkeerbesparing:
- jy kan nie alle data oordra nie, maar slegs 'n deel daarvan (byvoorbeeld, jy kan net sommige tabelle, sommige van hul kolomme of rekords wat aan 'n sekere kriterium voldoen, oordra);
- anders as laevlak-replikasie, wat deurlopend in asinchrone (geïmplementeer in die huidige weergawe van Tarantool - 1.10) of sinchrone (om in toekomstige weergawes van Tarantool geïmplementeer te word) modus uitgevoer word, kan hoëvlakreplikasie deur sessies uitgevoer word (d.w.s. die toepassing voer eers datasinchronisasie uit - 'n uitruilsessiedata, dan is daar 'n pouse in replikasie, waarna die volgende uitruilsessie plaasvind, ens.);
- as 'n rekord verskeie kere verander het, kan slegs die nuutste weergawe daarvan oorgedra word (in teenstelling met laevlak-replikasie, waarin alle veranderinge wat op die meester gemaak word, opeenvolgend op die replikas gespeel sal word).
2. Daar is geen probleme met die implementering van die uitruil via HTTP nie, wat jou toelaat om afgeleë databasisse te sinchroniseer.

Rys. 2. HTTP-replikasie
3. Die databasisstrukture waartussen data oorgedra word hoef nie dieselfde te wees nie (buitendien is dit in die algemene geval selfs moontlik om verskillende DBBS, programmeertale, platforms, ens. te gebruik).

Rys. 3. Replikasie in heterogene sisteme
Die nadeel is dat programmering gemiddeld moeiliker/duurder is as konfigurasie, en in plaas daarvan om die ingeboude funksionaliteit aan te pas, sal jy jou eie moet implementeer.
As die bogenoemde pluspunte in jou situasie 'n deurslaggewende rol speel (of 'n noodsaaklike voorwaarde is), dan maak dit sin om hoëvlak-replikasie te gebruik. Kom ons oorweeg verskeie maniere om hoëvlak data-replikasie in die Tarantool DBMS te implementeer.
Verkeer minimalisering
Dus, een van die voordele van hoëvlak-replikasie is verkeersbesparings. Om hierdie voordeel ten volle te manifesteer, is dit nodig om die hoeveelheid data wat tydens elke uitruilsessie oorgedra word, te verminder. Natuurlik moet mens nie vergeet dat die data-ontvanger aan die einde van die sessie met die bron gesinchroniseer moet word nie (ten minste in terme van die deel van die data wat by replikasie betrokke is).
Hoe om die hoeveelheid data wat tydens hoëvlakreplikasie oorgedra word, te verminder? Die besluit "op die voorkop" kan die keuse van data volgens datum-tyd wees. Om dit te doen, kan jy die datum-tyd-veld gebruik wat reeds in die tabel voorkom (indien dit bestaan). Byvoorbeeld, 'n "bestelling"-dokument kan 'n veld "vereis bestelling deurlooptyd" hê - delivery_time. Die probleem met hierdie oplossing is dat die waardes in hierdie veld nie hoef te wees in die volgorde waarin die bestellings geskep is nie. Ons kan dus nie die maksimum waarde van die veld onthou nie delivery_time, geslaag tydens die vorige uitruilsessie, en tydens die volgende uitruilsessie, kies alle rekords met 'n hoër veldwaarde delivery_time. In die interval tussen uitruilsessies kan rekords met 'n laer veldwaarde bygevoeg word delivery_time. Ook die bestelling kon veranderings ondergaan het wat nietemin nie die veld beïnvloed het nie delivery_time. In beide gevalle sal die veranderinge nie van die bron na die bestemming gepropageer word nie. Om hierdie probleme op te los, moet ons data "oorvleuel" oordra. Dié. by elke uitruilsessie sal ons alle data met die veldwaarde oordra delivery_time, wat 'n oomblik in die verlede oorskry (byvoorbeeld N uur vanaf die huidige oomblik). Dit is egter duidelik dat hierdie benadering vir groot stelsels hoogs oorbodig is en die verkeersbesparings waarna ons streef tot niks kan verminder. Daarbenewens het die oorgedra tabel dalk nie 'n veld wat met die datum-tyd geassosieer word nie.
Nog 'n oplossing, meer kompleks in terme van implementering, is om ontvangs van data te erken. In hierdie geval, tydens elke uitruilsessie, word alle data oorgedra, waarvan die ontvangs nie deur die ontvanger bevestig word nie. Om dit te implementeer, moet jy 'n Boole-kolom by die brontabel voeg (byvoorbeeld, is_transferred). As die ontvanger ontvangs van die rekord erken, word die ooreenstemmende veld ingestel op true, waarna die rekord nie meer aan uitruilings deelneem nie. Hierdie implementeringsopsie het die volgende nadele. Eerstens, vir elke ingediende inskrywing moet 'n erkenning gegenereer en gestuur word. Dit kan rofweg vergelyk word met die verdubbeling van die hoeveelheid data wat oorgedra word en 'n verdubbeling van die aantal heen- en terugreise tot gevolg het. Tweedens is daar geen moontlikheid om dieselfde rekord na verskeie ontvangers te stuur nie (die eerste ontvanger wat dit ontvang sal vir homself en vir al die ander ontvangs erken).
Die metode, sonder die nadele hierbo gegee, bestaan daarin om 'n kolom by die oorgedra tabel te voeg om veranderinge in sy rye op te spoor. So 'n kolom kan van die datum-tyd tipe wees en moet deur die toepassing gestel/bygewerk word na die huidige tyd elke keer wanneer rekords bygevoeg/gewysig word (atomies met byvoeging/wysiging). Kom ons neem die kolom as 'n voorbeeld. update_time. Nadat ons die maksimum waarde van die veld van hierdie kolom vir die oorgedra rekords gestoor het, kan ons die volgende uitruilsessie vanaf hierdie waarde begin (kies rekords met die veldwaarde update_timedie voorheen gestoorde waarde oorskry). Die probleem met laasgenoemde benadering is dat dataveranderinge in bondels kan plaasvind. As gevolg hiervan, die waardes van die velde in die kolom update_time mag nie uniek wees nie. Hierdie kolom kan dus nie gebruik word vir groepering (bladsy-vir-bladsy) data-uitvoer nie. Vir blaaidata sal jy bykomende meganismes moet uitvind wat waarskynlik baie lae doeltreffendheid sal hê (byvoorbeeld, onttrek uit die databasis alle rekords met die waarde update_time bo die gegewe een en die uitvoer van 'n sekere aantal rekords, vanaf 'n verskuiwing vanaf die begin van die monster).
U kan die doeltreffendheid van data-oordrag verbeter deur die vorige benadering effens te verbeter. Om dit te doen, sal ons 'n heelgetaltipe (lang heelgetal) gebruik as die waardes van die velde van die kolom om veranderinge na te spoor. Kom ons noem die kolom row_ver. Die veldwaarde van hierdie kolom moet steeds opgestel/bygewerk word elke keer as 'n rekord geskep/gewysig word. Maar in hierdie geval sal die veld nie die huidige datum-tyd toegeken word nie, maar die waarde van een of ander teller wat met een verhoog word. As gevolg hiervan, die kolom row_ver sal unieke waardes bevat en kan nie net gebruik word vir die uitreiking van "delta" data (data bygevoeg / verander na die einde van die vorige uitruilsessie), maar ook vir eenvoudige en doeltreffende paginering.
Die laaste voorgestelde metode om die hoeveelheid data wat binne die raamwerk van hoëvlak replikasie oorgedra word te minimaliseer, lyk vir my die mees optimale en universele. Laat ons in meer detail daaroor stilstaan.
Gee data deur met behulp van die ryweergawetelling
Implementering van die bediener / meester deel
In MS SQL Server, om hierdie benadering te implementeer, is daar 'n spesiale kolomtipe - rowversion. Elke databasis het 'n teller wat met een inkrementeer elke keer as 'n rekord bygevoeg/gewysig word in 'n tabel wat 'n kolom soos rowversion. Die waarde van hierdie teller word outomaties aan die veld van hierdie kolom in die bygevoegde/veranderde rekord toegeken. Die Tarantool DBMS het nie 'n soortgelyke ingeboude meganisme nie. In Tarantool is dit egter maklik om met die hand te implementeer. Kom ons kyk hoe dit gedoen word.
Eerstens, 'n paar terminologie: tabelle in Tarantool word spasies (spasie) genoem, en rekords word tupels genoem. Jy kan rye in Tarantool skep. Rye is niks meer as benoemde genereerders van geordende heelgetalwaardes nie. Dié. dit is net wat ons nodig het vir ons doeleindes. Hieronder sal ons so 'n volgorde skep.
Voordat u enige databasisbewerking in Tarantool uitvoer, moet u die volgende opdrag uitvoer:
box.cfg{}
As gevolg hiervan sal Tarantool databasisfoto's en die transaksielog na die huidige gids begin skryf.
Kom ons skep 'n volgorde row_version:
box.schema.sequence.create('row_version',
{ if_not_exists = true })
opsie if_not_exists laat jou toe om die skeppingskrip verskeie kere uit te voer: as die voorwerp bestaan, sal Tarantool nie weer probeer om dit te skep nie. Hierdie opsie sal in alle daaropvolgende DDL-opdragte gebruik word.
Kom ons skep 'n ruimte vir 'n voorbeeld.
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
})
Hier het ons die naam van die spasie gegee (goods), veldname en hul tipes.
Outo-inkrement velde in Tarantool word ook geskep met behulp van rye. Skep 'n outo-inkrementerende primêre sleutel per veld 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 ondersteun verskeie tipes indekse. Die indekse van TREE- en HASH-tipes word die meeste gebruik, wat gebaseer is op strukture wat ooreenstem met die naam. BOOM is die veelsydigste indekstipe. Dit laat jou toe om data op 'n georganiseerde manier te herwin. Maar vir gelykheidskeuse is HASH meer geskik. Gevolglik is dit raadsaam om HASH vir die primêre sleutel te gebruik (wat ons gedoen het).
Om 'n kolom te gebruik row_ver om veranderde data oor te dra, is dit nodig om volgordewaardes aan die velde van hierdie kolom te bind row_ver. Maar in teenstelling met die primêre sleutel, die kolom veld waarde row_ver moet met een verhoog, nie net wanneer nuwe rekords bygevoeg word nie, maar ook wanneer bestaandes verander word. Jy kan snellers hiervoor gebruik. Daar is twee tipes spasie-snellers in Tarantool: before_replace и on_replace. Snellers word afgevuur wanneer die data in die spasie verander ('n snellerfunksie word uitgevoer vir elke tupel wat deur die verandering geraak word). Anders as on_replace, before_replace-snellers laat jou toe om die data van die tupel waarop die sneller uitgevoer word, te verander. Gevolglik pas die laaste tipe snellers ons.
box.space.goods:before_replace(function(old, new)
return box.tuple.new({new[1], new[2], new[3],
box.sequence.row_version:next()})
end)
Die gegewe sneller vervang die waarde van die veld row_ver gestoor tuple na die volgende waarde van die ry row_version.
Om data uit die spasie te kan onttrek goods per kolom row_ver, skep 'n indeks:
box.space.goods:create_index('row_ver', {
parts = { 'row_ver' },
unique = true,
type = 'TREE',
if_not_exists = true
})
Indeks tipe - boom (TREE), want ons moet die data in stygende volgorde van die waardes in die kolom onttrek row_ver.
Kom ons voeg 'n paar data by die spasie:
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}
Omdat die eerste veld is 'n outo-inkrementeller, ons slaag eerder nul. Tarantool sal outomaties die volgende waarde vervang. Net so, as die waarde van die kolomvelde row_ver jy kan nul slaag - of glad nie 'n waarde spesifiseer nie, want hierdie kolom beklee die laaste posisie in die spasie.
Kom ons kyk na die resultaat van die insetsel:
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]
...
Soos u kan sien, word die eerste en laaste velde outomaties ingevul. Nou sal dit maklik wees om 'n funksie te skryf vir bladsy-vir-bladsy aflaai van spasieveranderings 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
Die funksie neem 'n waarde as 'n parameter row_ver, vanaf waar dit nodig is om veranderinge af te laai, en gee 'n gedeelte van die veranderde data terug.
Datasteekproefneming in Tarantool word deur indekse gedoen. Funksie get_goods gebruik iterator volgens indeks row_ver om die veranderde data te kry. Die iterator-tipe is GT (Groter as, groter as). Dit beteken dat die iterator die indekswaardes opeenvolgend sal deurkruis vanaf die geslaagde sleutel (veldwaarde row_ver).
Die iterator gee tupels terug. Om vervolgens data via HTTP te kan oordra, is dit nodig om tuples om te skakel na 'n struktuur wat gerieflik is vir daaropvolgende serialisering. Die voorbeeld gebruik die standaardfunksie hiervoor. tomap. In plaas daarvan om te gebruik tomap jy kan jou eie funksie skryf. Byvoorbeeld, ons wil dalk 'n veld hernoem name, moenie die veld verbysteek nie code en voeg veld by 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
Die grootte van die uitsetdatabladsy (die aantal rekords in een gedeelte) word deur die veranderlike bepaal page_size. In die voorbeeld, die waarde page_size is 5. In 'n regte program maak die bladsygrootte gewoonlik meer saak. Dit hang af van die gemiddelde grootte van die spasie tupel. Die optimale bladsygrootte kan empiries gekies word deur die data-oordragtyd te meet. Hoe groter die bladsygrootte, hoe minder heen- en terugreise tussen die stuur- en ontvangkant. Op hierdie manier kan jy die totale tyd vir die oplaai van veranderinge verminder. As die bladsygrootte egter te groot is, sal ons te veel tyd op die bediener spandeer om die haal te serialiseer. As gevolg hiervan kan daar vertragings wees in die verwerking van ander versoeke wat na die bediener gekom het. Parameter page_size kan vanaf die konfigurasielêer gelaai word. Vir elke versendte spasie kan jy jou eie waarde stel. In hierdie geval, vir die meeste spasies, kan die verstekwaarde (byvoorbeeld 100) geskik wees.
Voer die funksie uit 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
...
Neem die waarde van die veld row_ver vanaf die laaste reël en roep die funksie weer:
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
...
Weereens:
tarantool> get_goods(8)
---
- []
...
Soos u kan sien, gee die funksie met hierdie gebruik al die rekords van die spasie bladsy vir bladsy terug goods. Die laaste bladsy word gevolg deur 'n leë keuse.
Kom ons maak veranderinge aan die spasie:
box.space.goods:update(4, {{'=', 6, 'copybook'}})
box.space.goods:insert{nil, 'clip', 234}
box.space.goods:insert{nil, 'folder', 432}
Ons het die waarde van die veld verander name vir een inskrywing en het twee nuwe inskrywings bygevoeg.
Kom ons herhaal die laaste funksie oproep:
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
...
Die funksie het die veranderde en bygevoegde rekords teruggestuur. Dus die funksie get_goods laat jou toe om data te ontvang wat verander het sedert die laaste oproep, wat die basis is van die oorweegde replikasiemetode.
Kom ons laat die uitreiking van resultate via HTTP in die vorm van JSON buite die bestek van hierdie artikel. Jy kan hieroor lees:
Implementering van die kliënt/slaaf deel
Oorweeg hoe die implementering van die ontvangkant lyk. Kom ons skep 'n spasie aan die ontvangkant om die afgelaaide data te stoor:
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
})
Die struktuur van die ruimte lyk soos die struktuur van die ruimte in die bron. Maar aangesien ons nie die ontvangde data nêrens anders gaan deurgee nie, is die kolom row_ver ontbreek in die ontvanger se spasie. In die veld id bronidentifiseerders sal aangeteken word. Daarom, aan die ontvangerkant, is dit nie nodig om dit outomaties te laat inkrementeer nie.
Daarbenewens het ons 'n spasie nodig om die waardes te stoor 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
})
Vir elke gelaaide spasie (veld space_name) sal ons die laaste gelaaide waarde hier stoor row_ver (veld value). Die kolom is die primêre sleutel. space_name.
Kom ons skep 'n funksie om ruimtedata te laai goods oor HTTP. Om dit te doen, benodig ons 'n biblioteek wat 'n HTTP-kliënt implementeer. Die volgende reël laai die biblioteek en instansieer die HTTP-kliënt:
local http_client = require('http.client').new()
Ons benodig ook 'n json-deserialiseringsbiblioteek:
local json = require('json')
Dit is genoeg om 'n data-laaifunksie te skep:
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
Die funksie voer 'n HTTP-versoek by url uit, gaan daarheen oor row_ver as 'n parameter en gee die gedeserialiseerde navraagresultaat terug.
Die funksie om die ontvangde data te stoor is soos volg:
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
Die siklus van die stoor van data in die ruimte goods in 'n transaksie geplaas (hiervoor, die funksie box.atomic) om die aantal skyfbewerkings te verminder.
Ten slotte, die plaaslike ruimte-sinchronisasie funksie goods met bron kan so gedoen word:
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
Eerstens lees ons die voorheen gestoorde waarde row_ver vir ruimte goods. As dit afwesig is (die eerste uitruilsessie), dan neem ons as row_ver nul. Volgende, in die lus, voer ons 'n bladsy-vir-bladsy laai van die veranderde data uit die bron by die gespesifiseerde url. By elke iterasie stoor ons die ontvangde data in die ooreenstemmende plaaslike ruimte en werk die waarde op row_ver (in die ruimte row_ver en in die veranderlike row_ver) — neem die waarde row_ver vanaf die laaste ry gelaaide data.
Om te beskerm teen toevallige lus (in die geval van 'n fout in die program), die lus while vervang kan word deur for:
for _ = 1, max_req do ...
As gevolg van die uitvoering van die funksie sync_goods spasie goods in die ontvanger sal die nuutste weergawes van alle ruimterekords bevat goods in die bron.
Uitwissing van data kan natuurlik nie op hierdie manier uitgesaai word nie. As so 'n behoefte bestaan, kan jy die merk gebruik om te skrap. Voeg by spasie goods Boolese veld is_deleted en in plaas daarvan om die rekord fisies uit te vee, gebruik ons logiese skrapping - ons stel die waarde van die veld is_deleted tot betekenis true. Soms in plaas van 'n Boolese veld is_deleted geriefliker om die veld te gebruik deleted, wat die datum-tyd van die logiese verwydering van die rekord stoor. Nadat 'n logiese skrapping uitgevoer is, sal die rekord wat vir skrapping gemerk is van die bron na die bestemming oorgedra word (volgens die logika hierbo bespreek).
Volgorde row_ver kan gebruik word om data vanaf ander spasies oor te dra: dit is nie nodig om 'n aparte volgorde vir elke versendte spasie te skep nie.
Ons het 'n doeltreffende manier van hoëvlak-datareplikasie in toepassings oorweeg wat die Tarantool DBMS gebruik.
Bevindinge
- Tarantool DBMS is 'n aantreklike, belowende produk vir die skep van hoëladingstoepassings.
- Hoëvlak data replikasie het verskeie voordele bo laevlak replikasie.
- Die metode van hoëvlak-replikasie wat in die artikel oorweeg word, laat toe om die hoeveelheid data wat oorgedra word te minimaliseer deur slegs die rekords wat sedert die laaste uitruilsessie verander het, oor te dra.
Bron: will.com
