当前位置:首页 > 问答 > 正文

点赞系统 评论功能 基于Redis实现高效点赞与评论的简易系统,redis 点赞评论

Redis实战篇

"昨天发的朋友圈怎么才10个赞?"小王盯着手机屏幕嘟囔着,在当今社交网络盛行的时代,点赞和评论功能已成为每个内容平台的标配,但你知道吗?当你的手指轻轻一点"点赞"按钮时,背后可能正上演着一场高并发的技术较量,我们就来聊聊如何用Redis打造一个既简单又高效的点赞评论系统。

为什么选择Redis?

想象一下明星发微博的场景:一分钟内可能收到数万次点赞,如果用传统数据库直接记录每次点赞,数据库可能瞬间就被压垮了,Redis作为内存数据库,读写速度极快,特别适合这种高频写操作的场景。

Redis的主要优势:

  • 内存操作,速度比磁盘数据库快几个数量级
  • 丰富的数据结构,完美适配点赞评论场景
  • 原子操作,避免并发问题
  • 持久化选项,数据安全有保障

系统设计核心思路

点赞功能设计

点赞的核心是记录"谁给什么点了赞",在Redis中,我们可以用集合(Set)来存储这种关系:

# 用户123给文章1001点赞
SADD article:1001:likes 123
# 取消点赞
SREM article:1001:likes 123
# 获取文章点赞数
SCARD article:1001:likes
# 检查用户是否点过赞
SISMEMBER article:1001:likes 123

这种设计下,点赞、取消点赞、查询点赞数和检查点赞状态都是O(1)时间复杂度,性能极高。

评论功能设计

评论比点赞稍微复杂些,需要存储更多信息,我们可以使用Redis的列表(List)或有序集合(Sorted Set)来存储评论:

# 添加评论
ZADD article:1001:comments 1625000000 "{\"user_id\":123,\"content\":\"好文章!\",\"time\":1625000000}"
# 获取最新10条评论
ZREVRANGE article:1001:comments 0 9 WITHSCORES
# 获取评论总数
ZCARD article:1001:comments

使用有序集合可以方便地按时间排序,而且还能支持分页查询。

完整实现方案

数据结构设计

  1. 点赞数据

    • 键格式:article:{article_id}:likes
    • 类型:Set
    • 值:用户ID集合
  2. 评论数据

    点赞系统 评论功能 基于Redis实现高效点赞与评论的简易系统,redis 点赞评论

    • 键格式:article:{article_id}:comments
    • 类型:Sorted Set
    • 分数:评论时间戳
    • 值:JSON格式的评论内容
  3. 文章点赞数缓存

    • 键格式:article:{article_id}:likes_count
    • 类型:String
    • 值:点赞总数

伪代码实现

class LikeCommentSystem:
    def __init__(self, redis_conn):
        self.redis = redis_conn
    def like_article(self, user_id, article_id):
        """用户点赞文章"""
        if self.redis.sadd(f"article:{article_id}:likes", user_id):
            self.redis.incr(f"article:{article_id}:likes_count")
            return True
        return False
    def unlike_article(self, user_id, article_id):
        """用户取消点赞"""
        if self.redis.srem(f"article:{article_id}:likes", user_id):
            self.redis.decr(f"article:{article_id}:likes_count")
            return True
        return False
    def get_likes_count(self, article_id):
        """获取文章点赞数"""
        return int(self.redis.get(f"article:{article_id}:likes_count") or 0)
    def has_liked(self, user_id, article_id):
        """检查用户是否点赞过"""
        return self.redis.sismember(f"article:{article_id}:likes", user_id)
    def add_comment(self, user_id, article_id, content):
        """添加评论"""
        comment_data = {
            "user_id": user_id,
            "content": content,
            "time": int(time.time())
        }
        return self.redis.zadd(
            f"article:{article_id}:comments",
            {json.dumps(comment_data): comment_data["time"]}
        )
    def get_comments(self, article_id, page=1, page_size=10):
        """分页获取评论"""
        start = (page - 1) * page_size
        end = start + page_size - 1
        return self.redis.zrevrange(
            f"article:{article_id}:comments", start, end, withscores=True
        )
    def get_comment_count(self, article_id):
        """获取评论总数"""
        return self.redis.zcard(f"article:{article_id}:comments")

性能优化技巧

  1. 点赞数缓存:虽然可以通过SCARD直接获取集合大小,但在高并发下,单独维护一个计数器性能更好。

  2. 批量操作:使用管道(pipeline)将多个操作合并减少网络往返:

    pipe = self.redis.pipeline()
    pipe.sadd(f"article:{article_id}:likes", user_id)
    pipe.incr(f"article:{article_id}:likes_count")
    pipe.execute()
  3. 内存优化:对于大型集合,考虑使用IntSet编码:

    # Redis配置
    set-max-intset-entries 512
  4. 数据过期:为不活跃的内容设置过期时间,自动清理:

    self.redis.expire(f"article:{article_id}:likes", 30*24*3600)  # 30天

实际应用中的挑战与解决方案

数据持久化

Redis是内存数据库,虽然提供RDB和AOF两种持久化方式,但为防止极端情况下的数据丢失,可以考虑:

  1. 定期将Redis数据同步到MySQL等关系型数据库
  2. 使用Redis的RDB+AOF混合持久化模式
  3. 关键操作双写(先写数据库再写Redis)

热点数据

明星发微博可能造成某些键成为热点,解决方案:

  1. 分片:将数据分散到多个Redis实例

    shard_id = article_id % 4  # 假设有4个分片
    redis_conn = get_redis_connection(shard_id)
  2. 本地缓存:在应用层缓存热点内容的点赞数

大数据量

当单个文章的点赞数达到百万级别时,SCARD操作可能变慢,解决方案:

点赞系统 评论功能 基于Redis实现高效点赞与评论的简易系统,redis 点赞评论

  1. 使用HyperLogLog进行近似计数(如果不需要精确值)

    PFADD article:1001:likes_approx 123
    PFCOUNT article:1001:likes_approx
  2. 定期将大数据集合归档到磁盘数据库

扩展功能

基于这个基础系统,我们可以轻松扩展更多社交功能:

  1. 点赞排行榜

    # 使用有序集合维护最受欢迎文章
    ZINCRBY article:likes_rank 1 article:1001
  2. 互赞关系

    # 记录用户间的互赞关系
    SADD user:123:liked_by 456  # 用户456赞过123的内容
  3. 点赞通知

    # 当用户点赞时,给作者发通知
    LPUSH user:{author_id}:notifications "用户{user_id}赞了你的文章{article_id}"

用Redis实现点赞评论系统就像给高速跑车配上顶级引擎,既简单又高效,我们利用Redis的Set处理点赞关系,用Sorted Set存储按时间排序的评论,再配合一些计数器和缓存技巧,就能支撑起高并发的社交互动场景。

好的系统不是一开始就追求完美,而是先跑起来再不断优化,你现在就可以用几十行代码实现这个系统的基础版本,随着业务增长再逐步加入分片、持久化、监控等高级功能。

下次当你给喜欢的帖子点赞时,不妨想想背后这套精巧的系统设计,也许你的一个小小点击,正在驱动着世界上最繁忙的一些Redis实例呢!

发表评论