Каков практический подход к разветвлению при записи в Redis?

У меня есть новостной сайт с множеством тем. Могут быть миллионы пользователей, которые следят за темами. Я поддерживаю сортированный набор для каждого пользователя, чтобы загружать новости, относящиеся к темам, за которыми они следят. Когда статья будет добавлена ​​или обновлена, я напишу эту статью в списки затронутых пользователей. В частности, псевдокод выглядит следующим образом:

if a article is added/updated
  get all topics that the article belong (each article may belong to many topics)
    for each topic: get all topic followers
      update_user_news_list(userId, articleId)

Это java-код с jedis:

static final int LIMIT_BATCH = 1000;
static void addToUserHomeFeed(int index, Jedis jd) {
        int range_limit = index + LIMIT_BATCH - 1;
        Set<String> list = jd.zrange("Follower:Topic:Id", index, range_limit); // get list of followers
        if (list.isEmpty())  return;
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
           // update user list
        }
        addToUserHomeFeed(range_limit + 1, jd);
}

Проблема в том, что у моего сайта в настоящее время почти 1 миллион пользователей, некоторые популярные темы сопровождаются около 800000 пользователей, и иногда система выдает ошибки «переполнение буфера». Я что-то не так делаю или есть подходы получше? Я использую Redis 2.4


person ipkiss    schedule 05.04.2014    source источник
comment
Вы устранили ошибки переполнения буфера?   -  person readyornot    schedule 05.11.2014


Ответы (1)


Что ж, я не эксперт Redis, но мне кажется, что хранить самую последнюю статью + тему статьи в отсортированном по времени наборе должно:

ZADD lasttopics -[timestamp] Topic:1-Article:1 -[timestamp] Topic:2-Article:1 

добавляет статью 1 в набор, по 1 разу по каждой теме. Каждый ключ в наборе ранжируется по отрицательному значению временной метки unix (так что более поздние статьи становятся первыми в наборе)

Теперь, когда пользователь входит в систему, сначала получите все темы, за которыми он следит, а затем перебирайте отсортированный набор, используя «ZSCAN lasttopics 0» и т. Д., Пока у вас не будет достаточно статей по темам, которые интересуют пользователя.

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

В целях обслуживания вы можете использовать счетчик времени для удаления статей из набора по мере их устаревания.

person Ohad Asulin    schedule 15.01.2015