1) 【一句话结论】
采用微服务拆分+分布式事务(SAGA模式)+分库分表+Kafka事务消息队列+多级缓存+多活数据中心,通过异步解耦、水平扩展、容灾机制,实现百万级并发、低延迟、最终一致性的银行核心转账系统。
2) 【原理/概念讲解】
老师会解释关键概念:
- 分布式事务:跨多个服务或数据库的事务,需保证原子性(要么全成功,要么全失败)。类比:多人转账,需确保资金从A转出且B收到,或都失败(否则数据不一致)。
- CAP理论:系统需高可用(可用性),允许最终一致性(一致性),故采用SAGA模式(最终一致)。
- SAGA模式:通过消息队列解耦,每个服务独立事务,通过补偿事务回滚。类比:餐厅点餐,下单(扣库存)、支付(扣钱)、出餐(更新状态),若某步失败,后续步骤补偿(如支付失败则退库存)。
- 消息队列(Kafka):异步处理,削峰填谷,提高吞吐。类比:快递单,下单后系统不立即处理,而是放入队列,由消费者异步处理,避免阻塞。
- 数据库分库分表:水平扩展,解决单库容量限制。按账户ID哈希分表(如account_id % 1024),避免热点表;结合读写分离(主库写,从库读,通过读写分离代理负载均衡)。
- 缓存策略:Redis作为读写缓存(热点数据,如账户余额、交易记录),布隆过滤器用于接口限流(防缓存穿透),LRU淘汰冷数据。
3) 【对比与适用场景】
| 特性 | 两阶段提交(2PC) | SAGA模式 |
|---|
| 定义 | 集中式协调,保证强一致性 | 分段事务,通过消息和补偿保证最终一致 |
| 一致性 | 强一致性 | 最终一致性 |
| 可用性 | 低(协调者故障导致阻塞) | 高(服务独立,故障不影响其他服务) |
| 阻塞 | 是(协调者等待所有参与者响应) | 否(异步,无阻塞) |
| 适用场景 | 需强一致性,事务量小(如订单创建+库存扣减,量小) | 跨服务/跨行,高并发,高可用(如百万级转账) |
| 注意点 | 协调者故障导致全阻塞,不适合高并发 | 补偿事务可能失败,需幂等性设计;消息丢失需重试 |
4) 【示例】
跨行转账流程(伪代码):
- 前端调用:
POST /transfer?from=1001&to=2001&amount=100
- 本行转账服务:
a. 检查账户余额(Redis缓存,若不存在则查DB,分库分表按account_id哈希分表)
b. 发送Kafka事务消息到跨行转账队列:{"from": "1001", "to": "2001", "amount": 100, "transaction_id": "tx_12345"}
- 目标行转账服务:
a. 接收消息,检查目标账户余额(分库分表,哈希分表)
b. 扣减目标账户余额,更新DB(主从复制)
c. 发送确认消息到本行确认队列:{"from": "1001", "to": "2001", "amount": 100, "status": "success", "transaction_id": "tx_12345"}
- 本行确认服务:
a. 接收确认消息,更新本行账户余额(分库分表,哈希分表)
b. 若跨行未反馈(超时,如5秒),发送补偿消息到本行补偿队列:{"from": "1001", "to": "2001", "amount": 100, "status": "rollback", "transaction_id": "tx_12345"}
- 补偿服务:
a. 接收补偿消息,恢复本行账户余额(分库分表,哈希分表,幂等性:检查消息唯一标识或状态表记录是否已补偿)
5) 【面试口播版答案】
“面试官您好,针对百万级并发转账系统,我设计的架构核心是微服务拆分+分布式事务(SAGA模式)+分库分表+Kafka事务消息队列。前端通过负载均衡接入,后端拆分为账户服务(按账户ID哈希分表,读写分离,Redis缓存热点数据)、转账服务(处理请求后异步调用跨行服务,通过Kafka事务消息)。分布式事务用SAGA,每个服务独立事务,通过消息和补偿保证最终一致性。高可用方面,部署在K8s集群,多活数据中心,数据库主从复制,Redis集群,确保故障时快速切换。消息队列采用Kafka事务消息,生产端事务提交后消息持久化,消费端通过消息唯一标识或状态表实现幂等,避免重复消费。分库分表按账户ID哈希分表,避免热点表,读写分离通过代理负载均衡。跨行转账时,若跨行系统故障,设置超时后启动补偿事务,恢复本行账户余额。这样既能处理百万级并发,又能保证低延迟和高可用。”
6) 【追问清单】
- 问:消息队列如何保证可靠性?比如消息丢失或重复消费?
回答要点:采用Kafka的持久化存储+事务消息(确保至少一次投递),消费端通过消息唯一标识或状态表实现幂等处理,避免重复消费。
- 问:分库分表的具体策略?比如如何分表?如何避免热点?
回答要点:按账户ID哈希分表(如account_id % 1024),结合读写分离(主库写,从库读,通过读写分离代理),避免热点表(如按时间分表,如按月分表)。
- 问:跨行转账中,若跨行系统故障,如何处理?如何保证数据一致性?
回答要点:设置合理超时时间(如5秒),若跨行未响应则启动补偿事务,恢复本行账户余额;同时记录故障日志,人工干预或后续重试。
- 问:补偿事务的幂等性如何设计?避免重复执行?
回答要点:通过消息唯一标识(如transaction_id)或状态表(记录已补偿的转账记录),确保补偿消息只执行一次。
7) 【常见坑/雷区】
- 2PC的阻塞问题:若协调者故障,所有参与者阻塞,导致系统不可用,不适合高并发场景。
- SAGA补偿失败:若补偿事务失败,可能导致数据不一致(如资金多扣),需设计重试机制(如指数退避)和人工干预。
- 缓存穿透:若缓存未命中且DB查询失败(如账户不存在),可能导致服务崩溃,需布隆过滤器或空值缓存(存储null值)。
- 跨行事务的协调延迟:若依赖跨行系统响应慢,可能导致本行事务超时,需设置合理的超时时间并启动补偿,避免阻塞。
- 多活数据中心成本:若部署两地三中心,成本高,需权衡业务需求,通常采用同城多活(如主备切换)。