
【一句话结论】
针对交通银行核心交易系统海量读写需求,通过读写分离(MySQL主从复制+异步Binlog,延迟秒级)分担读压力,分库分表(ShardingSphere哈希+时间分片)水平扩展数据规模,结合两阶段提交保障强一致性、消息队列+补偿机制保障最终一致性,并设计分片合并策略与数据校验流程,最终实现性能提升与高并发下的数据一致性保障。
【原理/概念讲解】
老师:先讲读写分离。核心是主从数据库复制技术,主库负责所有写操作(如账户扣款、存款,事务提交、数据更新),从库通过异步复制(如MySQL的Binlog日志)同步主库数据,从库仅用于读操作(如查询余额、交易记录),分担主库压力。类比:超市收银台(主库)负责收银(写),自助结账机(从库)负责查询商品库存(读),减少收银台压力。异步复制导致从库数据有延迟(通常秒级),读操作需路由到从库,避免主库被频繁查询影响写性能。
再讲分库分表。当数据量超过单库容量时,按一定规则(如用户ID哈希、时间范围)拆分到多个数据库或表,水平扩展数据存储。比如用户表(user_table),按用户ID哈希分库(库1、库2),每个库按时间分表(表1、表2)。写操作时,路由到主库对应分库;读操作时,路由到从库对应分库和分表。水平扩展后,单库压力降低,查询性能提升。
分布式事务中,强一致性用两阶段提交(2PC):预提交(源账户扣款,主库写日志),执行提交(目标账户扣款,主库写日志),若预提交失败回滚;最终一致性用消息队列(如Kafka)发送更新指令,从库定时消费并更新,结合幂等性(检查点机制)确保数据最终一致。
【对比与适用场景】
| 技术方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 读写分离 | 主从数据库复制,主写从读 | 主库处理写,从库处理读,读压力分散 | 读多写少场景(如查询频繁,写操作较少) | 从库数据有延迟,读操作需路由到从库 |
| 分库分表 | 水平拆分数据表到多库或多表 | 水平扩展数据量,写操作需路由 | 数据量巨大,单库无法承载(如用户表、交易表) | 路由复杂,写操作可能跨库,查询需分片合并 |
【示例】
<shardingRule>
<tables>
<table name="user_table" dbShardingType="M masterslave">
<column name="user_id" type="long" shardingColumn="user_id"/>
<shardingKeyRule>
<shardingAlgorithm type="HASH" name="user_id_hash">
<property name="global">true</property>
</shardingAlgorithm>
</shardingKeyRule>
<tableShardingStrategy>
<shardingColumn>user_id</shardingColumn>
<shardingAlgorithm type="HASH" name="user_id_time">
<property name="global">true</property>
<property name="shardingCount">2</property> <!-- 分表数量 -->
</shardingAlgorithm>
</tableShardingStrategy>
</table>
</tables>
<drdsRule>
<writeSplit>ds_0_write,ds_1_write</writeSplit>
<readOnly>ds_0_read,ds_1_read</readOnly>
</drdsRule>
</shardingRule>
# 查询所有用户总余额
def query_total_balance():
shards = get_shards("user_table", "user_id")
total_balance = 0
for shard in shards:
data = query_shard(shard, "SELECT balance FROM user_table WHERE user_id IN (shard.user_ids)")
total_balance += sum(d['balance'] for d in data)
return total_balance
【面试口播版答案】
“面试官您好,针对交通银行核心交易系统处理海量读写操作的需求,我主要从读写分离和分库分表两方面来提升性能并保证一致性。首先,读写分离:通过MySQL主从复制,主库负责写操作(如账户扣款、存款),从库用于读操作(如查询余额、交易记录),异步Binlog同步数据,延迟通常秒级,显著降低主库压力。比如,用户查询余额时,请求会路由到从库,避免主库被频繁查询影响写操作。然后,分库分表:当用户表数据量超过单库容量时,按用户ID哈希分库(如ID模2分库),每个库再按时间分表(如按月分表),水平扩展数据存储。写操作时,路由到主库对应分库;读操作路由到从库对应分库和分表。对于需要强一致性的转账操作,采用两阶段提交(2PC):预提交源账户扣款(写日志),执行提交目标账户扣款(写日志),若预提交失败回滚;对于最终一致性场景,通过Kafka发送更新指令,从库定时消费并更新,结合幂等性(检查点)确保最终一致。此外,设计分片合并策略(如聚合查询时合并分片结果),以及每日数据校验流程(如账户余额比对),保障数据一致性。总结来说,读写分离解决读压力,分库分表解决数据量瓶颈,结合事务与补偿机制,能有效提升系统性能并满足高并发需求。”
【追问清单】
【常见坑/雷区】