Di Tarantool DBMS de dubarekirina asta bilind

Silav, ez ji bo DBMS serîlêdanan diafirînim Tarantool platformek e ku ji hêla Mail.ru Group ve hatî pêşve xistin ku DBMS-ya performansa bilind û serverek serîlêdanê ya bi zimanê Lua berhev dike. Leza bilind a çareseriyên ku li ser bingeha Tarantool-ê têne çêkirin, bi taybetî ji ber piştgirîya moda bîranînê ya DBMS û jêhatîbûna pêkanîna mantiqa karsaziya serîlêdanê di cîhek navnîşek yekane de bi daneyan re tê bidestxistin. Di heman demê de, domdariya daneyê bi karanîna danûstendinên ACID ve tê peyda kirin (têketinek WAL li ser dîskê tê parastin). Tarantool ji bo dubarekirin û parvekirinê piştgirîyek çêkirî ye. Ji guhertoya 2.1-ê dest pê dike, pirsên bi zimanê SQL têne piştgirî kirin. Tarantool çavkaniyek vekirî ye û di bin lîsansa BSD ya Hêsankirî de destûrdar e. Di heman demê de guhertoyek Enterprise ya bazirganî jî heye.

Di Tarantool DBMS de dubarekirina asta bilind
Hêzê hîs bikin! (…aka ji performansê kêfxweş bibin)

Hemî yên jorîn Tarantool ji bo afirandina serîlêdanên barkêş ên ku bi databasan re dixebitin platformek balkêş dike. Di serîlêdanên weha de, pir caran hewcedarî bi dubarekirina daneyan heye.

Wekî ku li jor behs kir, Tarantool xwedan dubarekirina daneyê ye. Prensîba xebata wê ev e ku bi rêzdarî li ser kopiyan hemî danûstendinên ku di navnîşa masterê (WAL) de hene, pêk bîne. Bi gelemperî dubarekirina wusa (em ê bêtir jê re bibêjin asta nizm) ji bo misogerkirina tolerasyona xeletiya serîlêdanê û/an ji bo belavkirina barê xwendinê di navbera girêkên komê de tê bikar anîn.

Di Tarantool DBMS de dubarekirina asta bilind
Birinc. 1. Replication di nav komekê de

Mînakek senaryoyek alternatîf dê veguheztina daneyên ku di databasek de hatî afirandin ji bo pêvajo / çavdêrîkirina danegehek din be. Di rewşa paşîn de, dibe ku çareseriyek hêsantir bikar bînin asta bilind dubarekirin - dubarekirina daneyê di asta mantiqa karsaziya serîlêdanê de. Ewan. Em çareseriyek amadekirî ya ku di DBMS-ê de hatî çêkirin bikar naynin, lê di nav sepana ku em pêş dixin de bi tena serê xwe dubarekirinê bicîh dikin. Ev nêzîkatî hem avantaj û hem jî kêmasiyên xwe hene. Ka em avantajên navnîş bikin.

1. Teserûfa trafîkê:

  • Hûn nekarin hemî daneyan, lê tenê beşek jê veguhezînin (mînak, hûn dikarin tenê hin tabloyan, hin stûnên wan an tomarên ku pîvanek diyar dikin veguhezînin);
  • Berevajî dubarekirina asta nizm, ku bi domdarî di asynkron de (di guhertoya heyî ya Tarantool - 1.10 de hatî bicîh kirin) an hemdem (ku di guhertoyên paşerojê yên Tarantool de were bicîh kirin) tête kirin, dubarekirina asta bilind dikare di danişînan de were kirin (ango, serîlêdan pêşî daneyan hevdeng dike - daneya danişîna danûstendinê, dûv re di dubarekirinê de sekinînek heye, piştî ku danişîna danûstendinê ya din çêdibe, hwd.);
  • heke tomarek çend caran hate guheztin, hûn dikarin tenê guhertoya wê ya herî paşîn veguhezînin (berevajî dubarekirina asta nizm, ku tê de hemî guheztinên ku li ser masterê hatine çêkirin dê li dû hev li ser kopiyan werin lîstin).

2. Di pêkanîna danûstendina HTTP de, ku destûrê dide te ku hûn databasên ji dûr ve hevdeng bikin, dijwarî tune.

Di Tarantool DBMS de dubarekirina asta bilind
Birinc. 2. Replication ser HTTP

3. Strukturên databasê yên ku di navbera wan de têne veguheztin ne hewce ye ku yek bin (ji bilî vê, di rewşa gelemperî de, heta gengaz e ku meriv DBMS-yên cihêreng, zimanên bernamekirinê, platform û hwd bikar bîne).

Di Tarantool DBMS de dubarekirina asta bilind
Birinc. 3. Replication di sîstemên heterojen

Nerazîbûn ev e ku, bi gelemperî, bername ji veavakirinê dijwartir / bihatir e, û li şûna ku hûn fonksiyona çêkirî xweş bikin, hûn neçar in ku ya xwe bicîh bikin.

Ger di rewşa we de avantajên jorîn girîng in (an şertek pêwîst in), wê hingê maqûl e ku hûn dubarekirina asta bilind bikar bînin. Werin em li çend awayan binihêrin ku ji bo pêkanîna dubarekirina daneya astek bilind di Tarantool DBMS de.

Kêmkirina trafîkê

Ji ber vê yekê, yek ji avantajên dubarekirina-asta bilind teserûfa trafîkê ye. Ji bo ku ev avantaj bi tevahî were fêhm kirin, pêdivî ye ku di her danişîna danûstendinê de mîqdara daneyên ku têne veguheztin kêm bikin. Bê guman, divê em ji bîr nekin ku di dawiya danişînê de, wergirê daneyê divê bi çavkaniyê re were senkronîze kirin (qet nebe ji bo wê beşa daneyê ya ku di nav dubarekirinê de ye).

Meriv çawa mîqdara daneya ku di dema dubarekirina asta bilind de hatî veguheztin kêm bike? Çareseriyek rasterast dikare hilbijartina daneyan li gorî tarîx û dem be. Ji bo kirina vê yekê, hûn dikarin qada tarîx-demê ku jixwe di tabloyê de heye (heke hebe) bikar bînin. Mînakî, belgeyek "fermandar" dibe ku qada "dema pêkanîna fermanê ya pêwîst" hebe - delivery_time. Pirsgirêka vê çareseriyê ev e ku nirxên di vê qadê de ne hewce ne ku di rêza ku bi afirandina fermanan re têkildar bin. Ji ber vê yekê em nikarin nirxa zeviyê ya herî zêde bîr nekin delivery_time, di danişîna danûstendina berê de hatî şandin, û di danişîna danûstendina paşîn de hemî tomarên bi nirxek zeviyê bilindtir hilbijêrin delivery_time. Dibe ku di navbera danişînên danûstendinê de tomarên bi nirxek zeviyê kêmtir hatine zêdekirin delivery_time. Di heman demê de, ferman dikaribû bihata guhertin, ku di heman demê de bandor li qadê nekir delivery_time. Di her du rewşan de, guhertin dê ji çavkaniyê berbi mebestê ve neyê veguheztin. Ji bo çareserkirina van pirsgirêkan, em ê hewce ne ku daneyên "lihevkirî" veguhezînin. Ewan. di her danişîna danûstendinê de em ê hemî daneyên bi nirxa zeviyê veguhezînin delivery_time, ji hin xalek berê derbas dibe (mînak, N demjimêr ji dema niha). Lêbelê, eşkere ye ku ji bo pergalên mezin ev nêzîkatî pir zêde zêde ye û dikare teserûfa trafîkê ya ku em ji bo wan hewl didin kêm bike. Wekî din, tabloya ku tê veguheztin dibe ku zeviyek bi dîrok-demê re têkildar nebe.

Çareseriyek din, di warê bicîhkirinê de tevlihevtir e, pejirandina wergirtina daneyan e. Di vê rewşê de, di her danişîna danûstendinê de, hemî dane têne şandin, ku wergirtina wan ji hêla wergir ve nehatiye pejirandin. Ji bo pêkanîna vê yekê, hûn ê hewce bikin ku stûnek Boolean li tabloya çavkaniyê zêde bikin (mînak, is_transferred). Ger wergir wergirtina tomarê qebûl bike, qada têkildar nirxê digire true, piştî ku têketin êdî di danûstendinan de nabe. Vê vebijarka pêkanînê dezawantajên jêrîn hene. Pêşîn, ji bo her tomarek hatî veguheztin, divê pejirandinek were çêkirin û şandin. Bi gelemperî, ev dikare bi ducarkirina mîqdara daneya ku hatî veguheztin û rê li ber duqatkirina hejmara gerokan ve were berhev kirin. Ya duyemîn, îmkana şandina heman tomarê ji çend wergirên re tune (wergirê yekem ku werdigire dê wergirtinê ji bo xwe û ji bo hemî yên din piştrast bike).

Rêbazek ku kêmasiyên ku li jor hatine destnîşan kirin tune ev e ku stûnek li tabloya veguheztî zêde bike da ku guheztinên di rêzên wê de bişopîne. Stûnek wusa dikare ji celebê tarîx-dem be û divê ji hêla serîlêdanê ve heya dema niha were saz kirin/nûve kirin her carê ku tomar têne zêdekirin/guhertin (bi atomî bi lêzêdekirin/guhertin). Weke nimûne, em gazî stûnê bikin update_time. Bi tomarkirina nirxa zeviyê ya herî zêde ya vê stûnê ji bo tomarên hatine veguheztin, em dikarin danişîna pevguherînê ya din bi vê nirxê dest pê bikin (qeydên bi nirxa zeviyê hilbijêrin update_time, ji nirxa ku berê hatî hilanîn zêdetir dike). Pirsgirêka nêzîkatiya paşîn ev e ku guhertinên daneyê dikarin di koman de çêbibin. Wekî encamek nirxên zeviyê di stûnê de update_time dibe ku yekta nebe. Ji ber vê yekê, ev stûn nikare ji bo hilberîna daneya perçekirî (rûpel-bi-rûpel) were bikar anîn. Ji bo nîşankirina daneyan rûpel bi rûpel, hûn neçar in ku mekanîzmayên din îcad bikin ku bi îhtîmalek mezin dê xwedan karîgeriyek pir kêm be (mînakî, ji databasê vekêşana hemî tomarên bi nirx update_time ji yeka diyarkirî bilindtir e û hejmareke diyarkirî tomar dike, ji destpêka nimûneyê ve ji deverek diyarkirî dest pê dike).

Hûn dikarin karbidestiya veguheztina daneyê bi hinekî baştirkirina nêzîkatiya berê baştir bikin. Ji bo kirina vê yekê, em ê ji bo şopandina guhertinan wekî nirxên qada stûnê tîpa yekjimar (hejmar dirêj) bikar bînin. Em navê stûnê bikin row_ver. Nirxa zeviyê ya vê stûnê dîsa jî divê her gava ku tomarek çêdibe/guhezîne were saz kirin/nûve kirin. Lê di vê rewşê de, zevî dê tarîx-demjimêra heyî neyê destnîşankirin, lê nirxa hin hejmarê, bi yek zêde dibe. Di encamê de, stûn row_ver dê nirxên bêhempa dihewîne û dikare ne tenê ji bo nîşankirina daneya "delta" (daneyên ku ji dawiya danişîna danûstendinê ya berê ve hatine zêdekirin/guheztin), lê di heman demê de ji bo veqetandina wê di rûpelan de bi hêsanî û bi bandor were bikar anîn.

Rêbaza paşîn a pêşniyarkirî ya kêmkirina mîqdara daneya ku di çarçoweya dubarekirina asta bilind de hatî veguheztin ji min re çêtirîn û gerdûnî xuya dike. Ka em bi berfirehî lê binêrin.

Derbaskirina Daneyên Bi Bikaranîna Berhevkarek Guhertoya Rêzê

Pêkanîna server / beşa sereke

Di MS SQL Server de, celebek stûnek taybetî heye ku vê nêzîkbûnê bicîh bîne - rowversion. Di her databasê de jimareyek heye ku her gava ku tomarek di tabloya ku stûnek mîna wê de tê zêdekirin/guheztin yek bi yek zêde dibe. rowversion. Nirxa vê hejmarê bixweber li qada vê stûnê ya di tomara zêde/guhertî de tê destnîşankirin. Tarantool DBMS xwedan mekanîzmayek çêkirî ya wekhev nîne. Lêbelê, di Tarantool de pêkanîna wê bi destan ne dijwar e. Ka em binêrin ka ev çawa tê kirin.

Pêşîn, termînolojiya piçûk: maseyên di Tarantool de cîh têne gotin, û tomar têne binav kirin. Di Tarantool de hûn dikarin rêzikan biafirînin. Rêz ji jeneratorên binavkirî yên nirxên yekjimar ên rêzkirî wêdetir ne. Ewan. ev tam ji bo mebestên me hewcedariya me ye. Li jêr em ê rêzek weha çêbikin.

Berî ku hûn operasyonek databasê li Tarantool bikin, hûn hewce ne ku emrê jêrîn bimeşînin:

box.cfg{}

Wekî encamek, Tarantool dê dest bi nivîsandina dîmenên databasê û têketinên danûstendinê li pelrêça heyî bike.

Ka em rêzek çêkin row_version:

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

Dibe if_not_exists dihêle ku skrîpta afirandinê gelek caran were darve kirin: heke tişt hebe, Tarantool dê hewl nede ku wê dîsa biafirîne. Ev vebijark dê di hemî fermanên DDL yên paşîn de were bikar anîn.

Werin em wekî nimûne cîhek çêbikin.

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

Li vir em navê cîhê destnîşan dikin (goods), navên zeviyan û celebên wan.

Zeviyên zêdekirina otomatîkî di Tarantool de jî bi karanîna rêzikan têne afirandin. Werin em li gorî zeviyê mifteyek seretayî ya xweser-zêde biafirînin 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 gelek celeb indexan piştgirî dike. Indeksên ku herî zêde têne bikar anîn celebên TREE û HASH in, ku li ser strukturên li gorî navan têne çêkirin. TREE cureya indexê ya herî pirreng e. Ew dihêle hûn daneyan bi rengek rêxistinkirî bistînin. Lê ji bo hilbijartina wekheviyê, HASH maqûltir e. Li gorî vê yekê, tê pêşniyar kirin ku ji bo mifteya bingehîn (ya ku me kir) HASH bikar bînin.

Ji bo stûnê bikar bînin row_ver ji bo veguheztina daneyên guhertî, hûn hewce ne ku nirxên rêzê bi qadên vê stûnê ve girêdin row_ver. Lê berevajî mifteya bingehîn, nirxa qada stûnê row_ver divê ne tenê dema lêzêdekirina tomarên nû, lê di heman demê de dema guheztina yên heyî jî yek yek zêde bibe. Hûn dikarin ji bo vê yekê kêşan bikar bînin. Tarantool xwedan du celeb kêşeyên cîhê ye: before_replace и on_replace. Dema ku daneyên di cîhê de diguhezin (ji bo her tîpek ku ji guhertinan bandor bûne, fonksiyonek tîrêjê tê destpêkirin) tetik têne avêtin. Unlike on_replace, before_replace-tetikîne destûrê dide te ku hûn daneyên tîrêja ku ji bo tetikê hatî darve kirin biguhezînin. Li gorî vê yekê, celebê paşîn ên tetikan li gorî me ye.

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

Çêkera jêrîn li şûna nirxa zeviyê digire row_ver tuple hilanîn ji bo nirxa din ya rêzê row_version.

Ji bo ku bikaribe ji fezayê daneyan derxîne goods bi stûnê row_ver, em indexek çêbikin:

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

Tîpa nîşanê - dar (TREE), ji ber ku em ê hewce ne ku daneyan bi rêza hilkişîna nirxên di stûnê de derxînin row_ver.

Ka em hin daneyan li cîhê zêde bikin:

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}

Bo Qada yekem jimarvanek oto-zêdebûnê ye; li şûna wê em nil derbas dikin. Tarantool dê bixweber nirxa paşîn biguhezîne. Bi heman awayî, wekî nirxa qadên stûnê row_ver hûn dikarin nil derbas bikin - an jî nirxê qet diyar nekin, ji ber ev stûn di mekanê de pozîsyona dawîn digire.

Ka em encama têxê kontrol bikin:

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

Wekî ku hûn dikarin bibînin, zeviyên yekem û paşîn bixweber têne dagirtin. Naha dê hêsan be ku meriv fonksiyonek ji bo barkirina rûpel-bi-rûpel guheztinên cîhê binivîse 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

Fonksîyon wekî parametre nirxê digire row_ver, dest pê dike ku ji kîjan pêdivî ye ku guhartinan dakêşin, û beşek ji daneyên guhertî vedigerîne.

Nimûneya daneyê di Tarantool de bi navnîşan têne kirin. Karkirin get_goods îteratorek ji hêla indexê ve bikar tîne row_ver ji bo wergirtina daneyên guhertin. Tîpa Iterator GT ye (Ji mezintir, ji mezintir). Ev tê vê wateyê ku îterator dê bi dû hevûdu nirxên îndeksê yên ku ji mifteya derbasbûyî dest pê dike (nirxa zeviyê row_ver).

Iterator tupleyan vedigerîne. Ji bo ku hûn paşê karibin daneyan bi HTTP-ê veguhezînin, pêdivî ye ku tupleyan veguherînin avahiyek hêsan a ji bo serialîzasyona paşê. Mînak ji bo vê yekê fonksiyona standard bikar tîne tomap. Li şûna ku bikar bînin tomap hûn dikarin fonksiyona xwe binivîsin. Mînakî, dibe ku em bixwazin navê zeviyek biguherînin name, derbaz nebin code û zeviyek lê zêde bike 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

Mezinahiya rûpelê ya daneyên derketinê (hejmara tomarên di yek beşê de) ji hêla guhêrbar ve tê destnîşankirin page_size. Di nimûneyê de nirx page_size e 5. Di bernameyek rastîn de, mezinahiya rûpelê bi gelemperî bêtir girîng e. Ew bi mezinahiya navînî ya cîhê cîhê ve girêdayî ye. Mezinahiya rûpelê ya çêtirîn dikare bi pîvandina dema veguheztina daneyê bi ezmûnî were destnîşankirin. Mezinahiya rûpelê her ku mezin be, hejmara gerokên di navbera aliyên şandin û wergirtinê de piçûktir dibe. Bi vî rengî hûn dikarin dema giştî ya dakêşana guhertinan kêm bikin. Lêbelê, heke mezinahiya rûpelê pir mezin be, em ê pir dirêj li ser serverê ku nimûneyê serial dike derbas bikin. Wekî encamek, dibe ku di pêvajoykirina daxwazên din ên ku têne serverê de dereng hebin. Parametre page_size dikare ji pelê veavakirinê were barkirin. Ji bo her cîhê veguhestî, hûn dikarin nirxa xwe destnîşan bikin. Lêbelê, ji bo pir deveran nirxa xwerû (mînak, 100) dibe ku guncan be.

Werin em fonksiyonê pêk bînin 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
...

Ka em nirxa zeviyê bigirin row_ver ji rêza paşîn û dîsa bangî fonksiyonê bikin:

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

Çi nûçe:

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

Wekî ku hûn dibînin, dema ku bi vî rengî tê bikar anîn, fonksiyon rûpel bi rûpel hemî tomarên cîhê vedigerîne goods. Li dû rûpela dawîn hilbijartinek vala tê.

Ka em li cîhê guhertinan bikin:

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

Me nirxa zeviyê guhertiye name ji bo yek têketinê û du navnîşên nû lê zêde kirin.

Ka em banga fonksiyona paşîn dubare bikin:

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

Fonksiyon tomarên guherî û zêdekirî vegerandin. Ji ber vê yekê fonksiyonê get_goods destûrê dide te ku hûn daneyên ku ji banga wê ya paşîn ve hatî guheztin, ku bingeha rêbaza dubarekirinê ya li ber çavan e, bistînin.

Em ê derxistina encaman bi riya HTTP di forma JSON de li derveyî çarçoveya vê gotarê bihêlin. Hûn dikarin li ser vê yekê li vir bixwînin: https://habr.com/ru/company/mailru/blog/272141/

Pêkanîna beşa xerîdar / xulam

Ka em binerin ka pêkanîna aliyê wergirtinê çawa xuya dike. Werin em li alîyê wergirtinê cîhek çêbikin ku daneyên dakêşandî hilînin:

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

Avahiya mekanê dişibihe avahiya mekanê ya di çavkaniyê de. Lê ji ber ku em ê daneyên wergirtî li cîhek din, stûnê derbas nekin row_ver ne di cihê wergir de ye. Li zeviyê id nasnameyên çavkaniyê dê bêne tomar kirin. Ji ber vê yekê, li aliyê wergirê ne hewce ye ku ew bixweber zêde bibe.

Wekî din, ji me re cîhek hewce ye ku nirxan xilas bike 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
})

Ji bo her cîhê barkirî (qada space_name) em ê nirxa dawî ya barkirî li vir hilînin row_ver (erd value). Stûn wekî mifteya bingehîn tevdigere space_name.

Ka em fonksiyonek biafirînin ku daneyên cîhê bar bike goods bi rêya HTTP. Ji bo vê yekê, em hewceyê pirtûkxaneyek ku xerîdarek HTTP bicîh tîne. Rêza jêrîn pirtûkxaneyê bar dike û muwekîlê HTTP-ê destnîşan dike:

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

Ji bo deserialîzasyona json jî pirtûkxaneyek pêdivî ye:

local json = require('json')

Ji bo afirandina fonksiyonek barkirina daneyê ev bes e:

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

Fonksiyon daxwazek HTTP ji navnîşana url-ê re dike û dişîne row_ver wekî pîvanek û encama deserialized ya daxwazê ​​vedigerîne.

Fonksiyona tomarkirina daneyên wergirtî wiha xuya dike:

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

Qonaxa tomarkirina daneyan li cîhê goods di danûstendinê de tê danîn (fonksiyona ji bo vê tê bikar anîn box.atomic) ji bo kêmkirina hejmara operasyonên dîskê.

Di dawiyê de, fonksiyona hevdemkirina cîhê herêmî goods bi çavkaniyek hûn dikarin wê bi vî rengî bicîh bikin:

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

Pêşî em nirxa ku berê hatî tomarkirin dixwînin row_ver ji bo cîh goods. Ger ew wenda be (danişîna pevguhertinê ya yekem), wê hingê em wê wekî xwe digirin row_ver sifir. Dûv re di çerçoveyê de em rûpel-rûpel dakêşana daneya guhertî ji çavkaniyê li url-a diyarkirî pêk tînin. Di her dubarekirinê de, em daneyên wergirtî li cîhê herêmî yê guncan tomar dikin û nirxê nûve dikin row_ver (li fezayê row_ver û di guherbarê de row_ver) - nirxê bigire row_ver ji rêza dawî ya daneyên barkirî.

Ji bo parastina li dijî lûleya bêserûber (di rewşek xeletiyek di bernameyê de), lûp while dikare bi şûna for:

for _ = 1, max_req do ...

Di encama pêkanîna fonksiyonê de sync_goods dem goods wergir dê guhertoyên herî dawî yên hemî tomarên cîhê hebin goods di çavkaniyê de.

Eşkere ye ku jêbirina daneyan bi vî rengî nayê weşandin. Ger hewcedariyek wusa hebe, hûn dikarin nîşanek jêbirinê bikar bînin. Li fezayê zêde bikin goods qada boolean is_deleted û li şûna ku em tomarek bi fîzîkî jêbirin, em jêbirina mentiqî bikar tînin - em nirxa zeviyê destnîşan dikin is_deleted nav wateyê de true. Carna li şûna zeviya boolean is_deleted bikaranîna zeviyê hêsantir e deleted, ku tarîx-dema jêbirina mentiqî ya tomarê diparêze. Piştî pêkanîna jêbirinek mentiqî, tomara ku ji bo jêbirinê hatî nîşankirin dê ji çavkaniyê berbi mebestê ve were veguheztin (li gorî mantiqa ku li jor hatî nîqaş kirin).

Dor row_ver dikare ji bo veguheztina daneyan ji cîhên din were bikar anîn: ne hewce ye ku ji bo her cîhek hatî veguheztin rêzek cûda were afirandin.

Me li rêgezek bi bandor a dubarekirina daneya bilind a di serîlêdanan de bi karanîna Tarantool DBMS nihêrî.

vebiguherin

  1. Tarantool DBMS ji bo afirandina serîlêdanên bargiraniya bilind hilberek balkêş, sozdar e.
  2. Vejandina daneya-asta bilind li ser dubarekirina asta nizm gelek avantajên xwe hene.
  3. Rêbaza dubarekirina-asta bilind a ku di gotarê de hatî nîqaş kirin dihêle hûn bi veguheztina tenê wan tomarên ku ji danişîna danûstendinê ya paşîn ve hatine guheztin mîqdara daneya veguheztinê kêm bikin.

Source: www.habr.com

Add a comment