Search code examples
tarantool

Can I use Tarantool instead of Redis?


I'd like to use Tarantool to store data. How can I store data with TTL and simple logic (without the spaces)?

Like this:

box:setx(key, value, ttl);
box:get(key)

Solution

  • Yes, you can expire data in Tarantool and in a much more flexible way than in Redis. Though you can't do this without spaces, because space is a container for data in Tarantool (like database or table in other database systems).

    In order to expire data, you have to install expirationd tarantool rock using tarantoolctl rocks install expirationd command. Full documentation on expirationd daemon can be found here.

    Feel free to use a sample code below:

    #!/usr/bin/env tarantool
    
    package.path = './.rocks/share/tarantool/?.lua;' .. package.path
    
    local fiber = require('fiber')
    local expirationd = require('expirationd')
    
    
    -- setup the database
    
    box.cfg{}
    box.once('init', function()
        box.schema.create_space('test')
        box.space.test:create_index('primary', {parts = {1, 'unsigned'}})
    end)
    
    -- print all fields of all tuples in a given space
    local print_all = function(space_id)
        for _, v in ipairs(box.space[space_id]:select()) do
            local s = ''
            for i = 1, #v do s = s .. tostring(v[i]) .. '\t' end
            print(s)
        end
    end
    
    -- return true if tuple is more than 10 seconds old
    local is_expired = function(args, tuple)
        return (fiber.time() - tuple[3]) > 10
    end
    
    -- simply delete a tuple from a space
    local delete_tuple = function(space_id, args, tuple)
        box.space[space_id]:delete{tuple[1]}
    end
    
    local space = box.space.test
    
    print('Inserting tuples...')
    
    space:upsert({1, '0 seconds', fiber.time()}, {})
    fiber.sleep(5)
    space:upsert({2, '5 seconds', fiber.time()}, {})
    fiber.sleep(5)
    space:upsert({3, '10 seconds', fiber.time()}, {})
    
    print('Tuples are ready:\n')
    
    print_all('test')
    
    print('\nStarting expiration daemon...\n')
    
    -- start expiration daemon
    -- in a production full_scan_time should be bigger than 1 sec
    expirationd.start('expire_old_tuples', space.id, is_expired, {
        process_expired_tuple = delete_tuple, args = nil,
        tuples_per_iteration = 50, full_scan_time = 1
    })
    
    fiber.sleep(5)
    print('\n\n5 seconds passed...')
    print_all('test')
    
    fiber.sleep(5)
    print('\n\n10 seconds passed...')
    print_all('test')
    
    fiber.sleep(5)
    print('\n\n15 seconds passed...')
    print_all('test')
    
    os.exit()