HAProxy内存池简介

HAProxy介绍

HAProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,HAProxy是完全免费的、借助HAProxy可以快速并且可靠的提供基于TCP和HTTP应用的代理解决方案。

HAProxy内存池概述

HAProxy的内存池按照类型分类,每种类型的内存池都有一个名字(name),用链表记录空闲链表,每种类型的内存池中的元素大小都是相等的,并且按照16字节对齐。
HAProxy用struct pool_head记录每种类型的内存池:

在程序执行过程中,内存池可能会像以下这个图形:

内存的申请是比较简单的,先尝试从空闲列表中获取,如果没有,向系统申请新的内存。如果再失败,主动调用垃圾回收接口,再次尝试申请内存。但只会尝试一次,如果失败,会直接退出,这样不会浪费太多的时间。
内存申请的核心函数是pool_refill_alloc:
这个函数请求申请avail+1个节点,放到空闲列表中,如果申请内存失败,会调用垃圾回收接口,但最多调用一次。

当然,使用者申请内存不会直接调用这个接口,一般调用pool_alloc2,这个函数再调用pool_alloc_dirty。其实逻辑还是比较简单的,先从空闲列表中申请内存,如果已经用光,最终还是调用pool_refill_alloc获取更多内存。另外,如果设置mem_poison_byte为非0,pool_alloc2还会对申请到的新内存做一个填充,但是mem_poison_byte默认就是0。

内存的回收

HAProxy使用内存池,但不会让内存一直生长,有一个垃圾回收机制,特别是当内存申请失败时,会主动调用垃圾回收接口。HAProxy的垃圾回收非常简单,它会遍历所有内存池,尽量释放所有可以释放的内存。

使用者可以也可以主动调用垃圾回收,但是只会回收自己创建的内存池,HAProxy提供的接口是pool_flush2,这个直接将所有空闲内存全部释放掉了(自己创建的内存池,不会释放其它创建者的内存池)。

内存释放

从内存池的构造来看,就知道HAProxy的内存池有这么一个问题:如果使用者不主动释放申请的内存,那释放内存池后,这块内存就无法被内存池回收了。不过这不是问题,只需要稍微注意一下就好了。内存释放时,只是将指针放到对应内存池的空闲链表的第一个节点。放到第一个节点有一个好处,下次申请时,也是优先获取第一个,就是使用最近使用的内存。

内存池的销毁

内存池的销毁是很简单的,释放所有内存池的空闲内存,然后释放所有内存池。但是如果还有正在使用的内存,pool->used != 0,那就不能释放内存,要不然会造成内存泄露。

监测工具

HAProxy还提供了一个工具,可以打印出当前内存池的状况,比如使用了多少,有多少空闲等。

PS: 这些代码在include/common/memory.h和src/memory.c中。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2015年2月18日
下一篇 2015年2月19日

相关推荐