Отсортированный набор Redis на основе счета и даты и времени в качестве тай-брейка?

Я хотел бы использовать отсортированный набор Redis в качестве таблицы лидеров. Но, используя ZREVRANGE 0 x, я могу получить только верхний x из оценки (конец отсортированного по возрастанию набора на основе оценки) с прерывателем связи по умолчанию, который есть в официальной документации Redis:

Лексикографический порядок используется для элементов с одинаковой оценкой.

Тай-брейк, который мне нужен, — это дата и время записи счета.

e.g.

submits (in order)     redis sorts it as      I need
User1 -- Score 50      User1                  User1
User3 -- Score 40      User2                  User3
User2 -- Score 40      User3                  User2

Единственное решение, которое я вижу, - это сохранить дату и время последнего обновления в записи, но по-прежнему использовать ZREVRANGE key 0 x для получения максимальных и минимальных оценок от x лучших пользователей. Затем сделайте ZREVRANGEBYSCORE key max min. Если длина результата больше, чем x, есть по крайней мере одна связь, поэтому я бы отсортировал этот меньший список в Lua, используя 2 ключа.

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

Мой код уже написан, поэтому я не могу изменить тип базы данных. Если у вас есть интересные идеи, мне будет интересно их услышать, так как я не эксперт по Redis.


person David Gourde    schedule 16.05.2017    source источник


Ответы (1)


Оценка отсортированного набора представляет собой значение с плавающей запятой. Ваш счет и дата и время счета могут вписаться в это.

  1. Оценка будет целым числом в некотором диапазоне, скажем, от 0 до 2 ^ 10, потребуется только 10 бит.
  2. Счет может быть временной меткой unix в секундах с января 2010 г. (чтобы уменьшить размер временной метки, для простоты вы даже можете использовать простую временную метку unix как целое число)

Теперь давайте назовем оценку Redis как RScore. Вы можете поместить оценку человека в крайние левые 10 бит числа, а временную метку — в крайние правые x бит. Биты в середине могут быть нулевыми.

Таким образом, всякий раз, когда вы сортируете Rscore, он будет сначала отсортирован по количеству очков, а если есть ничья, он будет отсортирован по отметке времени unix, присутствующей в правильных битах. Чтобы найти счет и отметку времени счета из RScore, вам просто нужно проанализировать правильный набор битов. Пример утилиты, которая делает это на python, находится здесь.

person DhruvPathak    schedule 16.05.2017