一、什么是Memcache

  memcache是一套分布式高速缓存数据库系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调到内存中,然后从内存中读取,从而大大提高读取速度,目前被许多网站使用以提升网站的访问速度。Memcache官方网站:http://memcached.org

  Memcache使用场景:
   1.非持久化存储:对数据存储要求不高
   2.分布式存储:不适合单机使用
   3.Key/Vaulue存储:格式简单,不支持List,Array数据格式
Memcache的基础知识

  特征和限制:
   1.在Memcached中可以保持的item数据量是没有限制的,只要内存足够。
   2.Memcached单进程在32位系统中最大使用内存为2G,若在64位系统则没有限制,这是由于32位系统限制但进程最多可使用2G内存,要使用更多内存,可以分多个端口开启多个Memcached进程。
   3.最大30天的数据过期时间,设置为永久的也会在这个时间过期,常量REALTIME_MAXDELTA 606024*30 控制
   4.最大键长为250字节,大于该长度无法存储,常量KEY_MAX_LENGTH控制
   5.单个item最大数据是1MB,超过1MB数据不予存储,常量POWER_BLOCK 1048576 进行控制,它是默认的slab大小
   6.最大同时连接数是200,通过 conn_init() 中的 freetotal 进行控制,最大软连接数是1024,通过 settings.maxconns=1024 进行控制
   7.跟空间占用相关的参数: settings.factor = 1.25 , settings.chunk_size = 48,影响slab的数据占用和步进方式

   memcached是一种无阻塞的socket通信方式服务,基于libevent库,由于无阻塞,对内存读写速度非常之快。

   memcached分服务器端和客户端,可以配置多个服务器端和客户端,应用于分布式的服务非常广泛。

   memcached作为小规模的数据分布式平台是十分有效果的。

   memcached是键值一一对应,key默认最大不能超过128个字节,value默认大小是1M,也就是一个slabs,如果要存2M的值(连续的),不能用两个slabs,因为两个slabs不是连续的,无法在内存中存储,故需要修改slabs的大小,多个key和value进行存储时,即使这个slabs没有利用完,那么也不会存放别的数据。

二、Mecached和memcache和memcached的区别

先来解释下标题中三种写法:首字母大写的Mecached,指的是Memcached服务器,就是独立运行Memcached的后台服务器,用作存储缓存数据的“容器”。Memcached是可以独立在web服务器之外任何服务器,甚至可以是集群。memcached和memcache是Memcached的客户端,通过二者访问Memcached服务器,向容器存取数据。二者用途一致,但在用法上稍有差异。如下:

  1.memcache最早是在2004年2月开发的,最后更新是在2013年4月,而memcached 最早是在2009年1月开发的,最后更多是在2014年1月更新的。因此 memcache的历史比 memcached 早。更多信息可以参考:
  memcache : http://pecl.php.net/package/memcache
  memcached : http://pecl.php.net/package/memcached
  2.memcache是一个原生版本,完全是在 PHP 框架内开发的,支持 OO(面向对象)和非 OO 两套接口并存,而memcahed是建立 libmemcached 的基础上的,只支持 OO 接口。这就意味着在 memcache 扩展的时候不要求安装其他的东西,但是在安装 memcached 的时候会要求你安装 libmemcached。因为 libmemcached 是 memcache 的 C 客户端,它具有低内存,线程安全等优点。据说新浪微博之前就全面将PHP的 memcache 替换成 PHP 的memcached,在高并发下,稳定性果断提高。
  3.memcached 有个比较 nice 的地方,就是 flag 不是在操作的时候设置的,而是有一个统一的 setOption() 函数进行设置,以添加缓存数据为例:

#memcache:
bool   Memcache::add   (string  $key,mixed  $var  [, int  $flag  [,int  $expire]])

#memcached:
public  bool  Memcached::add(string   $key ,mixed  $value  [, int    $expiration])

从上面各自的 add 方法可以看到,memcache 的 add 方法中的第三个参数代表是否对数据进行压缩,这样假如说我的缓存需要设置过期时间,但是 flag 参数在前面,我就得每一次都对 flag 进行设置!而 memcached 中使用 setOption() 来进行统一设置的(默认开启压缩)。
  4.memcached 比 memcache 支持更多的 memcache 协议,大概也就是说 memcached 有更多的方法,比如 getMulti() 和 setMulti() 函数非常有用,但是 memcache 并不支持。更多的方法可以看 PHP 的官方手册: memcache:http://php.net/manual/zh/book.memcache.php
memcached:http://php.net/manual/zh/book.memcached.php
  5.差别比较大的一点是,memcached支持 Binary Protocol,而 memcache 不支持,这意味着 memcached 会有更高的性能。但是很多说 memcached 不支持长连接,这其实不然,大家看官方手册:http://php.net/manual/zh/memcached.construct.php
  Memcache的基础知识
  上面明确的提出,当使用长链接的时候。。。。。因此 memcached 是能够实现长连接。
  6.两者在实现某些相同功能所使用的算法也是有一个差异的,例如大家都知道“一致性hash算法”是当添加或删除存储节点时,对存储在memcached上的数据影响较小的一种算法,在PHP的两个扩展库中,都可以使用该算法,但设置方法有所不同。

    memcache
    修改php.ini添加:
    [Memcache]
    Memcache.allow_failover = 1
    ......
    ......
    Memcache.hash_strategy = consistent
    Memcache.hash_function = crc32
    ......
    ......
    或在PHP中使用 ini_set 方法
    Ini_set('memcache.hash_strteagy ','standrad');
    Ini_set('memcache.hash_function','crc32');

    memcached
    $mem = new memcached();
    $men->setOption(Memcached::OPT_DISTRIBUTION,Memcached::DISTRIBUTION_CONSISTENT);
    $mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE,true);

总结三者关系描述:Memcahed 就比如是一个水库(容器),memcache 是一个塑料管,memcached 是一个 PVC 管。我们可以通过塑料管或者 PVC 管为水库上水或者取水,用哪种方式因人而异,而 PVC 管在输送水的效率上明显比塑料管快,而且可以装阀门、开口做分支等等,比塑料管的花样多。从上面的分析也可以得出一个结论:memcached 比 memcache 好,因此在以后的开发过程中,尽量使用memcached。

三、Linux下安装Memcache服务端和客户端

Memcache的基础知识
Memcache的基础知识
Memcache的基础知识
Memcache的基础知识
Memcache的基础知识
Memcache的基础知识

四、PHP中使用Memcache

  系统类:addServer,addServers,getStats,getVersion
  数据类:add,set,delete,flush,replace,increment,get
  进阶类:setMulti,deleteMulti,getMulti,getResultCode,getResultMessage

<?php
$m = new  Memcache();
$array  =  array(
                            array('127.0.0.1',11211),
                            array('127.0.0.2',11211),
                );
$m->addServers($array);        //连接服务端
print_r($m->getStats());           //查看状态
print_r($m->getVersion());       //查看版本号
//两个add,后面一个不会覆盖掉前面一个
$m->add('mkey','mvalue',600);
$m->add('mkey','mvalue2',600);
echo $m->get('mkey');
//replace覆盖前面相同的key
$m->replace('mkey','mvalue2',600);
//set方法既可以直接覆盖也会替换覆盖
$m->set('mkey','mvalue',600);
//删除
$m->delete('mkey');
//清空全部缓存
$m->flush();
//每次加5和减5操作
$m->increment('num',5);
echo  $m->get('num');
$m->decrement('num',5);
//setMulti第一个参数是存储的数据,第二个是过期时间
$data1 = array(
                'key'      =>       'value',
                'key2'    =>       'value2',
);
$m->setMulti($data,0);
$result = $m->getMulti(array('key','key2'));
print_r($result);
//一次性删除多条数据
$m->deleteMulti(array('key','key2'));
print_r($result);
//错误编码与错误内容,官方参考文档:https://www.php.net/manual/zh/memcached.getresultcode.php
echo  $m->getResultCode();
echo  $m->getResultMessage();