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

reuse proxy.Request and redis.Resp in proxy #1561

Open
wants to merge 1 commit into
base: release3.2
Choose a base branch
from

Conversation

imjustfly
Copy link

proxy 处理请求的过程中经常需要分配 proxy.Requestredis.Resp 两种对象。这个 PR 通过 sync.Pool 进行了复用,应当可以降低GC压力。

proxy.Request and redis.Resp is allocated most often in request processing. This PR try to reuse these objects using sync.Pool which should reduce the GC pressure.

@spinlock
Copy link
Member

spinlock commented Sep 4, 2018

谢谢。类似的方法其实我很早是写过的,自己维护一个 pool 而不是用 sync.Pool:

  1. 没有选择 sync.Pool 的原因使用因为 sync.Pool 太重了,相比于直接分配一个 Request{} 或者 Resp{} 而言,sync.Pool 的开销太大了。
  2. sync.Pool 适合用来维护分配+初始化操作开销巨大的数据结构,而不是 Request{} 或者 Resp{} 这种小对象。
  3. 之前我实现的 pool 原理是通过一次分配一个 Array 而减少对象分配次数/个数,但是实际效果带来的 performance 的提升微乎其微,但是容易引起爆堆(gc 不及时或者 bug 导致)。所以最后还是放弃了。

此外,Request{} 和 Resp{} 对象的大小被控制的足够小,go 对这种小对象分配足够快。并且,gc 的时候对象间不存在引用,gc 压力其实非常小的。

我建议你在生产环境中先进行足够长时间的测试,确定性能和堆的使用足够稳定。(至少爆堆我是经过压力测试后发现的,gc 不及时最后爆到大概100GB)。其实 codis 里面大量内存都在堆外分配,堆内 gc 的压力其实很小。

@imjustfly
Copy link
Author

imjustfly commented Sep 4, 2018

@spinlock soga,多谢提醒!我是在减小那个为了降低 GC 频率的 256M 预分配内存后想到的一个补偿方案

@imjustfly
Copy link
Author

sync.Pool 的话因为 go 两分钟保底的强制 GC,加上请求是来一个走一个,不会有过多对象被缓存,爆堆问题应该不大。

用 redis-benchmark 目前看性能没有明显变化,初衷是有时候业务部门会反应极其偶尔慢一下,想尽量减少 GC 的因素,这边先跑跑看看 :)

@hiqsociety
Copy link

can you push your request here?
https://github.com/cloudxaas/codis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants