Django накапливает данные перед сохранением в БД

#python #django #gunicorn

Вопрос:

На моем веб-сайте django мне нужен трекер, который измеряет, как долго пользователь выполнял определенную деятельность каждый день. Для этой цели браузер отправляет ajax-запрос на сервер каждые 30 секунд, пока пользователь выполняет свою деятельность. Поэтому при получении этого запроса сервер увеличивает счетчик активности пользователя на 30 секунд. Эти счетчики хранятся в базе данных.

Я подумал, что было бы довольно неэффективно обновлять данные в базе данных каждые 30 секунд для каждого пользователя веб-сайта. Поэтому моя идея состояла в том, чтобы накопить все отслеживаемое время в глобальном словаре {идентификатор пользователя: секунды}. Поэтому, когда запрос на активность ajax будет получен, я мог бы просто найти идентификатор пользователя в словаре и увеличить соответствующее значение в секундах. Тогда этот словарь можно было бы сбрасывать в базу данных каждые 10 минут.

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

Что меня беспокоит, так это:

  1. Насколько я понимаю, в django, работающем с gunicorn, может быть много рабочих процессов, поэтому у меня не будет глобального словаря. Я даже не могу быть уверен, что один и тот же пользователь всегда будет обрабатываться одним и тем же процессом.
  2. Я хотел бы сбросить словарь в базу данных, когда рабочий процесс вот-вот будет остановлен, что не кажется тривиальной задачей.

Две вышеперечисленные проблемы и отсутствие очевидного решения выглядят как намек на то, что я делаю что-то не так. Может быть, я слишком оптимизирую вещи, и это нормально хранить в базе данных каждые 30 секунд для каждого пользователя, или, может быть, есть более известная практика кэширования материалов в памяти перед отправкой их в базу данных, которую я пропускаю?

Не мог бы кто-нибудь направить меня в правильном направлении, пожалуйста?

Комментарии:

1. Вероятно, вам следует использовать базу данных NOSQL вместо глобального диктатора. Что-то вроде MongoDB или Redis.

2. Разве это не возможность, чтобы пользователь отправил сводку о своей деятельности, когда она закончится, сменив несколько вызовов только на один вызов? Если нет, я предполагаю, что это потому, что вам нужен какой-то контроль на стороне сервера над отслеживанием активности пользователей. В этом случае, я думаю, было бы более эффективно использовать долговременные соединения, такие как websockets. Каналы Django очень хорошо подходят для этого. Вместо использования словаря я бы рекомендовал использовать что-то вроде Redis для хранения промежуточного времени активности и записи в базу данных при отключении WS.

3. Спасибо за ответы! На данный момент мы решили начать с прямой записи в базу данных. Позже, если мы обнаружим, что это узкое место, использование Redis кажется хорошим решением.