要设计今日头条与抖音的千亿级点赞系统,需解决高并发、低延迟、数据一致性、海量存储四大核心挑战。结合字节跳动(两者母公司)的实践及行业通用方案,系统设计需从分层架构、数据结构、异步处理、热点应对、容灾备份等多维度展开,以下是具体实现细节:
一、系统架构:分层解耦,支撑高并发
点赞系统的核心架构采用“客户端-网关-服务-缓存-数据库”分层设计,各层职责明确,确保高并发下的稳定性:
客户端层:
采用请求合并(如1秒内多次点赞合并为1次请求)与防抖机制(避免用户快速点击导致的重复请求),减少客户端对服务端的压力。
前端展示乐观更新(点赞后立即显示“已赞”,无需等待服务端响应),提升用户体验。
API网关层:
作为系统入口,承担限流(如限制单个用户1分钟内的点赞次数)、熔断(当下游服务故障时,快速返回错误,避免雪崩)、鉴权(验证用户身份,防止黑灰产刷赞)等功能。
采用智能路由(如根据用户地理位置路由至最近的机房),降低延迟。
点赞服务层:
作为核心业务逻辑层,负责处理点赞/取消点赞的业务校验(如是否已点赞、是否超过每日上限)、数据操作(更新缓存与发送异步消息)。
采用微服务架构(如Spring Cloud),支持水平扩展,应对高并发请求。
缓存层:
使用Redis集群(支持分片与主从复制),存储实时点赞数据(如点赞计数、用户点赞关系),解决数据库高并发读写瓶颈。
缓存策略:
热点数据本地缓存:对突发热点(如周杰伦发新歌),采用Caffeine(本地缓存框架)缓存热点数据,减少Redis访问压力。
多级缓存:结合Redis与本地缓存,确保热点数据的高可用。
数据库层:
使用分布式数据库(如TiDB、CockroachDB),支持水平扩展(通过分片存储),解决海量数据存储问题。
数据库采用主从复制(如MySQL主从),实现高可用,确保数据不丢失。
二、数据结构:高效存储,支撑海量数据
点赞系统的核心数据需存储用户点赞关系(谁点了谁)、点赞计数(总点赞数)、点赞列表(用户点赞的内容),需选择合适的Redis数据结构,提升操作效率:
用户点赞关系(防重复点赞):
使用Redis Hash:Key为
like:{entityType}:{entityId}(如like:post:123,表示帖子123的点赞关系),Field为用户ID(如1001),Value为时间戳(如1620000000)。优势:Hash结构的
SADD(添加元素)与SISMEMBER(判断元素是否存在)操作均为O(1)时间复杂度,适合快速校验是否已点赞。
点赞计数(实时展示):
使用Redis String:Key为
like_count:{entityType}:{entityId}(如like_count:post:123),Value为点赞总数(如100000)。优势:String的
INCR(自增)与DECR(自减)操作均为原子操作,适合高并发下的计数更新。
点赞列表(用户维度的点赞内容):
使用Redis ZSet(有序集合):Key为
user_like:{userId}(如user_like:1001),Score为时间戳(如1620000000),Value为{entityType}:{entityId}(如post:123)。优势:ZSet的
ZADD(添加元素)与ZRANGE(按时间排序获取元素)操作均为O(logN)时间复杂度,适合快速获取用户点赞的内容(按时间排序)。
三、异步处理:解耦业务,提升吞吐量
为解决高并发下的数据库写入压力,点赞操作采用异步处理(写缓存+发消息+异步持久化):
写缓存:
当用户点赞时,先更新Redis中的用户点赞关系(Hash添加元素)、点赞计数(String自增)、用户点赞列表(ZSet添加元素)。
优势:Redis的内存操作延迟低(毫秒级),能快速响应用户请求。
发消息:
通过消息队列(如Kafka、RocketMQ)发送点赞事件(包含用户ID、实体类型、实体ID、时间戳),实现业务解耦(点赞服务无需等待数据库持久化完成)。
消息格式示例:
{ "userId": 1001, "entityType": "post", "entityId": 123, "timestamp": 1620000000 }
异步持久化:
持久化服务(如Spring Boot应用)消费消息队列中的点赞事件,将数据写入分布式数据库(如TiDB)。
优化策略:
批量写入:将多条点赞事件合并为1次数据库写入(如每100条事件写入1次),减少数据库IO次数。
异步提交:使用数据库的异步提交(如MySQL的
innodb_flush_log_at_trx_commit=2),提升写入性能(牺牲少量数据一致性,换取高吞吐量)。
四、热点应对:防止雪崩,保障稳定性
针对热点内容(如爆款视频、热门文章)的突发流量,需采用热点探测与本地缓存策略:
热点探测:
使用实时监控工具(如Prometheus+Grafana),监控Redis中各Key的访问频率(如每分钟访问次数)。
当某Key的访问频率超过阈值(如10万次/分钟),判定为热点Key(如
like:post:123)。
本地缓存:
对热点Key,采用Caffeine(本地缓存框架)缓存其点赞计数与用户点赞关系(如前1000个点赞用户)。
缓存更新策略:
定时同步:每10秒从Redis同步1次热点数据,确保本地缓存与Redis一致。
事件触发:当Redis中的热点数据更新时,发送事件通知(如Redis Pub/Sub),触发本地缓存更新。
分片策略:
对热点Key,采用Redis Cluster的分片策略(如基于实体ID的哈希分片),将热点Key分散到多个Redis节点,避免单点压力过大。
五、数据一致性:最终一致,保障准确性
点赞系统的数据一致性采用最终一致性模型(Redis为实时数据,数据库为持久化数据),通过以下策略保障:
缓存与数据库的一致性:
写操作:先更新Redis,再发消息到队列(确保Redis的实时性)。
读操作:优先读Redis(实时数据),若Redis中无数据,再读数据库(并更新Redis,避免缓存穿透)。
异常处理:若消息队列消费失败(如数据库宕机),采用重试机制(如Kafka的
retry.topic),确保数据最终写入数据库。
分布式事务:
对强一致性场景(如电商订单的点赞奖励),采用分布式事务框架(如Seata),实现Redis与数据库的原子操作(如点赞成功后,同时更新Redis计数与数据库奖励积分)。
六、容灾备份:高可用,防数据丢失
为保障系统在机房故障、数据库宕机等极端情况下的可用性,需采用以下容灾策略:
多机房部署:
将点赞服务、Redis集群、数据库部署在多个机房(如北京、上海、广州),采用异地多活架构(如字节跳动的“单元化架构”)。
当某机房故障时,流量自动切换至其他机房,确保服务可用。
数据备份:
Redis备份:采用RDB(快照备份)与AOF(日志备份),定期备份Redis数据(如每小时1次RDB备份,每分钟1次AOF备份)。
数据库备份:采用全量备份(如每天1次)与增量备份(如每小时1次),并将备份数据存储至对象存储(如阿里云OSS、字节跳动火山引擎对象存储)。
降级策略:
当Redis故障时,采用数据库直连(跳过Redis),直接读写数据库(牺牲性能,保障可用性)。
当数据库故障时,采用缓存降级(如显示“点赞数加载中”),避免服务完全不可用。
七、防刷与安全:保障公平性
为防止黑灰产刷赞(如机器人自动点赞、批量账号点赞),需采用以下安全策略:
用户行为分析:
使用机器学习模型(如TensorFlow),分析用户点赞行为(如点赞频率、点赞内容的关联性),识别异常行为(如1分钟内点赞100次)。
对异常用户,采用限流(如限制其1天内的点赞次数)或封禁(如永久封禁账号)。
验证码与滑块验证:
对高频点赞用户(如1小时内点赞超过50次),要求输入验证码或滑块验证,确认是真实用户操作。
设备指纹:
采集用户设备的唯一标识(如IMEI、MAC地址),识别批量设备(如同一台设备登录多个账号),防止刷赞。
总结:千亿级点赞系统的核心逻辑
今日头条与抖音的千亿级点赞系统,本质是“高并发下的实时性与一致性平衡”:
实时性:通过Redis缓存与本地缓存,实现毫秒级响应。
一致性:通过异步处理与最终一致性模型,确保数据不丢失。
稳定性:通过热点应对与容灾备份,保障高并发下的可用性。
安全性:通过防刷策略,保障点赞的公平性。
这种设计不仅能支撑千亿级点赞数据,还能应对突发热点(如爆款视频),是字节跳动(今日头条与抖音母公司)在海量数据场景下的实践总结。