Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

记解决一件奇怪的线上golang的"OOM"问题 #138

Open
AlexiaChen opened this issue Apr 30, 2021 · 5 comments
Open

记解决一件奇怪的线上golang的"OOM"问题 #138

AlexiaChen opened this issue Apr 30, 2021 · 5 comments
Labels
golang go programming language 杂记 比较杂,不知道说什么好 软件调试 调试技巧,思考

Comments

@AlexiaChen
Copy link
Owner

AlexiaChen commented Apr 30, 2021

为什么OOM打双引号,因为最终发现,不是内存泄露导致的OOM。

最近leader刚给我分配了一个OOM的任务给我,现象是explorer node在grafana的监控上出现在大量并发访问explorer node时,内存在监控上急剧上升,然后并没有下降,最终被systemd给kill掉了。

这种现象一般可以肯定都是OOM,就是代码哪里内存泄露了,导致分配的内存没有被GC。经过了我的一番排查,还写了一大段的英文分析报告,inuse_space是随着请求量增大而增高,但是随着请求量下降关闭,它也回归到了正常值,但是linux的top命令的RES项还是没有降低下来,所以当时我都怀疑人生了,是不是pprof哪里没用对或者哪里理解错了,后来还是请教了golang社区的一位哥们,他正好看过一个关于golang社区的提案,跟我说了,说的就是这个问题,很多人都遇到了,实际就是runtime GC掉的内存不会立刻归还给操作系统,所以就就给监控造成了麻烦。 这个feature主要是为了一些性能才这样做的,但是好心没办成好事。经过社区的讨论,最终还是恢复成原来的设置了,也就是在go 1.16中,被GC掉的内存会立刻归还给系统。

go的老版本需要 run binary with GODEBUG=madvdontneed=1 就可以归还给系统了,或者直接升级到go 1.16。

一下是社区的一些讨论:

真的,如果不是那位哥们的提示,这么一个乌龙事件,我一时半会还查不出来,没看过那些提案一时半会也不好查,毕竟golang我是0项目经验,业余写的不算。虽然语言只是工具,但是毕竟坑,还是要花时间填的,这个就是经验。经验少就是没办法。

下面就是我写的分析报告:

report.md

其实这不光golang有这问题,一般系统自带的glibc的malloc都一般free了不会立刻归还给操作系统,如果是其他技术栈,可以考虑tcmalloc. 好奇可以看看这位知乎上的老哥也遇到了同样的问题,只不过不是golang而已,据说已经是被glibc malloc坑了不知道第几个案例了

@AlexiaChen AlexiaChen added 软件调试 调试技巧,思考 杂记 比较杂,不知道说什么好 golang go programming language labels Apr 30, 2021
@AlexiaChen AlexiaChen changed the title 记解决一件奇怪的线上golang的"OOM"问题。 记解决一件奇怪的线上golang的"OOM"问题 Apr 30, 2021
@yufan022
Copy link

同遇到该问题,通过pprof分析现象比较类似。考虑升级版本有一定成本,添加GODEBUG=madvdontneed=1启动参数观察中。

@AlexiaChen
Copy link
Owner Author

AlexiaChen commented Jun 11, 2021

同遇到该问题,通过pprof分析现象比较类似。考虑升级版本有一定成本,添加GODEBUG=madvdontneed=1启动参数观察中。

Hey @yufan022 ethereum/go-ethereum#22567 ETH 有这个问题,是请求过多,加个rate limiter好了,如果GODEBUG=madvdontneed=1还没有缓解的话。暂时你不清楚你是什么环境。不好判断。

@zhucan
Copy link

zhucan commented Aug 11, 2023

@AlexiaChen 在k8s v1.22.15的环境下,用pprof和top命令查看apiserver查看内存使用情况,发现pprof看到的比top少很多,k8s v1.22.15版本使用的是golang v1.16.x版本
top:
image

pprof:
image

请问下这个是什么原因?

@AlexiaChen
Copy link
Owner Author

@AlexiaChen 在k8s v1.22.15的环境下,用pprof和top命令查看apiserver查看内存使用情况,发现pprof看到的比top少很多,k8s v1.22.15版本使用的是golang v1.16.x版本
top:
image

pprof:
image

请问下这个是什么原因?

就是我说的原因。top上的显示的都是没返回给系统的。pprof上只要认为返回给系统它就认为没占用了。但是各种报警监控系统的指标只认包括没归还给系统的内存也算。

@zhucan
Copy link

zhucan commented Aug 15, 2023

我们现在升级到k8s v1.23.17和golang1.19.6,设置了GOGC和GOMEMLIMIT目前看着是可以稳定在固定的内存范围内,只是加快GC会带来额外的CPU开销.

Repository owner deleted a comment Dec 29, 2023
Repository owner deleted a comment from fede-s Dec 30, 2023
Repository owner deleted a comment from tobarbaro Jan 1, 2024
Repository owner deleted a comment Jan 2, 2024
Repository owner deleted a comment Jan 2, 2024
Repository owner deleted a comment from mohamedSalehHegazy Jan 2, 2024
Repository owner deleted a comment Jan 2, 2024
Repository owner deleted a comment Jan 14, 2024
Repository owner deleted a comment from mkproject-admin Feb 21, 2024
Repository owner deleted a comment from Pappyskull1 Feb 21, 2024
Repository owner deleted a comment from Pappyskull1 Feb 21, 2024
Repository owner deleted a comment from jonas089 Feb 23, 2024
Repository owner deleted a comment from parth35 Mar 12, 2024
@github-staff github-staff deleted a comment from vishalgupta1987 Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
golang go programming language 杂记 比较杂,不知道说什么好 软件调试 调试技巧,思考
Projects
None yet
Development

No branches or pull requests

7 participants
@AlexiaChen @zhucan @yufan022 and others