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

设计一个高并发的游戏交易系统,要求支持百万级用户同时进行虚拟物品交易,保证交易原子性,并考虑缓存穿透、雪崩等场景,请描述系统架构、关键技术点及如何保证数据一致性。

多益网络程序类难度:困难

答案

1) 【一句话结论】
设计高并发游戏交易系统,核心是通过微服务拆分(交易、库存、订单服务),采用Saga模式实现分布式事务保证交易原子性,结合布隆过滤器防缓存穿透、分布式锁防并发、缓存过期时间随机化防雪崩,以及数据库分库分表,支撑百万级并发并确保数据一致性。

2) 【原理/概念讲解】
老师解释:百万用户同时交易需水平扩展。原子性指交易全流程(如扣减库存、创建订单)不可分割,失败需回滚(库存扣减失败则订单不创建)。

  • 分布式事务(Saga模式):将交易拆分为多个步骤(库存扣减、订单创建),成功后通过消息队列通知后续步骤,失败后补偿回滚,实现最终一致性(适合游戏场景,库存扣减失败订单不创建,允许最终一致性)。
  • 缓存穿透:查询不存在的数据(如虚拟物品ID不存在),导致数据库压力激增(类比:在人群中找不存在的人,所有人都去问,最终数据库被问崩溃)。
  • 缓存雪崩:大量缓存数据集中过期(如同一时间大量缓存失效),导致数据库压力激增(类比:多米诺骨牌倒下,连锁反应导致系统崩溃)。
  • 分布式锁:保证并发操作互斥(如抢购时锁库存),防止多人同时修改数据。

3) 【对比与适用场景】

  • 缓存穿透解决方案:
    方案定义特性使用场景注意点
    布隆过滤器位图结构,判断元素是否存在于集合确定否定(无则一定不存在),可能误报(误报率约1%左右,可通过增加位数降低)查询不存在的数据(如虚拟物品ID不存在)不能存储数据,需配合缓存
    缓存空值+互斥锁存储空值,加锁重试防穿透,但锁竞争高并发下查询不存在的数据锁竞争可能导致性能下降
  • 分布式事务一致性:
    方案定义特性使用场景注意点
    最终一致性(Saga)分步骤执行,失败补偿成本低,适合高并发(如游戏交易,库存扣减失败订单不创建,允许最终一致性)交易、库存、订单等步骤需监控补偿失败,人工干预
    强一致性(两阶段提交)全局事务,一步完成数据一致性高(如金融,库存扣减失败订单需删除,不允许最终一致性)金融等强一致性要求场景性能低,不适合高并发

4) 【示例】
交易服务购买物品流程(含布隆过滤器检查、分布式锁、Saga补偿,消息队列ACK机制):

# 交易服务:购买物品
def buy_item(user_id, item_id, count):
    # 1. 检查布隆过滤器(防穿透,误报率约1%)
    if not bloom_filter.contains(item_id):
        return "item not exist"
    # 2. 加分布式锁(Redis SETNX,10秒过期,避免死锁)
    lock_key = f"inventory:{item_id}:lock"
    if not redis.setnx(lock_key, 1, ex=10):
        return "lock failed, retry"
    try:
        # 3. 扣减库存(数据库更新)
        db.update("inventory", {"stock": stock - count}, where="id=?")
        # 4. 创建订单(消息队列,带ACK确认)
        order_msg = {"user_id": user_id, "item_id": item_id, "count": count, "status": "pending"}
        mq.publish("order.create", order_msg)
        # 5. 释放锁
        redis.delete(lock_key)
        return "transaction success"
    except Exception as e:
        # 6. 发送补偿消息回滚库存(消息队列,重试3次,失败人工介入)
        mq.publish("inventory.rollback", {"item_id": item_id, "count": count}, retry=3)
        redis.delete(lock_key)
        return "transaction failed, inventory rolled back"

# 库存服务:处理补偿消息(带幂等性)
def handle_inventory_rollback(msg):
    item_id = msg["item_id"]
    count = msg["count"]
    # 幂等性检查(订单号)
    order_id = msg.get("order_id", None)
    if not order_id:
        return "invalid message"
    # 执行回滚
    db.update("inventory", {"stock": stock + count}, where="id=?")

5) 【面试口播版答案】
面试官您好,设计高并发游戏交易系统,核心是通过微服务拆分(交易、库存、订单服务),采用Saga模式实现分布式事务保证交易原子性,结合布隆过滤器防缓存穿透、分布式锁防并发、缓存过期时间随机化防雪崩,以及数据库分库分表,支撑百万级并发并确保数据一致性。具体来说:

  1. Saga分布式事务:将交易拆分为库存扣减、订单创建等步骤,成功后通过消息队列通知后续步骤,失败后补偿回滚,实现最终一致性(适合游戏场景,库存扣减失败订单不创建,允许最终一致性)。
  2. 缓存双写与布隆过滤器:用布隆过滤器拦截不存在的物品查询(防穿透,误报率约1%),加锁后双写数据库和缓存,缓存过期时间随机化(防雪崩)。
  3. 分布式锁:Redis SETNX实现库存扣减的互斥,设置10秒过期时间避免死锁。
  4. 数据库分库分表:按物品类型分表,结合全局ID(雪花算法),支撑海量数据。
    数据一致性通过Saga的补偿机制和分布式锁保证,缓存预热(定时任务加载热门数据),以及限流熔断保护系统。总结来说,通过拆分服务、缓存优化、Saga事务和分布式锁,能支撑百万级并发,确保交易原子性和数据一致性。

6) 【追问清单】

  • 问题:Saga模式中,库存扣减和订单创建的顺序如何保证?
    回答要点:库存扣减成功后,通过消息队列通知订单服务创建订单,失败后补偿消息回滚库存,确保最终一致性。
  • 问题:缓存雪崩如何处理?
    回答要点:缓存预热(定时任务加载热门数据),过期时间随机化(避免集中过期),以及设置热点数据永不过期。
  • 问题:分布式锁的过期时间如何设置?
    回答要点:根据业务逻辑,比如库存扣减操作时间(假设10秒内完成),设置略长于操作时间的过期时间(如10秒),避免死锁。
  • 问题:数据不一致的风险如何规避?
    回答要点:Saga的补偿流程确保最终一致性,但需监控补偿失败,及时人工干预(如补偿失败后记录日志,人工重试)。
  • 问题:系统如何处理超时和重试?
    回答要点:设置请求超时时间(如3秒),失败后指数退避重试(避免重复提交,订单号唯一)。

7) 【常见坑/雷区】

  • 坑1:直接用数据库事务保证原子性,导致性能瓶颈(完全强一致性不可行,百万级并发下无法承受)。
  • 坑2:忽略Saga的补偿逻辑,导致库存扣减成功但订单未创建,数据不一致(需确保补偿流程可靠)。
  • 坑3:分布式锁未设置过期时间,导致死锁,影响系统可用性(如长时间持有锁导致其他请求阻塞)。
  • 坑4:缓存更新策略错误(先更新数据库再更新缓存),导致缓存雪崩(应双写,或设置过期时间)。
  • 坑5:限流策略设置不当,影响正常用户交易体验(如限流阈值过低,导致正常用户请求被拒绝)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1