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

关于内存使用和lua54 #827

Closed
linxiaolong opened this Issue Apr 21, 2018 · 8 comments

Comments

Projects
None yet
4 participants
@linxiaolong

linxiaolong commented Apr 21, 2018

之前在社区提过 #666 #762 两个issue,结合近期压测表现,最终得出原因就是lua53 的GC模式加剧了这种情况,情况大致是:lua53还没来得及GC垃圾内存,新的内存分配需求又陆续有来,结果导致jemalloc切割且冗余的内存在长期来看浪费率极高(假设skynet GC后实际占用内存为m,而GC前包含了垃圾内存可到达2 * m,而最终大概经过一天压测,jemalloc抢占内存可以高达2.5 * 2 * m)。在层层内存优化缓存的体系下,对于游戏服务器这种类型,分代GC或者类似python的引用计数+全量GC模式 会更适合,毕竟内存是有限的,尤其是上云服,各种配置都有定格,除非不计成本,否则内存很难随意增长。

我们目前在内服测试分支已经换上lua54进行测试,从压测结果来看,内存使用很稳定,对比之前lua53不断趋向向上的内存是更让人放心。

想咨询一下cloud:
1)目前lua54的work1版本,按lua社区习惯来说,应该是个非稳定版本?我们暂时只是拿来测试,不过确实测试结果很满意
2)对skynet后续版本会有换上lua54的打算么?

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Apr 21, 2018

Owner

lua 5.4 将在正式发布后合并。

对于长期服务,可以用主动调用 gc 的 step 加快循环周期,空闲时更应调用。因为单个 lua vm 的 gc 是由分配驱动的,你不创建新对象,老的就不会回收。对于短期服务,可以尽快退出,利用 close vm 关闭彻底回收。

jemalloc 可以考虑换掉。

Owner

cloudwu commented Apr 21, 2018

lua 5.4 将在正式发布后合并。

对于长期服务,可以用主动调用 gc 的 step 加快循环周期,空闲时更应调用。因为单个 lua vm 的 gc 是由分配驱动的,你不创建新对象,老的就不会回收。对于短期服务,可以尽快退出,利用 close vm 关闭彻底回收。

jemalloc 可以考虑换掉。

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Apr 21, 2018

Owner

对于内存紧张的环境,可以考虑不用一个 client 对一个服务;而是多对一。gate 最近做过修改,将 client fd 通过 session 夹带在网络消息中转发,可以用来区分不同的 client 网络消息。

Owner

cloudwu commented Apr 21, 2018

对于内存紧张的环境,可以考虑不用一个 client 对一个服务;而是多对一。gate 最近做过修改,将 client fd 通过 session 夹带在网络消息中转发,可以用来区分不同的 client 网络消息。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Apr 21, 2018

1、jemalloc换掉。这个是指使用其他类似tmalloc之类的?
2、之前试过停掉自动GC,定期调用step,对长期服务在繁忙期会有CPU的影响,这块的使用cloud有什么推荐的方式?

linxiaolong commented Apr 21, 2018

1、jemalloc换掉。这个是指使用其他类似tmalloc之类的?
2、之前试过停掉自动GC,定期调用step,对长期服务在繁忙期会有CPU的影响,这块的使用cloud有什么推荐的方式?

@cloudwu

This comment has been minimized.

Show comment
Hide comment
@cloudwu

cloudwu Apr 21, 2018

Owner

可以直接用 glibc 带的,未必会更差。另外,lua vm 注册的 alloc 可以考虑自己写一下。例如,自己 mmap 内存管理。skynet 大部分内存是从 lua vm 里分配的,改写这个可以解决大多数问题。

step 只是对 gc 的一个建议,调用 step 并不需要停掉 gc ,也不需要特别安装定时器调用。我建议在服务收到每条消息时都主动调一下(改写 skynet.dispatch_message 即可)。

Owner

cloudwu commented Apr 21, 2018

可以直接用 glibc 带的,未必会更差。另外,lua vm 注册的 alloc 可以考虑自己写一下。例如,自己 mmap 内存管理。skynet 大部分内存是从 lua vm 里分配的,改写这个可以解决大多数问题。

step 只是对 gc 的一个建议,调用 step 并不需要停掉 gc ,也不需要特别安装定时器调用。我建议在服务收到每条消息时都主动调一下(改写 skynet.dispatch_message 即可)。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong Apr 21, 2018

1、jemalloc替换的我测试一下
2、改写vm alloc这个事情之前考虑过,因为我们的设计几乎都是长期服务,之前考虑性价比不太高所以没动手,我近期试下
3、每次消息处理调用step,我也测试下,不过比较担心性能会有所下降

linxiaolong commented Apr 21, 2018

1、jemalloc替换的我测试一下
2、改写vm alloc这个事情之前考虑过,因为我们的设计几乎都是长期服务,之前考虑性价比不太高所以没动手,我近期试下
3、每次消息处理调用step,我也测试下,不过比较担心性能会有所下降

@sue602

This comment has been minimized.

Show comment
Hide comment
@sue602

sue602 Apr 23, 2018

我们也有遇到类似的问题,后来通过两种办法解决。
1.禁用系统默认的jemalloc,使用glibc,make linux MALLOC_STATICLIB= SKYNET_DEFINES=-DNOUSE_JEMALLOC
2.在一些需要修改gc步长。
经过上面两个步骤,发现内存使用比原来的好非常多。

sue602 commented Apr 23, 2018

我们也有遇到类似的问题,后来通过两种办法解决。
1.禁用系统默认的jemalloc,使用glibc,make linux MALLOC_STATICLIB= SKYNET_DEFINES=-DNOUSE_JEMALLOC
2.在一些需要修改gc步长。
经过上面两个步骤,发现内存使用比原来的好非常多。

@lmess

This comment has been minimized.

Show comment
Hide comment
@lmess

lmess Apr 24, 2018

Contributor

1 jemalloc替换成glibc,这个在高版本linux内核可以试下,我自己测试结果是在2.6.32版本内核下会变差很多。最早尝试过替换成tcmalloc,性能表现跟jemalloc没太大差异,内存表现没测到。
2 GC的一些设置,setpause&setstepmul可以适当加快回收周期,再不济就用step自己控制。不过你的情况重点是内存利用率低。
3 jemalloc可以通过配置来调整内存利用率,lg_dirty_mult&narenas,narenas的设置(减少narenas)效果会比较明显,对性能也有提升。
4 不太建议使用不稳定版本,你压测的时候没问题,不代表线上的复杂情况就稳定。

Contributor

lmess commented Apr 24, 2018

1 jemalloc替换成glibc,这个在高版本linux内核可以试下,我自己测试结果是在2.6.32版本内核下会变差很多。最早尝试过替换成tcmalloc,性能表现跟jemalloc没太大差异,内存表现没测到。
2 GC的一些设置,setpause&setstepmul可以适当加快回收周期,再不济就用step自己控制。不过你的情况重点是内存利用率低。
3 jemalloc可以通过配置来调整内存利用率,lg_dirty_mult&narenas,narenas的设置(减少narenas)效果会比较明显,对性能也有提升。
4 不太建议使用不稳定版本,你压测的时候没问题,不代表线上的复杂情况就稳定。

@linxiaolong

This comment has been minimized.

Show comment
Hide comment
@linxiaolong

linxiaolong May 4, 2018

压测环境:ubuntu14(linux4.4),采用jemalloc5.0
压测方式:一批老号持续不断地进行装备/道具/整理等行为,完全不下线持续至少一天,对比外服正常行为是比较严苛

近期对上次提及的做了些尝试:
1、jemalloc替换。就目前来看,如果完全取消jemalloc,情况变得更糟,无论是初始占用还是后期增长
2、改写vm alloc。采用 https://blog.codingnow.com/2015/07/skynet_lua_allocator.html 所提及的算法,jemalloc关闭和开放的情况都尝试过,从长期内存使用来说情况也较为糟糕
3、每次消息处理调用step。这个比较有效地调动了lua GC的积极性

目前我们采取的方案:
1、jemalloc调整选项:"background_thread:true,dirty_decay_ms:0,muzzy_decay_ms:0",这三个选项的调整对于jemalloc回收合并的积极性有较大提升
2、消息驱动collectgarbage("step"),针对部分内存分配释放频繁的服务采取较大的步长(譬如1024K)

目前效果比较良好,经过大概两天时间持续压测,内存使用会稳定在一个范围,持续增长的趋势有效控制抑或说大大减缓

上面有其他朋友说的其他方式而呈现不同的结果,估计跟环境和测试方式有些关系,不做深究。希望后面的朋友遇到此类问题,在lua54还没release/skynet还未合并lua54之前,也可以有个解决的手段,或者一起分享。

linxiaolong commented May 4, 2018

压测环境:ubuntu14(linux4.4),采用jemalloc5.0
压测方式:一批老号持续不断地进行装备/道具/整理等行为,完全不下线持续至少一天,对比外服正常行为是比较严苛

近期对上次提及的做了些尝试:
1、jemalloc替换。就目前来看,如果完全取消jemalloc,情况变得更糟,无论是初始占用还是后期增长
2、改写vm alloc。采用 https://blog.codingnow.com/2015/07/skynet_lua_allocator.html 所提及的算法,jemalloc关闭和开放的情况都尝试过,从长期内存使用来说情况也较为糟糕
3、每次消息处理调用step。这个比较有效地调动了lua GC的积极性

目前我们采取的方案:
1、jemalloc调整选项:"background_thread:true,dirty_decay_ms:0,muzzy_decay_ms:0",这三个选项的调整对于jemalloc回收合并的积极性有较大提升
2、消息驱动collectgarbage("step"),针对部分内存分配释放频繁的服务采取较大的步长(譬如1024K)

目前效果比较良好,经过大概两天时间持续压测,内存使用会稳定在一个范围,持续增长的趋势有效控制抑或说大大减缓

上面有其他朋友说的其他方式而呈现不同的结果,估计跟环境和测试方式有些关系,不做深究。希望后面的朋友遇到此类问题,在lua54还没release/skynet还未合并lua54之前,也可以有个解决的手段,或者一起分享。

@linxiaolong linxiaolong closed this May 5, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment