用于通知的 Django Redis

Django redis for notifications

我已经使用 Django REST 框架构建了一个 REST API。在应用程序中需要 facebook 类型的通知(新朋友请求、新消息等)。目前我正在使用长轮询处理这个问题:

注意:我们没有使用 websockets,如果需要请写信给我

我想用 django/redis 替换此方法,因为我认为我的长轮询方法大量滥用数据库,我认为 Redis 的速度和结构可以提供很多帮助。

关于我如何完成这样的事情有什么建议吗?

使用 Redis,您可以缓存通知并加快 仅在前端显示内容的过程,同时减少对数据库的滥用。 例如,您可以使用如下键:

<user_id>_new_message

现在,每当用户 ID = <user_id> 的用户收到一条新消息时,您可以更新 redis 缓存以将 <user_id>_new_message 更新为 1。 现在应该有一个 function/AJAX 调用检查 <user_id>_new_message,并将前端的通知更新为 previous unread notif count + 1。你可以着手更新数据库(如果你需要的话),比如每 20 分钟为所有用户批量更新一次。

现在,开始实际更新。由于您的系统需要服务器和用户端之间的交互(比如向该人显示消息并能够回复),Redis 无法在此处帮助您。您将需要像 websockets 这样的服务。您需要在用户和 API 之间进行交互以进行消息传递和好友请求。

使用基于内存的键值存储更适合您当前的用例,因为它将极大地减少数据库的负载并加快您的应用程序。

Redis 不仅仅是内存中的键值存储,因此您可以利用它更轻松地实现您的目标。

我正在此处编写您想要的简单实现,您很可能可以以此为基础来实现您想要的。

简而言之

  1. 我们将用户的所有通知保存在 HashMap in redis 中 以用户命名的 HashMap 的键。

  2. HashMap是notificationId到notificationData的映射(Json格式)。

  3. 通知的元数据保存在通知数据主体中。 (诸如日期、阅读状态等)

    from redis import StrictRedis
    import json
    
    # Function to add new notifications for user
    def add_notification(user_id, notification_id, data):
        r = StrictRedis(host='localhost', port=6379)
        r.hset('%s_notifications' % user_id, notification_id, json.dumps(data))
    
    # Function to set the notification as read, your Frontend looks at the "read" key in 
    # Notification's data to determine how to show the notification
    def set_notification_as_read(user_id, notification_id):
        r = StrictRedis(host='localhost', port=6379)
        data = json.loads(r.hget('%s_notifications' % user_id, notification_id))
        data['read'] = True
        add_notification(user_id, notification_id, data)
    
    # Gets all notifications for a user, you can sort them based on a key like "date" in Frontend
    def get_notifications(user_id):
        r = StrictRedis(host='localhost', port=6379)
        return r.hgetall('%s_notifications' % user_id)
    

您还可以构建更多功能或使用 redis 的不同功能来为您创建近乎实时的通知后端 website/application。 (我已经复制了 redis 连接创建部分,user_id 和......以便答案更清楚)

干杯