2011-02-25 2 views
0

Redis 2.0.3Хранение огромного рандомизированного списка аналогичных товаров в Redis

Мне нужно хранить огромный список предметов в Redis. Каждый элемент представляет собой короткую строку (менее 256 символов).

мне нужно сделать две операции в списке:

  • Добавить много (несколько тысяч до миллиона) одинаковых элементов. (Несколько раз в день)

  • Удалите из списка один случайный элемент. Не обязательно иметь «справедливое» случайное. Любой подход «достаточно хороший» будет делать. (До нескольких сотен раз в секунду)

У меня недостаточно ОЗУ для хранения всех предметов в списке по одному.

Я думаю, что мне нужно хранить предметы в партиях, имени и прилавке. (Там будет до нескольких тысяч отдельных элементов, больше как несколько сотен.)

Но я не уверен, как организовать это эффективно.

Любые подсказки?

ответ

0

Ну, так как никто не может мне помочь, вот «немое» решение, в псевдокоде.

  1. Получить случайный элемент:

    function maybe_get_next_item() 
        item_name = SRANDMEMBER "items-set" 
        item_key = "items:" + item_name 
    
        new_item_count = DECR (item_key) 
    
        if new_item_count < 0 then 
        LOCK -- As explained in SETNX docs 
         new_item_count = GET (item_key) -- More added while we were locking? 
         if new_item_count and new_item_count < 0 then 
         SREM (item_name) -- No, expire it 
         end 
        UNLOCK 
        end 
    
        if new_item_count and new_item_count >= 0 then 
        return item_name 
        end 
    
        return false -- this item not found 
    end 
    
    function get_next_item() 
        item_name = maybe_get_next_item() 
        while not item_name and (SCARD "items-set" > 0) do 
        item_name = maybe_get_next_item() 
        end 
        return item_name -- false if all items are expended 
    end 
    
  2. Вставьте новые элементы

    function insert_items(item_name, amount) 
        LOCK -- As explained in SETNX docs 
        SADD "items-set" (item_name) 
        INCRBY ("items:" + item_name) amount 
        UNLOCK 
    end 
    

Пожалуйста, предложить лучшее решение, если оно существует, я до сих пор groking Redis, и может пропустить что-то очевидное.

Я подозреваю, что LOCK/UNLOCK в insert_items() может быть излишним и может быть заменен MULTI/EXEC, но я думаю, что это необходимо для LOCK/UNLOCK в maybe_get_next_item(), чтобы работать должным образом (я не знаю, как заменить MULTI/EXEC) ...

+0

Обратите внимание, что вероятности здесь перекошены, так как количество одинаковых предметов не играет никакой роли в шансе получить предмет. Это нормально для моего конкретного случая использования. –

+0

На 2.2 лучше всего использовать WATCH: http://stackoverflow.com/questions/5118807/redis-how-to-atomically-remove-an-item-from-set-if-a-counter-in-another -key-это-б –

Смежные вопросы