51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

设计一个支持亿级用户的IM消息系统,要求消息实时性(延迟<100ms)、消息不丢失、可扩展。请描述系统架构、核心模块设计、数据存储方案及容灾策略。

Tencent软件开发-后台开发方向难度:困难

答案

1) 【一句话结论】采用“接入层-消息队列-分布式存储-业务层”四层架构,结合Redis缓存+数据库持久化+消息队列解耦,确保亿级用户下延迟<100ms、消息不丢失且可扩展。

2) 【原理/概念讲解】
首先解释“实时性”需求:延迟<100ms意味着消息处理链路需极短,需通过消息队列作为中间件解耦发送与接收,减少耦合度。
其次“消息不丢失”:需持久化存储,如将消息先写入数据库(MySQL),再写入Redis(缓存),同时消息队列提供重试机制(如Kafka的retries)。
最后“可扩展性”:需水平扩展,如消息队列集群、Redis集群、数据库分库分表,通过负载均衡和分片实现。
类比:消息队列像“快递中转站”——发送方把包裹(消息)放到中转站,接收方从站里取,中转站保证包裹不丢失且可扩展。

3) 【对比与适用场景】

方案定义特性使用场景注意点
消息队列(Kafka)分布式消息系统高吞吐、持久化、可水平扩展消息量大的实时系统(如亿级IM)需要持久化存储,处理延迟略高于内存数据库
Redis内存数据库低延迟、高并发、支持持久化消息缓存、会话存储内存限制,持久化有RDB/AOF,写入延迟高于数据库
MySQL关系型数据库持久化、事务支持长期消息存储、业务数据写入延迟较高,需分库分表提升性能

4) 【示例】
以用户A发送消息给用户B为例,流程:

  1. 用户A客户端通过WebSocket连接接入层(Nginx),发送消息“你好”。
  2. 接入层将消息发送到Kafka的“userA_userB”分区。
  3. 消费端(消息服务)从Kafka拉取消息,处理路由(根据用户ID匹配接收方)。
  4. 消息服务将消息写入Redis(缓存,用于实时推送),同时写入MySQL(持久化)。
  5. 推送服务监听Redis的发布/订阅,将消息推送给用户B的客户端(WebSocket)。
  6. 用户B客户端收到消息后,发送ACK给消息服务,消息服务更新状态(如“已读”)。

5) 【面试口播版答案】
“面试官您好,针对亿级用户的IM消息系统,我的设计核心是构建低延迟、高可靠的分布式架构。首先分层设计:接入层用WebSocket+Nginx处理实时连接,消息队列选Kafka作为中间件解耦发送与接收,确保消息不丢失且可扩展。存储层采用Redis+MySQL双存储——Redis缓存消息用于实时推送(延迟<100ms),MySQL持久化消息保证不丢失。消息路由通过用户ID哈希到Kafka分区,实现高效分发。容灾方面,多机房部署Kafka和Redis集群,消息重试机制(如Kafka的retries)和数据库主从复制保证数据一致性。整体架构能支撑亿级用户,延迟控制在100ms内,消息不丢失且可水平扩展。”

6) 【追问清单】

  • 问:如何保证消息不丢失?→ 回答:消息队列持久化+数据库双写+消息确认机制(ACK)。
  • 问:消息积压时如何处理?→ 回答:消息队列分区扩容、消费端增加并行度、临时存储(如S3)。
  • 问:如何扩展?→ 回答:消息队列和Redis集群水平扩展,数据库分库分表。
  • 问:消息路由的效率?→ 回答:用户ID哈希到Kafka分区,减少跨分区通信,提升路由效率。
  • 问:容灾的具体方案?→ 回答:多机房部署,数据同步(如MySQL主从),消息重试和幂等处理。

7) 【常见坑/雷区】

  • 忽略消息持久化:只说Redis缓存而忽略数据库,导致消息丢失。
  • 架构设计未分层:直接用单机服务,无法扩展。
  • 消息队列选择错误:用RabbitMQ而没考虑Kafka的高吞吐,导致延迟过高。
  • 未考虑消息确认机制:消息发送后未确认,可能导致重复或丢失。
  • 容灾方案不具体:只说“多机房”,未说明数据同步和消息重试的具体措施。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1