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

设计一个社交系统(好友、公会),需要支持高并发下的用户操作(如添加好友、加入公会)。请说明系统架构和关键技术点,如何保证性能和一致性。

游卡客户端主程难度:困难

答案

1) 【一句话结论】采用分层微服务架构,结合分布式缓存(Redis)、消息队列(Kafka)、数据库分库分表(MySQL),通过Seata分布式事务保证跨库一致性,消息幂等处理避免重复消费,缓存双写(互斥锁+空值缓存)应对雪崩,最终一致性模型下延迟控制在1分钟内,平衡高并发性能与数据一致性。

2) 【原理/概念讲解】系统拆解为用户层(API网关)、服务层(好友/公会服务)、数据层(Redis+MySQL分库分表)。关键点:

  • 分库分表:按用户ID分库(如每个库100万用户),按时间分表(好友表按月),水平扩展数据库,解决单库QPS瓶颈。
  • 分布式事务:使用Seata(AT模式),将跨库操作封装为事务,确保数据一致性(如添加好友时同时更新A和B的好友列表,跨库事务保证原子性)。
  • 消息队列:Kafka解耦服务调用,添加好友时先发消息到队列,异步处理,避免服务阻塞,提升吞吐量;消息幂等通过消息唯一标识(如用户ID+好友ID组合)避免重复消费。
  • 缓存优化:Redis缓存热点数据(好友列表、公会成员),减少数据库压力;缓存雪崩用随机过期时间+限流,缓存穿透用互斥锁+空值缓存(设置默认值,避免热点key失效后大量请求数据库)。
  • 一致性模型:最终一致性,因社交系统对实时性要求不高(如好友关系变更后1分钟内同步不影响体验),通过消息队列异步更新数据库,确保数据最终一致,延迟边界控制在1分钟内。

3) 【对比与适用场景】(分布式事务方案对比):

方案定义特性使用场景注意点
Seata (AT模式)分布式事务框架,支持本地事务与分布式事务切换基于本地事务,低开销,支持补偿机制跨库事务(如好友关系跨用户表)需配置事务管理器,补偿机制可能影响性能
2PC (两阶段提交)传统分布式事务,协调者与参与者两阶段强一致性,但高并发下性能差,阻塞风险高对一致性要求极高(如金融系统)适用于低并发场景,不适合社交系统

4) 【示例】(添加好友流程伪代码):

def add_friend(user_id_a, user_id_b):
    # 1. 缓存穿透检查(互斥锁+空值缓存)
    lock_key = f"friend_lock_{user_id_a}_{user_id_b}"
    with redis_lock(lock_key, timeout=10):
        if not cache.get(f"friend_list_{user_id_a}"):
            friend_list = db.get_user_friends(user_id_a)  # 数据库查
            cache.set(f"friend_list_{user_id_a}", friend_list, expire=3600)  # 缓存1小时
        
        # 2. 检查是否已存在
        if user_id_b in cache.get(f"friend_list_{user_id_a}"):
            return "已存在"
        
        # 3. 发送消息到Kafka(幂等)
        msg_id = f"{user_id_a}_{user_id_b}"
        kafka_producer.send("add_friend", value=msg_id, key=msg_id)  # 消息唯一标识
        
        # 4. 跨库事务(Seata)
        with db.transaction():
            db.add_friend(user_id_a, user_id_b)  # 更新A好友列表
            db.add_friend(user_id_b, user_id_a)  # 更新B联系人列表

消费端:

def process_add_friend(msg):
    user_id_a, user_id_b = msg.split('_')
    with db.transaction():
        db.add_friend(user_id_a, user_id_b)
        db.add_friend(user_id_b, user_id_a)

5) 【面试口播版答案】面试官您好,针对社交系统(好友、公会)的高并发设计,我的核心方案是分层微服务架构+分布式缓存+消息队列+数据库分库分表+Seata分布式事务+消息幂等+缓存双写,平衡性能与一致性。具体来说:
系统分层:用户层(API网关)负责请求路由与限流,服务层(好友/公会服务)处理业务,数据层(Redis+MySQL分库分表)存储数据。关键技术点:分库分表按用户ID分库(每个库100万用户)、按时间分表(好友表按月),解决数据库瓶颈;Seata分布式事务(AT模式)保证跨库操作的原子性(如添加好友时同时更新两个用户的好友列表);Kafka消息队列解耦服务,添加好友时先发消息到队列,异步处理,避免服务阻塞;Redis缓存热点数据(如用户好友列表),减少数据库压力;缓存雪崩用随机过期时间+限流,缓存穿透用互斥锁+空值缓存(设置默认值,避免热点key失效后大量请求数据库);消息幂等通过消息唯一标识(用户ID+好友ID)避免重复消费。流程示例:用户A添加好友B,先检查Redis缓存(若缓存无数据则查数据库),检查是否已存在,然后发送消息到Kafka,后台任务通过Seata事务更新数据库,确保数据一致。最终一致性模型下,延迟控制在1分钟内,不影响用户体验。总结来说,这套方案通过分层解耦、缓存加速、消息异步处理、分布式事务保证一致性,能有效支撑高并发操作,同时保证数据最终一致。

6) 【追问清单】:

  • Q1:如何处理跨库事务中的补偿机制?比如事务失败后如何回滚?
    回答要点:Seata的AT模式会自动生成补偿事务,事务失败后通过补偿事务回滚数据,确保数据一致性。
  • Q2:缓存雪崩时,如何避免大量请求同时打到数据库?
    回答要点:缓存雪崩用随机过期时间(避免同一时间大量key失效),结合限流(如熔断器)控制请求量,减少数据库压力。
  • Q3:消息队列延迟或消息丢失怎么办?
    回答要点:消息队列采用多副本、持久化存储(如Kafka的日志持久化),确保消息不丢失;延迟问题通过批量处理或优先级队列优化,设置延迟告警(如延迟超过5秒触发)。
  • Q4:分库分表后,如何保证跨库查询(如查询用户A的所有好友)?
    回答要点:通过分片路由(根据用户ID计算分片)或中间件(如ShardingSphere)统一管理分片查询,避免客户端处理分片逻辑。
  • Q5:系统如何监控和告警?关键指标有哪些?
    回答要点:通过Prometheus+Grafana监控缓存命中率(目标>80%)、数据库QPS(目标<5000)、消息队列延迟(目标<1秒)、分布式事务成功率(目标>99.9%)等指标,设置告警阈值(如缓存命中率<70%或QPS超过阈值时告警),及时处理问题。

7) 【常见坑/雷区】:

  • 坑1:未使用分布式事务导致跨库数据不一致(如添加好友时只更新一个用户的好友列表,另一个未更新)。
  • 雷区:滥用强一致性模型(如2PC),在高并发下性能差,阻塞风险高,不适合社交系统。
  • 坑2:缓存未做雪崩/穿透处理,导致缓存失效后大量请求数据库,造成雪崩效应。
  • 雷区:消息队列未做幂等处理,导致重复消费(如添加好友消息重复处理,导致好友关系重复添加)。
  • 坑3:分库分表后,未考虑跨库查询的复杂性,导致客户端需要处理分片逻辑,增加系统复杂度。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1