memcache

一、           Introduction

memcache是一套分布式的高速缓存系统。

memcache与redis的联系与区别。

联系,数据都存储在内存当中;数据类型都是key-value。

区别,memcache,每个key的数据最大是1M;对各种技术支持比较全面,比如,session可以存储memcache中,各种框架,比如thinkphp,对memcache的支持比较好;比较老牌,传统的内存缓存技术;适合存储简单实用的数据;数据类型只有string;没有持久化

redis,每个key的数据最大是1G;对各种技术支持没有memcache更好;新兴的内存缓存技术;适合集合计算(list/set/sortset);数据类型丰富(string/list/set/sortset/hash);有持久化

两种内存都重要,都有擅长的地方。memcache对session、框架支持;redis擅长集合计算。互相难以取代。

二、           安装与开启服务

解压win版的memcached,将执行文件拷贝到某个盘符路径下,便于使用cmd查找。

开启memcache服务,在cmd中,e:,进入e盘,然后,memcached,是在前台开启服务,一般不这样开启。memcache –help,调出命令参数。

memcache  -p 11213  -l  127.0.0.1 -m  128m   端口11213,监听本机ip,一共使用128m开启memcache。

设置开机启动项。安装开机启动项,memcached -d  install。卸载开机启动项,memcached -d  uninstall。如果需要在安装开机启动项时设置其他参数,可以memcached -d  install  -p xxx  -l   xxx -m  xxx  …。

启动memcache,可以在计算机右键,管理选项框中启动,也可以通过cmd命令,memcached -d  start,关闭服务,memcached  -d  stop。

三、           php使用memcache

首先,给php开启memcache的扩展extension=php_memcache.dll。如果在php的ext目录下没有php_memcache.dll文件,将这个文件拷贝到ext目录下。重启apache。

php操作memcache

在php中memcache体现为类,具体使用,实例化对象,对象调用成员方法。

1.       具体操作

设置$obj -> set(key,value,是否有压缩,有效期);//是否压缩,不考虑速度,考虑空间,就压缩,否则不。有效期,单位为秒。

获取$obj -> get(key);

删除$obj -> delete(key);

比如:

<?php

//php对memcache的操作

//1,实例化memcache对象

$mem = new Memcache();

//2,连接memcache服务器

$flag = $mem -> connect('localhost',11211);

//3,给内存设置key

$mem -> set('name','haha',0,3600*12);
<?php

//php对memcache的操作

//1,实例化memcache对象

$mem = new Memcache();

//2,连接memcache服务器

$flag = $mem -> connect('localhost',11211);

//3,读取设置的key

var_dump($mem -> get('name'));

注意,关于有效期,为0即不失效。key的名字组成比较随意,不能超过250字节,utf-8字符集的一个汉字是3个字节。有效期有两种方式,时间戳,时间差,一个时间数字,从目前往后延伸的时间长度。为了防止时间差与时间戳混淆,时间差不能超过30天,否则为时间戳。

//3,给内存设置key

$mem -> set('name','haha',0,30);

echo time();

$mem -> set('age',12,0,30,time()+100);

2.       各种数据类型的存储

php的数据类型,基本类型,int,string,boolean,float;复合类型,array,object,resource,null。

<?php

//php对memcache的操作

//1,实例化memcache对象

$mem = new Memcache();

//2,连接memcache服务器

$flag = $mem -> connect('localhost',11211);

//3,给内存设置key

$mem -> set('name','haha',0);

$mem -> set('age',12,0,0);

$mem -> set('eat',false,0);

$mem -> set('pai',3.14,0);

$user = array('usr1'=>'haha1','usr2'=>'hewh','usr3'=>'hlle');

class Student{

       var $name ="hee";

       var $height = 123;

       function eat(){

              echo "zaichi";

       }

}

$stu = new Student();

$mem -> set('arr',$user,0);

$mem -> set('stu',$stu,0);

$mem -> set('kong',null,0);

<?php

//php对memcache的操作

//1,实例化memcache对象

$mem = new Memcache();

//2,连接memcache服务器

$flag = $mem -> connect('localhost',11211);

//3,读取设置的key

//基本数据类型

var_dump($mem -> get('name'));

var_dump($mem -> get('age'));

var_dump($mem -> get('eat'));

var_dump($mem -> get('pai'));

//复合数据类型

var_dump($mem -> get('arr'));

var_dump($mem -> get('stu'));

var_dump($mem -> get('kong'));

3.       其他相关操作方法

add()//给memcache增加一个key,不存在就增加,存在就报错

set()//给memcache设置key,不存在就增加,存在就修改

close()//关闭memcache连接,一般设置到php代码的最后

decrement()//给key值减1

increment()//给key值加1

flush()//清空memcache的全部key

replace()//替换key的值为其他值,存在替换,不存在就报错

更多方法参考mamual。

四、           终端命令方式操作

登陆到memcache的操作终端,使用telnet远程登陆协议

telnet  ip port  比如,telnet  127.0.0.1  11211

如果telnet提示不是内部或外部指令,是因为没有开启telnet服务。控制面板中打开或关闭windows功能,勾选telnet客户端。

在终端操作实现memcache的操作

设置,

set  key  是否压缩  有效期  数据长度 【回车】

然后输入设置的数据长度的数据

比如set  name  0  50  6

回车后,输入hahaha。设置成功,提示stored。

add  key  是否压缩  有效期  数据长度 【回车】

然后输入数据

replace  key  是否压缩  有效期  数据长度  【回车】

软后数据数据

获取,

get  key,比如,get name

获取memcache的统计信息,stats

在php中通过getStats()获得memcache服务器的统计信息。

利用secureCRT一样可以实现对memcache的操作,走telnet协议。

五、           分布式memcache的部署

memcache与redis的不同,是把一台memcache的工作平均分配给多个memcache分担。

每个memcache服务器都是平等的,中间通过算法保障数据的平均分配。php代码的编写还保持原有习惯即可。

key的分配原则,依次轮询、求余。

分布式具体的实施

方案1,在一个服务器里边开启多个memcache服务。

默认的memcache服务器的端口号为11211,多开的话,设置为其他端口就可以多开。比如,打开cmd,在memcached的软件目录下,memcached -p  11212,开启以11212为端口的memcache,类推多开更多。

方案2,可以配置多个服务器,每个服务器里边都运行memcache服务。

部署了分布的memcache后,

<?php

//php对memcache的操作

//1,实例化memcache对象

$mem = new Memcache();

//2,连接memcache服务器(分布式的)

$mem -> addServer('127.0.0.1',11211);

$mem -> addServer('127.0.0.1',11212);

$mem -> addServer('127.0.0.1',11213);

//3,设置key

$mem -> set('te','haha',0);
<?php

//php对memcache的操作

//1,实例化memcache对象

$mem = new Memcache();

//2,连接memcache服务器(分布式的)

$mem -> addServer('127.0.0.1',11211);

$mem -> addServer('127.0.0.1',11212);

$mem -> addServer('127.0.0.1',11213);

//3,获取key

echo $mem -> get('te');

通过终端控制器,telnet 127.0.0.1  端口号  分别打开各个memcache服务器,get te查看保存在哪个服务器。注意,在每个php脚本内部设置数据和获取数据时保持连接服务器的顺序一致,否则数据可能取不到。

六、           缓存丢失

memcache中的key超过有效期,或被系统强制删除掉的等会使缓存丢失

1.       有效期过期

session信息过期,通过懒惰模式给删除的。session是在文件中存储,如果session已经过期,其文件还是存在的,下次有一个用户访问session信息,比如登陆系统。此时已经过期的session有一定几率被删除。这种就是懒惰模式。是被动的。

memcache中key的删除也是懒惰模式。如果key过期,文件还是存在,当再次被获取时,key被删除。

2.       空间不足被强制删除

memcache的可用空间为64MB,如果存储的数据非常多,可以空间不足了。此时仍然可以存储数据,因为memcache内部有LRU机制。least recently  use,最近不被使用的数据。内部空间如果不足,就会删除最近不被使用的数据。

如果不想使用LRU机制,就可以设置参数 –M,禁止LRU机制。在开启memcache服务时,比如,memcache -l  xxx  -p xxxxx -M

七、           session入memcache

传统的session的数据是在硬盘的文件中存储的。该session很大情况用于存储用户的相关信息,用于判断用户是否登陆系统。两个服务器的session是文件形式存储的,它们的session是不能通信的。

如果两个服务器的session是存储在memcache中的,则它们的session可以通信。

比如,在内容分布式部署中,特别是占带宽大的视频网站,一般有多个服务器支撑,当用户登陆后,也许看第一个视频时有服务器1提供,当看第2个视频时由服务器2提供,此时如果没有session通信,则可能提示用户登陆,这样的体验是不好的。或者某些大型购物平台在某些集中购物的节日,某个可能购买这个商品时,有服务器1提供,当购买别的商品时由服务器2提供数据,如果session不通信,就提示用户登陆,导致不好的用户体验。

hadoop大数据也可以做分布式,但是在这种情形下,是大材小用了。将用户登陆的session持久化信息保存在一个memcache服务器里边,这样服务器2、3、4也可以去session读取session信息,就可以保证用户访问服务器的时候无需重复登陆。

session存储在memcache的操作

修改php.ini的session存储设置,

session.save_handler= files  

session.save_path= "D:\002php\amp\php5\tmp"

编写php将session保存到memcache

<?php

//实现session在memcache中存储

ini_set("session.save_handler","memcache");

ini_set("session.save_path","tcp://127.0.0.1:11211");//连接memcache服务器

//正常操作session

session_start();

$_SESSION['username'] = 'haha';
<?php

//实现session在memcache中存储

ini_set("session.save_handler","memcache");

ini_set("session.save_path","tcp://127.0.0.1:11211");//连接memcache服务器

//正常操作session

session_start();

var_dump($_SESSION['username']);

session保存到memcache中key的名称为session_id的值。

使用php获得session_id,然后通过memcache获得session_id对应的session的内容。

<?php

//实现session在memcache中存储

ini_set("session.save_handler","memcache");

ini_set("session.save_path","tcp://127.0.0.1:11211");//连接memcache服务器

//正常操作session

session_start();

var_dump($_SESSION['username']);

echo "<br />";

$memsession = session_id();//获得session_id信息

$mem = new Memcache();

$mem -> connect('localhost',11211);

$sessioncontent = $mem -> get($memsession);

echo $sessioncontent;

如果memcache是分布式的,

<?php

//实现session在memcache中存储

ini_set("session.save_handler","memcache");

//ini_set("session.save_path","tcp://127.0.0.1:11211");//连接memcache服务器

//分布式memcache的设置

ini_set("session.save_path","tcp://127.0.0.1:11211;tcp://127.0.0.1:11212;tcp://127.0.0.1:11213");

//正常操作session

session_start();

var_dump($_SESSION['username']);

echo "<br />";

$memsession = session_id();//获得session_id信息

$mem = new Memcache();

$mem -> connect('localhost',11211);

$sessioncontent = $mem -> get($memsession);

echo $sessioncontent;

在获取分布式的memcache的session中的值是只要连接到每个memcache服务器,再获取

//1,实例化memcache对象

$mem = new Memcache();

//2,连接memcache服务器(分布式的)

$mem -> addServer('127.0.0.1',11213);

$mem -> addServer('127.0.0.1',11211);

$mem -> addServer('127.0.0.1',11212);

八、           memcache应用到thinkphp框架的例子

比如在网站前台商品列表页面,给商品列表信息存储在memcache中,这样许多人在访问时候就通过memcache获得数据,提高页面的请求速度,降低数据库开销。

 

在tp中使用memcache缓存,使用S()函数进行缓存的操作。

S(array(‘type’=>’memcache’,’host’=>主机名,’port’=>端口号码));

操作key

S(key,value,有效期);

获取key

S(key);

删除key

S(key,null);

比如:

    //列表展示

    public function showlist(){

          //设置memcache缓存

          S(array('type'=>'memcache','host'=>"localhost",'port'=>11211));

          //给存储的商品信息设置一个名字,goods_category_info

          //线上产品给key其名字,是md5(sql语句)

          $info = S("goods_category_info");

          if(empty($info)){

                     //获得商品列表信息

                     echo "从mysql获得数据";

                 $info=D("Goods")->order('goods_iddesc')->field("goods_name,goods_price,goods_small_img")->select();

                 //var_dump($info);die;

                 //把获得的信息存储在memcache中

                 S("goods_category_info",$info,0);

          }

          $this->assign("info",$info);

        $this->display();//没有传参,视图模版名称与当前操作方法名称一致              

    }

如果数据库的数据有修改,就要删除旧的缓存,根据新的数据内容生成新的缓存。或者直接删除旧的缓存,等前台第一次获取数据时,生成新的缓存也可以。

比如后台的商品管理控制器中,增删改操作都要做相应的处理

    public functionupd($goods_id){

        $goods = D('Goods');

        //dump($goods_id);

//        dump($height);

//        dump($addr);

        //find()方法获得数据表记录,每次通过一维数组返回一个记录结果

        //$model对象->find();没有设置参数获得第一条结果

        //$model对象->find(数字);获得主键为参数值的记录结果

//        $info = D('Goods')-> select($goods_id);

//        两个业务逻辑,展示和收集

        if (!empty($_POST)) {

            $z = $goods-> save($_POST);

            //获得全部的商品信息,给前台页面制作新缓存,删除旧缓存

           S(array('type'=>'memcache','host'=>"localhost",'port'=>11211));

            $info =D("Goods")->order('goods_iddesc')->field("goods_name,goods_price,goods_small_img")->select();          

            //把获得的信息存储在memcache中

           S("goods_category_info",$info,0);

            //或者直接删除旧的缓存也可以

            //S("goods_category_info",null);

            if ($z) {

                //页面跳转

               //$this->redirect(分组/控制器/操作方法,参数array,间隔时间,提示信息);

               // $this ->redirect("showlist",array(), 2, '数据添加成功');

                //如果设置参数,可以get方法传递,比如

                $this ->redirect("showlist",array(), 2, '数据修改成功');

            } else {

                $this ->redirect("upd",array('goods_id' => $goods_id), 2, '数据修改失败');

            }

        } else {

            $info = D('Goods')-> find($goods_id);

            $this ->assign('info', $info);

            $this ->display();

        }   

    }

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值