Kaniadto nag-atubang kami sa problema sa paglimpyo sa mga tuple sa mga wanang
Usa ka maayong panig-ingnan alang kanamo mao ang tarantool module nga gitawag
paghulagway
Ang dokumentasyon alang sa tarantool adunay maayo kaayo
Magsugod kita gikan sa layo ug tan-awon kung unsa ang hitsura sa usa ka naka-cap nga expiration nga module gikan sa gawas:
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
capped_connection = net_box:new(3300)
Alang sa kayano, gilusad namo ang tarantool sa direktoryo diin nahimutang ang among libcapped-expirationd.so library. Duha ka mga gimbuhaton ang gi-eksport gikan sa librarya: pagsugod ug pagpatay. Ang unang lakang mao ang paghimo niini nga mga function nga magamit gikan sa Lua gamit ang box.schema.func.create ug box.schema.user.grant. Dayon paghimo og usa ka luna kansang mga tuple adunay tulo lamang ka mga field: ang una usa ka talagsaon nga identifier, ang ikaduha mao ang email, ug ang ikatulo mao ang tibuok kinabuhi sa tuple. Nagtukod kami usa ka indeks sa kahoy sa ibabaw sa una nga uma ug gitawag kini nga panguna. Sunod makuha namon ang butang nga koneksyon sa among lumad nga librarya.
Pagkahuman sa trabaho sa pag-andam, pagdagan ang function sa pagsugod:
capped_connection:call('libcapped-expirationd.start', {'non-indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.primary, 3, 1024, 3600})
Kini nga pananglitan magamit sa panahon sa pag-scan nga parehas sa na-expire nga module, nga gisulat sa Lua. Ang unang argumento sa pagsugod function mao ang talagsaon nga ngalan sa buluhaton. Ang ikaduha mao ang space identifier. Ang ikatulo usa ka talagsaon nga indeks diin ang mga tuple matangtang. Ang ikaupat mao ang index diin ang mga tuple maagian. Ang ikalima mao ang gidaghanon sa tuple field nga adunay tibuok kinabuhi (pagnumero magsugod gikan sa 1, dili 0!). Ang ikaunom ug ikapito mao ang mga setting sa pag-scan. Ang 1024 mao ang kinatas-ang gidaghanon sa mga tuple nga makita sa usa ka transaksyon. 3600 β bug-os nga oras sa pag-scan sa mga segundo.
Timan-i nga ang pananglitan naggamit sa parehas nga indeks alang sa pag-crawl ug pagtangtang. Kung kini usa ka indeks sa kahoy, nan ang pagbiyahe gihimo gikan sa gamay nga yawe hangtod sa labi ka dako. Kung adunay uban pa, pananglitan, hash index, nan ang traversal gihimo, ingon nga usa ka lagda, sa random order. Ang tanan nga mga tuple sa wanang gi-scan sa usa ka pag-scan.
Atong isulod ang daghang tuple sa wanang nga adunay tibuok kinabuhi nga 60 segundos:
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
Atong susihon nga ang pagsal-ot malampuson:
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576418976]
- [1, '[email protected]', 1576418976]
- [2, '[email protected]', 1576418976]
...
Atong sublion ang pagpili human sa 60+ ka segundos (pag-ihap gikan sa sinugdanan sa pagsal-ot sa unang tuple) ug tan-awa nga ang gitakpan nga expirationd module naproseso na:
tarantool> box.space.tester.index.primary:select()
---
- []
...
Hunongon nato ang buluhaton:
capped_connection:call('libcapped-expirationd.kill', {'non-indexed'})
Atong tan-awon ang ikaduha nga pananglitan diin ang usa ka bulag nga indeks gigamit alang sa pag-crawl:
fiber = require('fiber')
net_box = require('net.box')
box.cfg{listen = 3300}
box.schema.func.create('libcapped-expirationd.start', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.start')
box.schema.func.create('libcapped-expirationd.kill', {language = 'C'})
box.schema.user.grant('guest', 'execute', 'function', 'libcapped-expirationd.kill')
box.schema.space.create('tester')
box.space.tester:create_index('primary', {unique = true, parts = {1, 'unsigned'}})
box.space.tester:create_index('exp', {unique = false, parts = {3, 'unsigned'}})
capped_connection = net_box:new(3300)
Ang tanan dinhi parehas sa una nga pananglitan, nga adunay pipila nga mga eksepsiyon. Nagtukod kami usa ka indeks sa kahoy sa ibabaw sa ikatulo nga uma ug gitawag kini nga exp. Kini nga indeks dili kinahanglan nga talagsaon, dili sama sa indeks nga gitawag nga panguna. Ang traversal himuon pinaagi sa exp index, ug pagtangtang pinaagi sa primary. Nahinumdom kami nga kaniadto ang duha gihimo lamang gamit ang panguna nga indeks.
Pagkahuman sa buluhaton sa pag-andam, gipadagan namon ang pagsugod nga function nga adunay bag-ong mga argumento:
capped_connection:call('libcapped-expirationd.start', {'indexed', box.space.tester.id, box.space.tester.index.primary, box.space.tester.index.exp, 3, 1024, 3600})
Atong isulod ang daghang tuple sa wanang pag-usab nga adunay tibuok kinabuhi nga 60 segundos:
box.space.tester:insert{0, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{1, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{2, '[email protected]', math.floor(fiber.time()) + 60}
Human sa 30 segundos, pinaagi sa analogy, magdugang kami og pipila pa ka tuple:
box.space.tester:insert{3, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{4, '[email protected]', math.floor(fiber.time()) + 60}
box.space.tester:insert{5, '[email protected]', math.floor(fiber.time()) + 60}
Atong susihon nga ang pagsal-ot malampuson:
tarantool> box.space.tester.index.primary:select()
---
- - [0, '[email protected]', 1576421257]
- [1, '[email protected]', 1576421257]
- [2, '[email protected]', 1576421257]
- [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
Atong sublion ang pagpili human sa 60+ ka segundos (pag-ihap gikan sa sinugdanan sa pagsal-ot sa unang tuple) ug tan-awa nga ang gitakpan nga expirationd module naproseso na:
tarantool> box.space.tester.index.primary:select()
---
- - [3, '[email protected]', 1576421287]
- [4, '[email protected]', 1576421287]
- [5, '[email protected]', 1576421287]
...
Naa pay pipila ka tuple nga nahabilin sa wanang nga adunay mga 30 ka segundo pa nga mabuhi. Dugang pa, ang pag-scan mihunong sa dihang mibalhin gikan sa tuple nga adunay ID nga 2 ug tibuok kinabuhi nga 1576421257 ngadto sa tuple nga adunay ID nga 3 ug tibuok kinabuhi nga 1576421287. Ang mga tuple nga adunay tibuok kinabuhi nga 1576421287 o labaw pa wala ma-scan tungod sa pag-order sa ang exp index nga mga yawe. Kini ang savings nga gusto namong makab-ot sa sinugdanan pa lang.
Hunongon nato ang buluhaton:
capped_connection:call('libcapped-expirationd.kill', {'indexed'})
Pagpatuman
Ang pinakamaayong paagi sa pagsulti mahitungod sa tanang bahin sa usa ka proyekto mao ang orihinal nga tinubdan niini.
Ang mga argumento nga atong gipasa sa pamaagi sa pagsugod gitipigan sa usa ka istruktura nga gitawag expirationd_task:
struct expirationd_task
{
char name[256];
uint32_t space_id;
uint32_t rm_index_id;
uint32_t it_index_id;
uint32_t it_index_type;
uint32_t field_no;
uint32_t scan_size;
uint32_t scan_time;
};
Ang ngalan nga hiyas mao ang ngalan sa buluhaton. Ang space_id attribute mao ang space identifier. Ang rm_index_id attribute mao ang identifier sa talagsaong index diin ang mga tuple matangtang. Ang it_index_id attribute mao ang identifier sa index diin ang mga tuple maagian. Ang it_index_type nga attribute mao ang tipo sa index diin ang mga tuple maagian. Ang filed_no attribute mao ang gidaghanon sa tuple field nga adunay tibuok kinabuhi. Ang scan_size attribute mao ang pinakataas nga gidaghanon sa mga tuple nga gi-scan sa usa ka transaksyon. Ang kinaiya sa scan_time mao ang tibuok nga oras sa pag-scan sa mga segundo.
Dili nato tagdon ang pag-parse sa mga argumento. Kini usa ka makuti apan yano nga trabaho, diin ang librarya makatabang kanimo
Gilista namon ang mga prototype sa tanan nga mga gimbuhaton nga gigamit alang sa pag-parse:
bool expirationd_parse_name(struct expirationd_task *task, const char **pos);
bool expirationd_parse_space_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index_unique(struct expirationd_task *task, const char **pos);
bool expirationd_parse_rm_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_id(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index_type(struct expirationd_task *task, const char **pos);
bool expirationd_parse_it_index(struct expirationd_task *task, const char **pos);
bool expirationd_parse_field_no(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_size(struct expirationd_task *task, const char **pos);
bool expirationd_parse_scan_time(struct expirationd_task *task, const char **pos);
Karon magpadayon kita sa labing hinungdanon nga butang - ang lohika sa pag-bypass sa wanang ug pagtangtang sa mga tuple. Ang matag bloke sa tuple nga dili modako sa scan_size gi-scan ug giusab ubos sa usa ka transaksyon. Kung malampuson, kini nga transaksyon nahimo; kung adunay sayup, kini gibalik. Ang katapusang argumento sa expirationd_iterate function kay usa ka pointer sa iterator diin nagsugod o nagpadayon ang scanning. Kini nga iterator gidugangan sa sulod hangtod nga adunay usa ka sayup nga mahitabo, ang wanang mahurot, o dili posible nga pahunongon ang proseso sa una. Ang function nga expirationd_expired nagsusi sa tibuok kinabuhi sa usa ka tuple, expirationd_delete nagtangtang sa usa ka tuple, expirationd_breakable nagsusi kon kita kinahanglan nga magpadayon.
Expirationd_iterate function code:
static bool
expirationd_iterate(struct expirationd_task *task, box_iterator_t **iterp)
{
box_iterator_t *iter = *iterp;
box_txn_begin();
for (uint32_t i = 0; i < task->scan_size; ++i) {
box_tuple_t *tuple = NULL;
if (box_iterator_next(iter, &tuple) < 0) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_rollback();
return false;
}
if (!tuple) {
box_iterator_free(iter);
*iterp = NULL;
box_txn_commit();
return true;
}
if (expirationd_expired(task, tuple))
expirationd_delete(task, tuple);
else if (expirationd_breakable(task))
break;
}
box_txn_commit();
return true;
}
Function code expirationd_expired:
static bool
expirationd_expired(struct expirationd_task *task, box_tuple_t *tuple)
{
const char *buf = box_tuple_field(tuple, task->field_no - 1);
if (!buf || mp_typeof(*buf) != MP_UINT)
return false;
uint64_t val = mp_decode_uint(&buf);
if (val > fiber_time64() / 1000000)
return false;
return true;
}
Expirationd_delete function code:
static void
expirationd_delete(struct expirationd_task *task, box_tuple_t *tuple)
{
uint32_t len;
const char *str = box_tuple_extract_key(tuple, task->space_id, task->rm_index_id, &len);
box_delete(task->space_id, task->rm_index_id, str, str + len, NULL);
}
Function code expiration_breakable:
static bool
expirationd_breakable(struct expirationd_task *task)
{
return task->it_index_id != task->rm_index_id && task->it_index_type == ITER_GT;
}
Paggamit
Mahimo nimong tan-awon ang source code sa
Source: www.habr.com