美团面试官详解 Kafka 实现百万级 QPS 的高性能原因及面试要点。
磁盘维度优化:采用顺序读写搭配操作系统页缓存,读写数据先存入页缓存再异步刷盘,消费者读取时命中页缓存可避免磁盘 IO;使用 sendfile 零拷贝技术,数据在内核态直接从磁盘传输到网卡,减少上下文切换与 CPU 拷贝。
网络维度优化:生产者通过 batch.size、linger.ms 参数攒批发送消息;采用 lz4/zstd 格式压缩消息,减少网络传输量与磁盘存储;Topic 分区分布在多 Broker,支持并行读写与消费。
数据格式优化:采用 V2 批次格式节省空间;用时间轮管理延迟任务,实现 O (1) 的查询效率,支持秒级到天级的大范围延迟。
竞品对比要点:Kafka 吞吐量高于 RocketMQ、RabbitMQ,但存在功能单一、原生延迟队列支持弱、不支持消息事务、低延迟场景表现差等劣势。
视频讲解了每秒 10w QPS 的爆火视频点赞导致数据库行锁卡死的解决方案及底层逻辑。
问题根源解析:InnoDB 引擎执行 UPDATE 语句需获取排它 X 锁,10 万并发请求排队获取锁,会使操作系统上下文切换频繁、MySQL 死锁检测压力剧增,CPU 利用率飙至 100%,吞吐量跌到个位数。
常规方案局限:仅用 Redis 原子递增加 MQ 异步写库,会出现 Redis 单机达到物理极限、MQ 消费者逐条更新仍导致数据库行锁排队的问题,只是推迟故障时间。
端侧本地缓冲:在 Web Server 内存开辟 200ms 时间窗口,用 AtomicLong 合并器将窗口内的散点点赞合并为单次批量请求,从源头减少 RPC 调用频率。
Redis 热点拆分:借鉴 LongAdder 空间换时间思想,将单个视频 ID 拆分为多个子 Key 分片,按用户 ID 取模分流请求,每个分片仅承担 1w QPS,查询时求和所有分片数据。
消费端批量写合:在 MQ 消费端搭建内存聚合引擎,按视频 ID 累加点赞数,最终仅向数据库执行一条合并后的 SQL,使加锁频率骤降三个数量级,终结行锁竞争。
满分方案为端侧聚合、缓存分片、批量写合的四位一体架构,配合定期快照与 Binlog 日志保障最终一致性与宕机恢复。
视频围绕 "Spring Boot 应用启动过慢如何排查" 展开,核心内容可总结为以下三点:
一、启动阶段拆分
Spring Boot 启动分为六大阶段:环境准备 → 上下文初始化 → 组件扫描 → 自动配置 → 嵌入式容器启动 → 自定义扩展。通过添加 --debug 参数或实现 ApplicationListener 统计各阶段耗时,可定位具体卡顿位置。
二、分阶段排查方法
环境准备慢:检查配置中心(如 Nacos、阿波罗)远程配置拉取是否因网络或重试机制卡住;
上下文 / 组件扫描慢:排查 Bean 的构造方法是否调用外部接口、@Configuration 类是否包含耗时操作、扫描包范围是否过大(如扫描了无关包)、是否存在循环依赖导致多次代理;
自动配置慢:检查 Starter 初始化连接时是否堵塞(如数据库连接失败导致重试);
容器启动慢:排查 Tomcat/Undertow 端口冲突、SSL 初始化耗时、静态资源扫描过多等问题。
三、面试高频考点
视频配套的面试题答案已整理在评论区,重点覆盖启动流程、各阶段耗时统计及针对性优化措施,适合 Java 后端面试突击准备。
视频讲解了 MySQL 中 WAL 预写日志技术的定义、原理及作用。
WAL 核心规则:WAL 全称 Write-Ahead Logging,核心规则是先写日志再写磁盘;对数据库修改时,需先将修改记录写入日志文件,日志落盘即算事务提交成功。
类比通俗解释:用古代客栈记账类比,流水账本对应预写日志,总账本对应磁盘数据文件;忙时先记流水账,空闲时再誊写总账。
解决效率痛点:磁盘数据页分散,直接改数据是随机读写,速度极慢;预写日志是顺序追加写入,速度比随机读写快几十倍,提升数据库并发处理能力。
解决安全痛点:数据库在内存缓冲池改数据,断电会丢失未刷盘数据;预写日志已写入磁盘,重启后可按日志重做恢复数据,保证事务持久性与崩溃恢复。
视频结尾提出思考题:MySQL 中负责该功能的具体日志文件是什么。
视频讲解 Redis 多命令执行的四种方案及对应业务场景选型逻辑。
批量命令方案:仅支持同类型命令,1 次网络往返且天然原子,适用于电商批量缓存商品信息场景。
Pipeline 方案:支持混合命令,1 次网络往返效率高,但不保证原子性,适用于凌晨数据同步、缓存初始化等无需原子性的场景,秒杀场景禁用。
事务方案:EXEC 执行时保证原子性,不支持逻辑判断,运行时错误不回滚,适用于金融转账等无复杂判断的原子性场景。
Lua 脚本方案:整个脚本视为一条原子命令,支持逻辑判断,可杜绝超卖,适用于秒杀、分布式锁等复杂原子性场景。
面试选型逻辑为:不要原子性时,同类型用批量命令、混合用 Pipeline;要原子性时,无逻辑判断用事务、有逻辑判断的秒杀场景用 Lua 脚本。
视频讲解了 MySQL 的索引结构类型,以及 InnoDB 不支持用户创建 Hash 索引的原因。
索引类型说明:MySQL 除 InnoDB 的 B+Tree 索引外,还有 Oracle 的权威索引、B 树空间索引、Memory 存储引擎支持的 Hash 索引等类型。
InnoDB Hash 限制:InnoDB 不支持用户创建 Hash 索引,仅内置自适应 Hash 索引优化机制,该机制会在内存中为频繁访问的值自动构建 Hash 结构加速等值查询,由引擎内部控制,用户无法干预。
不支持原因 1:InnoDB 面向的典型业务场景中范围查询常见,而 Hash 索引仅支持等值查询,无法满足范围查询需求。
不支持原因 2:B+Tree 在磁盘存储上可利用预读特性,将多个节点连续存储,减少随机 IO;Hash 索引在磁盘上随机分布,读数据需多次随机 IO,磁盘效率低于 B+Tree。
不支持原因 3:Hash 索引存在 Hash 冲突,需额外列表结构处理,会造成空间浪费;B+Tree 在空间利用率和稳定性上更具优势。
InnoDB 选择 B+Tree 作为主要索引存储结构,是多方面综合考量的结果。