惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Vulnerabilities – Threatpost
博客园_首页
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
罗磊的独立博客
V
Visual Studio Blog
Know Your Adversary
Know Your Adversary
Hacker News - Newest:
Hacker News - Newest: "LLM"
美团技术团队
L
LINUX DO - 最新话题
The Last Watchdog
The Last Watchdog
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
云风的 BLOG
云风的 BLOG
N
Netflix TechBlog - Medium
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
有赞技术团队
有赞技术团队
I
InfoQ
Last Week in AI
Last Week in AI
V2EX - 技术
V2EX - 技术
量子位
S
Secure Thoughts
L
LangChain Blog
The Hacker News
The Hacker News
H
Help Net Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
小众软件
小众软件
K
Kaspersky official blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
I
Intezer
Vercel News
Vercel News
Hacker News: Ask HN
Hacker News: Ask HN
Cisco Talos Blog
Cisco Talos Blog
Google DeepMind News
Google DeepMind News
S
Securelist
阮一峰的网络日志
阮一峰的网络日志
G
Google Developers Blog
Help Net Security
Help Net Security
Martin Fowler
Martin Fowler
爱范儿
爱范儿
Y
Y Combinator Blog
C
Check Point Blog

博客园 - koushr

hls k8s常用命令 k8s 1.18.0安装 mysql json函数 group by的列、where的列的有效性 go基础第六篇:sync包 doris脚本 es es语法 veo ride nacos 枫叶互动 极光矩阵 富途 移卡科技 nginx高可用 k8s第一篇:k8s集群架构组件 架构设计第二篇:支付模块架构设计 可观测性体系设计第一篇:可观测性体系基本概念 ES高级第一篇:倒排索引 山海星辰 python第一篇:基础语法 pulsar基础第二篇:命令行 pulsar基础第一篇:pulsar安装及基本概念 clickhouse第三篇:安装 clickhouse第二篇:MergeTree引擎 clickhouse第一篇:引擎 redis高阶第一篇:令牌桶算法限流 http2.0 gin入参多次获取 docker第二篇:docker安装常用中间件
架构设计第一篇:点赞模块功能设计
koushr · 2026-03-19 · via 博客园 - koushr

内容类app的点赞功能设计

点赞功能即用户对内容点赞,点赞后用户可以看到该内容最新的点赞数。用户可以查询自己的点赞列表,可以查看内容的点赞列表。

level1:用户对内容点赞时,往数据库中插入一条记录。取消点赞时,删除此条记录。

表结构是:id、user_id(用户id)、content_id(内容id)、create_time、update_time

为了防止重复点赞,需要在user_id和content_id上加唯一索引。

上面方案读写全部都走数据库,在并发大的情况下,对数据库会造成很大压力,响应时间也会很慢。

level2:引入redis,把高并发的读写放到redis中。

创建两种类型的key,一种是set类型的键值对,存放点赞事件,key形如content:likes:{user_id},member是content_id。点赞时,就sadd,取消点赞时,就srem。另一种是string类型的键值对,存放内容的点赞量,key形如content:likesnum:{content_id},value是该内容对应的点赞量。点赞时,就incr 1,取消点赞时,就incr -1。

举个例子,如果u1对c1点赞,则先sadd content:likes:u1 c1,如果返回0,则表示重复点赞,直接返回给前端即可。如果返回1,则再incr content:likesnum:c1,给点赞数加1。最后把点赞事件通过消息队列异步存到数据库中,注意要幂等,即insert ignore。这样,在拉取内容列表时,查用户对内容是否点了赞,只需执行sismember,查内容的点赞数,只需执行get。用户查询自己的点赞列表时,就有问题了,set没有存点赞时间,无法按照点赞时间倒序取。所以,要把set类型改为sorted set类型,key形如content:likes:zset:{user_id},member是content_id,score是点赞时间对应的时间戳,这样就会自动按照点赞时间排列。用户查询自己的点赞列表,只需zrangebyscore。用户查看内容的点赞列表,用当前两种key都不行,所以需要再创建一个sorted set类型的键值对,key形如content:likes:zset:{content_id},member是user_id,score是点赞时间对应的时间戳。这样,当执行一次点赞操作,需要操作三个key,那么最好是用lua脚本原子式执行多命令。

level3:高并发下,点赞事件一条条写到数据库,会对数据库造成压力。此外,还必须要考虑热点数据。

一条条写数据库,要改成批量写数据库。需要在应用层积攒消息,即一直poll,直到积攒到一定量或是积攒一定时间,再批量入库,再commitSync。注意,如果是一个消费者消费多个分区,则需要用那个有参数且参数是各分区偏移量的commitSync()方法,以保证每个分区都能commit正确。

热点数据,如一个内容被几十万个用户点赞,或者一个用户点赞了几十万个内容,那么存储点赞事件的那两个key就会变成大key,占用太多内存。我们可以只保留最近1万条记录,之前的记录清掉。这样的话,查询点赞列表时,如果取到1万条之后,就从数据库中取。基本上不会有人会翻到1w条之后。

还有一种热点数据,即一个内容短时间内收到了大量的赞,导致短时间内频繁操作存储点赞量的这个key。如果redis是集群,那么我们可以把这个key分片,即拆分成content:likesnum:{content_id}_0,content:likesnum:{content_id}_1。。。content:likesnum:{content_id}_n,让这些key分到不同的redis节点上,这样就可以提升吞吐率了。

点赞系统的设计核心是:

1. 使用 Redis 承担高并发读写:
- ZSet 存用户/内容点赞关系(支持分页)
- String 存点赞计数

2. 使用 Lua 保证多 key 操作原子性

3. 通过 MQ 异步落库,并采用批量写提升吞吐

4. 针对热点问题:
- 大 key:只保留最近数据 + DB 兜底
- 热点计数:采用分片计数(sharding counter)

5. 分片计数结合 Redis Cluster,实现多节点并行写入,
突破单节点吞吐瓶颈

6. 通过幂等设计(唯一索引)保证数据一致性