您现在的位置是:主页 > news > 建设适应连锁行业网站/国内最新十大新闻

建设适应连锁行业网站/国内最新十大新闻

admin2025/5/12 0:18:06news

简介建设适应连锁行业网站,国内最新十大新闻,the 7 wordpress主题教程,揭阳制作公司网站m3dbnode oomoom时排查内存火焰图: 80G内存 bytes_pool_get_on_empty qps 很高 db read qps增长 80% node cpu kernel 暴涨 看图结论 - m3dbnode 内存oom过程很短,很剧烈:总时间不超过7分钟 - 内存从27G增长到250G - 节点sys态cpu暴涨:因为大…

建设适应连锁行业网站,国内最新十大新闻,the 7 wordpress主题教程,揭阳制作公司网站m3dbnode oomoom时排查内存火焰图: 80G内存 bytes_pool_get_on_empty qps 很高 db read qps增长 80% node cpu kernel 暴涨 看图结论 - m3dbnode 内存oom过程很短,很剧烈:总时间不超过7分钟 - 内存从27G增长到250G - 节点sys态cpu暴涨:因为大…

953dcf0fa3913e223f7e98d0bb203679.png

m3dbnode oom

oom时排查

  • 内存火焰图: 80G内存

56daca7f836b7ff92d21bc1264ac413a.png
  • bytes_pool_get_on_empty qps 很高

01b2a5fcf710dc79216393e5fac0df86.png
  • db read qps增长 80%

01b2a5fcf710dc79216393e5fac0df86.png
  • node cpu kernel 暴涨

0f2ea4cfe8f0734c549366a7411f9405.png

看图结论 - m3dbnode 内存oom过程很短,很剧烈:总时间不超过7分钟 - 内存从27G增长到250G - 节点sys态cpu暴涨:因为大量的mem_alloca sys_call - 内存增长曲线和db_read_qps曲线和bytes_pool_get_on_empty曲线高度吻合 - 内存火焰图: 27G的rpc 40G的pool.(*objectPool).tryFill

查看代码,追踪火焰图中这个tryFill

内存分配器

目的很简单:自己管理内存,避免频繁的mem_allocate sys_call 提升速度,空间换时间

核心结构

  • 初始化时调用init 向池中注入
type objectPool struct {opts                ObjectPoolOptionsvalues              chan interface{}alloc               Allocatorsize                intrefillLowWatermark  intrefillHighWatermark intfilling             int32initialized         int32dice                int32metrics             objectPoolMetrics
}
for i := 0; i < cap(p.values); i++ {p.values <- p.alloc()}

从池中获取对象时

  • 池中还有剩余则直接获取否则走各自的alloc分配
  • 同时设置bytes_pool_get_on_empty
func (p *objectPool) Get() interface{} {if atomic.LoadInt32(&p.initialized) != 1 {fn := p.opts.OnPoolAccessErrorFn()fn(errPoolGetBeforeInitialized)return p.alloc()}var v interface{}select {case v = <-p.values:default:v = p.alloc()p.metrics.getOnEmpty.Inc(1)}p.trySetGauges()return v
}

同时判断池水位,是否加油

if p.refillLowWatermark > 0 && len(p.values) <= p.refillLowWatermark {p.tryFill()}

加油过程

  • 用CompareAndSwapInt32做并发控制标志位
  • 加油加到refillHighWatermark
func (p *objectPool) tryFill() {if !atomic.CompareAndSwapInt32(&p.filling, 0, 1) {return}go func() {defer atomic.StoreInt32(&p.filling, 0)for len(p.values) < p.refillHighWatermark {select {case p.values <- p.alloc():default:return}}}()
}

默认池参数

defaultRefillLowWaterMark  = 0.3defaultRefillHighWaterMark = 0.6

总结思考

  • 默认池低水位为什么不是0:因为 从水位判断到tryFill中间的并发请求使得最后tryFill开始时低水位可能低于0.3
  • 火焰图中的tryFill消耗了40G内存不是一次性的,类比右侧thriftrpc27,属于累加内存消耗值
  • 一次性的内存消耗肯定没有这么多:每次加油时内存消耗低于初始化
  • 所以可以得到结论,oom是因为在当时byte_pool频繁的get消耗,然后tryFill频繁的加油导致内存分配
  • 所以根本原因还是查询导致的

解决办法:限制query资源消耗保护db

修改m3coordinator参数

9e951709717925e2c9c76d4d49baf351.png