您的位置:首页 > 数据库 > Memcache

Memcached的安装配置及将PHP的session保存在Memcached中

2016-12-27 11:09 621 查看
Memcached是一款开源、高性能、分布式内存对象缓存系统,可应用各种需要缓存的场景,其主要目的是通过降低对Database的访问来加速web应用程序。它是一个基于内存的“键值对”存储,用于存储数据库调用、API调用或页面引用结果的直接数据,如字符串、对象等。

Memcached现已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。

Memcached有以特点
1. 简单key/value存储:服务器不关心数据本身的意义及结构,只要是可序列化数据即可。存储项由“键、过期时间、可选的标志及数据”四个部分组成;2. 功能的实现一半依赖于客户端,一半基于服务器端:客户负责发送存储项至服务器端、从服务端获取数据以及无法连接至服务器时采用相应的动作;服务端负责接收、存储数据,并负责数据项的超时过期;3. 各服务器间彼此无视:不在服务器间进行数据同步;4. O(1)的执行效率5. 清理超期数据:默认情况下,Memcached工作在Lazy模式下,是一个LRU(最近最少使用)缓存,同时,它按事先预订的时长清理超期数据;但事实上,memcached不会删除任何已缓存数据,只是在其过期之后不再为客户所见;而且,memcached也不会真正按期限清理缓存,而仅是当get命令到达时检查其时长;但是键一旦过期,则再次查询不会返回结果

Memcached虽然是一个键值存储server,但是它本身无法决定缓存那些数据,而是由客户端决定的键名,键值,缓存时长,标志位等

Memcached可以基于文本或者二进制上传和下载数据

Memcached将所有数据缓存再自己的内存中,并不会进行持久存储,且它认为自己也仅仅是一个缓存server,其上的数据丢失并不影响原数据,仅仅对服务有所影响

不同的memcached服务器之间不能进行通信,也不监控对方心跳信息,client端可以根据调度器如Nginx、haproxy、lvs等基于持久连接将数据缓存在多台memcached上(为了能够保证始终能够在同一个memcached找到同一个键,就需要对键做哈希运算,如将键做一定运算后/memcached的个数,再取余,根据余数将其存储在固定memcached服务器上,这样只要知道键一计算,就可以知道它在哪个server上存着;但这个取余法有个致命缺陷就是,万一挂掉或多了一个memcached服务器,其同一个键取余结果就会改变,就再也不能根据原来计算方法找到其对应的键值,即所有memcached上的缓存都失效)

这时就可以使用一致性哈希运算:1到2^32之间取几个对应区间对应每台服务器,然后对键/2^32取余,然后根据余数顺时针找最近服务器进行缓存,这样一旦挂了或加了一个memcached其结果也只让一台服务器上的缓存失效

Memcached有两个很重要组件:1:buddy system(伙伴系统)为了保证内存中的空间连续可用buddy system会将临近的空间碎片合并为一个大的连续空间,避免了内存碎片的产生2:slab allocator:当要存储小于内存页面大小(4K)数据时如存储一个128字节的数据,为了节省空间,slab allocator会将一个4K的内存页提前划分为许多128字节的块,将其存在里面,然后标记此块已近使用,而数据释放后也不会销毁这个128字节的块,会提供给以后的数据存储使用。并且slab allocator slab为不同大小的数据结构提前准备各种不同大小的内存块,存储时选择与它大小最近,且比它大的块进行存储,这样就提高了内存的利用效率

memcached依赖于libevent API,因此要事先安装之,项目主页:http://libevent.org/,且memcached是基于Event_Driven(事件驱动)的I/O机制,而event_driven是由libevent这个库提供的[root@node1 libevent-2.0.22-stable]# ./configure --prefix=/usr/local/libevent[root@node1 libevent-2.0.22-stable]# make && make install[root@node1 local]# echo "/usr/local/libevent/lib/" > /etc/ld.so.conf.d/libevent.conf[root@node1 local]# ldconfig -v[root@node1 ~]# yum install -y cyrus-sasl-devel

装memcached的服务端memcached memcached官网www.memcached,org [root@node1 tool]# tar memcached-1.4.33.tar.gz [root@node1 tool]# cd memcached-1.4.33[root@node1 memcached-1.4.33]# ./configure --enable-sasl --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent[root@node1 memcached-1.4.33]# make && make install

-l <ip_addr>:指定进程监听的地址;-d: 以服务模式运行;-u <username>:以指定的用户身份运行memcached进程;-m <num>:用于缓存数据的最大内存空间,单位为MB,默认为64MB;-c <num>:最大支持的并发连接数,默认为1024;-p <num>: 指定监听的TCP端口,默认为11211;-U <num>:指定监听的UDP端口,默认为11211,0表示关闭UDP端口;-t <threads>:用于处理入站请求的最大线程数,仅在memcached编译时开启了支持线程才有效;-f <num>:设定Slab Allocator定义预先分配内存空间大小固定的块时使用的增长因子;-M:当内存空间不够使用时返回错误信息,而不是按LRU算法利用空间;-n: 指定最小的slab chunk大小;单位是字节;-S: 启用sasl进行用户认证;

建立一个内存空间大小128M,slab chunk大小从20字节开始、增长因子为1.25、以nobody身份运行的memcache缓存空间,且显示详细过程[root@node1 init.d]# /usr/local/memcached/bin/memcached -m 128 -n 20 -f 1.25 -vv -u nobodyslab class 1: chunk size 72 perslab 14563slab class 2: chunk size 96 perslab 10922slab class 3: chunk size 120 perslab 8738slab class 4: chunk size 152 perslab 6898slab class 5: chunk size 192 perslab 5461slab class 6: chunk size 240 perslab 4369slab class 7: chunk size 304 perslab 3449slab class 8: chunk size 384 perslab 2730slab class 9: chunk size 480 perslab 2184slab class 10: chunk size 600 perslab 1747slab class 11: chunk size 752 perslab 1394slab class 12: chunk size 944 perslab 1110slab class 13: chunk size 1184 perslab 885slab class 14: chunk size 1480 perslab 708slab class 15: chunk size 1856 perslab 564slab class 16: chunk size 2320 perslab 451slab class 17: chunk size 2904 perslab 361slab class 18: chunk size 3632 perslab 288slab class 19: chunk size 4544 perslab 230slab class 20: chunk size 5680 perslab 184slab class 21: chunk size 7104 perslab 147slab class 22: chunk size 8880 perslab 118slab class 23: chunk size 11104 perslab 94slab class 24: chunk size 13880 perslab 75slab class 25: chunk size 17352 perslab 60slab class 26: chunk size 21696 perslab 48slab class 27: chunk size 27120 perslab 38slab class 28: chunk size 33904 perslab 30slab class 29: chunk size 42384 perslab 24slab class 30: chunk size 52984 perslab 19slab class 31: chunk size 66232 perslab 15slab class 32: chunk size 82792 perslab 12slab class 33: chunk size 103496 perslab 10slab class 34: chunk size 129376 perslab 8slab class 35: chunk size 161720 perslab 6slab class 36: chunk size 202152 perslab 5slab class 37: chunk size 252696 perslab 4slab class 38: chunk size 315872 perslab 3slab class 39: chunk size 394840 perslab 2slab class 40: chunk size 493552 perslab 2slab class 41: chunk size 616944 perslab 1slab class 42: chunk size 771184 perslab 1slab class 43: chunk size 1048576 perslab 1

从显示的信息可以看到slab chunk的最小值系统默认为72个字节,按1.25倍增长到了1048576大小

[root@node1 init.d]# netstat -tunlp |grep memcached tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 9268/memcached tcp 0 0 :::11211 :::* LISTEN 9268/memcached udp 0 0 0.0.0.0:11211 0.0.0.0:* 9268/memcached udp 0 0 :::11211 :::* 9268/memcached 可以看到监听在tcp和udp的11211端口

[root@node1 xinetd.d]# telnet localhost 11211Trying ::1...Connected to localhost.Escape character is '^]'.statsSTAT pid 9268STAT uptime 1483STAT time 1482739946STAT version 1.4.33STAT libevent 1.4.13-stableSTAT pointer_size 64STAT rusage_user 0.209968STAT rusage_system 1.007846STAT curr_connections 10STAT total_connections 12STAT connection_structures 11STAT reserved_fds 20STAT cmd_get 0STAT crawler_reclaimed 0STAT crawler_items_checked 0STAT lrutail_reflocked 0ENDadd mykey 0 30 5 ##添加一个键,键名为mykey,flag为0,键的有效期为30秒,大小为5个字符hello ##键值为helloSTORED ##显示已近%STOREDget mykey ##获取保存的键VALUE mykey 0 5hello ##键值为helloENDget mykey END ##30秒过去后,键值失效(虽然memcached为lazy模型,但过期后就不返回查询值)quit
Connection closed by foreign host.

此外memcached还有以下常用命令:

replace:仅当键已经存在时,replace 命令才会替换缓存中的键。如果缓存中不存在键,那么您将从 memcached 服务器接受到一条 NOT_STORED 响应。append:将数据追加到当前缓存数据的之后,当缓存数据存在时才存储。prepend:将数据追加到当前缓存数据的之前,当缓存数据存在时才存储incr: 让已近存在的键自动加一
derc: 让已近存在的键自动减一get : key 可以一个或多个,用空格格开gets:与 get 一样,但会返回多一个数字,这个数字用来检查数据是否被修改过,如修改过,这个 数字回改变。flash_all:清除所有键flash_all 900:在900秒内清空所有键delete: 删除缓存数据,数据存在返回DELETED,数据不存在返回NOT_FOUND
stats 查看memcached运行状态pid Memcached 进程ID uptime Memcached 运行时间,单位:秒 time Memcached 当前的UNIX时间 version Memcached 的版本号 rusage_user 该进程累计的用户时间,单位:秒 rusage_system 该进程累计的系统时间,单位:秒 curr_items Memcached 当前存储的内容数量 total_items Memcached 启动以来存储过的内容总数 bytes Memcached 当前存储内容所占用的字节数(*/1024/1024=mb) curr_connections 当前连接数量 total_connections Memcached 运行以来接受的连接总数 connection_structures Memcached 分配的连接结构的数量 cmd_get 查询请求总数 cmd_set 存储(添加/更新)请求总数 get_hits 查询成功获取数据的总次数 get_misses 查询成功未获取到数据的总次数 bytes_read Memcached 从网络读取到的总字节数 bytes_written Memcached 向网络发送的总字节数 limit_maxbytes Memcached 在存储时被允许使用的字节总数

更详细的memcached命令请参考下面网友写的文章http://blog.csdn.net/fdipzone/article/details/8655681 http://www.cnblogs.com/wayne173/p/5652034.html

如何让PHP使用memcached?(装memcached的客户端)
PHP要结合memcached必须依赖memcached的客户端库(也称为扩展),对于PHP来说其客户端库有两种,memcache和memcached,其中memcached功能更强大。而对Perl来说其所依赖的客户端库为cache:memcached模块。

简单来说memcached为memcached的服务器端,要让php在memcached服务器端缓存数据,就必须在在php所在server上装一个memcached的客户端(扩展),而这客户端有两种,一个叫memcache,另一个叫memcached(比较高级)对于C/C++来说其必须依赖libmemcached
下面将演示PHP扩展memcached扩展(要先安装libmemcached),如果安装memcache扩展则不用装libmemcached如果你要用memcache扩展下载可以点这个链接http://pecl.php.net/package/memcache
这个链接可以下载memcached http://pecl.php.net/package/memcached

[root@node1 tool]#wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz [root@node1 tool]# tar -xf libmemcached-1.0.18.tar.gz [root@node1 tool]# cd libmemcached-1.0.18 [root@node1 libmemcached-1.0.18]# ./configure --prefix=/usr/local/libmemcached --with-memcached [root@node1 libmemcached-1.0.18]#make && make install

[root@node1 tool]#tar -xf memcached-2.2.0.tgz
[root@node1 tool]#cd memcached-2.2.0 [root@node1 memcached-2.2.0]#/usr/local/php/bin/phpize
[root@node1 memcached-2.2.0]#./configure --with-php-config=/usr/local/php/bin/php-config --enable-memcached --with-libmemcached-dir=/usr/local/libmemcached
[root@node1 memcached-2.2.0]#make && make install
[root@node1 memcached-2.2.0]#vim /etc/php.d/memcache.ini extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/memcached.so [root@node1 memcached-2.2.0]#service php-fpm restart 启用Nginx转发php功能 [root@node1 ~]# vi /etc/nginx/nginx.conf
location ~ \.php$ {
root /web/read;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
[root@node1 ~]# service nginx reload



可以看到memcached扩展已近完成

Nginx结合memcached

[root@node1 ~]# vim /etc/nginx/nginx.conf

server { listen 80; server_name www.magedu.com;

location / { set $memcached_key $uri;#set 键名$memcached_key 键$uri; memcached_pass 127.0.0.1:11211; #memcached服务器IP:port default_type text/html; #默认缓存纯文本的内容 error_page 404 @fallback; #如果返回404错误(即memcached中没有相 应的缓存),则转发给fallback }

location @fallback { proxy_pass http://172.16.0.1; #反向代理到后端172.16.0.1处理请求 }}
配置php将它的会话(session)保存至memcached中

前提:1、配置各php支持使用memcache;2、安装配置好memcached服务器,这里假设其地址为172.16.200.11,端口为11211;

编辑php.ini文件,确保如下两个参数的值分别如下所示:
[root@node1 ~]# vim /etc/php.ini
session.save_handler = memcachesession.save_path = "tcp://192.168.139.2:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

tcp://172.16.200.11:11211?是你的memcached服务器端的IP:port?persistent=1 ?传递参数,persistent表示持久连接timeout=1 超时时间为1秒retry_interval=15 重视时间为15秒

新建php页面setsess.php,为客户端设置启用session:[root@node1 ~]# vim /web/read/setsess.php <?phpsession_start();if (!isset($_SESSION['www.zxl.com'])) { $_SESSION['www.zxl.com'] = time();}print $_SESSION['www.zxl.com'];print "<br><br>";print "Session ID: " . session_id();?>

新建php页面showsess.php,获取当前用户的会话ID:[root@node1 ~]# vim /web/read/showsess.php<?phpsession_start();$memcache_obj = new Memcache;$memcache_obj->connect('192.168.139.2', 11211);$mysess=session_id();var_dump($memcache_obj->get($mysess));$memcache_obj->close();?>

然后用浏览器分别访问setsess.php和showsess.php会看到session信息已近保存在了memcached中

安装memcached的web界面管理工具memadmin
[root@node1 tool]#tar -xf memadmin-1.0.12.tar.gz [root@node1 tool]#mv memadmin /web/read/[root@node1 tool]#cd /web/read/ 配置文件如下,可以修改用户和密码 [root@node1 read]# vim memadmin/config.php

<?phpif (!defined('IN_MADM')) exit();

$config['user'] = "admin"; // your username$config['passwd'] = "admin"; // your password
然后你用浏览器就行web界面访问http://192.18.139.2/memadmin









可以看到memadmin已近安装完成

为编译安装的Memcached配置启动脚本,Memcached SysV的startup脚本代码如下所示,将其建立为/etc/init.d/memcached文件:

[root@node1 ~]# vim /etc/init.d/memcached
#!/bin/bash
#
# Init file for memcached
#
# chkconfig: - 86 14
# description: Distributed memory caching daemon
#
# processname: memcached
# config: /etc/sysconfig/memcached

. /etc/rc.d/init.d/functions

## Default variables
PORT="11211"
USER="nobody"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""

RETVAL=0
prog="/usr/local/memcached/bin/memcached"
desc="Distributed memory caching"
lockfile="/var/lock/subsys/memcached"

start() {
echo -n $"Starting $desc (memcached): "
daemon $prog -d -p $PORT -u $USER -c $MAXCONN -m $CACHESIZE -o "$OPTIONS"
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch $lockfile
return $RETVAL
}

stop() {
echo -n $"Shutting down $desc (memcached): "
killproc $prog
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f $lockfile
return $RETVAL
}

restart() {
stop
start
}

reload() {
echo -n $"Reloading $desc ($prog): "
killproc $prog -HUP
RETVAL=$?
echo
return $RETVAL
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
condrestart)
[ -e $lockfile ] && restart
RETVAL=$?
;;
reload)
reload
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
RETVAL=1
esac

exit $RETVAL

使用如下命令配置memcached成为系统服务:
[root@node1 ~]# chmod +x /etc/init.d/memcached
[root@node1 ~]# chkconfig --add memcached
[root@node1 ~]# service memcached start
Starting Distributed memory caching (memcached): [ OK ]

本次实验完成!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  安装 配置 Memcached