PHP与memcached实战

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baochao95/article/details/56479193

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

PHP使用Memcached的基本步骤
环境:
服务器:CentOS 6.4
PHP版本:5.6.30

1、编译安装memcached系统服务
http://memcached.org/下载memcached,然后进行编译安装

2、编译安装memcache扩展

pecl.php.net网址下载扩展,并进行编译安装,形成.so的文件,然后把.so的文件路径添加到php.ini中,然后重启php-fpm

3、学习memcached的简单命令

前台启动:./bin/memcached -u nobody -p 11211 -m 64 -vvv
后台启动:./bin/memcached -u nobody -p 11211 -m 64 -vvv &

4、实战案例:实现隔5秒去查询数据库

可以参考php手册中的memcache扩展Api

<?php
$mem = new Memcache();
$mem->connect('localhost',11211);
$users = $mem->get('users');//从memcached中读取users数据
if(empty($users)){
    $dsn = 'mysql:host=localhost;dbname=test';
    $pdo = new PDO($dsn,'root','1234');
    $sql = 'select * from user;';
    $st = $pdo->prepare($sql);
    $st->execute();
    $users = $st->fetchAll(PDO::FETCH_ASSOC);
    $mem->add('users',$users,false,5);//将users数据添加到memcached中并保存5秒
    echo 'from mysql'.'<br/>';
}else{
    echo 'from cache'.'<br/>';
}
print_r($users);
?>

思路:
创建一个memcache的对象,然后连接到memcached服务器上,首先从memcached中读取是否存在users数据,如果不存在,就连接数据库服务器,然后查询数据,并将数据存储到memcached中,最后进行输出。

效果图:
这里写图片描述

展开阅读全文

[分享]PHP Memcached客户端memcache,memcached比较

11-13

[url=http://blog.csdn.net/lgg201/archive/2010/11/13/6007307.aspx]本文博客地址[/url]rnrn1. 系统级锁定支持:rnmemcache客户端不支持锁相关的功能,而服务端又支持并发,这样其实就会带来数据混乱的问题,我们之前的做法是实现一个应用层的锁:rn[code=PHP]rn 1. addServer(......); rn 9. //锁定 rn 10. function lock($m, $key, $timeout = 5000, $wait = 15) rn 11. while($i ++ <= $wait && false !== $m->get('lock_'.$key)); rn 12. return false === $m->get('lock_'.$key) && ($m->set('lock_'.$key, $timeout)); rn 13. rn 14. //解锁 rn 15. function unlock($m, $key) rn 16. return $m->delete('lock_'.$key); rn 17. rn 18. ?> rn[/code]rnrn上面的方式构建锁定与解锁方法,然后在需要锁定的地方,get前加锁,set后解锁。rn上面的解决方法,会降低并发导致的数据混乱问题,但不能根治,因为我们在lock的时候可能会是并发的,同时拿到了锁。。rn后来,考虑过应用层实现的乐观锁机制,不过没有应用起来,也就不了了之了。。rn最近换了Memcached客户端,发现其中支持cas这个方法,其实就是一个系统层的乐观锁。rn[code=PHP]rn 1. addServer(....); rn 4. $value = $m->get($key, $cas); rn 5. //业务操作 rn 6. $m->cas($cas, $key, $value); rn 7. ?> rn[/code]rnrnget的时候,传一个$cas参数,Memcached::get这个方法在定义的时候,$cas是一个引用参数,执行完后,$cas这个名字已经被修改为memcached服务端返回的一个唯一标识了。rn当我们set这个key的时候,带上这个cas值,以cas接口设置过去,服务端就能根据cas值判断该key对应的值是否被修改过,如果被修改过,说明是脏数据,向客户端发送错误消息。rn由于这个锁定的验证机制是memcached的服务端提供的,因此,我们可以相信它的正确性。rnrn2. 获取Memcached中的所有的keyrn这个在memcache扩展中支持,Memcached扩展中反而不支持。rn使用的方法是Memcache::getExtendedStats(....),三个参数,这个这里就不写了,php-memcache文档翻译的时候,我会加进去。rn顺便提下,有精力有时间的朋友请参与支持:http://code.google.com/p/phpdoc-zh/,PHP官方文档翻译,公益项目rnrn3. 持久化连接问题rnMemcache客户端是支持持久化连接的,而Memcached客户端不支持持久化连接,并且Memcached客户端在释放连接的时候本身可能有bug,在高并发的情况下会导致Memcached服务端大量的连接处于time_wait状态无法释放。。这样就会导致一部分请求失败。。rn我们使用的是memcache作为session的handler,因为这个问题导致我们的session无法取到,客户端丢失连接,问题是比较严重的。rnrn最终从网上找到了解决方案就是修改Memcached服务端的socket释放相关的配置,我们进行的是如下修改:rn修改文件:/etc/sysctl.cnf,加入或修改下面两个配置rnnet.ipv4.tcp_tw_recycle=1 //回收time_wait状态的socketrnnet.ipv4.tcp_fin_timeout=3 //认为的超时时间rn然后/sbin/sysctl -p把这个文件reload一下rn这个配置的修改,在网上有一位朋友使用apache的ab做过并发测试rn1000000请求30000并发,没有出现Memcached的连接失败问题。rn呵呵,这几天了解到的就这么多,有不足之处或错误的地方,还望指正。rn谢谢 论坛

没有更多推荐了,返回首页