用 ChaosBlade 模拟 MySQL 慢查询,如何设置延迟分布更接近真实

解读

面试官想确认三件事:

  1. 你是否知道 ChaosBlade 只能注入“网络/系统”层延迟,而不是真正让 SQL 执行变慢;
  2. 你是否能把“真实慢查询”的分布特征(长尾、偶发抖动、主从差异、时段性)翻译成 ChaosBlade 可识别的参数;
  3. 你是否能在不破坏基准数据的前提下,把延迟注入到正确的调用路径(端口、线程、SQL 特征)上,并给出可观测闭环。

知识点

  1. ChaosBlade 延迟注入原理:基于 tc/netem 或 iptables,在 MySQL 端口(默认 3306)出口做排队,单位是毫秒。
  2. 真实慢查询分布特征:
    • 90% 在 0–50 ms,99% 在 200 ms 内,99.9% 存在 500 ms~2 s 长尾;
    • 白天高峰时段平均延迟比凌晨高 30%–50%;
    • 主从延迟分布不同,从库往往拖后 20–100 ms;
    • 偶发“毛刺”受刷脏页、锁等待、半同步复制影响,呈突发状。
  3. ChaosBlade 网络延迟参数: --time:固定基础延迟; --offset:波动范围,产生均匀分布; --timeout:单次注入持续时间; --target-port:MySQL 端口; --sql-pattern:社区版 1.7.2 开始支持按 SQL 正则匹配注入。
  4. 分布拟合技巧:用 shell 循环多次执行 blade,每次随机化 time+offset,可近似正态/长尾;或把延迟拆成两段,主库 10 ms±5 ms,从库 50 ms±20 ms,分别打标签。
  5. 观测与回滚:必须同时打开 MySQL general log / performance_schema 或接入 APM,验证 QPS、RT 直方图与预期分布一致;实验结束立即 destroy 实验 UID,防止 tc 规则残留。

答案

步骤一:先采集真实分布
在夜间低峰与白天高峰分别跑 pt-query-digest 或 performance_schema,得到
P50=18 ms,P99=230 ms,P99.9=1.8 s,峰谷比 1:0.7。

步骤二:把分布拆成三段注入

  1. 常见查询(90%):
    blade create network delay --target-port 3306 --time 20 --offset 10 --interface eth0 --timeout 300s --uid mysql_normal
  2. 长尾查询(9.9%):
    blade create network delay --target-port 3306 --time 200 --offset 100 --interface eth0 --timeout 300s --uid mysql_tail
  3. 毛刺查询(0.1%):
    for i in {1..10}; do blade create network delay --target-port 3306 --time ((RANDOM((RANDOM%1500+500)) --offset 0 --interface eth0 --timeout 2s; sleep ((RANDOM%30+10)); done

步骤三:区分主从
主库只跑第一段;从库跑第一+第二段,并在业务只读连接池 IP 段上生效,防止误伤写库。

步骤四:验证
通过 Grafana 看 P99 曲线是否从 18 ms 涨到 230 ms 左右,且直方图形状与线下采集对齐;同时检查错误日志无 “MySQL server has gone away” 等异常。

步骤五:清理
blade destroy mysql_normal mysql_tail,再用 tc -s qdisc show 确认无残留。

拓展思考

  1. 如果 ChaosBlade 版本不支持 SQL 特征匹配,可改用 iptables + u32 模块按包 payload 匹配 “select” 关键字,实现“只延迟读查询,不延迟写”。
  2. 对云数据库 RDS,因无主机权限,可把 ChaosBlade 注入到应用侧容器 Sidecar,延迟出口流量,效果等价。
  3. 想模拟“锁等待”而非网络延迟,可改用 sysbench 的 update_non_index 或手工 begin; select … for update; sleep 产生行锁,再观察线程状态,弥补 ChaosBlade 无法制造 InnoDB 锁等待的不足。
  4. 在 CI 阶段,可把上述脚本封装成 Helm 钩子,随性能基线流水线自动执行,实现“每次发布都验证 P99 上涨 < 5%”的 SLA 门禁。