最近需要对tracer服务进行扩容,一来是因为SKVS顺序写更快,所以将不相干的服务都移到了pageDB的机器上,这样就空下来不少内存。二来是因为系统初期设计的1.6亿条url的容量好像不够,10月份上线一个月不到,就已经写到1.4个亿了,所以扩容不得不做。
就在更该共享内存的时候,出现了问题。
扩容前,4个ls,每个ls开2G内存作为共享内存的存储。
扩容后,4个ls,每个ls开3G内存作为共享内存存储。
悲剧也就在此刻发生了,2个ls创建共享内存成功,另外2个失败。miniStore在初始化的时候,报了如下的错误:
shmget error
: No space left on device
最开始的时候,以为是内存里面buffer太多,导致内存分配不出来了。
于是打算先清缓存
sync
echo 3 > /proc/sys/vm/drop_caches
然后再试,发现仍然不行。于是baidu之,发现有人问相同的问题,却没人给出回答,google之,发现n多老外的程序员在不同的邮件列表里问这个问题,没过回邮件的人也没给出答复。但有一个人的邮件作为了一些分析,建议出错的人检查memory configuration,于是我突然想起了共享内存的有几个参数
SHMMAX用来表示单个程序可以开的内存最大大小,单位是字节。这个做线上程序之前已经做过改动。
SHMMIN用来表示共享内存中每个页的最小大小,一般在linux中是4k.
另外一个参数很关键了,SHMALL,这个表示此前这台机器上能够开辟共享内存的最大值,单位是页面
所以SHMALL * SHMMIN 就是当前这台机器上所有进程总共能开启的最大内享内存的值
扩容前 SHMALL 为2097152, SHMMIN为4096,于是最大共享内存只能开到8G,刚好是我4个ls开辟共享内存的总和。
而扩容后,单个ls开的共享内存为3G,所以只能有2个ls能够创建成功,剩下的失败。
解决方法,增大SHMALL的值,然后重启,搞定。
附上一下linux下清内存中清缓存的解释:
有关/proc/sys/vm/drop_caches的用法在下面进行了说明
/proc/sys/vm/drop_caches (since Linux 2.6.16)
Writing to this file causes the kernel to drop clean caches,
dentries and inodes from memory, causing that memory to become
free.
To free pagecache, use echo 1 > /proc/sys/vm/drop_caches; to
free dentries and inodes, use echo 2 > /proc/sys/vm/drop_caches;
to free pagecache, dentries and inodes, use echo 3 >
/proc/sys/vm/drop_caches.
Because this is a non-destructive operation and dirty objects
are not freeable, the user should run sync(8) first.