Cassandra 2.1: как моделировать N последних активных пользователей?

Мне нужно получить список из N пользователей с самыми последними действиями с использованием кассандры.

Я пробовал использовать следующую схему:

CREATE TABLE user_actions(
  partition_key int, 
  username int,
  action_time timestamp,
PRIMARY KEY(partition_key, action_time)
WITH CLUSTERING ORDER BY(action_time DESC);

Когда пользователь впервые входит в систему, он создает новую запись. Однако я не могу обновить свойство start_time, поскольку оно используется в качестве ключа кластеризации. Я мог удалить старые данные и создать новую запись, когда пользователь предпримет другое действие, но действия пользователя происходят часто, и мы быстро достигнем предела захоронения.

Кто-нибудь знает, как лучше всего я могу смоделировать данные, чтобы добиться этого?


person cscan    schedule 16.12.2016    source источник


Ответы (1)


Вам не нужно удалять отдельные ячейки. Просто продолжайте добавлять. Добавьте еще один компонент к ключу раздела, чтобы он не стал слишком широким:

PRIMARY KEY((partition_key, day), action_time)

Затем запросите, используя что-то вроде (псевдокода):

y = floor(time() / (60 * 60 * 24))
oldest_possible = y - 7
r = []
while len(r) < N and y >= oldest_possible:
    R.append(query('SELECT * FROM user_actions where partition_key = {x} AND day = {y} LIMIT {N};', x, y, N)
    y -= 1

чтобы получить последних N пользователей. Если в разделе нет N, уменьшите день на 1 и запросите и его. Установите TTL от 1 до 5 дней или что-то в этом роде, и старые записи будут сжаты. Это предполагает, что у вас есть как минимум N действий за 24 часа, иначе вы можете получить неполный список. Если ваши записи суперактивны, вы можете использовать hour вместо дня.

Компонент день / час может быть простым floor(time() / (60*60*24))

person Chris Lohfink    schedule 16.12.2016
comment
Спасибо, Крис, я реализовал это. Однако есть одна проблема: запрос возвращает дубли. Хотя я могу отфильтровать эти дубликаты в своем приложении, мне было интересно, есть ли способ, который не создавал бы эти дубли. - person cscan; 16.12.2016
comment
Фильтрация, наверное, самый простой вариант. В этом случае вы, вероятно, захотите удалить LIMIT из запроса. Ограничение на выборку драйверов будет обрабатывать подкачку через раздел за вас. Тем не менее, это может привести к некоторым худшим сценариям. Вы могли бы потенциально сделать: ((partition_key, day), username), который просто сохраняет последнее action_time для каждого пользователя и при этом сохраняет верхние N повторений. Я ожидал, что это будет хуже, но это действительно может зависеть от количества активных пользователей. Если у вас всего несколько активных пользователей в день, которые много делают, исходная модель должна пройти больше, чем другие. - person Chris Lohfink; 16.12.2016