天天看点

如何对memcache的数据(key-value)进行遍历操作什么是memcache为什么要遍历如何遍历memcache

   目前,用到memcache的公司和网站也越来越多。memcache的客户端操作一般都只提供了get,set等简单的操作,这些操作都是非常高效的。   虽然memcache是个key-value存储的系统,但是在某些时候,我们可能需要遍历memcache的数据。     

 memcache的stats命令包括:

如何对memcache的数据(key-value)进行遍历操作什么是memcache为什么要遍历如何遍历memcache

stats    

stats reset    

stats malloc    

stats maps    

stats sizes    

stats slabs    

stats items    

stats cachedump slab_id limit_num    

stats detail [on|off|dump]  

 通过命令完成遍历

       通过这些stats命令我们就可以完成memcache存储的内容的遍历,ok,下面我们通过telnet直接连接到memcache通过这些命令来完成相关的操作。 

      telnet到192.168.15.225(局域网测试机器)的memcache服务器

执行stats items命令,可以看到出现 很多的items行。

贴上一段php实现的遍历memcache数据的代码,其他语言可以参考代码自己实现。

如何对memcache的数据(key-value)进行遍历操作什么是memcache为什么要遍历如何遍历memcache

<?php  

$host='localhost';  

$port=11211;  

$mem=new memcache();  

$mem->connect($host,$port);  

$items=$mem->getextendedstats ('items');  

$items=$items["$host:$port"]['items'];  

foreach($items as $key=>$values){  

    $number=$key;  

    $str=$mem->getextendedstats ("cachedump",$number,0);  

    $line=$str["$host:$port"];  

    if( is_array($line) && count($line)>0){  

        foreach($line as $key=>$value){  

            echo "<pre>".$key.'=>';  

            print_r($mem->get($key));  

            echo "</pre><br/>";  

        }  

    }  

}  

?>  

memcached如何实现高性能批量删除,插入

memcached 的批量删除,向来是 memcached 使用者很头疼的事情,因为 memcached 采取的缓存方案是哈希表结构,所以没有办法实现 delete from tablename where key like ‘%xx%’ 类似这样的批量删除功能。所以不得不自己采取一些策略实现批量删除。常见的删除方案主要有以下两种:

第一种方案:通过记录 key 到 db 然后循环删除。 

其实这也是最常规的删除方法,最容易想到,可能大部分人首先都会这么考虑。具体方法如下: 

1.  添加业务数据时,在向 memcached 缓存 set 数据的时候,将其 key 记录到数据库(或内存中,或文件中,由于数据量大,内存中基本不可行),也就是每 set 一条数据到 memcached 缓存中,就向记录 key 的数据表(这类专门用于辅助删除缓存的表可以按业务分类建表,为了方便,我们下文简称 keytable, 因为不可能所有的 key 都用一张表,即使按业务分类建,数据量也是很庞大的) insert 一条记录。数据表结构可以设计为这两个字段: key( 对应缓存 key),   id( 对应业务实体 id) ,这里的存储 id 主要是方便批量查询出需要从缓存删除的 key 时方便 , 也可以根据实际业务设计。 

2.  删除业务数据时,首先从数据库的业务数据表删除数据,然后从 keytable  中查询出 keylist. 查询语句类似, select key from keytable where  条件   ,再然后循环 keylist 从 memcached 缓存中 remove 掉相应的记录,最后删除 keytable表中相应的记录,删除语句类似 delete key from keytable where  条件. 

这种方法的优点:方案设计思路简单,符合常规思维,而且能达到精确删除的目的。 

这种方法的缺点:删除代价比较高,需要数据库或其他存储介质辅助,而且实际应用中,缓存量是很大的,会导致大量频繁的对 keytable 表的 insert 操作,性能问题将会很严重,需要根据具体情况运用。

这种方案主要是利用 memcached 缓存根据 lru 算法进行定期自动清理不用或少用的缓存,通过对 key 增加版本管理来实现。 

该方案的具体方法如下(拿商品数据举例说明): 

1.   对缓存中的每个 key 进行版本管理,比如缓存商品数据的 key 为 product_10001.0, 这里的 product 表示商品这类业务数据, product_10001 表示具体的商品对象 10001 , 0 表示版本号。

2.  在 memcached 中维护一版本记录数据,这个很简单,比如整个系统只有商品,订单,用户这三类缓存数据,则在memcached 中只维护三个 key ,类似 product_version,book_version,user_version. 他们的取值范围为 0-99 之间循环,之所有循环是防止数据版本多了无限增大,管理麻烦,而且数字大了占用空间大(要对应到每个 key 的值)。 

3.  删除商品数据时,首先从数据库删除对应商品数据的记录。然后更新对应商品的版本: product_version = product_version+1 (记得当 product_version=99 时, product_version=0 )。 

4.  从 memcached 中 get 数据时,需要 get 两次,首次按 get 对应业务数据的版本号,如 product_version ,然后根据数据本身的 key+  最新的 product_version 作为真正的 key 去取数据。这样删除了的数据自动为过期数据, memcached 会根据 lru 算法清理。 

5.  向 memcached 中 set 数据时,也是先取最新的 product_version ,然后将数据本身的 key+product_version 作为 key保存数据到缓存。 

这种方案的优点:减少了批量删除从 memcached 真正删除数据的麻烦。利用 memcached 自身的特点解决删除问题,符合 memcached 的设计思想。 

这种方案的缺点: a. 每次 set 数据都要,先 get 版本,然后 set, 性能上差不多降低了 1 倍,虽然性能方面还是不错。不过这个问题好像没有办法解决,原先考虑在客户端缓存版本,因为版本毕竟不是时时都变,但是考虑到版本数据时多进程间共享数据,所以不能这样做,每次必须从 memcached 中取版本。否则难以保证是最新的。 b. 这种方案对内存上有点浪费,虽然 memcached 会根据 lru 算法清理低版本的垃圾数据,但是毕竟不是实时清理,所以必然浪费内存,所以内存不足的情况下,要仔细考虑采取此方案。