Memcache学习总结


Memcache 学习总结 版本号: V1.2 最后跟新: 2015-04-01 作者: http://www.lai18.com/ 讨论组:http://www.lai18.com/group/214130.html QQ 群:263832661 关键字:Memcache,Memcached Memcache 与 Memcached 介绍及安装配置 也许大家一看到 Memcache 和 Memcached 会有点晕,这两者有什么关系又有什么区别呢,下面先 给大家说下 Memcached,Memcached 是一个高性能的分布式内存对象缓存系统,用于动态 Web 应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、 数据库驱动网站的速度。 想必大家也听说过 Memcached,就是一个缓存系统,我们可以把一些经常要查询的数据放到缓存中, 避免每次要使用的时候都去查询数据库。这样既能大幅的加快数据读取速度,而且也降低了服务器的 压力,所以一般大访问量的网站都会用的 Memcached。 Memcached 与 Memcache 的区别 至于 Memcached 和 Memcache 的区别,其实很简单,一个是服务端,一个是客户端,就像 mysql 一样,我们在命令行里输入各种 sql 语句就能查询到需要的结果,这就是客户端,客户端接收我们输 入的命令从服务端查询,mysqld 就是服务端,就是响应客户端的额后台进程,在这里也一样 Memcached 是服务端,而 Memcache 就是客户端。 所以我们要使用 Memcached,首先在服务端安装好 Memcached,并运行 Memcached,然后安 装 Memcache 就能使用了。 在这里我们会详细的讲解在 Linux 下安装 Memcached 服务端,并讲解通过 PHP 扩展安装 Memcache,以便我们直接通过 PHP 来测试 Memcached。 Memcached 的安装(Linux 环境下) 由于 Memcache 用到了 libevent 这个库用于 Socket 的处理,所以还需要安装 libevent,我们先把 这两个软件都下载下来 #1.分别把 memcached 和 libevent 下载回来,放到 /tmp 目录下: # cd /tmp # wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz # wget http://www.monkey.org/~provos/libevent-1.2.tar.gz #2.先安装 libevent: # tar zxvf libevent-1.2.tar.gz # cd libevent-1.2 #./configure --prefix=/usr # make # make install #3.测试 libevent 是否安装成功: # ls -al /usr/lib | grep libevent lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1. 0.3 -rwxr-xr-x 1 root root 263546 11?? 12 17:38 libevent-1.2.so.1.0.3 -rw-r--r-- 1 root root 454156 11?? 12 17:38 libevent.a -rwxr-xr-x 1 root root 811 11?? 12 17:38 libevent.la lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent.so -> libevent-1.2.so.1.0.3 还不错,都安装上了。 #4.安装 memcached,同时需要安装中指定 libevent 的安装位置: # cd /tmp # tar zxvf memcached-1.2.0.tar.gz # cd memcached-1.2.0 #./configure --with-libevent=/usr # make # make install 如果中间出现报错,请仔细检查错误信息,按照错误信息来配置或者增加相应的库或者路径。 安装完成后会把 memcached 放到 /usr/local/bin/memcached , #5.测试是否成功安装 memcached: # ls -al /usr/local/bin/mem* -rwxr-xr-x 1 root root 137986 11?? 12 17:39 /usr/local/bin/memcached -rwxr-xr-x 1 root root 140179 11?? 12 17:39 /usr/local/bin/memcached-debug 好了,以上就把 memcached 安装成功了 下面安装 Memcache 的 PHP 扩展 1.在 http://pecl.php.net/package/memcache 选择相应想要下载的 memcache 版本。 2.安装 PHP 的 memcache 扩展 tar vxzf memcache-2.2.1.tgz cd memcache-2.2.1 /usr/local/php/bin/phpize ./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with-zlib-dir make make install 3.上述安装完后会有类似这样的提示: Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-2007xxxx/ 4.把 php.ini 中的 extension_dir = "./"修改为 extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-2007xxxx/" 5.添加一行来载入 memcache 扩展:extension=memcache.so 6、修改未配置后重启 PHP 到这里我们已经把 Memcache 的服务端和客户端都安装好了,下面我们来通过 PHP 做一个简单地测 试 Memcache 功能测试 首先我们得在服务端启动已经安装好的 Memcached /usr/local/bin/memcached -d -m 10 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid 参数说明: -d 选项是启动一个守护进程, -m 是分配给 Memcache 使用的内存数量,单位是 MB,我这里是 10MB, -u 是运行 Memcache 的用户,我这里是 root, -l 是监听的服务器 IP 地址,如果有多个地址的话,我这里指定了服务器的 IP 地址 192.168.0.200, -p 是设置 Memcache 监听的端口,我这里设置了 12000,最好是 1024 以上的端口, -c 选项是最大运行的并发连接数,默认是 1024,我这里设置了 256,按照你服务器的负载量来设定, -P 是设置保存 Memcache 的 pid 文件,我这里是保存在 /tmp/memcached.pid, 然后编写 PHP 测试: 1. < ?php 2. $mem = new Memcache; 3. $mem->connect("127.0.0.1", 11211); //此处的 IP 和端口号就是上一步我们启动 memcached 指定的,否则会连接不上 4. $mem->set('key','set a value', 0, 60); 5. $val = $mem->get('key'); 6. echo $val; 7. ?> Memcache 的使用基本介绍 上一次总结中我们已经安装部署好了 Memcached,并且把 PHP 扩展 Memcache 也安装好了,这 一节我们详细学习一下 PHP 扩展 Memcache。Memcache 客户端包含两组接口,一组是面向过程 的接口,一组是面向对象的接口,具体可以参考 PHP 手册: http://php.net/manual/zh/book.memcache.php . 我们为了简单方便,就使用面向对象的方式,也便于维护和编写代码,那我们先来一段示例代码吧。 Memcache 使用方法实例代码 [php] view plaincopy 1. connect("192.168.0.200", 12000); 5. 6. //保存数据 7. $mem->set('key1','This is first value', 0, 60); 8. $val = $mem->get('key1'); 9. echo "Get key1 value: ". $val ."
"; 10. 11. //替换数据 12. $mem->replace('key1','This is replace value', 0, 60); 13. $val = $mem->get('key1'); 14. echo "Get key1 value: ". $val ."
"; 15. 16. //保存数组 17. $arr = array('aaa','bbb','ccc','ddd'); 18. $mem->set('key2', $arr, 0, 60); 19. $val2 = $mem->get('key2'); 20. echo "Get key2 value: "; 21. print_r($val2); 22. echo "
"; 23. 24. //删除数据 25. $mem->delete('key1'); 26. $val = $mem->get('key1'); 27. echo "Get key1 value: ". $val ."
"; 28. 29. //清除所有数据 30. $mem->flush(); 31. $val2 = $mem->get('key2'); 32. echo "Get key2 value: "; 33. print_r($val2); 34. echo "
"; 35. 36. //关闭连接 37. $mem->close(); 38. ?> 如果正常的话,浏览器将输出: Get key1 value: This is first value Get key1 value: This is replace value Get key2 value: Array ([0] => aaa [1] => bbb [2] => ccc [3] => ddd ) Get key1 value: Get key2 value: 热身之后我们再来分析下上面的代码实例吧。 Memcache 使用详解 初始化一个 Memcache 的对象: $mem = new Memcache; 连接到我们的 Memcache 服务器端,第一个参数是服务器的 IP 地址,也可以是主机名,第二个参数 是 Memcache 的开放的端口: $mem->connect("192.168.0.200", 12000); 保存一个数据到 Memcache 服务器上,第一个参数是数据的 key,用来定位一个数据,第二个参数 是需要保存的数据内容,这里是一个字符串,第三个参数是一个标记,一般设置为 0 或者 MEMCACHE_COMPRESSED 就行了,第四个参数是数据的有效期,就是说数据在这个时间内是有 效的,如果过去这个时间,那么会被 Memcache 服务器端清除掉这个数据,单位是秒,如果设置为 0,则是永远有效,我们这里设置了 60,就是一分钟有效时间: $mem->set('key1', 'This is first value', 0, 60); 从 Memcache 服务器端获取一条数据,它只有一个参数,就是需要获取数据的 key,我们这里是上 一步设置的 key1,现在获取这个数据后输出输出: $val = $mem->get('key1'); echo "Get key1 value: ". $val; 现在是使用 replace 方法来替换掉上面 key1 的值,replace 方法的参数跟 set 是一样的,不过第一 个参数 key1 是必须是要替换数据内容的 key,最后输出了: $mem->replace('key1', 'This is replace value', 0, 60); $val = $mem->get('key1'); echo "Get key1 value: ". $val; 同样的,Memcache 也是可以保存数组的,下面是在 Memcache 上面保存了一个数组,然后获取回 来并输出 $arr = array('aaa', 'bbb', 'ccc', 'ddd'); $mem->set('key2', $arr, 0, 60); $val2 = $mem->get('key2'); print_r($val2); 现在删除一个数据,使用 delte 接口,参数就是一个 key,然后就能够把 Memcache 服务器这个 key 的数据删除,最后输出的时候没有结果 $mem->delete('key1'); $val = $mem->get('key1'); echo "Get key1 value: ". $val ."
"; 最后我们把所有的保存在 Memcache 服务器上的数据都清除,会发现数据都没有了,最后输出 key2 的数据为空,最后关闭连接 $mem->flush(); $val2 = $mem->get('key2'); echo "Get key2 value: "; print_r($val2); echo "
"; 更多 Memcache 我们可以看 Memcache 的类定义 Memcache 类定义 [php] view plaincopy 1. Memcache { 2. bool add ( string $key , mixed $var [, int $flag [, int $expire ]]) 3. bool addServer ( string $host [, int $port = 11211 [, bool $persistent [, in t $weight [, int $timeout [, int $retry_interval [, bool $status [, callback $failure_callback [, int $timeoutms ]]]]]]]]) 4. bool close ( void ) 5. bool connect ( string $host [, int $port [, int $timeout ]]) 6. int decrement ( string $key [, int $value = 1 ]) 7. bool delete ( string $key [, int $timeout = 0 ]) 8. bool flush ( void ) 9. string get ( string $key [, int &$flags ]) 10. array getExtendedStats ([ string $type [, int $slabid [, int $limit = 100 ]]] ) 11. int getServerStatus ( string $host [, int $port = 11211 ]) 12. array getStats ([ string $type [, int $slabid [, int $limit = 100 ]]]) 13. string getVersion ( void ) 14. int increment ( string $key [, int $value = 1 ]) 15. mixed pconnect ( string $host [, int $port [, int $timeout ]]) 16. bool replace ( string $key , mixed $var [, int $flag [, int $expire ]]) 17. bool set ( string $key , mixed $var [, int $flag [, int $expire ]]) 18. bool setCompressThreshold ( int $threshold [, float $min_savings ]) 19. bool setServerParams ( string $host [, int $port = 11211 [, int $timeout [, int $retry_interval = false [, bool $status [, callback $failure_callback ]]]] ]) 20. } Memcache 成员方法概览 Memcache::add — 增加一个条目到缓存服务器 Memcache::addServer — 向连接池中添加一个 memcache 服务器 Memcache::close — 关闭 memcache 连接 Memcache::connect — 打开一个 memcached 服务端连接 Memcache::decrement — 减小元素的值 Memcache::delete — 从服务端删除一个元素 Memcache::flush — 清洗(删除)已经存储的所有的元素 Memcache::get — 从服务端检回一个元素 Memcache::getExtendedStats — 缓存服务器池中所有服务器统计信息 Memcache::getServerStatus — 用于获取一个服务器的在线/离线状态 Memcache::getStats — 获取服务器统计信息 Memcache::getVersion — 返回服务器版本信息 Memcache::increment — 增加一个元素的值 Memcache::pconnect — 打开一个到服务器的持久化连接 Memcache::replace — 替换已经存在的元素的值 Memcache::set — Store data at the server Memcache::setCompressThreshold — 开启大值自动压缩 Memcache::setServerParams — 运行时修改服务器参数和状态 Memcache 的配置项详解 Memcache 的配置项和用意如下列表 memcache.allow_failover boolean 是否在发生错误时(对用户)透明的转移到其他服务器。 memcache.max_failover_attempts integer 定义在写入和获取数据时最多尝试的服务器次数(即:故障转移最大尝试数),仅和 memcache.allow_failover 结合使用。 memcache.chunk_size integer 数据传输块大小,这个值越小网络 I/O 次数越多,如果发现莫名的速度降低, 可以尝试将此值调至 32768。 memcache.default_port string 在尝试连接 memcache 的时候如果没有单独指定端口默认使用的 TCP 端口号。 memcache.hash_strategy string 控制 key 到服务器的映射(分布式)策略。值 consistent 允许服务器增减而不会(大量)导致健的 重新映射 (译注:参见 http://tech.idv2.com/2008/07/24/memcached-004/),设置为 standard 则使用余数方式进行 key 的映射。 memcache.hash_function string 控制在 key-server 映射时使用哪个 hash 函数 crc32 标明使用标准 CRC32 进行 hash,fnv 则说明 使用 FNV-1a。 session.save_handler string 当值为 memcache 时标记使用 memcache 作为 session 处理器。 session.save_path string 定义一个逗号分割的用于 session 存储的服务器 url 列表,例如: "tcp://host1:11211, tcp://host2:11211". 每个 url 可以包含参数,这些参数于方法 Memcache::addServer()的参数相同。比如: "tcp://host1:11211?persistent=1&weight=1&timeout=1&retry_interval=15" Memcache 在中型网站的使用和 Memcache 的安全考虑 使用 Memcache 的网站一般流量都是比较大的,为了缓解数据库的压力,让 Memcache 作为一个 缓存区域,把部分信息保存在内存中,在前端能够迅速的进行存取。那么一般的焦点就是集中在如何 分担数据库压力和进行分布式,毕竟单台 Memcache 的内存容量的有限的。我这里简单提出我的个 人看法,未经实践,权当参考。 Memcache 在中型网站的使用 分布式应用 Memcache 本来支持分布式,我们客户端稍加改造,更好的支持。我们的 key 可以适当进行有规律 的封装,比如以 user 为主的网站来说,每个用户都有 User ID,那么可以按照固定的 ID 来进行提取 和存取,比如 1 开头的用户保存在第一台 Memcache 服务器上,以 2 开头的用户的数据保存在第二 胎 Mecache 服务器上,存取数据都先按照 User ID 来进行相应的转换和存取。 但是这个有缺点,就是需要对 User ID 进行判断,如果业务不一致,或者其他类型的应用,可能不是 那么合适,那么可以根据自己的实际业务来进行考虑,或者去想更合适的方法。 减少数据库压力 这个算是比较重要的,所有的数据基本上都是保存在数据库当中的,每次频繁的存取数据库,导致数 据库性能极具下降,无法同时服务更多的用户,比如 MySQL,特别频繁的锁表,那么让 Memcache 来分担数据库的压力吧。我们需要一种改动比较小,并且能够不会大规模改变前端的方式来进行改变 目前的架构。 我考虑的一种简单方法: 后端的数据库操作模块,把所有的 Select 操作提取出来(update/delete/insert 不管),然后把对 应的 SQL 进行相应的 hash 算法计算得出一个 hash 数据 key(比如 MD5 或者 SHA),然后把这个 key 去 Memcache 中查找数据,如果这个数据不存在,说明还没写入到缓存中,那么从数据库把数 据提取出来,一个是数组类格式,然后把数据在 set 到 Memcache 中,key 就是这个 SQL 的 hash 值,然后相应的设置一个失效时间,比如一个小时,那么一个小时中的数据都是从缓存中提取的,有 效减少数据库的压力。 缺点是数据不实时,当数据做了修改以后,无法实时到前端显示,并且还有可能对内存占用比较大, 毕竟每次 select 出来的数据数量可能比较巨大,这个是需要考虑的因素。 上面只是我两点没有经过深思熟虑的简单想法,也许有用,那就最好了。 Memcache 的安全考虑 我们上面的 Memcache 服务器端都是直接通过客户端连接后直接操作,没有任何的验证过程,这样 如果服务器是直接暴露在互联网上的话是比较危险,轻则数据泄露被其他无关人员查看,重则服务器 被入侵,因为 Mecache 是以 root 权限运行的,况且里面可能存在一些我们未知的 bug 或者是缓冲 区溢出的情况,这些都是我们未知的,所以危险性是可以预见的。 为了安全起见,我做两点建议,能够稍微的防止黑客的入侵或者数据的泄露。 内网访问 最好把两台服务器之间的访问是内网形态的,一般是 Web 服务器跟 Memcache 服务器之间。普遍 的服务器都是有两块网卡,一块指向互联网,一块指向内网,那么就让 Web 服务器通过内网的网卡 来访问 Memcache 服务器,我们 Memcache 的服务器上启动的时候就监听内网的 IP 地址和端口, 内网间的访问能够有效阻止其他非法的访问。 # memcached -d -m 1024 -u root -l 192.168.0.200 -p 11211 -c 1024 -P /tmp/memcached.pid Memcache 服务器端设置监听通过内网的 192.168.0.200 的 ip 的 11211 端口,占用 1024MB 内存, 并且允许最大 1024 个并发连接 设置防火墙 防火墙是简单有效的方式,如果却是两台服务器都是挂在网的,并且需要通过外网 IP 来访问 Memcache 的话,那么可以考虑使用防火墙或者代理程序来过滤非法访问。 一般我们在 Linux 下可以使用 iptables 或者 FreeBSD 下的 ipfw 来指定一些规则防止一些非法的访 问,比如我们可以设置只允许我们的 Web 服务器来访问我们 Memcache 服务器,同时阻止其他的 访问。 # iptables -F # iptables -PINPUTDROP # iptables -AINPUT-p tcp -s 192.168.0.2 --dport 11211 -j ACCEPT # iptables -AINPUT-p udp -s 192.168.0.2 --dport 11211 -j ACCEPT 上面的 iptables 规则就是只允许 192.168.0.2 这台 Web 服务器对 Memcache 服务器的访问,能够 有效的阻止一些非法访问,相应的也可以增加一些其他的规则来加强安全性,这个可以根据自己的需 要来做。 Memcache 的扩展性 Memcache 算是比较简洁高效的程序,Memcache 1.2.0 的源代码大小才 139K,在 Windows 平 台上是不可想象的,但是在开源世界来说,这是比较正常合理的。 Memcache 目前都只是比较简单的功能,简单的数据存取功能,我个人希望如果有识之士,能够在 下面两方面进行扩展。 1. 日志功能 目前 Memcache 没有日志功能,只有一些命令在服务器端进行回显,这样是很不利于对一个服务器 的稳定性和负载等等进行监控的,最好能够相应的加上日志的等功能,便于监控。 2. 存储结构 目前的数据形式就是: key => data 的形式,特别单一,只能够存储单一的一维数据,如果能够扩展 的话,变成类似数据库的格式,能够存储二维数据,那样会让可以用性更强,使用面更广,当然相应 的可能代码效率和存取效率更差一些。 3. 同步功能 数据同步是个比较重要的技术,因为谁都不能保证一台服务器是持久正常的运行的,如果能够具有类 似 MySQL 的 Master/Slave 的功能,那么将使得 Memcache 的数据更加稳定,那么相应的就可以 考虑存储持久一点的数据,并且不用害怕 Memcache 的 down 掉,因为有同步的备份服务器,这个 问题就不是问题了。 以上三点只是个人拙见,有识之士和技术高手可以考虑。 参考资料: Memcache 学习总结 1-Memcache 与 Memcached 介绍及安装配置 http://www.lai18.com/content/407157.html Memcache 学习总结 2-Memcache 的使用基本介绍 http://www.lai18.com/content/407158.html Memcache 的使用和协议分析详解 http://blog.csdn.net/heiyeshuwu/article/details/1380838 Memcache 学习总结 3-Memcache 的配置项详解 http://www.lai18.com/content/407172.html 对于各项的默认值大家可以参考 PHP 官方文档 http://php.net/manual/zh/memcache.ini.php Memcache 学习总结 4-Memcache 在中型网站的使用和 Memcache 的安全考虑 http://www.lai18.com/content/407173.html 问题交流 本总结文档有不足或不解之处,欢迎大家加入我们的 QQ 群交流 263832661,同时也开通我们的讨 论组(http://www.lai18.com/group/214130.html ),和大家一起共同学习。
还剩20页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 2 人已下载

下载pdf

pdf贡献者

bw45

贡献于2015-04-07

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf