消息已读未读功能如何系统设计?

消息系统中的「已读/未读」功能,虽然看似简单,但在高并发、大规模分布式系统中涉及到存储设计、性能优化、数据一致性、延迟与实时性权衡等诸多技术点。下面我从系统设计角度进行完整拆解。


✅ 一、场景定义与目标

1. 应用场景

  • IM系统(如微信、钉钉、飞书)

  • 评论通知(如微博、知乎)

  • 系统消息/站内信

  • 电商站内通知

2. 核心目标

  • 支持查看消息是否已读

  • 支持未读消息计数

  • 高并发、高性能

  • 可拓展性好,支持海量消息(千万级别)


✅ 二、数据模型设计

模型一:按用户维度记录未读消息

✅ 表结构示例:
# 消息主表(公共)
Message(id, sender_id, content, type, send_time)

# 用户收件表(每人一条记录)
User_Message(user_id, message_id, is_read, read_time)
  • is_read:标记是否已读

  • message_id:指向消息主体,节省存储

  • 每用户一份收件副本,便于个性化状态维护


✅ 三、未读消息计数的处理方式

方式一:数据库实时查询(不推荐)

SELECT COUNT(*) FROM user_message WHERE user_id = ? AND is_read = false;
  • 缺点:效率差,随着数据增长性能骤降

✅ 方式二:缓存未读计数(推荐)

  • 使用 Redis 存储用户维度的未读计数

HINCRBY unread_count:{user_id} {type} 1
HGET unread_count:{user_id} comment
  • 消息写入时同步更新未读计数

  • 消息阅读后(或批量设为已读)异步减少计数


✅ 四、已读状态更新策略

✅ 方式一:逐条标记为已读(粒度高)

UPDATE user_message SET is_read = true, read_time = NOW() 
WHERE user_id = ? AND message_id = ?

✅ 方式二:批量已读(优化性能)

UPDATE user_message SET is_read = true, read_time = NOW() 
WHERE user_id = ? AND is_read = false AND send_time < ?
  • 对于 列表下滑加载全部视为已读,或 点击“全部已读” 也适用

  • 批量操作建议走异步消息(MQ)或延迟任务处理


✅ 五、优化点与扩展设计

1. 使用 Redis Bitmap 表示已读(稀疏消息场景)

  • 每个用户一份 Bitmap,offset = message_id

  • 查询快,占内存小,但不支持稀疏离散 message_id 过大场景

2. 将未读消息 ID 单独记录在 Redis Set/List

  • unread:{user_id} → Set(message_id)

  • 拉取列表时与总消息交集过滤,或快速定位未读消息

3. 分布式场景下同步一致性

  • 未读计数更新建议采用异步方式(MQ 机制)

  • 操作幂等处理,避免并发刷读/回滚引起脏数据


✅ 六、关键接口设计(简要)

接口描述
GET /messages拉取消息列表
GET /messages/unread获取未读计数
POST /message/{id}/read标记某条消息为已读
POST /message/read-all标记所有消息为已读

✅ 七、压测&挑战

场景应对方案
消息表千万级别表分区、索引优化、冷热分离
大用户拉取未读消息或状态Redis缓存、分页加载、预聚合
多端同时操作已读状态幂等操作、乐观锁或最终一致重试机制
多维度消息统计(按类型/级别)Redis Hash 存储,定期与 DB 进行双写校准

✅ 八、最终架构简化图

[Web/APP客户端]
       ↓
  [API Gateway]
       ↓
  [消息服务] --(缓存命中)--> [Redis]
       ↓
  [消息中心DB] <--异步补偿-- [MQ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值