Salom, men DBMS uchun ilovalar yaratyapman
Quvvatni his eting! (...aka spektakldan zavqlaning)
Yuqorida aytilganlarning barchasi Tarantool-ni ma'lumotlar bazalari bilan ishlaydigan yuqori yuklangan ilovalarni yaratish uchun jozibali platformaga aylantiradi. Bunday ilovalarda ko'pincha ma'lumotlarni ko'paytirishga ehtiyoj bor.
Yuqorida aytib o'tilganidek, Tarantool o'rnatilgan ma'lumotlar replikatsiyasiga ega. Uning ishlash printsipi asosiy jurnalda (WAL) mavjud bo'lgan barcha operatsiyalarni takrorlashda ketma-ket bajarishdir. Odatda bunday replikatsiya (biz uni keyinroq chaqiramiz past darajadagi) dasturning nosozlikka chidamliligini ta'minlash va/yoki o'qish yukini klaster tugunlari o'rtasida taqsimlash uchun ishlatiladi.
Guruch. 1. Klaster ichida replikatsiya
Muqobil stsenariyga misol sifatida bitta ma'lumotlar bazasida yaratilgan ma'lumotlarni qayta ishlash/monitoring uchun boshqa ma'lumotlar bazasiga o'tkazish mumkin. Ikkinchi holda, foydalanish uchun qulayroq echim bo'lishi mumkin yuqori daraja replikatsiya - ilovaning biznes mantiqiy darajasida ma'lumotlarni takrorlash. Bular. Biz DBMSga o'rnatilgan tayyor yechimdan foydalanmaymiz, lekin biz ishlab chiqayotgan dastur doirasida replikatsiyani o'zimiz amalga oshiramiz. Ushbu yondashuv ham afzalliklarga, ham kamchiliklarga ega. Keling, afzalliklarini sanab o'tamiz.
1. Trafikni tejash:
- Siz barcha ma'lumotlarni o'tkaza olmaysiz, lekin uning faqat bir qismini (masalan, siz faqat ba'zi jadvallarni, ularning ba'zi ustunlarini yoki ma'lum bir mezonga javob beradigan yozuvlarni o'tkazishingiz mumkin);
- Asinxron (Tarantool ning joriy versiyasida joriy etilgan - 1.10) yoki sinxron (Tarantoolning keyingi versiyalarida amalga oshiriladi) doimiy ravishda amalga oshiriladigan past darajadagi replikatsiyadan farqli o'laroq, yuqori darajadagi replikatsiya sessiyalarda (ya'ni, ilova birinchi navbatda ma'lumotlarni sinxronlashtiradi - almashish seansi ma'lumotlari, keyin replikatsiyada pauza bo'ladi, shundan so'ng keyingi almashinuv seansi sodir bo'ladi va hokazo);
- agar yozuv bir necha marta o'zgargan bo'lsa, siz uning faqat so'nggi versiyasini o'tkazishingiz mumkin (past darajadagi replikatsiyadan farqli o'laroq, masterda kiritilgan barcha o'zgarishlar replikalarda ketma-ket ijro etiladi).
2. Masofaviy ma'lumotlar bazalarini sinxronlashtirish imkonini beruvchi HTTP almashinuvini amalga oshirishda hech qanday qiyinchiliklar yo'q.
Guruch. 2. HTTP orqali replikatsiya
3. Ma'lumotlar uzatiladigan ma'lumotlar bazasi tuzilmalari bir xil bo'lishi shart emas (bundan tashqari, umumiy holatda, hatto turli xil DBMS, dasturlash tillari, platformalar va boshqalarni ishlatish mumkin).
Guruch. 3. Geterogen sistemalarda replikatsiya
Salbiy tomoni shundaki, o'rtacha hisobda dasturlash konfiguratsiyadan ko'ra qiyinroq/xarajatdir va o'rnatilgan funksiyani sozlash o'rniga o'zingiznikini amalga oshirishingiz kerak bo'ladi.
Agar sizning vaziyatingizda yuqoridagi afzalliklar hal qiluvchi ahamiyatga ega bo'lsa (yoki zaruriy shart bo'lsa), unda yuqori darajadagi replikatsiyadan foydalanish mantiqan to'g'ri keladi. Keling, Tarantool DBMSda yuqori darajadagi ma'lumotlar replikatsiyasini amalga oshirishning bir necha usullarini ko'rib chiqaylik.
Trafikni minimallashtirish
Shunday qilib, yuqori darajadagi replikatsiyaning afzalliklaridan biri bu trafikni tejashdir. Ushbu afzallik to'liq amalga oshirilishi uchun har bir almashuv sessiyasida uzatiladigan ma'lumotlar hajmini minimallashtirish kerak. Albatta, sessiya oxirida ma'lumotlarni qabul qiluvchi manba bilan sinxronlashtirilishi kerakligini unutmasligimiz kerak (hech bo'lmaganda replikatsiyada ishtirok etadigan ma'lumotlarning bir qismi uchun).
Yuqori darajadagi replikatsiya vaqtida uzatiladigan ma'lumotlar miqdorini qanday kamaytirish mumkin? To'g'ridan-to'g'ri yechim sana va vaqt bo'yicha ma'lumotlarni tanlash bo'lishi mumkin. Buni amalga oshirish uchun siz jadvalda mavjud bo'lgan sana-vaqt maydonidan foydalanishingiz mumkin (agar mavjud bo'lsa). Masalan, "buyurtma" hujjatida "buyurtmani bajarish vaqti" maydoni bo'lishi mumkin - delivery_time
. Ushbu yechim bilan bog'liq muammo shundaki, bu sohadagi qiymatlar buyurtmalarni yaratishga mos keladigan ketma-ketlikda bo'lishi shart emas. Shunday qilib, biz maksimal maydon qiymatini eslay olmaymiz delivery_time
, oldingi almashuv seansida uzatiladi va keyingi almashinuv seansida yuqoriroq maydon qiymatiga ega barcha yozuvlarni tanlang delivery_time
. Birja seanslari orasida kichikroq maydon qiymatiga ega yozuvlar qo'shilgan bo'lishi mumkin delivery_time
. Bundan tashqari, buyurtma o'zgarishlarga duch kelishi mumkin edi, ammo bu maydonga ta'sir qilmadi delivery_time
. Ikkala holatda ham o'zgarishlar manbadan belgilangan joyga o'tkazilmaydi. Ushbu muammolarni hal qilish uchun biz ma'lumotlarni "bir-biriga mos keladigan" uzatishimiz kerak bo'ladi. Bular. har bir almashinuv seansida biz barcha ma'lumotlarni maydon qiymati bilan uzatamiz delivery_time
, o'tmishdagi bir nuqtadan oshib ketgan (masalan, hozirgi paytdan boshlab N soat). Biroq, katta tizimlar uchun bu yondashuv juda keraksiz va biz harakat qilayotgan trafikni tejashni hech narsaga kamaytirishi aniq. Bundan tashqari, uzatilayotgan jadvalda sana-vaqt bilan bog'langan maydon bo'lmasligi mumkin.
Amalga oshirish nuqtai nazaridan murakkabroq bo'lgan yana bir yechim - ma'lumotlarning qabul qilinishini tan olishdir. Bunday holda, har bir almashuv sessiyasida barcha ma'lumotlar uzatiladi, ularning olinganligi qabul qiluvchi tomonidan tasdiqlanmagan. Buni amalga oshirish uchun siz manba jadvaliga mantiqiy ustun qo'shishingiz kerak bo'ladi (masalan, is_transferred
). Agar qabul qiluvchi yozuvni olganligini tan olsa, tegishli maydon qiymatni oladi true
, shundan so'ng kirish endi almashinuvlarda ishtirok etmaydi. Ushbu amalga oshirish opsiyasi quyidagi kamchiliklarga ega. Birinchidan, o'tkazilgan har bir yozuv uchun tasdiq yaratilishi va yuborilishi kerak. Taxminan aytganda, bu uzatilgan ma'lumotlar miqdorini ikki baravar oshirish va aylanma sayohatlar sonini ikki baravar oshirish bilan solishtirish mumkin. Ikkinchidan, bir xil yozuvni bir nechta qabul qiluvchilarga yuborish imkoniyati yo'q (birinchi qabul qiluvchi o'zi uchun ham, qolganlari uchun ham kvitansiyani tasdiqlaydi).
Yuqorida keltirilgan kamchiliklarga ega bo'lmagan usul - uzatilgan jadvalga uning satrlaridagi o'zgarishlarni kuzatish uchun ustun qo'shishdir. Bunday ustun sana-vaqt turiga ega bo'lishi mumkin va har safar yozuvlar qo'shilgan/o'zgartirilganda (qo'shish/o'zgartirish bilan atomik tarzda) joriy vaqtga ilova tomonidan o'rnatilishi/yangilanishi kerak. Misol tariqasida, ustunni chaqiramiz update_time
. O'tkazilgan yozuvlar uchun ushbu ustunning maksimal maydoni qiymatini saqlash orqali biz ushbu qiymat bilan keyingi almashinuv seansini boshlashimiz mumkin (maydon qiymatiga ega yozuvlarni tanlang. update_time
, oldindan saqlangan qiymatdan oshib ketgan). Oxirgi yondashuv bilan bog'liq muammo shundaki, ma'lumotlar o'zgarishi partiyalarda sodir bo'lishi mumkin. Ustundagi maydon qiymatlari natijasida update_time
noyob bo'lmasligi mumkin. Shunday qilib, bu ustundan qismlarga bo'lingan (sahifa-sahifa) ma'lumotlarni chiqarish uchun foydalanilmaydi. Ma'lumotlarni sahifama-sahifa ko'rsatish uchun siz juda past samaradorlikka ega bo'lgan qo'shimcha mexanizmlarni ixtiro qilishingiz kerak bo'ladi (masalan, ma'lumotlar bazasidan qiymati bo'lgan barcha yozuvlarni olish). update_time
ma'lum biridan yuqori va namunaning boshidan ma'lum bir ofsetdan boshlab ma'lum miqdordagi yozuvlarni ishlab chiqaradi).
Oldingi yondashuvni biroz yaxshilash orqali ma'lumotlarni uzatish samaradorligini oshirishingiz mumkin. Buning uchun biz o'zgarishlarni kuzatish uchun ustun maydoni qiymatlari sifatida butun son turini (uzun butun son) ishlatamiz. Keling, ustunga nom beraylik row_ver
. Ushbu ustunning maydon qiymati har safar yozuv yaratilganda/o'zgartirilganda o'rnatilishi/yangilanishi kerak. Ammo bu holda, maydonga joriy sana-vaqt tayinlanmaydi, lekin ba'zi hisoblagichning qiymati bittaga oshiriladi. Natijada, ustun row_ver
noyob qiymatlarni o'z ichiga oladi va nafaqat "delta" ma'lumotlarini ko'rsatish uchun (oldingi almashinuv seansining oxiridan beri qo'shilgan/o'zgartirilgan ma'lumotlar), balki ularni oddiy va samarali ravishda sahifalarga ajratish uchun ham ishlatilishi mumkin.
Yuqori darajadagi replikatsiya doirasida uzatiladigan ma'lumotlar miqdorini minimallashtirishning oxirgi taklif qilingan usuli menga eng maqbul va universal ko'rinadi. Keling, buni batafsil ko'rib chiqaylik.
Qator versiyasi hisoblagichi yordamida ma'lumotlarni uzatish
Server/master qismini amalga oshirish
MS SQL Serverda ushbu yondashuvni amalga oshirish uchun maxsus ustun turi mavjud - rowversion
. Har bir ma'lumotlar bazasida ustunga ega bo'lgan jadvalga yozuv qo'shilganda/o'zgartirilganda bittaga ko'payadigan hisoblagich mavjud rowversion
. Ushbu hisoblagichning qiymati qo'shilgan/o'zgartirilgan yozuvdagi ushbu ustunning maydoniga avtomatik ravishda tayinlanadi. Tarantool DBMSda shunga o'xshash o'rnatilgan mexanizm yo'q. Biroq, Tarantoolda uni qo'lda amalga oshirish qiyin emas. Keling, bu qanday amalga oshirilganini ko'rib chiqaylik.
Birinchidan, bir oz terminologiya: Tarantool-dagi jadvallar bo'shliqlar deb ataladi va yozuvlar kortejlar deb ataladi. Tarantool-da siz ketma-ketliklar yaratishingiz mumkin. Ketma-ketliklar tartiblangan tamsayΔ± qiymatlarining nomlangan generatorlaridan boshqa narsa emas. Bular. bu bizning maqsadlarimiz uchun kerak bo'lgan narsadir. Quyida biz shunday ketma-ketlikni yaratamiz.
Tarantool-da har qanday ma'lumotlar bazasi operatsiyasini bajarishdan oldin, siz quyidagi buyruqni bajarishingiz kerak:
box.cfg{}
Natijada, Tarantool joriy katalogga ma'lumotlar bazasi suratlari va tranzaksiya jurnallarini yozishni boshlaydi.
Keling, ketma-ketlikni yarataylik row_version
:
box.schema.sequence.create('row_version',
{ if_not_exists = true })
Variant if_not_exists
yaratish skriptini bir necha marta bajarishga imkon beradi: agar ob'ekt mavjud bo'lsa, Tarantool uni qayta yaratishga urinmaydi. Ushbu parametr barcha keyingi DDL buyruqlarida qo'llaniladi.
Keling, misol sifatida bo'sh joy yarataylik.
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
})
Bu erda biz bo'sh joy nomini o'rnatamiz (goods
), maydon nomlari va ularning turlari.
Tarantool'da avtomatik o'sish maydonlari ham ketma-ketliklar yordamida yaratiladi. Maydonlar bo'yicha avtomatik o'sadigan asosiy kalitni yarataylik 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 bir necha turdagi indekslarni qo'llab-quvvatlaydi. Eng ko'p ishlatiladigan indekslar TREE va HASH turlari bo'lib, ular nomga mos keladigan tuzilmalarga asoslangan. TREE - eng ko'p qirrali indeks turi. Bu sizga ma'lumotlarni tartibli tarzda olish imkonini beradi. Ammo tenglikni tanlash uchun HASH ko'proq mos keladi. Shunga ko'ra, asosiy kalit uchun HASH dan foydalanish tavsiya etiladi (biz shunday qildik).
Ustunni ishlatish uchun row_ver
o'zgartirilgan ma'lumotlarni uzatish uchun siz ushbu ustunning maydonlariga ketma-ketlik qiymatlarini bog'lashingiz kerak row_ver
. Lekin asosiy kalitdan farqli o'laroq, ustun maydoni qiymati row_ver
nafaqat yangi yozuvlarni qo'shganda, balki mavjudlarini o'zgartirganda ham bittaga ko'payishi kerak. Buning uchun triggerlardan foydalanishingiz mumkin. Tarantool ikki turdagi kosmik tetiklarga ega: before_replace
ΠΈ on_replace
. Triggerlar bo'shliqdagi ma'lumotlar har safar o'zgarganda ishga tushiriladi (o'zgarishlardan ta'sirlangan har bir kortej uchun trigger funktsiyasi ishga tushiriladi). Undan farqli o'laroq on_replace
, before_replace
-triggerlar trigger bajariladigan kortej ma'lumotlarini o'zgartirish imkonini beradi. Shunga ko'ra, oxirgi turdagi triggerlar bizga mos keladi.
box.space.goods:before_replace(function(old, new)
return box.tuple.new({new[1], new[2], new[3],
box.sequence.row_version:next()})
end)
Quyidagi trigger maydon qiymatini almashtiradi row_ver
ketma-ketlikning keyingi qiymatiga saqlanadi row_version
.
Kosmosdan ma'lumotlarni chiqarib olish uchun goods
ustun bo'yicha row_ver
, indeks yaratamiz:
box.space.goods:create_index('row_ver', {
parts = { 'row_ver' },
unique = true,
type = 'TREE',
if_not_exists = true
})
Indeks turi - daraxt (TREE
), chunki ustundagi qiymatlarning o'sish tartibida ma'lumotlarni chiqarib olishimiz kerak bo'ladi row_ver
.
Keling, bo'sh joyga ba'zi ma'lumotlarni qo'shamiz:
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}
Chunki Birinchi maydon avtomatik o'sish hisoblagichi; biz uning o'rniga nolga o'tamiz. Tarantool avtomatik ravishda keyingi qiymatni almashtiradi. Xuddi shunday, ustun maydonlarining qiymati sifatida row_ver
nolga o'tishingiz mumkin - yoki umuman qiymatni belgilamaysiz, chunki bu ustun bo'shliqda oxirgi o'rinni egallaydi.
Keling, kiritish natijasini tekshiramiz:
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]
...
Ko'rib turganingizdek, birinchi va oxirgi maydonlar avtomatik ravishda to'ldiriladi. Endi bo'sh joy o'zgarishlarini sahifama-sahifa yuklash funksiyasini yozish oson bo'ladi 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
Funktsiya parametr sifatida qiymatni oladi row_ver
, undan boshlab o'zgarishlarni tushirish kerak va o'zgartirilgan ma'lumotlarning bir qismini qaytaradi.
Tarantool-da ma'lumotlarni tanlash indekslar orqali amalga oshiriladi. Funktsiya get_goods
indeks bo'yicha iteratordan foydalanadi row_ver
o'zgartirilgan ma'lumotlarni olish uchun. Iterator turi GT (kattaroq, kattaroq). Bu shuni anglatadiki, iterator o'tkazilgan kalitdan (maydon qiymati) boshlab indeks qiymatlarini ketma-ket bosib o'tadi. row_ver
).
Iterator kortejlarni qaytaradi. Keyinchalik HTTP orqali ma'lumotlarni uzatish imkoniyatiga ega bo'lish uchun kortejlarni keyingi ketma-ketlashtirish uchun qulay tuzilishga aylantirish kerak. Misol uchun standart funksiyadan foydalaniladi tomap
. Foydalanish o'rniga tomap
o'z funktsiyangizni yozishingiz mumkin. Misol uchun, biz maydon nomini o'zgartirishni xohlashimiz mumkin name
, maydondan o'tmang code
va maydon qo'shing 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
Chiqish ma'lumotlarining sahifa hajmi (bir qismdagi yozuvlar soni) o'zgaruvchi tomonidan belgilanadi page_size
. Misolda qiymat page_size
5. Haqiqiy dasturda sahifa hajmi odatda ko'proq ahamiyatga ega. Bu kosmik tuplening o'rtacha hajmiga bog'liq. Optimal sahifa hajmi ma'lumotlarni uzatish vaqtini o'lchash orqali empirik tarzda aniqlanishi mumkin. Sahifaning o'lchami qanchalik katta bo'lsa, jo'natuvchi va qabul qiluvchi tomonlar o'rtasidagi aylanishlar soni shunchalik kichik bo'ladi. Shunday qilib, siz o'zgarishlarni yuklab olish uchun umumiy vaqtni qisqartirishingiz mumkin. Biroq, agar sahifa o'lchami juda katta bo'lsa, biz namunani serializatsiya qilish uchun serverda juda uzoq vaqt sarflaymiz. Natijada, serverga keladigan boshqa so'rovlarni qayta ishlashda kechikishlar bo'lishi mumkin. Parametr page_size
konfiguratsiya faylidan yuklanishi mumkin. Har bir uzatilgan makon uchun siz o'z qiymatini belgilashingiz mumkin. Biroq, ko'pchilik bo'shliqlar uchun standart qiymat (masalan, 100) mos kelishi mumkin.
Funktsiyani bajaramiz 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
...
Maydon qiymatini olaylik row_ver
oxirgi qatordan boshlab funktsiyani qayta chaqiring:
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
...
Yana bir bor:
tarantool> get_goods(8)
---
- []
...
Ko'rib turganingizdek, shu tarzda foydalanilganda, funksiya barcha bo'sh joy yozuvlarini sahifama-sahifa qaytaradi goods
. Oxirgi sahifadan keyin bo'sh tanlov mavjud.
Keling, bo'shliqqa o'zgartirish kiritamiz:
box.space.goods:update(4, {{'=', 6, 'copybook'}})
box.space.goods:insert{nil, 'clip', 234}
box.space.goods:insert{nil, 'folder', 432}
Biz maydon qiymatini o'zgartirdik name
bitta kirish uchun va ikkita yangi yozuv qo'shildi.
Keling, oxirgi funktsiya chaqiruvini takrorlaymiz:
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
...
Funktsiya o'zgartirilgan va qo'shilgan yozuvlarni qaytardi. Shunday qilib, funktsiya get_goods
ko'rib chiqilayotgan replikatsiya usulining asosi bo'lgan oxirgi qo'ng'iroqdan keyin o'zgargan ma'lumotlarni olish imkonini beradi.
HTTP orqali natijalarni JSON ko'rinishida chiqarishni ushbu maqola doirasidan tashqarida qoldiramiz. Bu haqda bu yerda oβqishingiz mumkin:
Mijoz/qul qismini amalga oshirish
Keling, qabul qiluvchi tomonning amalga oshirishi qanday ko'rinishini ko'rib chiqaylik. Yuklab olingan ma'lumotlarni saqlash uchun qabul qiluvchi tomonda bo'sh joy yarataylik:
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
})
Kosmosning tuzilishi manbadagi makonning tuzilishiga o'xshaydi. Ammo biz qabul qilingan ma'lumotlarni boshqa joyga o'tkazmasligimiz sababli, ustun row_ver
oluvchining maydonida emas. Dalada id
manba identifikatorlari yozib olinadi. Shuning uchun, qabul qiluvchi tomonda uni avtomatik ravishda oshirishga hojat yo'q.
Bundan tashqari, qadriyatlarni saqlash uchun bizga bo'sh joy kerak 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
})
Har bir yuklangan joy uchun (maydon space_name
) oxirgi yuklangan qiymatni shu yerda saqlaymiz row_ver
(maydon value
). Ustun asosiy kalit vazifasini bajaradi space_name
.
Keling, kosmik ma'lumotlarni yuklash funksiyasini yarataylik goods
HTTP orqali. Buning uchun bizga HTTP mijozini amalga oshiradigan kutubxona kerak. Quyidagi qator kutubxonani yuklaydi va HTTP mijozini ishga tushiradi:
local http_client = require('http.client').new()
Bizga json deserialization uchun kutubxona ham kerak:
local json = require('json')
Bu ma'lumotlarni yuklash funksiyasini yaratish uchun etarli:
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
Funktsiya url manziliga HTTP so'rovini bajaradi va uni yuboradi row_ver
parametr sifatida va so'rovning seriyasizlashtirilgan natijasini qaytaradi.
Qabul qilingan ma'lumotlarni saqlash funktsiyasi quyidagicha ko'rinadi:
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
Kosmosga ma'lumotlarni saqlash davri goods
tranzaktsiyaga joylashtirilgan (funktsiya buning uchun ishlatiladi box.atomic
) diskdagi operatsiyalar sonini kamaytirish uchun.
Nihoyat, mahalliy kosmik sinxronizatsiya funktsiyasi goods
manba bilan siz buni shunday amalga oshirishingiz mumkin:
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
Avval biz avval saqlangan qiymatni o'qiymiz row_ver
bo'sh joy uchun goods
. Agar u etishmayotgan bo'lsa (birinchi almashinuv seansi), biz uni shunday qabul qilamiz row_ver
nol. Keyingi tsiklda biz belgilangan urldagi manbadan o'zgartirilgan ma'lumotlarni sahifama-sahifa yuklab olishni amalga oshiramiz. Har bir iteratsiyada biz olingan ma'lumotlarni tegishli mahalliy maydonga saqlaymiz va qiymatni yangilaymiz row_ver
(kosmosda row_ver
va o'zgaruvchida row_ver
) - qiymatni qabul qiling row_ver
yuklangan ma'lumotlarning oxirgi qatoridan.
Tasodifiy tsikldan himoya qilish uchun (dasturda xatolik bo'lsa), pastadir while
bilan almashtirilishi mumkin for
:
for _ = 1, max_req do ...
Funktsiyani bajarish natijasida sync_goods
bo'sh joy goods
qabul qiluvchi barcha kosmik yozuvlarning so'nggi versiyalarini o'z ichiga oladi goods
manbada.
Shubhasiz, ma'lumotlarni o'chirishni bu tarzda translyatsiya qilish mumkin emas. Agar bunday ehtiyoj mavjud bo'lsa, siz o'chirish belgisidan foydalanishingiz mumkin. Bo'sh joyga qo'shing goods
mantiqiy maydon is_deleted
va yozuvni jismonan o'chirish o'rniga biz mantiqiy o'chirishdan foydalanamiz - biz maydon qiymatini o'rnatamiz is_deleted
ma'noga kiradi true
. Ba'zan mantiqiy maydon o'rniga is_deleted
daladan foydalanish qulayroqdir deleted
, bu yozuvni mantiqiy o'chirish sana-vaqtini saqlaydi. Mantiqiy o'chirishni amalga oshirgandan so'ng, o'chirish uchun belgilangan yozuv manbadan belgilangan joyga o'tkaziladi (yuqorida muhokama qilingan mantiq bo'yicha).
Tartib row_ver
boshqa bo'shliqlardan ma'lumotlarni uzatish uchun ishlatilishi mumkin: har bir uzatiladigan maydon uchun alohida ketma-ketlikni yaratishga hojat yo'q.
Biz Tarantool DBMS yordamida ilovalarda yuqori darajadagi ma'lumotlarni ko'paytirishning samarali usulini ko'rib chiqdik.
topilmalar
- Tarantool DBMS - bu yuqori yuklangan ilovalarni yaratish uchun jozibali, istiqbolli mahsulot.
- Yuqori darajadagi ma'lumotlarni takrorlash past darajadagi replikatsiyaga nisbatan bir qator afzalliklarga ega.
- Maqolada muhokama qilingan yuqori darajadagi replikatsiya usuli faqat oxirgi almashinuv seansidan keyin o'zgargan yozuvlarni o'tkazish orqali uzatilgan ma'lumotlar miqdorini minimallashtirishga imkon beradi.
Manba: www.habr.com