etcd 实战课
唐聪
腾讯云资深工程师,etcd 活跃贡献者
28449 人已学习
新⼈⾸单¥59
登录后,你可以任选3讲全文学习
课程目录
已完结/共 28 讲
开篇词 (1讲)
etcd 实战课
15
15
1.0x
00:00/00:00
登录|注册

15 | 内存:为什么你的etcd内存占用那么高?

处理典型的场景导致的内存异常
优化业务expensive request
核心数据结构、场景导致的内存异常
在macOS下行为是否一样
为什么执行compact和defrag后的结果不是1G左右
etcd bug导致的内存泄露
goroutines泄露
etcd中使用了v2的API写入了大量的key-value数据
count-only、limit查询导致内存占用增加
查询大包导致内存占用突增
监控watch事件堆积
创建watcher耗费的内存
配置合理的压缩策略
优化key-value大小
控制boltdb文件大小
清理旧版本,防止过多内存占用
防止etcd出现OOM的方法
快照和压缩功能
结果分析
更新完后并进行compact、defrag操作
执行1000次的put同一个key操作
Watcher监听机制
boltdb使用的mmap技术
treeIndex模块的B-tree
RaftLog的内存存储
gRPC Server连接数导致内存占用上涨
内存异常的分析方法
分析内存异常现场
遇到内存占用高的情况时的反应
总结
思考题
etcd v2/goroutines/bug
Expensive Request
Watcher
boltdb
treeIndex
RaftLog
一个key使用数G内存的案例
核心模块与数据结构
思路
etcd内存占用高分析

该思维导图由 AI 生成,仅供参考

你好,我是唐聪。
在使用 etcd 的过程中,你是否被异常内存占用等现象困扰过?比如 etcd 中只保存了 1 个 1MB 的 key-value,但是经过若干次修改后,最终 etcd 内存可能达到数 G。它是由什么原因导致的?如何分析呢?
这就是我今天要和你分享的主题:etcd 的内存。 希望通过这节课,帮助你掌握 etcd 内存抖动、异常背后的常见原因和分析方法,当你遇到类似问题时,能独立定位、解决。同时,帮助你在实际业务场景中,为集群节点配置充足的内存资源,遵循最佳实践,尽量减少 expensive request,避免 etcd 内存出现突增,导致 OOM。

分析整体思路

当你遇到 etcd 内存占用较高的案例时,你脑海中第一反应是什么呢?
也许你会立刻重启 etcd 进程,尝试将内存降低到合理水平,避免线上服务出问题。
也许你会开启 etcd debug 模式,重启 etcd 进程等复现,然后采集 heap profile 分析内存占用。
以上措施都有其合理性。但作为团队内 etcd 高手的你,在集群稳定性还不影响业务的前提下,能否先通过内存异常的现场,结合 etcd 的读写流程、各核心模块中可能会使用较多内存的关键数据结构,推测出内存异常的可能原因?
全方位的分析内存异常现场,可以帮助我们节省大量复现和定位时间,也是你专业性的体现。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

etcd内存占用异常一直是使用者头疼的问题。本文通过分析etcd的读写流程和核心模块中可能使用较多内存的关键数据结构,揭示了etcd内存异常的常见原因和分析方法。文章以一个实际案例为例,深入介绍了内存异常的分析方法。在分析过程中,重点讨论了raftLog的内存占用问题,并介绍了etcd提供的快照和压缩功能来解决内存占用问题。此外,还提及了MVCC模块的treeIndex/boltdb模块对内存的使用情况。通过本文的总结,读者可以快速了解etcd内存占用异常的原因和解决方法,为实际业务场景中配置充足的内存资源提供了指导。文章还介绍了watcher、expensive request、etcd v2/goroutines/bug等场景可能导致的内存占用高的情况,并提供了相应的解决方法。总之,本文全面解析了etcd内存占用异常的原因和解决方法,为读者提供了深入的技术指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《etcd 实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • [小狗]
    大佬,我想阅读下etcd的源码,有什么建议吗? 目前只是为了简历好看些,以后会深度学习下

    作者回复: 建议可以先从早期的v2代码看起,那时逻辑最简单,https://github.com/etcd-io/etcd/blob/release-0.4/server/v2/get_handler.go,然后再看etcd v3的代码,在这个过程中,我给你几个小建议: 1. 抓住主次,比如核心读写流程是怎样的,忽略一些特殊细节 2. 看看测试用例如何使用核心模块的API的,比如etcd v3 mvcc的模块测试文件 https://github.com/etcd-io/etcd/blob/v3.4.9/mvcc/kv_test.go 3. 自己可动手写写源码分析 4. 自己多实践下,部署个单机etcd集群,至少要把etcdctl各个命令给操作下 5. 日志级别可以改成debug, 更加方便观察

    2021-03-24
    3
    16
  • i_chase
    这一期的思考题有答案吗

    作者回复: 主要原因是etcd 3.4 版本是使用 go 1.12 编译的,go runtime 的默认内存管理策略是 MADV_FREE, 它的性能较好,但是会导致你看到的etcd内存虚高,监控指标异常、用户体验不佳等问题,原因是这种策略,在系统内存有压力的时候,内核才会释放占用的内存。 从 go v1.16 起,Go 在 Linux 下的默认内存管理策略变成了 MADV_DONTNEED 策略。MADV_DONTNEED 虽然效率相比 MADV_FREE 策略较低,但是会让 rss 内存下降较快,更加符合直观感受,能避免 MADV_FREE 相关的副作用。 更详细的可以参考golang issue和etcd 3.5 blog. https://github.com/golang/go/issues/42330 https://etcd.io/blog/2021/announcing-etcd-3.5 Monitoring部分

    2022-05-01
    5
  • 江山未
    老师,想问下。工作中有用到etcd,如果想通过看etcd源码提升了解的话,建议从哪里入手呢。 如果可能的话,也希望能像你一样,为社区做一些贡献。 直接从启动命令看下去吗?还有就是 treeindex和bbolt有必要看吗。

    作者回复: 在上一个问题,我给了一些要点,建议可以先从早期的v2代码看起,那时逻辑最简单,https://github.com/etcd-io/etcd/blob/release-0.4/server/v2/get_handler.go,然后再看etcd v3的代码,在这个过程中,我给你几个小建议: 1. 抓住主次,比如核心读写流程是怎样的,忽略一些特殊细节 2. 看看测试用例如何使用核心模块的API的,比如etcd v3 mvcc的模块测试文件 https://github.com/etcd-io/etcd/blob/v3.4.9/mvcc/kv_test.go 3. 自己可动手写写源码分析 4. 自己多实践下,部署个单机etcd集群,至少要把etcdctl各个命令给操作下 5. 日志级别可以改成debug, 更加方便观察 如果给社区做贡献,可以多关注下社区正在讨论的issue和PR,寻找切入点,比如文档完善、拼写错误、不稳定的测试用例修复等开始,有时候大家会标注label help wanted, https://github.com/etcd-io/etcd/issues?q=is%3Aopen+is%3Aissue+label%3A%22Help+Wanted%22 treeIndex核心是btree,boltdb核心是b+ tree,早期不建议你看,了解它的功能即可,当你对etcd有一定掌握后,可以详细看看,了解下生产级的btree及b+ tree实现,相信你会收货很多。

    2021-03-24
    2
    3
  • shuff1e
    etcd v2 的 key-value 都是存储在内存树中,具体指的是什么呢

    作者回复: 是指etcd v2的key-value数据存储在内存中的,如果你etcd v3里面存储了大量的etcd v2 key-value数据,就会导致内存占用较高。 你可以参考下etcd v2 store的定义,etcd v2的key-value数据就是直接存储在这个结构哈 https://github.com/etcd-io/etcd/blob/release-3.3/store/store.go#L73:L83

    2021-02-22
    3
  • 孔宣
    大佬,能给个联系方式吗?想请教一下kstone方面的问题,目前的问题主要是: 1、能否支持3.5.0版本的etcd集群新建? 2、是否支持指定不同的k8s集群来新建etcd集群?在dashbord上没看到这能力 3、目前支持的k8s版本相对老旧,是否有升级计划,我们也可以共建
    2023-04-07归属地:北京
  • 孔宣
    请问,kstone目前最新只支持etcd的3.4.13版本,但我们对etcd 3.5版本有强需求,支持3.5版本,需要做改造吗?盼复。。。微信加的kstone助手,没人理
    2023-04-06归属地:北京
  • HelloBug
    一个客户端是一个Client,watch一个key是一个watcher,gRPC Watch Stream 数如何确定呢?
    2021-11-19
  • HelloBug
    >其次是 goroutines 泄露导致内存占用高。此问题可能会在容器化场景中遇到。etcd 在打印日志的时候,若出现阻塞则可能会导致 goroutine 阻塞并持续泄露,最终导致内存泄露 老师,这里不太明白,为什么打印日志阻塞会导致内存泄露呢?
    2021-11-19
  • sxfworks
    这几天看了etcd的源码,最开始一直好奇leader和follower怎么只同步一次snapshot,是我看错了,还是真的这么粗暴😂
    2021-05-29
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部