memcache 总结笔记

时间:2023-12-18 18:50:20

(一):基础概念

  1. memcache是什么?

Memcache 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

  1. memcache的工作原理?

memcache 总结笔记

RDBMS :关系数据库管理系统(Relational Database Management System)。

memcached:

php有两个memcache客户端,一个是php memcached, 一个是php memcache。客户端的memcached

相当于memcache的Plus版,实际在操作上和memcache几乎类似,当然作为memcache的升级版,memcached在稳定性和速度上更好,php操作memcached提供了更多的方法。在php官方的手册中分别搜索memcached和memcache 能发现他们的异同点。

  1. memcache的主要特点?
  1. 协议简单 基于C/S架构(Client/Server)

    2.基于libevent的事件处理

    3.内置内存存储方式

    4.互不通信的分布式内纯缓存服务器
  1. memcache的使用场景?

1.因为memcache是不能持久化数据的,一旦memcache宕机或者重启之类的,原来存入的数据都会丢失,所以对一些数据的安全性要求不高的可以考虑使用memcache

2.因为memcache存储的单个对象的最大是1M所以,当有一些体积相对较小,但是频繁被访问的数据时,可以是考虑memcache

3.当一个系统有大量的动态内容时,存在大量的读取数据库的操作,造成数据库负载过高时,可以考虑使用memcache做缓存来缓解数据库压力

4.多台服务器需要共享某些数据的时候,可以考虑使用memcache,例如:session共享

5.小结:memcache基本就是做缓存用的,为的是缓解服务器的压力,提高系统悉能

(二) 安装memcache

1.准备工具

1.1 : Xshell

1.2 :一个可用的LAMP/LNMP环境

1.3:我测试的是LAMP CentOS7+Apache(2.4.6)+MySql(5.6.35)+PHP(5.416)

2.安装基本流程

2.1 安装memcached的服务器端

一般在服务器端安装memcached得首先安装libevent库才行,但是在CentSO上使用yum方式安装可以解决这种依赖

yum install memcached


2.2 安装php的memcache扩展

yum install php-memcache

2.3 重启一下服务器

3.memcache安装后测试

3.1 开启memcache服务器端

memcache 总结笔记

3.1.1memcached指令参数基础解释

//在memcache的服务器端,我们可以通过memcached -help查该指令有那些参数,我们只解释下他的基础参数的意思
//例如 指令 /usr/bin/memcached -d -l 127.0.0.1 -p 11211 -m 150 -u root
-d 表示是守护进程
-l 连接的ip地址
-p memcached服务器监听的端口
-m 分配给memcached服务的最大的内存,单位是MB,默认是64M
-u 以谁的身份运行,示例中的是root用户运行,实际中少这么用,权限太高了
-c 同时最大的连接数 默认是1024
-n 最小分配空间 key+value+flags 默认是48

3.2 查看php的memcache安装是否成功

3.2.1 进入你应用的根目录 例如:/var/www/html/ 下

3.2.2. 新建一个文件 vim phpinfo.php

<?php
phpinfo();
?>

3.2.3 使用浏览器访问该文件 如果出现如下信息

memcache 总结笔记

3.2.4 表示php的memcache扩展开启成功了

3.2.5 注意: 当你的memcache都安装好了,在服务器上写的php脚本,通过客户端浏览器访问却没有什么内容返回的情况,我们首先查看一下Linux上的访问日志和错误日志,我是的LAMP环境,访问日志和错误日志都是放在了默认的位置 /var/log/httpd 目录下.打开access_log

memcache 总结笔记

状态码是200 表示访问是ok的

我们再看错误日志error_log

memcache 总结笔记

我们看到最近的一次错误是许可被拒绝了

基本分析是可能和权限,安全保护有关(SELinux,防火墙等)

此处我临时关闭SElinux即可 指令如下

setenforce 0

(三):PHP操作memcache

  1. 简单的讲memcache是php对内存操作的一种媒介
  1. 既然是对内存的操作,不能免俗的就要从增删改查四部曲开始
  2. php操作memcache,就和操作一个普通的类是一样的

php连接memcache服务器

  1. 我们进入项目的根目录(例如:/var/www/html/)新建一个文件con.php
<?php

//新建一个memcache对象$mem

$mem = new Memcache;

//连接memcache服务器

//connect("memcache服务器地址","memcache服务器使用的端口号")

$mem->connect("127.0.0.1",11211);

//查看memcache服务器的统计状态

print_r($mem->getStats());

```php
<?php

//新建一个memcache对象$mem

$mem = new Memcache;

//向连接池中添加一个memcache服务器

/*

*使用addServer方法也可以连接memcache服务器上,引用php手册上的说法是:

*"使用这个方法的时候网络连接并不会立刻建立,而是直到真正使用的时候才建立。 因此在加

*入大量服务器到连接池中时也是没有开销的,因为它们可能并不会被使用"

*/

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

//查看memcache服务器的统计状态

print_r($mem->getStats());

  1. 通过浏览器访问该文件

    memcache 总结笔记

    2.1 返回的统计信息是一个数组,我们大概了解一下返回的统计信息的意思
    [pid] => 37344   服务器的进程id
[uptime] => 21672 服务从启动到当前所经过的时间,单位是秒
[time] => 1489951190 服务器所在主机当前系统的时间,单位是秒
[version] => 1.4.15 memcached的版本号
[libevent] => 2.0.21-stable
[pointer_size] => 64 服务器所在主机操作系统的指针大小
[rusage_user] => 1.174806
[rusage_system] => 0.931503
[curr_connections] => 8 表示当前系统打开的连接数
[total_connections] => 33 表示从memcached服务启动到当前时间,系统打开过的连接的总数
[connection_structures] => 9
[reserved_fds] => 20
[cmd_get] => 14 累积获取数据的数量
[cmd_set] => 1 累积保存数据的数量
[cmd_flush] => 0
[cmd_touch] => 0
[get_hits] => 12 表示获取数据成功的次数
[get_misses] => 2 表示获取数据失败的次数
[delete_misses] => 0 表示删除数据失败的次数
[delete_hits] => 0 表示删除数据命中的次数
[incr_misses] => 0 表示增加一个元素失败的次数
[incr_hits] => 0 表示增加一个元素命中的次数
[decr_misses] => 0 表示减少一个元素失败的次数
[decr_hits] => 0 表示减少一个元素命中的次数
[cas_misses] => 0
[cas_hits] => 0
[cas_badval] => 0
[touch_hits] => 0
[touch_misses] => 0
[auth_cmds] => 0
[auth_errors] => 0
[bytes_read] => 270 memcached服务器从网络读取的总的字节数
[bytes_written] => 12788 memcached服务器发送到网络的总的字节数。
[limit_maxbytes] => 157286400 memcached服务缓存允许使用的最大字节数
[accepting_conns] => 1
[listen_disabled_num] => 0
[threads] => 4 被请求的工作线程的总数量
[conn_yields] => 0
[hash_power_level] => 16
[hash_bytes] => 524288
[hash_is_expanding] => 0
[bytes] => 0
[curr_items] => 0
[total_items] => 1
[expired_unfetched] => 0
[evicted_unfetched] => 0
[evictions] => 0
[reclaimed] => 0

2.2 我们看到使用php操作memcache,首先是实例化一个memcache的对象,然后建立一个memcache服务端的连接.

php操作memcache

添加数据###

1.1 例如文件位置 : /var/www/html/con.php

<?php
$mem = Memcache;
$mem->connect('127.0.0.1',11211);
//memcache缓存数据的结构是基于 key -> value (键值)的
//add('键名','值','是否压缩','多少秒后失效')
$mem->add('one','故人西辞黄鹤楼',0,60);

1.2 我们再用一个文件验证是否存入 文件位置:/var/www/html/test.php

<?php
$mem = Memcache;
$mem->connect('127.0.0.1',11211);
echo date("Y-m-d H:i:s");
echo $mem->get('one');

1.3 通过浏览器访问执行,结果如下

memcache 总结笔记

超过设定的时间后就失效了

memcache 总结笔记

1.4 我们也可以使用set('键名','值',是否压缩,失效时间)来添加数据

<?php
$mem = Memcache;
$mem->connect('127.0.0.1',11211);
//set('键名','值','是否压缩','多少秒后失效')
$mem->add('one','故人西辞黄鹤楼',0,60);
$mem->set('one','烟花三月下扬州',0,60);

1.5 我们再获取一下这个值

memcache 总结笔记

1.6 add()和set()方法的区别: add()添加一个值,如果这个值存在,则添加失败

set()添加一个值,如果这个值存在,则替换掉原有的

删除数据###

2.1 修改 /var/www/html/test.php 文件

<?php
$mem = new Memcache;
$mem->connect("127.0.0.1",11211);
echo date("Y-m-d H:i:s");
echo $mem->get('one')."<br />";
$mem->delete('one');
$one = $mem->get('one');
if(empty($one))
{
echo "数据已经删除";
}

2.2 执行该文件后的效果

memcache 总结笔记

memcache 总结笔记

2.3 使用flush()方法清除已经存储的所有数据

2.3.1 修改 /var/www/html/con.php 文件并执行

<?php
$mem = new Memcache;
$mem->addServer("127.0.0.1",11211);
$mem->add('one','故人西辞黄鹤楼',false,0);
$mem->set('two','烟花三月下扬州',0,0);
$mem->set('three','孤帆远影碧空尽',0,0);
$mem->set('four','唯见长江天际流',0,0);

2.3.2 修改 /var/www/html/test.php 文件并执行

<?php
$mem = new Memcache;
$mem->connect("127.0.0.1",11211);
$result = $mem->get(array('one','two','three','four'));
echo "<pre>";
var_dump($result);

2.3.3 结果如下

memcache 总结笔记

2.3.4 再修改 /var/www/html/test.php 文件并执行

<?php
$mem = new Memcache;
$mem->connect("127.0.0.1",11211);
$mem->flush();
$result = $mem->get(array('one','two','three','four'));
echo "<pre>";
var_dump($result);

2.3.5 结果如下

memcache 总结笔记

修改数据###

3.1 php修改memcache的数据一般有两个方法set() 和replace()

3.1.1再修改 /var/www/html/test.php 文件并执行

<?php
$mem = new Memcache;
$mem->connect("127.0.0.1",11211);
//replace('被更新的键','新值','是否压缩','过期时间')
$flag = $mem->replace('four','欢迎来到扬州',0,0);
if($flag === FALSE)
{
echo "更新数据失败";
}else{
echo "更新数据成功";
} $result = $mem->get(array('one','two','three','four'));
echo "<pre>";
var_dump($result);

3.1.2 通过浏览器访问test.php文件后的结果如下:

memcache 总结笔记

3.1.3 我们再次修改 /var/www/html/test.php 文件并执行

<?php
$mem = new Memcache;
$mem->connect("127.0.0.1",11211);
//更新一个不存在的键 例如:five
$flag = $mem->replace('five','火星欢迎您',0,0);
if($flag === FALSE)
{
echo "更新数据失败";
}else{
echo "更新数据成功";
} $result = $mem->get(array('one','two','three','four'));
echo "<pre>";
var_dump($result);

3.1.4 执行后结果如下:

memcache 总结笔记

3.2 set()和replace是区别是:

当数据存在的时候,set()方法和replace()方法都能更新(修改),作用相同
当数据不存在的时候,set()方法会添加这样一条数据,replace()方法会返回FALSE

查询数据###

//memcache有关查询的几个方法
get()获取memcache上key的值,前面有示例,既能是单一的key值也可以是一组key的数组
getStatus()获取当前memcache服务器的统计信息
getServerStatus('服务器地址','端口号')用于获取一个服务器的在线/离线状态,返回一个服务器的状态,0表示服务器离线,非0表示在线。
getExtendedStats()缓存服务器池中所有服务器统计信息,如果缓存池中有多台memcache服务器,就将这些服务器的信息以二维数组的形式都返回
//例如,我向连接池中添加两台memcache服务器:
$mem->addServer("127.0.0.1",11211);
$mem->addServer("127.0.0.1",11212);
$stats = $mem->getExtendedStats();
print_r($stats);
//返回的信息格式将会是:
Array
(
[127.0.0.1:11211]=>Array
(
.........
)
[127.0.0.1:11212]=>Array
(
.........
)
)

增加或者减少一个元素的值###

increment('要增加值的元素的键','增加的量');
decrement('要减少值的元素的键','减少的量');

我们修改 /var/www/html/con.php 文件并执行

<?php
$mem = new Memcache;
$mem->connect("127.0.0.1",11211);
$mem->set('num',4,0,0);

我们修改 /var/www/html/test.php 文件并执行

<?php
$mem = new Memcache;
$mem->connect("127.0.0.1",11211);
$mem->increment('num',3);
echo $mem->get('num');

结果如下:

memcache 总结笔记

键 , 压缩 ,过期时间,缓存过期,分配内存耗尽

  1. 键(key) : 因为memcache是基于键和值的存储方式,memcache中键的命名很可以很随意,但是我们还是推荐比较有意义键名,key的最大长度是250个字节
  2. 压缩 :因为memcache存储单个item最大数据是在1MB内.所以当我们进行存储,会考虑是否开启压缩
//e.g:
bool memcache::set(key,value,是否压缩[0/1],失效时间);

2.1 压缩会节省更多的内存空间,但是也会带来额外的CPU开销,运行速度相对会慢

2.2 未压缩,占用的内存空间小,但是运行速度快

2.3memcache 支持的最大存储对象是1M,所以在将单个大于1M的内容存储到memcache的时候需要开压缩

3. 有效时间:

memcache::set("key","value",是否压缩,有效时间);
memcache::add("key","value",是否要锁,有效时间);

memcache的有效时间单位是秒(s),手册的解释是"当前写入缓存的数据的失效时间",设置有效时间有两种写法,并且有区别

//这种设置的有效时间的最大值是2592000秒既30天,但是要是有效时间大于30天怎么办?
memcache::set("home","love",0,2592000);
//这样这种时间戳的方式可以设置大于30天的有效时间
memcache::set("hope","love",0,time()+2592001);
  1. 当我们设置的一个缓存超过的有效期,那么这个缓存就"过期"了,不能再使用了,那么些过期的缓存数据会被memcache清除掉吗?会的,memcache清除过期的数据是采用的一种"懒惰"的机制,过期后不会立刻清除掉,而是当再次通过get()方式获取缓存时删除过期的数据
  2. 我们再开启memcache的时候曾经通过-m这个参数给开启的这个memcache分配一定内存大小,可是当这个分配的内存被使用殆尽的时候会怎么样呢?当分配的内存用尽,此时再向memcache中存入数据,那么memcache就会将最近不常用的数据删除掉,这种机制就是LRU(least recently used )

php操作memcache 基础示例

我们模拟一个场景,我现在的user表(仅三个字段)中存在52W条数据,我要取出最新的2万条数据.

分析:第一次访问,memcache中没有这些数据,我们就从DB中取得这些数据,并且将这些数据存入memcache中,当需要访问相同的数据的时候,直接从memcache中提供这些数据

  1. 准备数据

    memcache 总结笔记
  2. 编写基本脚本(php)文件

    我们在根目录下新建一个文件 vim /var/www/html/test2.php

get($key);
if(!$data)
{
try{

            $pdo = new PDO("mysql:host=localhost;dbname=test",'root','123456');
}catch(PDOException $e){
die($e->getMessage());
}
$stmt = $pdo->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$memcache->set($key,$data,MEMCACHE_COMPRESSED, 0);
  }

return $data;

}

$mem = new Memcache();

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

$sql = "select * from user order by id desc limit 0,20000";

$data = getmemcache($sql,$mem);

print_r($data);

$mem->close();

$endtime = microtime(true);

echo $endtime;

echo '执行时间'.round($endtime-$starttime,3).'秒';

3.通过客户端浏览器第一次访问test2.php文件

memcache 总结笔记

4.再次访问test2.php文件

memcache 总结笔记

5.我们可以看到第二访问是从memcache中获取测数据,应为我在test2.php文件中有2W条数据输出,感觉还是耗时很多,我们将数据输出那段代码注释掉,再次并且清空一下memcache缓存,再次访问test2.php文件

memcache 总结笔记

memcache 总结笔记

学习本是一个自我修正的过程,总结中有许多的不足,万望不吝赐教

[参考资料]:

1.http://php.net/manual/zh/class.memcache.php php手册memcache部分

2.http://www.w3cschool.cn/memcached/ W3Cschool memcached部分

3.http://blog.csdn.net/heiyeshuwu/article/details/3950532 Memcached原理和使用详情

[拓展资料]:

  1. 《大型网站技术架构》李智慧著
  2. http://www.songyawei.cn/content/5008?utm_source=tuicool&utm_medium=referral memcache和memcached的区别
  3. http://www.cnblogs.com/caoxiaojian/p/5715568.html Memcache介绍与应用场景
  4. http://yw666.blog.51cto.com/11977292/1910163?utm_source=tuicool&utm_medium=referral memcache缓存服务器
  5. http://www.cnblogs.com/crazyacking/p/5793239.html 走进缓存的世界
  6. http://www.imooc.com/learn/527 近距离探索memcache缓存