导出Memcached中的全部数据

jackxiang 2011-2-22 15:52 | |
因为特别的原因,需要从Memcached中导出所有的数据。因为Memcached对数据的遍历是明确不支持的,所以必须想歪门邪道的方法。

现在网络上主要有两种思路,一种是通过Memcached提供的stats cachedump命令导出,例如下面这些网址:

dump all keys from memcached
Dumping MemcacheD Content (Keys) with PHP
Robbin的文章
以上文章都利用这个命令导出了部分数据。但事实上,cachedump的输出会限制在 2*1024*1024=2M 字节的长度内(Memecahed source: items.c, func: do_item_cachedump),其导出的格式如下所示:

ITEM key990017 [1 b; 1270394155 s]
ITEM key990016 [1 b; 1270394155 s]
ITEM key990015 [1 b; 1270394155 s]
ITEM key990014 [1 b; 1270394155 s]
即使不计算key的长度,每一条数据至少要占掉近三十个字节,2M最多到几万项数据。对于Item数量很大的情况下,这种方法并不能导出全部数据。

下面的地址佐证了这些观点。

官方邮件列表上的解释
上面提到的文章 memcache dump and load 的读者也在评论中进行了分析
第二种思路来自 Twitter infrastructure team 的 Evan Weaver 的 peeping into memcached , 利用 linux 的 ptrace 系统调用导出memcached进程中数据,分析这些数据得到memcached的所有Key。

但是这种方式有其限制的,一方面,编译Memcached时必须编译入调试信息 (参见link); 另一方面,在分析时对内存消耗太大。我们对一个只使用了64M内存、含有76万左右数据项的Memcached进程进行分析,在完成23万左右数据项时,分析进程占用内存的达到1040M,导致虚拟机内存用满,关闭了该进程。

因为我们现在运行的memcached是不带编译符号的,所以放弃了第二种方式。 第一种方式,则只能考虑怎么将slabs中的数据分批导出来。 Memcached 支持一个可选的 slabs reassign 命令,可以将一个slab内的数据项移动到其他slab。但这个命令必须在编译 memcached 时加入该特性。

最后,还是利用了第一种方法,每一次导出一批数据以后就从memcached中删除这一批数据,直到全部导出为止。 虽然这种办法很土,但是还是能够应付一次性数据迁移。 当然这是不得以而为之,明智的做法还是在一开始就不要将需要持久化的数据持久化到其他服务中,而不是只存放于memcached中。

来源:http://blog.feihoo.com/2010/04/dump_memcached.html

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/4054/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!

评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]