CentOS下Memcached的安装

在CentOS下安装Memcached和需要的libevent。

1. CentOS 开发环境一键安装 :)

yum groupinstall 'Development Tools'

 

2. 安装libevent

    $ wget http://www.monkey.org/~provos/libevent-1.4.8-stable.tar.gz
    $ tar xzf libevent-1.4.8-stable.tar.gz
    $ cd libevent-1.4.8-stable
    $ ./configure
    $ make
    $ make install

 

3. 安装memcached

    $ wget http://www.danga.com/memcached/dist/memcached-1.2.6.tar.gz
    $ tar xzf memcached-1.2.6.tar.gz
    $ cd memcached-1.2.6
    $ ./configure
    $ make
    $ make install

 

测试是否安装成功:
    $ memcached -u nobody -d -m 64 -p 11211
/usr/local/bin/memcached: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory


安装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/bin/phpize
./configure -enable-memcache -with-php-config=/usr/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

memcached的基本设置:
1.启动Memcache的服务器端:
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.12.201 -p 13001 -c 256 -P /tmp/memcached.pid
 
实现Session的功能,基本上是通过
 *          设置客户端的Cookie来保存SessionID,
 *          然后把用户的数据保存在服务器端,最后通

 *          Cookie中的Session Id来确定一个数据是否是用户的,


原始
session.save_handler = files


mem:

session.save_handler = memcache

session.save_path = "tcp://192.168.0.26:13001,tcp://192.168.0.26:13002"

session.use_cookies = 1

 


//memcache 配置数组
$memcache_servers=array(
      array("host"=>"192.168.0.26",
            "port"=>"14001",
            "persistent"=>true,
            "weight"=>1,
            "timeout"=>1,//1为默认值,单位为秒
            "retry_interval"=>2,
            "status"=>true,
            "failure_callback"=>"memcacheConnectLog"
      ),
      array("host"=>"192.168.0.26",
            "port"=>"14002",
            "persistent"=>true,
            "weight"=>1,
            "timeout"=>1,//1为默认值,单位为秒
            "retry_interval"=>2,
            "status"=>true,
            "failure_callback"=>"memcacheConnectLog" //写入日志函数
      )
);

 

 ====================监控

 

netstat -an | grep memcache

ps -ef|grep  memcache

 

 

 

 

 cd memcache-2.2.4

[zhangy@BlackGhost memcache-2.2.4]$ ls |grep .php
example.php
memcache.php
run-tests.php

把memcache.php文件,cp到你的web服务器上面


cp memcache.php /home/zhangy/www/test

vim /home/zhangy/www/test/memcache.php 打开修改配置

 

define('ADMIN_USERNAME','zhangy');     // Admin Username
define('ADMIN_PASSWORD','adsfadf');      // Admin Password

$MEMCACHE_SERVERS[] = '192.168.12.201:13001'; // add more as an array

$MEMCACHE_SERVERS[] = '192.168.12.201:13002'; // add more as an array

 

 能过url访问memcache.php

 

Hits: 29 (67.4%)          #点击了29

Misses: 14 (32.6%)      #字面意思,丢失了14。我这样说肯定有很多人想,这14是memcache没起作用。

对的,是没有起作用,第一次都不会起作用,如果不明白,去搞清楚,memcache的调用原理。

 

 

 

 -----------------

telnet 192.168.12.201 13001 这样的命令连接上memcache,然后直接输入stats就可以得到当前memcache的状态

 

 

这些状态的说明如下:
pid     memcache服务器的进程ID
uptime     服务器已经运行的秒数
time     服务器当前的unix时间戳
version     memcache 版本
pointer_size     当前操作系统的指针大小(32位系统一般是32bit)
rusage_user     进程的累计用户时间
rusage_system     进程的累计系统时间
curr_items     服务器当前存储的items数量
total_items     从服务器启动以后存储的items总数量
bytes     当前服务器存储items占用的字节数
curr_connections     当前打开着的连接数
total_connections     从服务器启动以后曾经打开过的连接数
connection_structures     服务器分配的连接构造数
cmd_get     get命令(获取)总请求次数
cmd_set     set 命令(保存)总请求次数
get_hits     总命中次数
get_misses     总未命中次数
evictions     为获取空闲内存而删除的items数(分配给memcache的空间用满后需要删除旧的items来得到空间分配给新的items)
bytes_read     总读取字节数(请求字节数)
bytes_written     总发送字节数(结果字节数)
limit_maxbytes     分配给memcache的内存大小(字节)
threads     当前线程数

 

 

 

 

===========================shell脚本检查memcache进程并自动重启

vim /etc/memcached_check.sh

#!/bin/sh
#check memcache process and restart if down

mm_bin="/usr/local/bin/memcached"
mm_log="/usr/local/webserver/apache2/logs/memcached_check.log"
mm_ports=("13002")
mm_param=("-d -m 500 -u www -p 13002 -c 256")
mm_count=${#mm_ports[@]}

t=$(date -d "today" +"%Y-%m-%d %H:%M:%S")
i=0
while [ $i -lt $mm_count ]
do
mm_exists=`ps -ef|grep "memcached"|grep "${mm_ports[$i]}"|grep -v grep|wc -l`

if [ "$mm_exists" == "0" ]; then
${mm_bin} ${mm_param[$i]} 2>&1 > /dev/null &
echo "${t} : ${mm_bin} ${mm_param[$i]}" >> ${mm_log}
fi

let i++
done

============

chmod +x /etc/memcached_check.sh

添加为自动执行:
#crontab -e
0-59 * * * * /bin/sh /etc/memcached_check.sh

系统每10分钟会自动执行memcached_check.sh
*/10 * * * * /bin/sh /etc/memcached_check.sh

-----------


#!/bin/sh
#check memcache process and restart if down

mm_bin="/usr/local/bin/memcached"
mm_log="/home/xxx/memcached_check.log"
mm_ports=("11211" "11212")
mm_param=("-d -m 20480 -p 11211 -u www" "-d -m 256 -p 11212 -u www")
mm_count=${#mm_ports[@]}

t=$(date -d "today" +"%Y-%m-%d %H:%M:%S")
i=0
while [ $i -lt $mm_count ]
do
mm_exists=`ps -ef|grep "memcached"|grep "${mm_ports[$i]}"|grep -v grep|wc -l`

if [ "$mm_exists" == "0" ]; then
${mm_bin} ${mm_param[$i]} 2>&1 > /dev/null &
echo "${t} : ${mm_bin} ${mm_param[$i]}" >> ${mm_log}
fi

let i++
done

======================

添加为自动执行:
    #crontab -e
*/10 * * * * /bin/sh /home/xxx/memcached_check.sh

系统每10分钟会自动执行memcached_check.sh

 

 

---------------------

备用shell语句:

#检查mysql状态
PORT=`netstat -na | grep "LISTEN" | grep "3306" | awk '{print $4}' | awk -F. '{print $2}'`
if [ "$PORT" -eq "3306" ]

#检查mysql占CPU负载
mysql_cpu=`top -U root -b -n 1 | grep mysql | awk '{print $10}'|awk -F. '{print $1}'`
#如果mysql cpu负载大于80,则重启mysql
if [ "$mysql_cpu" -ge "80" ]

#获得相关信息
ps -ef|grep "memcached"|grep -v "grep"|wc -l
ps -ef|grep "memcached"|grep "11211"|grep -v "grep"|wc -l
ps aux|grep "memcached"|grep -v "grep"|awk '{sum+=$4;n++};END{print sum}'
ps aux|grep "memcached"|grep -v "grep"|awk '{printf $1}'

MYPORT=`netstat -na|grep "tcp"|grep "3306"|awk -F[:" "]+ '{print $5}'`
HAPORT=`netstat -na|grep "udp"|grep "694"|awk -F[:" "]+ '{print $5}'`
PING=`ping -c 5 www.linuxtone.org|awk -F, '/packets/{print $3}'|cut -c 2-|awk '{print $1}'`
DB1IP=`ifconfig eth0|awk '/inet/{print $2}'|cut -c 6-`

 

-----------------------
shell if语句的一些资料:
–b 当file存在并且是块文件时返回真
-c 当file存在并且是字符文件时返回真
-d 当pathname存在并且是一个目录时返回真
-e 当pathname指定的文件或目录存在时返回真
-f 当file存在并且是正规文件时返回真
-g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
-h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
-k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
-p 当file存在并且是命令管道时返回为真
-r 当由pathname指定的文件或目录存在并且可读时返回为真
-s 当file存在文件大小大于0时返回真
-u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
-w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
-o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。

UNIX Shell 里面比较字符写法:
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
-le 小于等于
-ge 大于等于
-z 空串
= 两个字符相等
!= 两个字符不等
-n 非空串





以下命令是查看哪个patch需要使用这个组件:

[root@tmp]# LD_DEBUG=libs memcached -v
2989: find library=libevent-1.4.so.2 [0]; searching
2989: search cache=/etc/ld.so.cache
2989: search path=/lib64/tls/x86_64:/lib64/tls:/lib64/x86_64:/lib64:/usr/lib64/tls/x86_64:/usr/lib64/tls:/usr/lib64/x86_64:/usr/lib64 (system search path)
2989: trying file=/lib64/tls/x86_64/libevent-1.4.so.2
2989: trying file=/lib64/tls/libevent-1.4.so.2
2989: trying file=/lib64/x86_64/libevent-1.4.so.2
2989: trying file=/lib64/libevent-1.4.so.2
2989: trying file=/usr/lib64/tls/x86_64/libevent-1.4.so.2
2989: trying file=/usr/lib64/tls/libevent-1.4.so.2
2989: trying file=/usr/lib64/x86_64/libevent-1.4.so.2
2989: trying file=/usr/lib64/libevent-1.4.so.2
2989:
memcached: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory

 


PHP memcached 应用示例

首先 下载 memcached-client.php,在下载了 memcached-client.php 之后,就可以通过这个文件中的类“memcached”对 memcached 服务进行操作了。其实代码调用非常简单,主要会用到的方法有 add()、get()、replace() 和 delete(),方法说明如下:

add ($key, $val, $exp = 0)
往 memcached 中写入对象,$key 是对象的唯一标识符,$val 是写入的对象数据,$exp 为过期时间,单位为秒,默认为不限时间;

get ($key)
从 memcached 中获取对象数据,通过对象的唯一标识符 $key 获取;

replace ($key, $value, $exp=0)
使用 $value 替换 memcached 中标识符为 $key 的对象内容,参数与 add() 方法一样,只有 $key 对象存在的情况下才会起作用;

delete ($key, $time = 0)
删除 memcached 中标识符为 $key 的对象,$time 为可选参数,表示删除之前需要等待多长时间。

下面是一段简单的测试代码,代码中对标识符为 'mykey' 的对象数据进行存取操作:

<?php
//    包含 memcached 类文件
require_once('memcached-client.php');
//    选项设置
$options = array(
    'servers' => array('192.168.1.1:11211'), //memcached 服务的地址、端口,可用多个数组元素表示多个 memcached 服务
    'debug' => true,  //是否打开 debug
    'compress_threshold' => 10240,  //超过多少字节的数据时进行压缩
    'persistant' => false  //是否使用持久连接
    );
//    创建 memcached 对象实例
$mc = new memcached($options);
//    设置此脚本使用的唯一标识符
$key = 'mykey';
//    往 memcached 中写入对象
$mc->add($key, 'some random strings');
$val = $mc->get($key);
echo "n".str_pad('$mc->add() ', 60, '_')."n";
var_dump($val);
//    替换已写入的对象数据值
$mc->replace($key, array('some'=>'haha', 'array'=>'xxx'));
$val = $mc->get($key);
echo "n".str_pad('$mc->replace() ', 60, '_')."n";
var_dump($val);
//    删除 memcached 中的对象
$mc->delete($key);
$val = $mc->get($key);
echo "n".str_pad('$mc->delete() ', 60, '_')."n";
var_dump($val);
?>

是不是很简单,在实际应用中,通常会把数据库查询的结果集保存到 memcached 中,下次访问时直接从 memcached 中获取,而不再做数据库查询操作,这样可以在很大程度上减轻数据库的负担。通常会将 SQL 语句 md5() 之后的值作为唯一标识符 key。下边是一个利用 memcached 来缓存数据库查询结果集的示例(此代码片段紧接上边的示例代码):

 之前我曾经写过一篇名为《PHP 实现多服务器共享 SESSION 数据》文章,文中的 SESSION 是使用数据库保存的,在并发访问量大的时候,服务器的负载会很大,经常会超出 MySQL 最大连接数,利用 memcached,我们可以很好地解决这个问题,工作原理如下:

用户访问网页时,查看 memcached 中是否有当前用户的 SESSION 数据,使用 session_id() 作为唯一标识符;如果数据存在,则直接返回,如果不存在,再进行数据库连接,获取 SESSION 数据,并将此数据保存到 memcached 中,供下次使用; 当前的 PHP 运行结束(或使用了 session_write_close())时,会调用 My_Sess::write() 方法,将数据写入数据库,这样的话,每次仍然会有数据库操作,对于这个方法,也需要进行优化。使用一个全局变量,记录用户进入页面时的 SESSION 数据,然后在 write() 方法内比较此数据与想要写入的 SESSION 数据是否相同,不同才进行数据库连接、写入数据库,同时将 memcached 中对应的对象删除,如果相同的话,则表示 SESSION 数据未改变,那么就可以不做任何操作,直接返回了; 那么用户 SESSION 过期时间怎么解决呢?记得 memcached 的 add() 方法有个过期时间参数 $exp 吗?把这个参数值设置成小于 SESSION 最大存活时间即可。另外别忘了给那些一直在线的用户延续 SESSION 时长,这个可以在 write() 方法中解决,通过判断时间,符合条件则更新数据库数据
创建硬链接:

Locate the file surely that is in /usr/local/lib and make a symbolic link

$ ln -s /usr/local/lib/libevent-1.4.so.2.1.2 /usr/lib64/libevent-1.4.so.2


如果memcache启动时伪静态不能访问 则结束下memcache中的缓存即可  【[Flush this server]】


posted @ 2012-12-04 09:57  冲天鸟  阅读(262)  评论(0)    收藏  举报