大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
容器化RDS:计算存储分离架构下的“Split-Brain”
容器化RDS:计算存储分离还是本地存储?
容器化RDS:你需要了解数据是如何被写"坏"的
容器化RDS:借助 CSI 扩展 Kubernetes 存储能力
发现性能瓶颈
确定问题组件
借助 CPU Profile 和 Flame Graph,快速缩小范围,定位到问题 code-path
有针对的优化
所有的编程人员都是乐观主义者,毕竟在可能出现问题的地方,一定都会遇到问题,在耗时 3600 秒后,95% 的 PVC 处于 Pending 状态,严格的说,在批量创建的场景,该功能不可用。
大量 PVC 处于 Pending 状态
kube-apiserver
kube-controller-manager
kubelet
external-provisioner
external-attacher
csi-driver
qcfs-csi-plugin
架构图
以及业务流程的梳理,kube-controller-manager、external-provisioner 和 csi-driver 嫌疑较大。通过 kubelet logs 查看日志,可以在 external-provisioner 中发现可疑日志:
I0728 19:19:50.504069 1 request.go:480] Throttling request took 192.714335ms, request: POST:https://10.96.0.1:443/api/v1/namespaces/default/events I0728 19:19:50.704033 1 request.go:480] Throttling request took 190.667675ms, request: POST:https://10.96.0.1:443/api/v1/namespaces/default/events
external-provisioner 访问 kube-apiserver 触发限流
external-provisioner 有重大嫌疑。
阅读 external-provisioner 代码,加入调试日志,理解逻辑
不断缩小 code-path
采集堆栈样本
找到在采样手气内消耗 CPU 时间比率最高的函数,把该函数作为调试的起点
函数的调用关系以及采样周期内 CPU 耗时百分比:
提供 CPU profile 和 Heap profile;
在采样时获得堆栈(几乎所有)信息, 以此为依据估算整个采样周期内堆栈的CPU占用百分比, 并不是 100% 准确;
采样成本并不低,100赫兹既可以采样够用的堆栈信息,又不会给应用程序带来过大开销;
CPU 采样频率默认为 100 赫兹,并硬编码到模块中, 不建议调到 500 赫兹以上。
借助第三方工具 go-torch 绘制
每个矩形代表一个堆栈,采样时间内,CPU 占用百分比越高 Y 轴越长,X 轴表明了堆栈之间的调用关系
从左到右按照字母表排序
颜色随机选择,无具体含义
来自于 external-provisioner 调用的第三方模块 kubenetes-incubator/external-storage
所以,只要引用例如了模块 Kubenetes-incubator/external-storage 实现卷创建功能,都可以复现 api throttling。
再针对性的加入调试日志到 code-path 中,理解逻辑,很快可以确定问题:
在创建卷时,external-storage 需要访问 API 资源(譬如 configmap、pvc、pv、event、secrets、storageclass 等),为减少 kube-apiserver 工作负荷,不建议直接访问 kube-apiserver,而应该利用本地缓存(由 informer cache 构建)。但 external-storage 恰好直接访问 kube-apiserver。通过下图可以看到,有18.84%的采样时间在 list event,这是导致 api throttling 的原因。
最终定位到问题原因:
Lock 的抢占导致 api throttling,引发 Lock 抢占 timeout,timeout 后抢占重试,进一步恶化 api throttling。
从下图可以进一步得到验证,有 8.7% 的采样时间在进行 Leader Election。
采用 sharedinformer cache
修改 Leader Lock 粒度
external-provisioner 日志中的 throttling 关键字消失
100 PVC 的时间缩短到60秒以内全部创建成功,无任何报错。
对于终端用户而言,交互的界面越来越简单,但对于开发者而言,组件越来越多,编译一次的时间越来越久,加上无处不在的并发,导致定位问题的难度越来越大,尤其是性能问题。所以,对体系架构的理解能帮我们快速锁定问题组件,配合 Profile 工具和 Flame Graph 快速定位 code-path,再加上对业务逻辑的理解找到解决方案。
所有的编程人员都是乐观主义者,无论是什么样的程序,结果是勿庸置疑的:"这次它肯定会运行。" 或者 "我刚刚找出了最后一个问题。" ——人月神话
熊中哲·沃趣科技联合创始人
曾就职于阿里巴巴和百度,超过10年关系型数据库工作经验,目前致力于将云原生技术引入到关系型数据库服务中。