Репликатсияи сатҳи баланд дар DBMS Tarantool

Салом, ман барои DBMS замимаҳо эҷод мекунам Тарантул платформаест, ки аз ҷониби Mail.ru Group таҳия шудааст, ки DBMS-и баландсифат ва сервери барномаро бо забони Lua муттаҳид мекунад. Суръати баланди қарорҳо дар асоси Tarantool, аз ҷумла, аз ҳисоби дастгирии режими хотираи DBMS ва қобилияти иҷро кардани мантиқи тиҷорати барнома дар фазои суроғаи ягона бо маълумот ба даст оварда мешавад. Ҳамзамон, устувории маълумот бо истифода аз транзаксияҳои ACID таъмин карда мешавад (дар диск сабти WAL нигоҳ дошта мешавад). Tarantool дорои дастгирии дарунсохт барои такрорӣ ва sharding мебошад. Аз версияи 2.1 сар карда, дархостҳо бо забони SQL дастгирӣ карда мешаванд. Tarantool манбаи кушода аст ва тибқи иҷозатномаи соддакардашудаи BSD иҷозатнома дорад. Инчунин як версияи тиҷоратии Enterprise вуҷуд дорад.

Репликатсияи сатҳи баланд дар DBMS Tarantool
Қувватро ҳис кунед! (...ака аз иҷрои лаззат баред)

Ҳамаи чизҳои дар боло зикршуда Tarantool-ро платформаи ҷолиб барои эҷоди замимаҳои сербориш, ки бо пойгоҳи додаҳо кор мекунанд, месозад. Дар чунин барномаҳо аксар вақт ба такрори маълумот ниёз доранд.

Тавре ки дар боло зикр гардид, Tarantool нусхабардории дарунсохт дорад. Принсипи кори он иборат аз он аст, ки пай дар пай дар репликаҳо иҷро кардани ҳамаи транзаксияҳои дар журнали асосӣ (WAL) мавҷудбуда. Одатан чунин такрорӣ (мо минбаъд онро даъват хоҳем кард сатҳи паст) барои таъмини таҳаммулпазирии хатогиҳои барнома ва/ё барои тақсими сарбории хониш байни гиреҳҳои кластер истифода мешавад.

Репликатсияи сатҳи баланд дар DBMS Tarantool
Райс. 1. Репликатсия дар дохили кластер

Намунаи сенарияи алтернативӣ интиқоли додаҳои дар як пойгоҳи додаҳо ба пойгоҳи додаи дигар барои коркард/мониторинг мебошад. Дар ҳолати охирин, ҳалли муносибтар метавонад истифода шавад сатҳи баланд такрорӣ - такрори маълумот дар сатҳи мантиқи тиҷорати барнома. Онхое. Мо ҳалли тайёреро, ки дар DBMS сохта шудааст, истифода намебарем, балки дар дохили барномае, ки мо таҳия карда истодаем, репликатсияро мустақилона амалӣ мекунем. Ин равиш ҳам афзалиятҳо ва ҳам нуқсонҳо дорад. Биёед бартариҳоро номбар кунем.

1. Сарфаи трафик:

  • Шумо наметавонед ҳамаи маълумотро интиқол диҳед, балки танҳо як қисми онро интиқол диҳед (масалан, шумо метавонед танҳо баъзе ҷадвалҳо, баъзе сутунҳо ё сабтҳои ба меъёри муайян ҷавобгӯро интиқол диҳед);
  • Баръакси репликатсияи сатҳи паст, ки пайваста дар реҷаи асинхронӣ (дар версияи ҷории Tarantool - 1.10 амалӣ карда мешавад) ё синхронӣ (дар версияҳои минбаъдаи Tarantool амалӣ карда мешавад) иҷро карда мешавад, репликатсияи сатҳи баландро метавон дар сессияҳо иҷро кард (яъне. барнома аввал маълумотро ҳамоҳанг мекунад - маълумоти сеанси мубодила, пас дар репликатсия таваққуф ба амал меояд, ки пас аз он сессияи навбатии мубодила ба амал меояд ва ғайра);
  • агар сабт якчанд маротиба тағир дода шуда бошад, шумо метавонед танҳо версияи охирини онро интиқол диҳед (баръакси репликатсияи сатҳи паст, ки дар он ҳама тағиротҳои дар устод воридшуда дар репликаҳо пайдарпай навохта мешаванд).

2. Дар татбиқи мубодилаи HTTP, ки ба шумо имкон медиҳад синхронизатсияи пойгоҳи додаҳои дурдаст, мушкилот вуҷуд надорад.

Репликатсияи сатҳи баланд дар DBMS Tarantool
Райс. 2. Репликатсия тавассути HTTP

3. Сохторњои базаи маълумотњо, ки байни онњо интиќол дода мешавад, набояд якхела бошанд (гайр аз ин, дар њолати умумї, њатто истифодаи МБМ гуногун, забонњои барномасозї, платформањо ва ѓайра имконпазир аст).

Репликатсияи сатҳи баланд дар DBMS Tarantool
Райс. 3. Репликатсия дар системаҳои гетерогенӣ

Камбудӣ дар он аст, ки ба ҳисоби миёна барномасозӣ нисбат ба конфигуратсия мушкилтар/гаронарзиш аст ва ба ҷои танзим кардани функсияи дарунсохт, шумо бояд худатонро амалӣ кунед.

Агар дар вазъияти шумо бартариҳои дар боло зикршуда муҳим бошанд (ё шарти зарурӣ), пас истифодаи такрории сатҳи баланд маъно дорад. Биёед якчанд роҳҳои татбиқи репликатсияи сатҳи баландро дар DBMS Tarantool дида бароем.

Кам кардани трафик

Ҳамин тариқ, яке аз бартариҳои такрории сатҳи баланд сарфаи трафик мебошад. Барои он ки ин бартарият пурра амалӣ гардад, миқдори маълумоте, ки дар давоми ҳар як сеанси мубодила интиқол дода мешавад, кам кардан лозим аст. Албатта, мо набояд фаромӯш кунем, ки дар охири сессия қабулкунандаи маълумот бояд бо манбаъ ҳамоҳанг карда шавад (ҳадди ақал барои он қисми маълумоте, ки дар репликатсия иштирок мекунанд).

Миқдори маълумотро ҳангоми такрори сатҳи баланд чӣ гуна бояд кам кард? Як ҳалли оддӣ метавонад интихоби маълумот аз рӯи сана ва вақт бошад. Барои ин, шумо метавонед майдони санаи вақти дар ҷадвал мавҷудбударо истифода баред (агар он мавҷуд бошад). Масалан, ҳуҷҷати "фармоиш" метавонад майдони "вақти иҷрои фармоиш" дошта бошад - delivery_time. Мушкилоти ин ҳалли он дар он аст, ки арзишҳо дар ин соҳа набояд дар пайдарпайие бошанд, ки ба эҷоди фармоишҳо мувофиқат кунанд. Ҳамин тавр, мо арзиши ҳадди ниҳоии майдонро дар хотир надорем delivery_time, ки дар давоми сеанси қаблии мубодила интиқол дода мешавад ва дар давоми сеанси навбатии мубодила ҳамаи сабтҳоро бо арзиши майдони баландтар интихоб кунед delivery_time. Дар байни сеансҳои мубодила сабтҳо бо арзиши майдони камтар метавонанд илова карда шаванд delivery_time. Инчунин, фармоиш метавонист тағирот ворид кунад, ки бо вуҷуди ин ба майдон таъсир нарасонд delivery_time. Дар ҳарду ҳолат, тағиротҳо аз манбаъ ба макони таъинот интиқол дода намешаванд. Барои ҳалли ин мушкилот, ба мо лозим меояд, ки маълумотро "якҷоя" интиқол диҳем. Онхое. дар ҳар як сессияи мубодила мо ҳама маълумотро бо арзиши майдон интиқол медиҳем delivery_time, зиёда аз як нуқтаи дар гузашта (масалан, N соат аз лаҳзаи ҷорӣ). Аммо, равшан аст, ки барои системаҳои калон ин равиш хеле зиёдатист ва метавонад сарфаи трафикро, ки мо барои он кӯшиш мекунем, кам кунад. Илова бар ин, ҷадвали интиқолшаванда метавонад майдони бо санаи вақт алоқаманд надошта бошад.

Як роҳи ҳалли дигар, ки аз ҷиҳати татбиқ мураккабтар аст, ин эътирофи гирифтани маълумот мебошад. Дар ин ҳолат, дар давоми ҳар як сессияи мубодила, ҳама маълумот интиқол дода мешавад, ки гирифтани онҳо аз ҷониби гиранда тасдиқ карда нашудааст. Барои татбиқи ин, ба шумо лозим меояд, ки сутуни мантиқиро ба ҷадвали манбаъ илова кунед (масалан, is_transferred). Агар қабулкунанда гирифтани сабтро эътироф кунад, майдони мувофиқ арзишро мегирад true, ки пас аз он вуруд аст, дигар дар табодули ҷалб. Ин варианти татбиқ дорои нуқсонҳои зерин мебошад. Аввалан, барои ҳар як сабти интиқолшуда бояд тасдиқнома таҳия ва фиристода шавад. Тақрибан гӯем, ин метавонад бо ду баробар зиёд шудани ҳаҷми интиқол ва боиси дучанд зиёд шудани шумораи сафарҳои гардишшаванда бошад. Сониян, имкони фиристодани як сабт ба якчанд қабулкунанда вуҷуд надорад (қабулкунандаи аввалине, ки қабул мекунад, барои худ ва барои ҳамаи дигарон квитансияро тасдиқ мекунад).

Усуле, ки камбудиҳои дар боло овардашударо надорад, илова кардани сутун ба ҷадвали интиқолшуда барои пайгирии тағирот дар сатрҳои он мебошад. Чунин сутун метавонад аз навъи санаи вақт бошад ва бояд аз ҷониби барнома ба вақти ҷорӣ ҳар дафъа илова/тағйир додани сабтҳо (ба таври атомӣ бо илова/тағйир) муқаррар/навсозӣ карда шавад. Ба сифати мисол сутунро даъват мекунем update_time. Бо захира кардани арзиши максималии майдони ин сутун барои сабтҳои интиқолшуда, мо метавонем сеанси навбатии мубодиларо бо ин арзиш оғоз кунем (сабтҳоро бо арзиши майдон интихоб кунед update_time, зиёдтар аз арзиши қаблан захирашуда). Мушкилот бо равиши охирин дар он аст, ки тағироти додаҳо метавонанд дар гурӯҳҳо рух диҳанд. Дар натиҷаи арзишҳои майдон дар сутун update_time метавонад беназир бошад. Ҳамин тариқ, ин сутунро барои баровардани маълумот қисман (саҳифа ба саҳифа) истифода бурдан мумкин нест. Барои намоиш додани саҳифа ба саҳифа, шумо бояд механизмҳои иловагиеро ихтироъ кунед, ки эҳтимолан самаранокии хеле паст доранд (масалан, аз базаи маълумот дарёфт кардани ҳама сабтҳо бо арзиши update_time баландтар аз як додашуда ва истеҳсоли шумораи муайяни сабтҳо, аз ҷуброни муайян аз аввали интихоб).

Шумо метавонед самаранокии интиқоли маълумотро тавассути каме беҳтар кардани равиши қаблӣ беҳтар кунед. Барои ин, мо навъи бутунро (тамоми дароз) ҳамчун арзишҳои майдони сутун барои пайгирии тағирот истифода мебарем. Биёед сутунро номбар кунем row_ver. Қимати майдони ин сутун бояд ҳар дафъае, ки сабт/тағйир дода шавад, танзим/навсозӣ карда шавад. Аммо дар ин ҳолат, ба майдон на санаи ҷорӣ таъин карда мешавад, балки арзиши баъзе ҳисобкунакҳо як маротиба зиёд карда мешавад. Дар натича колонна row_ver дорои арзишҳои беназир хоҳад буд ва онҳоро на танҳо барои намоиши додаҳои "delta" (маълумот аз охири сеанси қаблии мубодила иловашуда/тағйир додаанд), балки барои содда ва самаранок тақсим кардани он ба саҳифаҳо истифода бурдан мумкин аст.

Усули охирини пешниҳодшудаи кам кардани ҳаҷми додаҳо дар доираи репликатсияи сатҳи баланд ба назари ман беҳтарин ва универсалӣ ба назар мерасад. Биёед онро муфассалтар дида бароем.

Интиқоли маълумот бо истифода аз ҳисобкунаки версияи сатр

Амалисозии қисми сервер/мастер

Дар MS SQL Server як намуди махсуси сутун барои татбиқи ин равиш мавҷуд аст - rowversion. Ҳар як базаи маълумот ҳисобкунак дорад, ки ҳар дафъае, ки сабт дар ҷадвале, ки сутуни монанд дорад, илова/тағйир дода мешавад, як маротиба зиёд мешавад rowversion. Қимати ин ҳисобкунак ба майдони ин сутун дар сабти иловашуда/тағиршуда ба таври худкор таъин карда мешавад. DBMS Tarantool механизми шабеҳи дарунсохт надорад. Хол он ки дар Тарантул дастй чорй кардани он душвор нест. Биёед бубинем, ки ин чӣ тавр анҷом дода мешавад.

Аввалан, истилоҳоти каме: ҷадвалҳо дар Tarantool фосила номида мешаванд ва сабтҳо tuple номида мешаванд. Дар Tarantool шумо метавонед пайдарпай эҷод кунед. Пайдарпайҳо ҷуз генераторҳои номбаршудаи арзишҳои бутуни тартибёфта чизе нестанд. Онхое. ин маҳз он чизест, ки мо барои мақсадҳои худ ниёз дорем. Дар поён мо чунин пайдарпайро эҷод мекунем.

Пеш аз иҷрои ягон амалиёти пойгоҳи додаҳо дар Tarantool, шумо бояд фармони зеринро иҷро кунед:

box.cfg{}

Дар натиҷа, Tarantool ба навиштани аксҳои пойгоҳи додаҳо ва гузоришҳои транзаксия ба феҳристи ҷорӣ шурӯъ мекунад.

Биёед пайдарпай эҷод кунем row_version:

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

Интихоб if_not_exists имкон медиҳад, ки скрипти эҷод чанд маротиба иҷро шавад: агар объект мавҷуд бошад, Tarantool кӯшиш намекунад, ки онро дубора эҷод кунад. Ин хосият дар ҳама фармонҳои минбаъдаи DDL истифода мешавад.

Биёед ҳамчун як фосила эҷод кунем.

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

Дар ин ҷо мо номи фазоро муқаррар мекунем (goods), номҳои майдонҳо ва намудҳои онҳо.

Майдонҳои худкор афзоишёбанда дар Tarantool инчунин бо истифода аз пайдарпайҳо сохта мешаванд. Биёед калиди ибтидоии худкорро аз рӯи майдон эҷод кунем 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 якчанд намуди индексҳоро дастгирӣ мекунад. Индексҳои бештар истифодашаванда намудҳои TREE ва HASH мебошанд, ки ба сохторҳои мувофиқ ба ном асос ёфтаанд. TREE як навъи индекси универсалтарин аст. Он ба шумо имкон медиҳад, ки маълумотро ба таври муташаккил дарёфт кунед. Аммо барои интихоби баробарӣ, HASH мувофиқтар аст. Аз ин рӯ, тавсия дода мешавад, ки HASH-ро барои калиди ибтидоӣ истифода барем (ки мо ин корро кардем).

Барои истифода бурдани сутун row_ver барои интиқол додани маълумоти тағирёфта, шумо бояд арзишҳои пайдарпайро ба майдонҳои ин сутун пайваст кунед row_ver. Аммо бар хилофи калиди ибтидоӣ, арзиши майдони сутун row_ver на танхо дар вакти илова кардани сабтхои нав, балки хангоми тагйир додани сабтхои мавчуда хам бояд як баробар зиёд шавад. Барои ин шумо метавонед триггерҳоро истифода баред. Tarantool ду намуди триггерҳои фазо дорад: before_replace и on_replace. Ҳар вақте ки маълумот дар фазо тағир меёбад, триггерҳо кор мекунанд (барои ҳар як наворе, ки аз тағирот зарар дидааст, функсияи триггер оғоз мешавад). Баръакси on_replace, before_replace-триггерҳо ба шумо имкон медиҳанд, ки маълумоти навореро, ки барои он триггер иҷро мешавад, тағир диҳед. Бинобар ин, навъи охирини триггерҳо ба мо мувофиқанд.

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

Триггери зерин арзиши майдонро иваз мекунад row_ver tuple нигоҳ дошта то арзиши навбатии пайдарпай row_version.

Барои он ки аз кайхон маълумот гирифта тавонанд goods аз рӯи сутун row_ver, биёед индекс эҷод кунем:

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

Навъи индекс - дарахт (TREE), зеро мо бояд маълумотро бо тартиби афзоиши арзишҳои сутун истихроҷ кунем row_ver.

Биёед баъзе маълумотро ба фазо илова кунем:

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}

Зеро Майдони аввал ҳисобкунаки автоматии афзоишёбанда аст; мо ба ҷои сифр мегузарем. Tarantool ба таври худкор арзиши навбатиро иваз мекунад. Ба ҳамин монанд, ҳамчун арзиши майдонҳои сутун row_ver шумо метавонед сифр гузарад - ё арзиши муайян нест, дар ҳама, зеро ин сутун дар фазо чои охиринро ишгол мекунад.

Биёед натиҷаи воридкуниро тафтиш кунем:

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

Тавре ки шумо мебинед, майдонҳои аввал ва охирин ба таври худкор пур карда мешаванд. Акнун навиштани функсия барои саҳифа ба саҳифа боркунии тағйироти фазо осон хоҳад буд 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

Функсия ҳамчун параметр арзишро мегирад row_ver, аз он сар карда тағиротро холӣ кардан лозим аст ва як қисми маълумоти тағирёфтаро бармегардонад.

Намунаи маълумот дар Tarantool тавассути индексҳо анҷом дода мешавад. Функсия get_goods итераторро аз рӯи индекс истифода мебарад row_ver барои гирифтани маълумоти тағирёфта. Навъи итератор GT аст (Бузургтар аз, бузургтар аз). Ин маънои онро дорад, ки итератор арзишҳои индексро аз калиди додашуда (қимати майдон) пай дар пай мегузарад. row_ver).

Итератор наворҳоро бармегардонад. Барои он ки минбаъд маълумотро тавассути HTTP интиқол дода тавонед, кортҳоро ба сохторе, ки барои силсиласозии минбаъда мувофиқ аст, табдил додан лозим аст. Мисол барои ин функсияи стандартиро истифода мебарад tomap. Ба ҷои истифода tomap шумо метавонед функсияи худро нависед. Масалан, мо метавонем номи майдонро тағир диҳем name, аз майдон нагузаранд code ва майдонро илова кунед 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

Андозаи саҳифаи маълумоти баромад (шумораи сабтҳо дар як қисм) аз ҷониби тағирёбанда муайян карда мешавад page_size. Дар мисол арзиши page_size аст 5. Дар як барномаи воқеӣ, андозаи саҳифа одатан муҳимтар. Он аз андозаи миёнаи tuple фазо вобаста аст. Андозаи оптималии саҳифаро тавассути чен кардани вақти интиқоли маълумот ба таври ампирикӣ муайян кардан мумкин аст. Чӣ қадаре ки андозаи саҳифа калон бошад, ҳамон қадар шумораи гардишҳо байни тарафҳои ирсолкунанда ва қабулкунанда камтар мешавад. Бо ин роҳ шумо метавонед вақти умумии зеркашии тағиротро кам кунед. Аммо, агар андозаи саҳифа хеле калон бошад, мо барои сериализатсияи намуна дар сервер вақти зиёд сарф мекунем. Дар натиҷа, дар коркарди дархостҳои дигар, ки ба сервер меоянд, метавонад таъхир шавад. Параметр page_size аз файли конфигуратсия бор кардан мумкин аст. Барои ҳар як фазои интиқолшуда шумо метавонед арзиши худро муқаррар кунед. Аммо, барои аксари ҷойҳо арзиши пешфарз (масалан, 100) метавонад мувофиқ бошад.

Биёед функсияро иҷро кунем 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
...

Биёед арзиши майдонро гирем row_ver аз сатри охирин ва боз функсияро даъват кунед:

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

Бори дигар:

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

Тавре ки шумо мебинед, вақте ки ин тавр истифода мешавад, функсия ҳамаи сабтҳои фазоиро саҳифа ба саҳифа бармегардонад goods. Саҳифаи охиринро интихоби холӣ пайгирӣ мекунад.

Биёед ба фазо тағирот ворид кунем:

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

Мо арзиши майдонро тағир додем name барои як вуруд ва ду вурудоти нав илова.

Биёед занги охирини функсияро такрор кунем:

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

Функсия сабтҳои тағирёфта ва иловашударо баргардонд. Ҳамин тавр, функсия get_goods ба шумо имкон медиҳад, ки маълумотеро, ки пас аз занги охиринаш тағйир ёфтааст, қабул кунед, ки асоси усули такрории баррасишаванда мебошад.

Мо додани натиҷаҳоро тавассути HTTP дар шакли JSON берун аз доираи ин мақола мегузорем. Шумо метавонед дар ин ҷо бихонед: https://habr.com/ru/company/mailru/blog/272141/

Амалисозии қисми муштарӣ/ғулом

Биёед бубинем, ки татбиқи ҷониби қабулкунанда чӣ гуна аст. Биёед дар тарафи қабул ҷой барои нигоҳ доштани маълумоти зеркашидашуда эҷод кунем:

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

Сохтори фазо ба сохтори фазо дар сарчашма шабоҳат дорад. Аммо азбаски мо маълумоти гирифташударо ба ягон чои дигар гузаронем, сутун row_ver дар фазои қабулкунанда нест. Дар майдон id идентификаторхои манбаъ кайд карда мешаванд. Аз ин рӯ, дар тарафи қабулкунанда лозим нест, ки он ба таври худкор афзоиш ёбад.

Илова бар ин, мо барои захира кардани арзишҳо ҷой лозим аст 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
})

Барои ҳар як фазои боршуда (майдон space_name) мо арзиши охирини боршударо дар ин ҷо захира мекунем row_ver (майдон value). Сутун ҳамчун калиди асосӣ амал мекунад space_name.

Биёед як функсияро барои бор кардани маълумоти фазоӣ созем goods тавассути HTTP. Барои ин ба мо китобхонае лозим аст, ки муштарии HTTP-ро амалӣ мекунад. Сатри зерин китобхонаро бор мекунад ва мизоҷи HTTP-ро эҷод мекунад:

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

Мо инчунин ба китобхона барои deserialization json ниёз дорем:

local json = require('json')

Ин барои эҷоди функсияи боркунии маълумот кифоя аст:

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

Функсия дархости HTTP-ро ба суроғаи url иҷро мекунад ва онро мефиристад row_ver ҳамчун параметр ва натиҷаи ғайрисериявии дархостро бармегардонад.

Функсияи нигоҳдории маълумоти гирифташуда чунин менамояд:

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

Давраи сарфаи маълумот ба фазо goods дар транзаксия ҷойгир карда шудааст (функсия барои ин истифода мешавад box.atomic) барои кам кардани шумораи амалиёти диск.

Ниҳоят, функсияи ҳамоҳангсозии фазои маҳаллӣ goods бо як манбаъ шумо метавонед онро ба таври зерин иҷро кунед:

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

Аввалан мо арзиши қаблан захирашударо мехонем row_ver барои фазо goods. Агар он нопадид бошад (сессияи мубодилаи аввал), пас мо онро ҳамчун row_ver сифр. Минбаъд дар давра мо зеркашии саҳифа ба саҳифаи маълумоти тағирёфтаро аз манбаъ дар URL-и муайяншуда иҷро мекунем. Дар ҳар як такрор, мо маълумоти гирифташударо дар фазои мувофиқи маҳаллӣ нигоҳ медорем ва арзишро навсозӣ мекунем row_ver (дар фазо row_ver ва дар тағирёбанда row_ver) - арзишро гиред row_ver аз сатри охирини маълумоти боршуда.

Барои муҳофизат аз гардиши тасодуфӣ (дар сурати хато дар барнома), давра while иваз кардан мумкин аст for:

for _ = 1, max_req do ...

Дар натичаи ичрои вазифаи sync_goods фазо goods Дар приёмник версияхои охирини хамаи сабтхои кайхонй мавчуданд goods дар манбаъ.

Аён аст, ки несткунии маълумотро бо ин роҳ пахш кардан мумкин нест. Агар чунин эҳтиёҷ вуҷуд дошта бошад, шумо метавонед аломати ҳазфкуниро истифода баред. Ба фазо илова кунед goods майдони булӣ is_deleted ва ба ҷои аз ҷиҳати ҷисмонӣ нест кардани сабт, мо ҳазфи мантиқиро истифода мебарем - мо арзиши майдонро муқаррар мекунем is_deleted ба маъно true. Баъзан ба ҷои майдони булӣ is_deleted истифода бурдани киштзор кулайтар аст deleted, ки санаи вақти ҳазфи мантиқии сабтро нигоҳ медорад. Пас аз анҷом додани ҳазфи мантиқӣ, сабти барои ҳазф нишондодашуда аз манбаъ ба макони таъинот интиқол дода мешавад (мувофиқи мантиқи дар боло баррасӣшуда).

Пайдарпаӣ row_ver барои интиқоли маълумот аз дигар ҷойҳо истифода бурдан мумкин аст: барои ҳар як фазои интиқолшуда пайдарпайии алоҳида эҷод кардан лозим нест.

Мо роҳи самараноки такрори маълумотҳои сатҳи баландро дар барномаҳо бо истифода аз DBMS Tarantool дида баромадем.

натиҷаҳои

  1. Tarantool DBMS як маҳсулоти ҷолиб ва ояндадор барои эҷоди барномаҳои пурбор аст.
  2. Репликатсияи маълумот дар сатҳи баланд нисбат ба такрори сатҳи паст як қатор бартариҳо дорад.
  3. Усули такрории сатҳи баланд, ки дар мақола баррасӣ шудааст, ба шумо имкон медиҳад, ки миқдори маълумоти интиқолшударо тавассути интиқоли танҳо он сабтҳое, ки пас аз сессияи охирини мубодила иваз шудаанд, кам кунед.

Манбаъ: will.com

Илова Эзоҳ