memcache遭遇out of memory错误
今天在服务器上碰到memcache的out of memory错误,这还是第一次遇到,稍稍有些慌。一共有15台服务器,每台服务器分配了1G内存给memcache,合计有15个G,遇到错误的时候,大概只使用了4个G不到的内存。
现象比较很灵异,设置一个很小的value的时候就会出现这个错误
[root@slave1 bin]# telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
set key1 0 0 2
SERVER_ERROR out of memory
如果设置一个较大的value,反而Stored成功。
翻看了几篇关于memcache内存分配的介绍,大概有一些了解。
其中后一篇有实际操作的介绍,更为实用。根据个人理解先写个大概。
Memcache为了避免产生内存碎片,采用Slab Allocation机制来整理内存。比如某前端机分配了1G内存给memcache,那么它会将内存按照不同尺寸的小块(chunk)分成若干个组(classes),组的数目不是很固定,每个组分配1M内存。见下图:

当一条记录插入memcache中的时候,首先会寻找一个合适的能足够容纳这条记录的class。比如你insert一条100字节的数据,它会使用128字节的class来存储这条记录,只有28字节被浪费。
如果用memcached-tool来查看memcache的使用情况,会看到类似下面列出的情况。
[root@sql-slave1 bin]# ./memcached-tool localhost # Item_Size Max_age 1MB_pages Full? 6 64 B 0 s 0 no 7 128 B 742970 s 4 yes 8 256 B 1174852 s 2 yes 9 512 B 1279658 s 1 yes 10 1 kB 6494118 s 1 yes 11 2 kB 434918 s 71 yes 12 4 kB 917228 s 140 yes 13 8 kB 794192 s 30 no 14 16 kB 1373208 s 6 yes 15 B 0 s 0 yes 16 B 0 s 0 yes
此时插入一条很小的记录,比如只有2个字节,那么memcache会尝试用最小的class(64字节)来保存这条记录,这时候由于64字节的class已满或未分配内存,写入数据的时候就会遭遇到前面所说的out of memcache错误了。
更糟糕的是,这时候增加cache大小似乎也不能解决问题。可行的办法是利用memcached-tool对内存进行移动操作:
[root@sql-slave1 bin]# ./memcached-tool localhost move 14 6
上面的操作会移动class 14的一个page到class 6。
作者: Volcano 发表于July 15, 2008 at 5:34 pm
avenger 于 2008-07-15 @ 18:04:16 留言 :
关注下文
猴子 于 2008-07-16 @ 11:11:11 留言 :
你好,可否交换blogroll,http://www.dreamdu.com/blog/ ,贵站的链接已经加好,请查看。
Volcano 于 2008-07-16 @ 17:35:37 留言 :
近期懒得交换链接了,对不起
猴子 于 2008-07-17 @ 09:24:24 留言 :
没关系,你的blog有很多我非常喜欢的内容,以后有兴趣随时可以交换链接。