Dyblygiad lefel uchel yn DBMS Tarantool

Helo, rydw i'n creu cymwysiadau ar gyfer DBMS Tarantool yn blatfform a ddatblygwyd gan Mail.ru Group sy'n cyfuno DBMS perfformiad uchel a gweinydd cymhwysiad yn yr iaith Lua. Cyflawnir cyflymder uchel atebion sy'n seiliedig ar Tarantool, yn arbennig, oherwydd cefnogaeth ar gyfer modd cof y DBMS a'r gallu i weithredu rhesymeg busnes cymhwysiad mewn un gofod cyfeiriad gyda data. Ar yr un pryd, sicrheir dyfalbarhad data gan ddefnyddio trafodion ACID (cedwir log WAL ar y ddisg). Mae gan Tarantool gefnogaeth fewnol ar gyfer atgynhyrchu a darnio. Gan ddechrau o fersiwn 2.1, cefnogir ymholiadau yn iaith SQL. Mae Tarantool yn ffynhonnell agored ac wedi'i drwyddedu o dan y drwydded BSD Syml. Mae fersiwn Menter fasnachol hefyd.

Dyblygiad lefel uchel yn DBMS Tarantool
Teimlwch y pŵer! (…a mwynhewch y perfformiad)

Mae'r uchod i gyd yn gwneud Tarantool yn llwyfan deniadol ar gyfer creu cymwysiadau llwyth uchel sy'n gweithio gyda chronfeydd data. Mewn cymwysiadau o'r fath, yn aml mae angen atgynhyrchu data.

Fel y soniwyd uchod, mae gan Tarantool atgynhyrchu data adeiledig. Egwyddor ei weithrediad yw gweithredu'n ddilyniannol ar atgynyrchiadau o'r holl drafodion sydd yn y prif log (WAL). Fel arfer atgynhyrchiad o'r fath (byddwn yn ei alw ymhellach lefel isel) yn cael ei ddefnyddio i sicrhau goddefgarwch namau cymhwysiad a/neu i ddosbarthu'r llwyth darllen rhwng nodau clwstwr.

Dyblygiad lefel uchel yn DBMS Tarantool
Reis. 1. Dyblygiad o fewn clwstwr

Enghraifft o senario amgen fyddai trosglwyddo data a grëwyd mewn un gronfa ddata i gronfa ddata arall ar gyfer prosesu/monitro. Yn yr achos olaf, efallai mai ateb mwy cyfleus fydd ei ddefnyddio lefel uchel atgynhyrchu - atgynhyrchu data ar lefel rhesymeg busnes cymhwysiad. Y rhai. Nid ydym yn defnyddio datrysiad parod sydd wedi'i ymgorffori yn y DBMS, ond yn gweithredu atgynhyrchu ar ein pen ein hunain o fewn y cymhwysiad rydym yn ei ddatblygu. Mae gan y dull hwn fanteision ac anfanteision. Gadewch i ni restru'r manteision.

1. Arbedion traffig:

  • Ni allwch drosglwyddo'r holl ddata, ond dim ond rhan ohono (er enghraifft, dim ond rhai tablau y gallwch eu trosglwyddo, rhai o'u colofnau neu gofnodion sy'n bodloni maen prawf penodol);
  • Yn wahanol i ddyblygiad lefel isel, sy'n cael ei berfformio'n barhaus mewn modd asyncronaidd (a weithredir yn y fersiwn gyfredol o Tarantool - 1.10) neu gydamserol (i'w weithredu mewn fersiynau dilynol o Tarantool), gellir ailadrodd lefel uchel mewn sesiynau (h.y., y cais yn gyntaf yn cydamseru'r data - sesiwn cyfnewid data, yna mae saib yn dyblygu, ac ar ôl hynny y sesiwn cyfnewid nesaf yn digwydd, ac ati);
  • os yw cofnod wedi newid sawl gwaith, dim ond ei fersiwn ddiweddaraf y gallwch chi ei drosglwyddo (yn wahanol i ddyblygiad lefel isel, lle bydd yr holl newidiadau a wneir ar y meistr yn cael eu chwarae yn ôl yn olynol ar y copïau).

2. Nid oes unrhyw anawsterau gyda gweithredu cyfnewid HTTP, sy'n eich galluogi i gydamseru cronfeydd data o bell.

Dyblygiad lefel uchel yn DBMS Tarantool
Reis. 2. Dyblygiad dros HTTP

3. Nid oes rhaid i'r strwythurau cronfa ddata y trosglwyddir data rhyngddynt fod yr un peth (ar ben hynny, yn yr achos cyffredinol, mae hyd yn oed yn bosibl defnyddio gwahanol DBMSs, ieithoedd rhaglennu, llwyfannau, ac ati).

Dyblygiad lefel uchel yn DBMS Tarantool
Reis. 3. Dyblygiad mewn systemau heterogenaidd

Yr anfantais yw bod rhaglennu, ar gyfartaledd, yn fwy anodd / costus na chyfluniad, ac yn lle addasu'r swyddogaeth fewnol, bydd yn rhaid i chi weithredu eich rhaglen eich hun.

Os yw'r manteision uchod yn hanfodol (neu'n gyflwr angenrheidiol) yn eich sefyllfa chi, yna mae'n gwneud synnwyr defnyddio atgynhyrchu lefel uchel. Gadewch i ni edrych ar sawl ffordd o weithredu ailadrodd data lefel uchel yn DBMS Tarantool.

Lleihau traffig

Felly, un o fanteision atgynhyrchu lefel uchel yw arbedion traffig. Er mwyn gwireddu'r fantais hon yn llawn, mae angen lleihau faint o ddata a drosglwyddir yn ystod pob sesiwn gyfnewid. Wrth gwrs, ni ddylem anghofio bod yn rhaid i'r derbynnydd data gael ei gydamseru â'r ffynhonnell ar ddiwedd y sesiwn (o leiaf ar gyfer y rhan honno o'r data sy'n ymwneud â dyblygu).

Sut i leihau faint o ddata a drosglwyddir yn ystod atgynhyrchu lefel uchel? Ateb syml fyddai dewis data yn ôl dyddiad ac amser. I wneud hyn, gallwch ddefnyddio'r maes dyddiad-amser sydd eisoes yn bodoli yn y tabl (os yw'n bodoli). Er enghraifft, efallai y bydd gan ddogfen “gorchymyn” faes “amser gweithredu gorchymyn gofynnol” - delivery_time. Y broblem gyda'r ateb hwn yw nad oes rhaid i'r gwerthoedd yn y maes hwn fod yn y dilyniant sy'n cyfateb i greu gorchmynion. Felly ni allwn gofio uchafswm gwerth y maes delivery_time, a drosglwyddwyd yn ystod y sesiwn gyfnewid flaenorol, ac yn ystod y sesiwn gyfnewid nesaf dewiswch yr holl gofnodion sydd â gwerth maes uwch delivery_time. Mae'n bosibl bod cofnodion â gwerth maes is wedi'u hychwanegu rhwng sesiynau cyfnewid delivery_time. Hefyd, gallai'r gorchymyn fod wedi mynd trwy newidiadau, nad oedd serch hynny yn effeithio ar y maes delivery_time. Yn y ddau achos, ni fydd y newidiadau yn cael eu trosglwyddo o'r ffynhonnell i'r cyrchfan. Er mwyn datrys y problemau hyn, bydd angen i ni drosglwyddo data "gorgyffwrdd". Y rhai. ym mhob sesiwn cyfnewid byddwn yn trosglwyddo'r holl ddata gyda'r gwerth maes delivery_time, yn mynd y tu hwnt i ryw bwynt yn y gorffennol (er enghraifft, N awr o'r eiliad gyfredol). Fodd bynnag, mae'n amlwg bod y dull hwn yn ddiangen iawn ar gyfer systemau mawr a gall leihau'r arbedion traffig yr ydym yn ymdrechu i'w cael i ddim. Yn ogystal, efallai na fydd gan y tabl sy'n cael ei drosglwyddo faes sy'n gysylltiedig ag amser dyddiad.

Ateb arall, mwy cymhleth o ran gweithredu, yw cydnabod derbyn data. Yn yr achos hwn, yn ystod pob sesiwn gyfnewid, trosglwyddir yr holl ddata, ac nid yw'r derbynnydd wedi cadarnhau ei dderbyn. I weithredu hyn, bydd angen i chi ychwanegu colofn Boole i'r tabl ffynhonnell (er enghraifft, is_transferred). Os yw'r derbynnydd yn cydnabod derbyn y cofnod, mae'r maes cyfatebol yn cymryd y gwerth true, ac ar ôl hynny nid yw'r cofnod yn ymwneud â chyfnewidiadau mwyach. Mae gan yr opsiwn gweithredu hwn yr anfanteision canlynol. Yn gyntaf, ar gyfer pob cofnod a drosglwyddir, rhaid cynhyrchu ac anfon cydnabyddiaeth. Yn fras, gallai hyn fod yn gymaradwy â dyblu swm y data a drosglwyddwyd ac arwain at ddyblu nifer y teithiau crwn. Yn ail, nid oes unrhyw bosibilrwydd o anfon yr un cofnod at sawl derbynnydd (bydd y derbynnydd cyntaf i'w dderbyn yn cadarnhau ei dderbyn ei hun ac ar gyfer y lleill i gyd).

Dull nad oes ganddo'r anfanteision a roddir uchod yw ychwanegu colofn at y tabl a drosglwyddir i olrhain newidiadau yn ei resi. Gall colofn o'r fath fod o fath dyddiad-amser a rhaid ei gosod/diweddaru gan y cais i'r amser presennol bob tro y caiff cofnodion eu hychwanegu/newid (yn atomig gyda'r ychwanegiad/newid). Fel enghraifft, gadewch i ni alw'r golofn update_time. Trwy arbed uchafswm gwerth maes y golofn hon ar gyfer y cofnodion a drosglwyddwyd, gallwn ddechrau'r sesiwn cyfnewid nesaf gyda'r gwerth hwn (dewiswch gofnodion gyda gwerth y maes update_time, yn fwy na'r gwerth a storiwyd yn flaenorol). Y broblem gyda'r dull olaf yw y gall newidiadau data ddigwydd mewn sypiau. O ganlyniad i'r gwerthoedd maes yn y golofn update_time efallai nad yw'n unigryw. Felly, ni ellir defnyddio'r golofn hon ar gyfer allbwn data wedi'i rannu (tudalen-wrth-dudalen). I arddangos data fesul tudalen, bydd yn rhaid i chi ddyfeisio mecanweithiau ychwanegol a fydd yn fwyaf tebygol o fod yn isel iawn effeithlonrwydd (er enghraifft, adalw o'r gronfa ddata yr holl gofnodion gyda'r gwerth update_time uwch nag un a roddwyd ac yn cynhyrchu nifer penodol o gofnodion, gan ddechrau o wrthbwyso penodol o ddechrau'r sampl).

Gallwch wella effeithlonrwydd trosglwyddo data trwy wella ychydig ar y dull blaenorol. I wneud hyn, byddwn yn defnyddio'r math cyfanrif (cyfanrif hir) fel gwerthoedd maes y golofn ar gyfer olrhain newidiadau. Gadewch i ni enwi'r golofn row_ver. Rhaid dal i osod/diweddaru gwerth maes y golofn hon bob tro y caiff cofnod ei greu/ei addasu. Ond yn yr achos hwn, ni fydd y maes yn cael ei neilltuo ar hyn o bryd dyddiad-amser, ond mae gwerth rhai cownter, cynyddu gan un. O ganlyniad, y golofn row_ver yn cynnwys gwerthoedd unigryw a gellir ei ddefnyddio nid yn unig i arddangos data “delta” (data wedi'i ychwanegu / newid ers diwedd y sesiwn gyfnewid flaenorol), ond hefyd i'w dorri i lawr yn dudalennau yn syml ac yn effeithiol.

Mae'n ymddangos i mi mai'r dull arfaethedig diwethaf o leihau faint o ddata a drosglwyddir o fewn fframwaith atgynhyrchu lefel uchel yw'r mwyaf optimaidd a chyffredinol. Gadewch i ni edrych arno'n fwy manwl.

Pasio Data Gan Ddefnyddio Rhifydd Fersiwn Rhes

Gweithredu'r rhan gweinydd / meistr

Yn MS SQL Server, mae yna fath arbennig o golofn i weithredu'r dull hwn - rowversion. Mae gan bob cronfa ddata gyfrifydd sy'n cynyddu un bob tro y caiff cofnod ei ychwanegu/newid mewn tabl sydd â cholofn debyg rowversion. Mae gwerth y rhifydd hwn yn cael ei aseinio'n awtomatig i faes y golofn hon yn y cofnod a ychwanegwyd/newidiwyd. Nid oes gan y Tarantool DBMS fecanwaith adeiledig tebyg. Fodd bynnag, yn Tarantool nid yw'n anodd ei weithredu â llaw. Gadewch i ni edrych ar sut y gwneir hyn.

Yn gyntaf, ychydig o derminoleg: gelwir tablau yn Tarantool yn ofodau, a gelwir cofnodion yn tuples. Yn Tarantool gallwch greu dilyniannau. Nid yw dilyniannau yn ddim mwy na chynhyrchwyr a enwir o werthoedd cyfanrif trefnedig. Y rhai. dyma'n union sydd ei angen arnom at ein dibenion. Isod byddwn yn creu dilyniant o'r fath.

Cyn perfformio unrhyw weithrediad cronfa ddata yn Tarantool, mae angen i chi redeg y gorchymyn canlynol:

box.cfg{}

O ganlyniad, bydd Tarantool yn dechrau ysgrifennu cipluniau cronfa ddata a logiau trafodion i'r cyfeiriadur cyfredol.

Gadewch i ni greu dilyniant row_version:

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

Opsiwn if_not_exists yn caniatáu i'r sgript creu gael ei weithredu sawl gwaith: os yw'r gwrthrych yn bodoli, ni fydd Tarantool yn ceisio ei greu eto. Bydd yr opsiwn hwn yn cael ei ddefnyddio ym mhob gorchymyn DDL dilynol.

Gadewch i ni greu gofod fel enghraifft.

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

Yma rydym yn gosod enw'r gofod (goods), enwau caeau a'u mathau.

Mae meysydd cynyddu awtomatig yn Tarantool hefyd yn cael eu creu gan ddefnyddio dilyniannau. Gadewch i ni greu allwedd gynradd sy'n cynyddu'n awtomatig fesul maes 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
})

Mae Tarantool yn cefnogi sawl math o fynegeion. Y mynegeion a ddefnyddir amlaf yw mathau COEDEN a HASH, sy'n seiliedig ar strwythurau sy'n cyfateb i'r enw. TREE yw'r math mynegai mwyaf amlbwrpas. Mae'n caniatáu ichi adalw data mewn modd trefnus. Ond ar gyfer dewis cydraddoldeb, mae HASH yn fwy addas. Yn unol â hynny, fe'ch cynghorir i ddefnyddio HASH ar gyfer y brif allwedd (sef yr hyn a wnaethom).

I ddefnyddio'r golofn row_ver i drosglwyddo data wedi'i newid, mae angen i chi rwymo gwerthoedd dilyniant i feysydd y golofn hon row_ver. Ond yn wahanol i'r allwedd gynradd, gwerth maes y golofn row_ver Dylai gynyddu o un nid yn unig wrth ychwanegu cofnodion newydd, ond hefyd wrth newid rhai sy'n bodoli eisoes. Gallwch ddefnyddio sbardunau ar gyfer hyn. Mae gan Tarantool ddau fath o sbardunau gofod: before_replace и on_replace. Mae sbardunau'n cael eu tanio pryd bynnag y bydd y data yn y gofod yn newid (ar gyfer pob tuple yr effeithir arno gan y newidiadau, mae swyddogaeth sbardun yn cael ei lansio). Yn wahanol on_replace, before_replace-triggers yn caniatáu ichi addasu data'r tuple y gweithredir y sbardun ar ei gyfer. Yn unol â hynny, mae'r math olaf o sbardunau yn addas i ni.

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

Mae'r sbardun canlynol yn disodli'r gwerth maes row_ver storio tuple i werth nesaf y dilyniant row_version.

Er mwyn gallu tynnu data o'r gofod goods wrth golofn row_ver, gadewch i ni greu mynegai:

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

Math mynegai - coeden (TREE), achos bydd angen i ni echdynnu'r data yn nhrefn esgynnol y gwerthoedd yn y golofn row_ver.

Gadewch i ni ychwanegu rhywfaint o ddata i'r gofod:

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}

Achos Y maes cyntaf yw rhifydd cynyddran ceir; rydym yn pasio dim yn lle hynny. Bydd Tarantool yn disodli'r gwerth nesaf yn awtomatig. Yn yr un modd, fel gwerth y meysydd colofn row_ver gallwch chi basio dim - neu beidio â nodi'r gwerth o gwbl, oherwydd mae'r golofn hon yn y safle olaf yn y gofod.

Gadewch i ni wirio'r canlyniad mewnosod:

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

Fel y gwelwch, mae'r meysydd cyntaf ac olaf yn cael eu llenwi'n awtomatig. Nawr bydd yn hawdd ysgrifennu swyddogaeth ar gyfer lanlwytho newidiadau gofod fesul tudalen 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

Mae'r swyddogaeth yn cymryd y gwerth fel paramedr row_ver, gan ddechrau o ble mae angen dadlwytho newidiadau, ac yn dychwelyd cyfran o'r data wedi'i newid.

Gwneir samplu data yn Tarantool trwy fynegeion. Swyddogaeth get_goods yn defnyddio iterator yn ôl mynegai row_ver i dderbyn data wedi'i newid. Math iterator yw GT (Fwy na, mwy na). Mae hyn yn golygu y bydd yr iterator yn croesi'r gwerthoedd mynegai yn ddilyniannol gan ddechrau o'r allwedd a basiwyd (gwerth maes row_ver).

Mae'r iterator yn dychwelyd tuples. Er mwyn gallu trosglwyddo data trwy HTTP wedyn, mae angen trosi'r tuples i strwythur sy'n gyfleus ar gyfer cyfresoli dilynol. Mae'r enghraifft yn defnyddio'r swyddogaeth safonol ar gyfer hyn tomap. Yn lle defnyddio tomap gallwch ysgrifennu eich swyddogaeth eich hun. Er enghraifft, efallai y byddwn am ailenwi maes name, peidiwch â mynd heibio i'r cae code ac ychwanegu maes 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

Mae maint tudalen y data allbwn (nifer y cofnodion mewn un dogn) yn cael ei bennu gan y newidyn page_size. Yn yr enghraifft y gwerth page_size yw 5. Mewn rhaglen go iawn, mae maint y dudalen fel arfer yn bwysicach. Mae'n dibynnu ar faint cyfartalog y tuple gofod. Gellir pennu maint tudalen optimaidd yn empirig trwy fesur amser trosglwyddo data. Po fwyaf yw maint y dudalen, y lleiaf yw nifer y teithiau crwn rhwng yr ochr anfon a derbyn. Fel hyn, gallwch leihau'r amser cyffredinol ar gyfer lawrlwytho newidiadau. Fodd bynnag, os yw maint y dudalen yn rhy fawr, byddwn yn treulio gormod o amser ar y gweinydd yn cyfresoli'r sampl. O ganlyniad, efallai y bydd oedi wrth brosesu ceisiadau eraill sy'n dod i'r gweinydd. Paramedr page_size gellir ei lwytho o'r ffeil ffurfweddu. Ar gyfer pob gofod a drosglwyddir, gallwch osod ei werth ei hun. Fodd bynnag, ar gyfer y rhan fwyaf o leoedd gall y gwerth rhagosodedig (er enghraifft, 100) fod yn addas.

Gadewch i ni gyflawni'r swyddogaeth 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
...

Gadewch i ni gymryd gwerth y maes row_ver o'r llinell olaf a ffoniwch y swyddogaeth eto:

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

Unwaith eto:

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

Fel y gallwch weld, pan gaiff ei ddefnyddio fel hyn, mae'r swyddogaeth yn dychwelyd yr holl gofnodion gofod fesul tudalen goods. Dilynir y dudalen olaf gan ddetholiad gwag.

Gadewch i ni wneud newidiadau i'r gofod:

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

Rydym wedi newid gwerth y maes name ar gyfer un cofnod ac ychwanegu dau gynnig newydd.

Gadewch i ni ailadrodd yr alwad swyddogaeth olaf:

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

Dychwelodd y swyddogaeth y cofnodion wedi'u newid a'u hychwanegu. Felly y swyddogaeth get_goods yn eich galluogi i dderbyn data sydd wedi newid ers ei alwad ddiwethaf, sef sail y dull atgynhyrchu dan sylw.

Byddwn yn gadael cyhoeddi canlyniadau trwy HTTP ar ffurf JSON y tu allan i gwmpas yr erthygl hon. Gallwch ddarllen am hyn yma: https://habr.com/ru/company/mailru/blog/272141/

Gweithredu'r rhan cleient/caethwas

Gadewch i ni edrych ar sut olwg sydd ar weithrediad yr ochr sy'n derbyn. Gadewch i ni greu gofod ar yr ochr dderbyn i storio'r data sydd wedi'i lawrlwytho:

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

Mae strwythur y gofod yn debyg i strwythur y gofod yn y ffynhonnell. Ond gan nad ydym yn mynd i basio'r data a dderbyniwyd yn unrhyw le arall, y golofn row_ver nad yw yng ngofod y derbynnydd. Yn y cae id bydd dynodwyr ffynhonnell yn cael eu cofnodi. Felly, ar ochr y derbynnydd nid oes angen ei wneud yn cynyddu'n awtomatig.

Yn ogystal, mae angen lle i arbed gwerthoedd 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
})

Ar gyfer pob gofod llwytho (maes space_name) byddwn yn arbed y gwerth llwytho diwethaf yma row_ver (maes value). Mae'r golofn yn gweithredu fel yr allwedd gynradd space_name.

Gadewch i ni greu swyddogaeth i lwytho data gofod goods trwy HTTP. I wneud hyn, mae angen llyfrgell arnom sy'n gweithredu cleient HTTP. Mae'r llinell ganlynol yn llwytho'r llyfrgell ac yn cyflymu'r cleient HTTP:

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

Mae angen llyfrgell arnom hefyd ar gyfer dad-sefydlu json:

local json = require('json')

Mae hyn yn ddigon i greu swyddogaeth llwytho data:

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

Mae'r swyddogaeth yn gweithredu cais HTTP i'r cyfeiriad url ac yn ei anfon row_ver fel paramedr ac yn dychwelyd canlyniad dad-gyfresi'r cais.

Mae'r swyddogaeth ar gyfer arbed data a dderbyniwyd yn edrych fel hyn:

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

Cylch o arbed data i'r gofod goods gosod mewn trafodiad (defnyddir y ffwythiant ar gyfer hyn box.atomic) i leihau nifer y gweithrediadau disg.

Yn olaf, y swyddogaeth cydamseru gofod lleol goods gyda ffynhonnell gallwch chi ei gweithredu fel hyn:

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

Yn gyntaf rydym yn darllen y gwerth a arbedwyd yn flaenorol row_ver ar gyfer gofod goods. Os yw ar goll (y sesiwn gyfnewid gyntaf), yna rydym yn ei gymryd fel row_ver sero. Nesaf yn y cylch rydym yn perfformio lawrlwythiad tudalen wrth dudalen o'r data wedi'i newid o'r ffynhonnell yn yr url penodedig. Ar bob iteriad, rydym yn arbed y data a dderbyniwyd i'r gofod lleol priodol ac yn diweddaru'r gwerth row_ver (yn y gofod row_ver ac yn y newidyn row_ver) - cymerwch y gwerth row_ver o'r llinell olaf o ddata llwytho.

Er mwyn amddiffyn rhag dolennu damweiniol (rhag ofn y bydd gwall yn y rhaglen), y ddolen while gellir ei ddisodli gan for:

for _ = 1, max_req do ...

O ganlyniad i gyflawni'r swyddogaeth sync_goods gofod goods bydd y derbynnydd yn cynnwys y fersiynau diweddaraf o'r holl gofnodion gofod goods yn y ffynhonnell.

Yn amlwg, ni ellir darlledu dileu data yn y modd hwn. Os oes angen o'r fath, gallwch ddefnyddio marc dileu. Ychwanegu at y gofod goods cae boolean is_deleted ac yn lle dileu cofnod yn gorfforol, rydym yn defnyddio dileu rhesymegol - rydym yn gosod gwerth y maes is_deleted i mewn i ystyr true. Weithiau yn lle cae boolean is_deleted mae'n fwy cyfleus i ddefnyddio'r maes deleted, sy'n storio dyddiad-amser dileu'r cofnod yn rhesymegol. Ar ôl cyflawni dileu rhesymegol, bydd y cofnod sydd wedi'i farcio i'w ddileu yn cael ei drosglwyddo o'r ffynhonnell i'r cyrchfan (yn ôl y rhesymeg a drafodwyd uchod).

Dilyniant row_ver gellir ei ddefnyddio i drosglwyddo data o fannau eraill: nid oes angen creu dilyniant ar wahân ar gyfer pob gofod a drosglwyddir.

Edrychwyd ar ffordd effeithiol o ddyblygu data lefel uchel mewn cymwysiadau sy'n defnyddio Tarantool DBMS.

Canfyddiadau

  1. Mae Tarantool DBMS yn gynnyrch deniadol, addawol ar gyfer creu cymwysiadau llwyth uchel.
  2. Mae gan atgynhyrchu data lefel uchel nifer o fanteision o gymharu â dyblygu lefel isel.
  3. Mae'r dull ail-greu lefel uchel a drafodir yn yr erthygl yn caniatáu ichi leihau faint o ddata a drosglwyddir trwy drosglwyddo'r cofnodion hynny sydd wedi newid ers y sesiwn gyfnewid ddiwethaf yn unig.

Ffynhonnell: hab.com

Ychwanegu sylw