Réplikasi tingkat luhur dina Tarantool DBMS

Halo, Kuring keur nyieun aplikasi pikeun DBMS Tarantool nyaéta platform anu dikembangkeun ku Mail.ru Group anu ngagabungkeun DBMS kinerja luhur sareng server aplikasi dina basa Lua. Kecepatan luhur solusi dumasar kana Tarantool kahontal, khususna, kusabab dukungan pikeun modeu mémori DBMS sareng kamampuan pikeun ngalaksanakeun logika bisnis aplikasi dina rohangan alamat tunggal sareng data. Dina waktos anu sami, kegigihan data dipastikeun nganggo transaksi ACID (log WAL dijaga dina disk). Tarantool ngagaduhan dukungan anu diwangun pikeun réplikasi sareng sharding. Mimitian ti vérsi 2.1, patarosan dina basa SQL dirojong. Tarantool mangrupikeun sumber terbuka sareng dilisensikeun dina lisénsi BSD Sederhana. Aya ogé versi perusahaan komérsial.

Réplikasi tingkat luhur dina Tarantool DBMS
Ngarasakeun kakuatan! (...alias ngarasakeun pagelaran)

Sadayana di luhur ngajadikeun Tarantool platform anu pikaresepeun pikeun nyiptakeun aplikasi beban tinggi anu tiasa dianggo sareng pangkalan data. Dina aplikasi sapertos kitu, sering aya kabutuhan pikeun réplikasi data.

Sakumaha didadarkeun di luhur, Tarantool geus diwangun-di réplikasi data. Prinsip operasina nyaéta ngaéksekusi sacara berurutan dina réplika sadaya transaksi anu aya dina master log (WAL). Biasana réplikasi sapertos kitu (urang salajengna bakal nyebatna tingkat handap) dipaké pikeun mastikeun kasabaran kasalahan aplikasi jeung / atawa ngadistribusikaeun beban bacaan antara titik klaster.

Réplikasi tingkat luhur dina Tarantool DBMS
Sangu. 1. Réplikasi dina klaster

Conto skenario alternatif bakal nransferkeun data anu dijieun dina hiji database ka database sejen pikeun ngolah/monitoring. Dina kasus anu terakhir, solusi anu langkung saé tiasa dianggo tingkat luhur réplikasi - réplikasi data dina tingkat logika bisnis aplikasi. Jelema. Kami henteu nganggo solusi siap-siap anu diwangun dina DBMS, tapi ngalaksanakeun réplikasi sorangan dina aplikasi anu kami kembangkeun. Pendekatan ieu gaduh kaunggulan sareng kalemahan. Hayu urang daptar kaunggulan.

1. Hemat Lalu Lintas:

  • Anjeun teu bisa nransper sakabéh data, tapi ngan bagian tina eta (contona, Anjeun ngan bisa nransper sababaraha tabel, sababaraha kolom maranéhanana atawa rékaman nu minuhan hiji kriteria tangtu);
  • Teu kawas réplikasi tingkat low, anu dipigawé terus-terusan dina Asynchronous (dilaksanakeun dina versi kiwari Tarantool - 1.10) atawa sinkron (pikeun dilaksanakeun dina versi saterusna Tarantool) mode, réplikasi tingkat luhur bisa dipigawé dina sesi (ie, nu. aplikasi mimiti nyingkronkeun data - data sési bursa, teras aya jeda dina réplikasi, nu satutasna sési bursa salajengna lumangsung, jsb);
  • lamun rékaman geus robah sababaraha kali, Anjeun ngan bisa nransper versi panganyarna na (teu kawas réplikasi-tingkat low, nu sagala parobahan dijieun dina master bakal diputer deui sequentially on réplika).

2. Aya henteu kasusah jeung nerapkeun bursa HTTP, nu ngidinan Anjeun pikeun nyingkronkeun database jauh.

Réplikasi tingkat luhur dina Tarantool DBMS
Sangu. 2. Réplikasi leuwih HTTP

3. Struktur database antara nu data ditransfer teu kudu sarua (malihan, dina kasus umum, malah mungkin ngagunakeun DBMSs béda, basa programming, platform, jsb).

Réplikasi tingkat luhur dina Tarantool DBMS
Sangu. 3. Réplikasi dina sistem hétérogén

The downside nyaeta, rata-rata, programming leuwih hese / ongkosna mahal ti konfigurasi, sarta tinimbang ngaropéa pungsionalitas diwangun-di, anjeun bakal kudu nerapkeun sorangan.

Upami dina kaayaan anjeun kaunggulan di luhur penting pisan (atanapi mangrupikeun kaayaan anu diperyogikeun), maka masuk akal ngagunakeun réplikasi tingkat luhur. Hayu urang tingali sababaraha cara pikeun nerapkeun réplikasi data tingkat luhur dina Tarantool DBMS.

Ngaminimalkeun lalulintas

Janten, salah sahiji kaunggulan réplikasi tingkat luhur nyaéta penghematan lalu lintas. Supados kaunggulan ieu kawujud pinuh, perlu pikeun ngaleutikan jumlah data ditransfer salila unggal sési bursa. Tangtosna, urang henteu kedah hilap yén dina ahir sési, panampi data kedah disingkronkeun sareng sumberna (sahenteuna pikeun bagian tina data anu kalibet dina réplikasi).

Kumaha ngaminimalkeun jumlah data anu ditransfer salami réplikasi tingkat luhur? Solusi anu gampang nyaéta milih data dumasar kana tanggal sareng waktos. Jang ngalampahkeun ieu, anjeun tiasa nganggo widang tanggal-waktos anu tos aya dina tabél (upami aya). Salaku conto, hiji dokumen "pesenan" tiasa gaduh kolom "waktos palaksanaan pesenan anu diperyogikeun" - delivery_time. Masalah sareng solusi ieu nyaéta nilai-nilai dina widang ieu henteu kedah dina urutan anu didamel. Janten urang teu tiasa nginget nilai lapangan maksimal delivery_time, dikirimkeun salila sési bursa saméméhna, sarta salila sési bursa salajengna pilih sadaya rékaman kalawan nilai widang luhur delivery_time. Rékam kalayan nilai médan anu langkung handap tiasa ditambihan antara sési bursa delivery_time. Ogé, urutan bisa geus undergone parobahan, nu Tapi teu mangaruhan sawah delivery_time. Dina dua kasus, parobihan moal dialihkeun tina sumber ka tujuan. Pikeun ngajawab masalah ieu, urang bakal perlu mindahkeun data "tumpang tindih". Jelema. dina unggal sési bursa kami bakal nransper sadaya data sareng nilai lapangan delivery_time, ngaleuwihan sababaraha titik nu geus kaliwat (contona, N jam ti momen ayeuna). Sanajan kitu, éta écés yén pikeun sistem badag pendekatan ieu kacida kaleuleuwihan sarta bisa ngurangan tabungan lalulintas nu urang striving pikeun nanaon. Sajaba ti éta, tabel nu keur ditransfer bisa jadi teu boga widang pakait sareng tanggal-waktu.

Solusi anu sanés, langkung rumit dina hal palaksanaan, nyaéta ngaku nampi data. Dina hal ieu, salila unggal sési bursa, sadaya data dikirimkeun, resi nu teu acan dikonfirmasi ku panarima. Pikeun ngalaksanakeun ieu, anjeun kedah nambihan kolom Boolean kana tabel sumber (contona, is_transferred). Lamun panarima acknowledges resi rékaman, widang pakait nyokot nilai true, nu satutasna entri geus euweuh aub dina bursa. Pilihan palaksanaan ieu ngagaduhan kalemahan di handap ieu. Kahiji, pikeun tiap rékaman ditransfer, hiji pangakuan kudu dihasilkeun sarta dikirim. Sacara kasar, ieu tiasa dibandingkeun sareng ngagandakeun jumlah data anu ditransfer sareng nyababkeun ngagandakeun jumlah perjalanan. Bréh, teu aya kamungkinan pikeun ngirim rékaman anu sarua ka sababaraha panarima (panarima pangheulana narima bakal mastikeun resi keur dirina jeung sakabeh batur).

Métode anu henteu ngagaduhan kalemahan anu dijelaskeun di luhur nyaéta nambihan kolom kana tabel anu ditransfer pikeun ngalacak parobahan dina barisan na. Kolom sapertos kitu tiasa janten jinis tanggal-waktos sareng kedah disetél / diropéa ku aplikasi kana waktos ayeuna unggal waktos rékaman ditambah / dirobah (sacara atom sareng tambihan / robih). Salaku conto, hayu urang nelepon kolom update_time. Ku nyimpen nilai médan maksimum kolom ieu pikeun rékaman ditransfer, urang bisa ngamimitian sési bursa salajengna kalawan nilai ieu (pilih rékaman jeung nilai widang update_time, ngaleuwihan nilai nu disimpen saméméhna). Masalah sareng pendekatan anu terakhir nyaéta parobahan data tiasa lumangsung dina bets. Salaku hasil tina nilai widang dina kolom update_time bisa jadi teu unik. Ku kituna, kolom ieu teu bisa dipaké pikeun porsi (halaman-demi-kaca) kaluaran data. Pikeun ningalikeun halaman data ku halaman, anjeun kedah nyiptakeun mékanisme tambahan anu paling dipikaresep bakal gaduh efisiensi anu handap pisan (contona, nyandak tina pangkalan data sadaya rékaman anu gaduh nilai. update_time leuwih luhur ti hiji dibikeun tur ngahasilkeun jumlah nu tangtu rékaman, mimitian ti offset tangtu ti mimiti sampel).

Anjeun tiasa ningkatkeun efisiensi transfer data ku rada ningkatkeun pendekatan saméméhna. Jang ngalampahkeun ieu, urang bakal ngagunakeun tipe integer (integer panjang) salaku nilai kolom kolom pikeun nyukcruk parobahan. Hayu urang ngaranan kolom row_ver. Nilai widang kolom ieu masih kudu disetel / diropéa unggal waktos rékaman dijieun / dirobah. Tapi dina hal ieu, sawah moal ditugaskeun tanggal-waktos ayeuna, tapi nilai sababaraha counter, ngaronjat ku hiji. Hasilna, kolom row_ver bakal ngandung nilai-nilai unik sareng tiasa dianggo henteu ngan ukur pikeun nampilkeun data "delta" (data ditambah / dirobih ti tungtung sési bursa sateuacana), tapi ogé sacara sederhana sareng efektif ngarecahna kana halaman.

Metodeu anu diusulkeun terakhir pikeun ngaminimalkeun jumlah data anu ditransfer dina kerangka réplikasi tingkat luhur sigana anu paling optimal sareng universal. Hayu urang nempo eta dina leuwih jéntré.

Ngalirkeun Data Ngagunakeun Counter Versi Baris

Palaksanaan bagian server / master

Dina MS SQL Server, aya tipe kolom husus pikeun nerapkeun pendekatan ieu - rowversion. Unggal database ngabogaan counter nu naek ku hiji unggal waktos rékaman ditambahkeun / robah dina tabel nu boga kolom kawas rowversion. Nilai counter ieu otomatis ditugaskeun ka widang kolom ieu dina ditambahkeun / rékaman robah. Tarantool DBMS henteu gaduh mékanisme anu sami. Nanging, dina Tarantool henteu sesah pikeun nerapkeunana sacara manual. Hayu urang tingali kumaha ieu dilakukeun.

Kahiji, terminologi saeutik: tabel di Tarantool disebut spasi, sarta rékaman disebut tuples. Dina Tarantool anjeun tiasa nyiptakeun sekuen. Runtuyan teu leuwih ti generator ngaranna tina nilai integer maréntahkeun. Jelema. ieu persis naon urang kudu keur kaperluan urang. Di handap ieu urang bakal nyieun runtuyan saperti.

Sateuacan ngalakukeun operasi database di Tarantool, anjeun kedah ngajalankeun paréntah di handap ieu:

box.cfg{}

Hasilna, Tarantool bakal ngamimitian nyerat snapshots database sareng log transaksi kana diréktori ayeuna.

Hayu urang nyieun runtuyan row_version:

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

Pilihan if_not_exists ngamungkinkeun naskah kreasi bisa dieksekusi sababaraha kali: lamun obyék aya, Tarantool moal coba nyieun deui. Pilihan ieu bakal dianggo dina sadaya paréntah DDL salajengna.

Hayu urang nyieun spasi salaku conto.

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

Di dieu urang nyetel ngaran spasi (goods), ngaran widang sareng jinisna.

Widang nambahan otomatis di Tarantool ogé didamel nganggo sekuen. Hayu urang nyieun konci primér nambahan otomatis dumasar widang 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 ngadukung sababaraha jinis indéks. Indéks anu paling sering dianggo nyaéta jinis tangkal sareng HASH, anu dumasar kana struktur anu cocog sareng nami. TREE mangrupikeun jinis indéks anu paling serbaguna. Eta ngidinan Anjeun pikeun meunangkeun data dina ragam diatur. Tapi pikeun pilihan sarua, HASH leuwih cocog. Sasuai, éta sasaena ngagunakeun HASH pikeun konci primér (anu kami lakukeun).

Pikeun ngagunakeun kolom row_ver Pikeun nransferkeun data anu dirobih, anjeun kedah ngabeungkeut nilai sekuen kana widang kolom ieu row_ver. Tapi teu kawas konci primér, nilai kolom kolom row_ver kedah ningkat ku hiji henteu ngan nalika nambahkeun rékaman anyar, tapi ogé nalika ngarobah nu geus aya. Anjeun tiasa nganggo pemicu pikeun ieu. Tarantool ngagaduhan dua jinis pemicu rohangan: before_replace и on_replace. Pemicu dipecat iraha waé data dina rohangan robih (pikeun unggal tuple anu kapangaruhan ku parobihan, fungsi pemicu diluncurkeun). Beda jeung on_replace, before_replace-triggers ngidinan Anjeun pikeun ngaropea data tina tuple nu pemicu nu dieksekusi. Sasuai, tipe panungtungan pemicu cocog kami.

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

Pemicu handap ngagantikeun nilai widang row_ver disimpen tuple kana nilai salajengna runtuyan row_version.

Dina raraga bisa nimba data ti spasi goods ku kolom row_ver, hayu urang jieun indéks:

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

Jenis indéks - tangkal (TREE), sabab urang kedah nimba data dina urutan naek tina nilai dina kolom row_ver.

Hayu urang tambahkeun sababaraha data kana rohangan:

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}

Sabab Widang kahiji mangrupikeun konter naékna otomatis; urang ngalangkungan nil. Tarantool bakal otomatis ngagantikeun nilai salajengna. Nya kitu, salaku nilai kolom kolom row_ver anjeun tiasa lulus nihil - atanapi henteu nangtukeun nilai pisan, sabab kolom ieu nempatan posisi panungtungan dina spasi.

Hayu urang pariksa hasil sisipan:

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

Sakumaha anjeun tiasa tingali, widang kahiji jeung panungtung dieusian otomatis. Ayeuna bakal gampang nulis fungsi pikeun unggah halaman-demi-halaman parobahan rohangan 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

Fungsi nyokot salaku parameter nilai row_ver, mimitian ti mana perlu pikeun ngabongkar momotanana parobahan, sarta mulangkeun sabagian tina data robah.

Sampling data dina Tarantool dilakukeun ngaliwatan indéks. Fungsi get_goods ngagunakeun hiji iterator ku indéks row_ver pikeun nampa data robah. Tipe Iterator nyaéta GT (Greater Than, Greater than). Ieu ngandung harti yén iterator bakal sequentially melintasi nilai indéks mimitian ti konci lulus (nilai widang row_ver).

Iterator mulih tuples. Dina raraga salajengna bisa mindahkeun data via HTTP, perlu pikeun ngarobah tuples kana struktur merenah pikeun serialization saterusna. Conto ngagunakeun fungsi standar pikeun ieu tomap. Gantina ngagunakeun tomap anjeun tiasa nyerat fungsi anjeun nyalira. Contona, urang meureun hoyong ngaganti ngaran hiji widang name, ulah ngaliwat ka lapang code jeung nambahkeun widang 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

Ukuran halaman tina data kaluaran (jumlah rékaman dina hiji porsi) ditangtukeun ku variabel page_size. Dina conto nilai page_size mangrupa 5. Dina program nyata, ukuran kaca biasana leuwih penting. Ieu gumantung kana ukuran rata-rata tuple spasi. Ukuran kaca optimal bisa ditangtukeun sacara émpiris ku cara ngukur waktu mindahkeun data. Beuki gede ukuran kaca, beuki leutik jumlah roundtrips antara sisi ngirim jeung narima. Ku cara ieu Anjeun bisa ngurangan waktu sakabéh pikeun ngundeur parobahanana. Sanajan kitu, lamun ukuran kaca badag teuing, urang bakal méakkeun panjang teuing dina server serializing sampel. Hasilna, meureun aya telat dina ngolah requests séjén datang ka server. Parameter page_size tiasa dimuat tina file konfigurasi. Pikeun unggal spasi dikirimkeun, Anjeun bisa nyetel nilai sorangan. Nanging, pikeun sabagéan ageung rohangan, nilai standar (contona, 100) tiasa cocog.

Hayu urang ngajalankeun fungsi 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
...

Hayu urang nyandak nilai widang row_ver ti baris panungtungan sarta nelepon deui fungsi:

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

Sakali deui:

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

Sakumaha anjeun tiasa tingali, nalika dianggo ku cara ieu, fungsina ngabalikeun sadaya rékaman rohangan halaman ku halaman goods. Kaca panungtungan dituturkeun ku pilihan kosong.

Hayu urang robih kana rohangan:

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

Kami parantos ngarobih nilai lapangan name pikeun hiji éntri sareng nambihan dua éntri énggal.

Hayu urang ngulang panggero fungsi panungtungan:

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

fungsi nu balik rékaman dirobah sarta ditambahkeun. Jadi fungsina get_goods ngidinan Anjeun pikeun nampa data nu geus robah ti panggero panungtungan na, nu jadi dadasar metoda réplikasi dina tinimbangan.

Urang bakal ninggalkeun penerbitan hasil via HTTP dina bentuk JSON luar ruang lingkup artikel ieu. Anjeun tiasa maca ngeunaan ieu di dieu: https://habr.com/ru/company/mailru/blog/272141/

Palaksanaan bagian klien / budak

Hayu urang tingali kumaha palaksanaan sisi panarima. Hayu urang jieun spasi dina sisi panarima pikeun nyimpen data nu diundeur:

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

Struktur rohangan nyarupaan struktur rohangan dina sumberna. Tapi saprak urang teu bade lulus data narima mana sejenna, kolom row_ver teu aya dina rohangan panarima. Di sawah id identifiers sumber bakal dirékam. Ku alatan éta, dina sisi panarima teu kudu nyieun otomatis-incrementing.

Salaku tambahan, urang peryogi rohangan pikeun ngahémat nilai 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
})

Pikeun unggal rohangan anu dimuat (field space_name) urang bakal nyimpen nilai dimuat panungtungan dieu row_ver (sawah value). Kolom tindakan salaku konci primér space_name.

Hayu urang nyieun fungsi pikeun muka data spasi goods via HTTP. Jang ngalampahkeun ieu, urang peryogi perpustakaan nu implements hiji klien HTTP. Baris di handap ieu muka perpustakaan jeung instantiates klien HTTP:

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

Urang ogé peryogi perpustakaan pikeun deserialization json:

local json = require('json')

Ieu cukup pikeun nyieun fungsi loading 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

Fungsina ngalaksanakeun pamundut HTTP ka alamat url sareng ngirimkeunana row_ver salaku parameter sarta mulih hasil deserialized pamundut teh.

Fungsi pikeun nyimpen data anu ditampi sapertos kieu:

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

Siklus nyimpen data ka spasi goods disimpen dina transaksi (fungsina dianggo pikeun ieu box.atomic) pikeun ngurangan jumlah operasi disk.

Tungtungna, fungsi sinkronisasi spasi lokal goods kalayan sumber anjeun tiasa nerapkeun sapertos kieu:

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

Kahiji urang baca nilai disimpen saméméhna row_ver pikeun spasi goods. Lamun leungit (sesi bursa munggaran), lajeng urang nyandak salaku row_ver nol. Salajengna dina siklus urang ngalakukeun undeuran halaman-demi-kaca tina data anu dirobih tina sumberna dina url anu ditangtukeun. Dina unggal iterasi, urang simpen data narima kana spasi lokal luyu jeung ngamutahirkeun nilai row_ver (di angkasa row_ver jeung dina variabel row_ver) - nyandak nilai row_ver ti baris panungtungan data dimuat.

Pikeun ngajaga tina looping teu kahaja (bisi aya kasalahan dina program), loop anu while bisa diganti ku for:

for _ = 1, max_req do ...

Salaku hasil tina executing fungsi sync_goods angkasa goods panarima bakal ngandung versi panganyarna sadaya rékaman spasi goods dina sumberna.

Jelas, ngahapus data teu tiasa disiarkeun ku cara ieu. Upami peryogi sapertos kitu, anjeun tiasa nganggo tanda ngahapus. Tambahkeun ka spasi goods widang boolean is_deleted jeung tinimbang fisik ngahapus rékaman, kami nganggo ngahapus logis - urang nyetel nilai widang is_deleted kana harti true. Sok tinimbang widang boolean is_deleted leuwih merenah ngagunakeun sawah deleted, nu nyimpen tanggal-waktu ngahapus logis tina rékaman. Saatos ngahapus logis, catetan anu ditandaan pikeun ngahapus bakal ditransfer tina sumber ka tujuan (nurutkeun logika anu dibahas di luhur).

Teraskeun row_ver bisa dipaké pikeun ngirimkeun data ti spasi séjén: teu perlu nyieun runtuyan misah pikeun tiap spasi dikirimkeun.

Urang nempo hiji cara éféktif réplikasi data tingkat luhur dina aplikasi ngagunakeun Tarantool DBMS.

papanggihan

  1. Tarantool DBMS mangrupikeun produk anu pikaresepeun, ngajangjikeun pikeun nyiptakeun aplikasi beban tinggi.
  2. Réplikasi data tingkat luhur ngabogaan sajumlah kaunggulan dibandingkeun réplikasi tingkat handap.
  3. Metodeu réplikasi tingkat luhur anu dibahas dina tulisan ngamungkinkeun anjeun ngaminimalkeun jumlah data anu ditransfer ku ngan ukur nransferkeun rékaman anu parantos robih ti sési bursa terakhir.

sumber: www.habr.com

Tambahkeun komentar