面试记录 2026-09-27
题目:如何设计一个高性能的分布式系统
难度:high
标签:arch/high-performance, architecture/high-performance
评分:⭐⭐⭐☆☆(3/5)
我的回答
属于高性能分布式系统,这个高性能需要考虑对比性。正常指的是能提供大量的并发,并且返回的数据结果时间很短,又快又能支撑大量的请求,支撑高并发。
首先要支撑高并发,就需要做前置的网络层的负载均衡的接入,要把大量的请求分摊给大量的服务器去进行分别的处理。单台机器的处理能力是一定是有上限的。
而高性能层面就需要根据具体业务去判定。我们日常接触的整个链路中,涉及性能方面的,首先有网络方面的开销,然后是构建链接,然后是资源的资源的获取,也就是说调数据库或者调缓存,再然后是业务逻辑的处理,这几方面都要支撑高性能。另外对于特殊的请求,比如说业务处理复杂度相对高,就做异步处理,不在本次内的请求进行处理,做异步的,后续给他注册的返回。
高性能分布式系统架构基本上是网络接入,接入之后是负载均衡。负载均衡的话,在中间层增加缓存层,或者说增加一个过滤层,将异常的请求先过滤掉,正常有效的请求才正常的访问到业务服务。然后在业务服务内做缓存,首先是本地缓存,从本地缓存内获取数据,进行,能获取到就最快速的反馈给客户端,性能最高。如果本地缓存没有,去掉分布式服务的分布式缓存,从分布式缓存中读取数据,读取到了之后加载到本地缓存,然后反馈给客户。如果缓存内都没有数据,就正常的去查业务库。再将业务库的数据返回给本地缓存跟远程分布式缓存,最终实现大批数据从缓存加载,而不是去打数据库,这样可以更高地提高性能。
另外一些耗时的操作能异步就异步。比如说一个请求中有多组操作要调用三方,这时候多个三方的调用可以通过线程池异步去调用,每一个三方请求做一个线程的请求,在三方都请求完之后做一个结果的聚合,再做处理,而不是同步的顺序去调用。
点评
优点:
- 架构分层讲得清晰:网络接入 → 负载均衡 → 缓存层 → 业务服务,层次分明
- 多级缓存思路到位:本地缓存 → 分布式缓存 → 数据库,逐级降级
- 提到请求过滤:中间层拦截异常请求,避免脏流量打到业务层
- 异步化思路对:耗时三方调用用线程池并行 + 结果聚合,避免顺序调用的累加延迟
- 从"链路延迟"角度看性能(网络 + 建连 + 资源获取 + 业务逻辑),有系统性
不足:
- 完全没有量化指标:高性能到底是多少?QPS、P99 延迟、可用性 SLO 一个数字都没给
- 只讲读链路,写链路没提:数据库分库分表、索引优化、读写分离、批量写、异步写等核心手段缺失
- 没提数据库层优化:连接池调优、慢查询排查、批量操作、读写分离——这是"高性能"的重灾区
- 没提消息队列削峰:秒杀/大促场景下的关键手段
- 没提协议优化:HTTP/2 多路复用、TCP 长连接、Protobuf 序列化、HTTP 压缩
- 没提线程模型:BIO/NIO/Reactor/虚拟线程,是 Netty/Undertow 的核心
- "过滤异常请求"没具体说:是限流?鉴权?参数校验?WAF?
补充:
- 量化目标(SLO):QPS(如 10 万)、P99 延迟(如 100ms)、可用性(如 99.99%)、错误率(如 <0.1%)
- 写路径优化:分库分表、批量写入、异步写入(先写 MQ 再异步落库)、CQRS(读写分离架构)
- 数据库层:连接池(HikariCP 参数调优)、索引设计、慢查询监控、SQL 审核
- 队列削峰:Kafka/RabbitMQ 吸收流量峰值,后端按能力消费
- 协议层:HTTP/2 多路复用、gRPC、Protobuf(比 JSON 小 3-10 倍)、gzip/zstd 压缩
- 线程模型:Netty Reactor 模型、Undertow、Virtual Thread(JDK21)
- 观测:APM(SkyWalking/Jaeger)、指标(Prometheus/Grafana)、日志(ELK)
完整讲解
第一部分:知识重点剖析
核心考点定位:考察对高性能分布式系统的完整方法论,包括"量化目标→架构设计→各层优化→治理运维"的系统性思考。
知识点拆解:
- 量化先行(80% 的回答都缺这步):
- QPS/TPS:目标 10 万 QPS
- P99 延迟:目标 <100ms
- 可用性:99.99%(允许 4.3 分钟/年不可用)
- 错误率:<0.1%
- 有了目标才能推导架构和选型
- 网络接入层:
- CDN:静态资源全球加速
- DDoS 防护:Cloudflare、高防 IP
- 网关:Nginx/APISIX/Spring Cloud Gateway(限流、鉴权、路由)
- 负载均衡层:
- L4(LVS)+ L7(Nginx)+ 客户端 LB(Ribbon/LoadBalancer)
- 一致性哈希、会话保持
- 缓存层:
- 多级缓存:本地(Caffeine)→ 分布式(Redis Cluster)→ 数据库
- 缓存穿透/击穿/雪崩防护(布隆过滤器、互斥锁、随机过期时间)
- 数据层:
- 读写分离、分库分表、CQRS
- 连接池(HikariCP)、慢查询监控、批量操作
- 冷热数据分离(ES/HBase 存冷数据)
- 异步与削峰:
- MQ(Kafka/RocketMQ)吸收流量峰值
- 事件驱动、最终一致性
- 协议与序列化:
- HTTP/2 多路复用、gRPC、Protobuf
- TCP 长连接、HTTP keep-alive
- gzip/zstd 压缩
- 线程模型:
- Netty Reactor(Boss + Worker)
- 虚拟线程(JDK21)应对高并发 IO
- 线程池隔离(避免共享池打满)
- 可观测性:
- 三大支柱:Metrics(Prometheus)、Tracing(SkyWalking/Jaeger)、Logging(ELK)
- 容量规划:压测、水位告警
- 韧性设计:
- 限流/熔断/降级、超时/重试/幂等
- 优雅启停、灰度发布
递进:从"量化目标"→ "架构分层"→ "各层优化手段"→ "可观测性"→ "韧性设计",是完整的系统思考。
第二部分:考察方向与延伸递进
考察方向:
- 深度:多级缓存的一致性、读写分离的延迟、CQRS 的最终一致
- 广度:与新基础设施(Service Mesh、Serverless、eBPF)的关系
- 应用:真实业务(秒杀/直播/支付)如何设计、如何做容量规划
延伸递进面试题:
- 你说 P99 目标 100ms,如何验证?
- 解答要点:压测工具(JMeter/AB),指标采集(SkyWalking APM),看 P50/P95/P99 分布;容量规划(单机 QPS 80% 机器数 = 系统 QPS)。
- 多级缓存如何保证一致性?
- 解答要点:Cache-Aside 模式(先查缓存,未命中查库并回写);更新时"先更库再删缓存";延迟双删;Redis 发布订阅通知本地缓存失效。
- 数据库是瓶颈时怎么办?
- 解答要点:先看慢查询(SHOW SLOW QUERIES)、加索引、读写分离、分库分表、热点数据缓存、离线任务(ETL 到 ES/HBase)、异步写入(先写 MQ 再异步落库)。
- 虚拟线程能解决所有高并发问题吗?
- 解答要点:虚拟线程对 IO 密集型有效,CPU 密集型无效(还是受限于 CPU 核数);需要 JDK21+;对 synchronized 有 pinning 问题,建议用 ReentrantLock。
第三部分:面试者参考回答(300-600 字口语化)
面试官您好,设计一个高性能分布式系统,我会从"量化目标 → 架构分层 → 各层优化 → 治理运维"四个维度来做。
第一步,量化目标:先和 PM 对齐 SLA。比如 QPS 10 万、P99 延迟 100ms、可用性 99.99%、错误率 <0.1%。有了目标才能推导架构和选型。
第二步,架构分层(自上而下):
- 接入层:CDN(静态加速)+ DDoS 防护 + 网关(限流/鉴权/路由)
- 负载均衡层:L4(LVS)+ L7(Nginx)+ 客户端 LB,用一致性哈希
- 业务层:无状态微服务,水平扩展
- 缓存层:多级缓存(Caffeine 本地 + Redis 分布式)
- 数据层:MySQL 分库分表 + ES(搜索)+ HBase(冷数据)
- 异步层:Kafka/RocketMQ 削峰、事件驱动
第三步,各层优化:
- 网络:HTTP/2 多路复用、TCP 长连接、keep-alive、HTTP 压缩(zstd)
- 序列化:Protobuf 替代 JSON,体积小 3-10 倍
- 缓存:多级缓存(先本地后分布式后数据库),缓存穿透用布隆过滤器,击穿用互斥锁,雪崩用随机 TTL
- 数据库:HikariCP 连接池调优、索引优化、慢查询监控、批量写入、读写分离
- 异步:耗时操作进 MQ,事件驱动,最终一致性
- 线程模型:Netty Reactor、虚拟线程(JDK21)应对 IO 密集
第四步,韧性 + 可观测性:
- 韧性:限流(Sentinel 令牌桶)+ 熔断(Hystrix/Sentinel)+ 降级(兜底值)+ 超时/重试/幂等
- 可观测:Prometheus 指标、SkyWalking 链路、ELK 日志
举例:秒杀场景。用户下单峰值 10 万 QPS,通过 CDN + Nginx 限流 → 网关做黑名单过滤 → Kafka 削峰 → 后端按 1000 QPS 消费落库 → Redis 库存预扣(Lua 原子操作)→ 订单 MQ 异步持久化。P99 延迟 <200ms。