Tarantool: historia de aceleración de búsqueda en 1C


Recientemente, nuestros buenos amigos de una gran red minorista tuvieron la tarea de acelerar las búsquedas en 1C.


-, ( , 9 , %like%) - 2,5 . , — Tarantool. ElasticSearch, .. , , . , , MS SQL.


-, . , 0,2 5-12 1 ( ). 90 , , 10-50 .


Stage 1


- . 1 ( ) 700 90 . 200 .


, Elastic. ( ) - . 50 100 , .


MySQL PostgreSQL, . 10 10 700 . 10 100 insert 0,9 , 20 2,5 . 30 1.


1- , « 1 ». , 1- , «, MS SQL».


MS SQL 45 . , in-memory .


, , 3-5 .


, , , ( ) ( , ).


, 1 .


, RabbitMQ + Memcached / Redis, . 1. — « » .


MS SQL 2017 — Memory Optimized Tables.


Tarantool.


«» . , , , () .


, , , MS SQL Tarantool.


(*) 5 (15 , , , ).


imagen


Stage 2


, , Tarantool 2.1 SQL- Tarantool PHP.


- , Tarantool , .
, . Lua ( Tarantool Cartridge Vshard). 0,004 0,21 . 30 100 . 7 .


Tarantool , SQL — . Lua, . 6 . SQL- 20 , Lua 50 , , 1 .


Tarantool ( read only, updated: 3 1,5 ) : MS SQL 50 , Tarantool 120 ( : Tarantool 2.2, , 2.3 , Tarantool 2.3 — ). . 1 300 , (Tarantool memtx).


Lua, Tarantool. .


: ElasticSearch.


---      ,    
local function get_stockBalance_to_queue(spaceIn)
    local x = os.clock();

    local space_name = 'STOCKBALANCES';
    if spaceIn ~= nil and 'string' == type(spaceIn) and spaceIn ~= '' then
        space_name = spaceIn;
    end

    local maxRows = 50000;
    local goods = {};
    local goodsIds = '';

    --- 
    local i = 0;
    local iStock = 0;

    local session = os.time(os.date("!*t"));    
    local borderTime = session — (10); 

    box.begin()
    for _, tuple in pairs(box.space[space_name].index.ISPROCESSED:select(0, { iterator = box.index.EQ, offset = 0, limit = maxRows })) do

        if i == maxRows then break end
        --- tuple[1] — GUID 1 
        --- tuple[2] — GUID 1 
        --- tuple[6] — ,    
        if tuple[6] < borderTime then

            --- ,     ,       —    
            if goods[tuple[1]] == nil then
                goods[tuple[1]] = 1;
                ---  —     
                i = i + 1;
                ---      
                goodsIds = goodsIds .. '"' .. tuple[1] .. '",';
            end
            ---     =  
            pcall(function() box.space[space_name]:update({ tuple[1], tuple[2] }, { { '=', 5, 1 }, { '=', 6, session } }) end);
            ---  —      
            iStock = iStock + 1;
        end
    end

    local stockTmp = {};
    local goodsInStockTmp = {};
    local instock = 0;

    ---   getSumStock       (  ,    ..)
    local stockBalance = _G.Functions.getSumStock(goodsIds);

    ---   getGoodsInStock      in stock — 1/0 (/)
    local goodsInStock = _G.Functions.getGoodsInStock(goodsIds);

    local iGoods = 0;
    for _, tuple in pairs(goods) do

        ---      (   ,        tuple[1],   )
        stockTmp = stockBalance[tuple[1]]['quantityNet'];

        ---      (   ,        tuple[1],   )
        goodsInStockTmp = goodsInStock[tuple[1]];

        ---        — /,      1/0 (/)
        if not stockTmp then
            instock = 0;
        elseif stockTmp > 0 then
            instock = 1;
        elseif stockTmp < 0 then
            instock = 0;
        else
            instock = 0;
        end

        ---           ,       
        if instock ~= goodsInStockTmp then
            ---  —    
            iGoods = iGoods + 1;
            ---  100 —  ( — ISPROCESSED) (/),  ,     
            ---  105 — , / (1/0)
            pcall(function() box.space.GOODS:update(tuple[1], { { '=', 100, 0 }, { '=', 105, instock } }) end);
        end
    end

    box.commit();
    return space_name .. ' for update: ' .. iStock .. '  Goods for update: ' .. i .. ' Updated goods: ' .. iGoods .. ', ' .. (string.format("elapsed time: %.2f", os.clock() — x));
end;

ElasticSearch / , Tarantool .


:


imagen


, , . , , .


(, , ) Tarantool box.slab.info. 1 . .


, Mail.ru Group, , Telegram, , .


Stage 3


« , — . — . Tarantool, Bitrix- Bitrix-?» ( , )


« ? — . — , ».


«» — , , Tarantool. , . , , , .


P.S. , . . ,


All Articles