dbcached 是一款基于 Memcached 和 NMDB 的分布式 key-value 数据库内存缓存系统.
协议:New BSD License
作者:张宴
网址:http://code.google.com/p/dbcached/
作者blog: http://blog.s135.com
对这个项目不太清楚的,请到作者blog详细了解.我这里就不重复了.这里我简单写一下从安装到简单测试,所得到的结果.
个人不太会写blog,看到下面的流水帐大家要冷静
一.安装
安装需要几个包:libevent,dbcached,qdbm,nmdb,按照作者blog上的做法应该是不会遇到任何问题的.
但是我之前看到过作者blog上提到的另一款key-value的dbm -- tokyocabinet(tc),看作者的说明,tc是qdbm的successor,也是拥有非常好的性能.于是我到处找,希望可以用tc来替换qdbm来完成同样的功能.
结果,在nmdb的作者的git源上,我发现nmdb上已经支持tc作为backend,兴奋不已,down下来最新版的nmdb,把backend换成tc编译nmdb,OK没问题.
然后是安装dbcached,很简单,装上libevent,然后configure,make,make install就OK了
二.测试
这里只是做了简单的测试,测试环境:
nmdb服务:10.0.0.2
nmdb -d /data/test.tch -t 26010 -u 26010 -c 10240
memcache服务:10.0.0.3,10.0.0.4
memcached -d -m 64 -p 11211 -c 51200 -u nobody -x 10.0.0.2 -y 26010 -z 26010
1.测试双memcache的数据共享
代码:
1.php
<?
$mem = new Memcache;
if(!$mem->addServer("10.0.0.3",11211)) die("conn failed");
$mem->add("sarin_mpersist_keys","sarin_persist_value");
echo "sarin_mpersist_keys:".$mem->get("sarin_mpersist_keys")."/n";
?>
执行正常完成.下面测试在另外一台memcache读取是否正常
代码:
1.php
<?
$mem = new Memcache;
if(!$mem->addServer("10.0.0.4",11211)) die("conn failed");
echo "sarin_mpersist_keys:".$mem->get("sarin_mpersist_keys")."/n";
?>
执行结果:没有取到数据.数据共享失败.
检查原因,先是在nmdb服务器上抓包.tcpdump,结果在执行的时候是可以抓到由前端memcache发送过来的数据包的.这说明memcache本身是没问题的.问题应该是出在nmdb或者tc上面.
重新编译nmdb,把backend换成qdbm,重复上面的测试,结果还是没法共享数据.这.......
那看来不是backend的问题了.
重新下载一个nmdb,不用git上的最新版了.然后编译.这个版本只支持qdbm作为backend
重启memcache,重做上面的测试,这次数据共享没问题了.一个memcache把数据set进去以后.另外一个memcache可以正常共享到数据.
dbcached对版本要求还真严格...............
2.测试memcache的过期功能.
代码:
3.php
<?
$mem = new Memcache;
if(!$mem->addServer("10.0.0.3",11211)) die("conn failed");
$mem->add("sarin_mpersist_keys","sarin_persist_value");
$mem->set("sarin_timeout_key","sarin_timeout_value",0,3);
echo "data send OK /n";
sleep(5);
echo "sarin_mpersist_keys:".$mem->get("sarin_mpersist_keys")."/n";
echo "sarin_timeout_key:".$mem->get("sarin_timeout_key")."/n";
?>
正常的结果应该是,sarin_mpersist_keys可以取到数据,而sarin_timeout_key因为时间过期而取不到数据.
但是测试的结果很让我失望,sarin_mpersist_keys没问题.但是sarin_timeout_key却没有正常过期,仍然可以取到结果.看来memcache的timeout只是在memcache端被删除,而这个过期删除的操作并没有通知nmdb去执行.导致本该过期的数据还是被读取出来了.
这个问题会很大的限制memcache的使用范围:只有我们有信心管理的数据才能放入到dbcached中,而很多状态信息,比如用户登录状态,session,文章某时间段内的点击数等原本适合放到memcache中的数据现在都变得不再适合丢到dbcached中.qdbm里的无效数据也会越来越多.当然,通过定期重建cache数据库的方法是可以解决无效数据的问题,但是也就杜绝了我们将次关键数据放到qdbm的想法.
那怎么样才能将dbcached利用起来呢?
只能将memcache分组,
一组使用dbcached,用来存储那些可控的数据,比如用户信息,用户文章数等.定期重建.
另一组使用传统的memcache,利用其过期机制,存储一些时间相关的状态信息.
然后合理的分配程序对cache的使用,尽量用最小的资源消耗做最大的事情.
我会继续考虑dbcached使用的可行性,或者是否有更好的替代方案.
经过肖的提醒.做了另外一个测试,也失败了.
测试删除.当两个memcache都获取过同样的key以后,这个key是在两个memcache内存里存放的.
但是当其中的一个memcache调用了delete(key)的操作以后,只是将本地和nmdb段的数据清除了.另外一台memcache的数据经过测试还在.
这个问题显然无法容忍.........