MySQL高并发写入面试场景题是后端岗位面试的常见考察内容,面试官通常会给出类似“电商大促期间每秒10万订单写入,如何保证MySQL不宕机且数据不丢失”的场景,考察候选人的综合技术能力。

常见面试场景题示例
面试官常问的高并发写入场景题主要有以下几类:
- 秒杀系统中大量订单同时写入,MySQL出现死锁和写入超时,怎么优化
- 物联网设备每秒上报数万条日志,直接写入MySQL性能不足,如何解决
- 现有MySQL单库单表,写入量从每秒1千涨到每秒5万,需要怎么做架构调整
核心答题思路拆解
回答这类问题时,可以按照“瓶颈分析-分层解决-落地细节”的逻辑展开,避免零散堆砌知识点。
第一步:定位核心瓶颈
高并发写入场景下,MySQL的常见瓶颈包括:
- 磁盘IO瓶颈:大量写入操作导致redo log、binlog刷盘频繁,磁盘负载过高
- 锁竞争瓶颈:行锁、表锁竞争导致事务阻塞,写入延迟升高
- 单点性能瓶颈:单库单表无法承载过高的写入吞吐量
- 网络瓶颈:大量写入请求同时到达,数据库连接数耗尽
第二步:分层给出解决方案
1. 应用层优化
首先在流量入口做前置处理,减少到达MySQL的写入压力:
- 引入消息队列做写入削峰,将同步写入改为异步批量写入
- 对写入数据做合并处理,相同维度的数据先聚合再批量入库
- 限制单客户端写入频率,避免恶意请求打满数据库
以下是使用RabbitMQ做写入削峰的简化代码示例:
// 订单写入生产者,将订单消息发送到MQ
public class OrderProducer {
private RabbitTemplate rabbitTemplate;
public void sendOrder(Order order) {
// 发送消息到订单写入队列
rabbitTemplate.convertAndSend("order_write_queue", order);
}
}
// 订单写入消费者,批量消费消息后写入MySQL
public class OrderConsumer {
private OrderMapper orderMapper;
// 每次消费100条订单后批量插入
@RabbitListener(queues = "order_write_queue")
public void processOrders(List<Order> orderList) {
if (orderList.size() >= 100) {
orderMapper.batchInsert(orderList);
}
}
}
2. 数据库层优化
针对MySQL本身的配置和表结构做优化:
- 调整
innodb_flush_log_at_trx_commit参数,非核心场景可设置为2,减少redo log刷盘频率 - 合理设计索引,避免写入时触发不必要的索引更新,主键尽量使用自增ID减少页分裂
- 拆分大事务,将长事务拆分为多个短事务,降低锁持有时间
- 开启
bulk_insert_buffer_size参数,提升批量插入的性能
批量插入的SQL示例:
-- 批量插入订单数据,比单条插入性能高5-10倍 INSERT INTO t_order (order_id, user_id, amount, create_time) VALUES (1001, 2001, 99.9, '2024-05-01 10:00:00'), (1002, 2002, 199.8, '2024-05-01 10:00:01'), (1003, 2003, 299.7, '2024-05-01 10:00:02');
3. 架构层优化
当单库性能达到上限时,需要做架构拆分:
- 分库分表:按用户ID哈希拆分订单表,将数据分散到多个库表,降低单表写入压力
- 读写分离:写入走主库,查询走从库,避免查询请求占用写入连接
- 引入分布式数据库:核心场景可替换为TiDB等兼容MySQL协议的分布式数据库,原生支持高并发写入
分库分表后的写入路由简单示例:
public class OrderRouter {
// 根据user_id哈希路由到对应的库表
public static String getTableName(long userId) {
int tableIndex = (int) (userId % 16);
return "t_order_" + tableIndex;
}
public static String getDbName(long userId) {
int dbIndex = (int) ((userId / 16) % 4);
return "order_db_" + dbIndex;
}
}
面试答题注意事项
回答时要结合场景给出取舍,比如核心订单数据不能为了性能牺牲数据可靠性,要说明参数调整的前提;同时可以主动提及可能遇到的问题,比如分库分表后的分布式事务问题,展现思考的全面性。不要只背解决方案,要讲清楚每个方案解决的是什么瓶颈,适用什么场景,这样更容易获得面试官的认可。