首先拥有一个lnmp 或者 lamp的架构,

然后开始安装memcache

memcached是基于libevent的事件处理。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥I/O的性能。 memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。

首先先安装memcached依赖库libevent

[root@memcache ~]# tar zxf libevent-2.0.22-stable.tar.gz 

[root@memcache ~]# cd libevent-2.0.22-stable/

[root@memcache libevent-2.0.22-stable]# ./configure

[root@memcache libevent-2.0.22-stable]# make&& make install

安装memcached

[root@memcache ~]# tar zxf memcached-1.4.33.tar.gz 

[root@memcache ~]# cd memcached-1.4.33/

[root@memcache memcached-1.4.33]# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local

[root@memcache memcached-1.4.33]# make&& make install

检测是否成功安装

[root@memcache ~]# ls /usr/local/memcached/bin/memcached 

/usr/local/memcached/bin/memcached

通过以上操作就很简单的把memcached服务端编译好了。这时候就可以打开服务端进行工作了。

配置环境变量:

进入用户宿主目录,编辑.bash_profile,为系统环境变量LD_LIBRARY_PATH增加新的目录,需要增加的内容如下:

[root@memcache ~]# vi ~/.bash_profile

MEMCACHED_HOME=/usr/local/memcached

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MEMCACHED_HOME/lib

[root@memcache ~]# /usr/local/memcached/bin/memcached -d -m 2048 -l 192.168.31.250 -p 11211 -u root -c 10240 -P /usr/local/memcached/memcached.pid

启动参数说明:

-d  选项是启动一个守护进程。

-m  分配给Memcache使用的内存数量,单位是MB,默认64MB。

-l  监听的IP地址。(默认:INADDR_ANY,所有地址)

-p  设置Memcache的TCP监听的端口,最好是1024以上的端口。

-u  运行Memcache的用户,如果当前为root的话,需要使用此参数指定用户。

-c  选项是最大运行的并发连接数,默认是1024。

-P  设置保存Memcache的pid文件。

-M 内存耗尽时返回错误,而不是删除项

-f 块大小增长因子,默认是1.25

-n 最小分配空间,key+value+flags默认是48

-h 显示帮助

[root@memcache ~]# netstat -anpt |grep memcached

tcp   0  0 192.168.31.250:11211    0.0.0.0:*  LISTEN      12840/memcached 

设置防火墙:

[root@memcache ~]# firewall-cmd --permanent --add-port=11211/tcp

success

[root@memcache ~]# firewall-cmd --reload 

success

刷新用户环境变量:

[root@memcache ~]# source ~/.bash_profile

编写memcached服务启停脚本

[root@memcache ~]# vi /etc/init.d/memcached

脚本内容如下:

[root@memcache ~]# cat /etc/init.d/memcached 

#!/bin/sh

#

# pidfile: /usr/local/memcached/memcached.pid

# memcached_home: /usr/local/memcached

# chkconfig: 35 21 79

# description: Start and stop memcached Service


# Source function library

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


RETVAL=0


prog="memcached"

basedir=/usr/local/memcached

cmd=${basedir}/bin/memcached

pidfile="$basedir/${prog}.pid"


#interface to listen on (default: INADDR_ANY, all addresses)

ipaddr="192.168.31.250"

#listen port

port=11211

#username for memcached

username="root"

#max memory for memcached,default is 64M

max_memory=2048

#max connections for memcached

max_simul_conn=10240

start() {

echo -n $"Starting service: $prog"

$cmd -d -m $max_memory -u $username -l $ipaddr -p $port -c $max_simul_conn -P $pidfile

RETVAL=$?

echo

[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog

}


stop() {

echo -n $"Stopping service: $prog  "

run_user=$(whoami)

pidlist=$(ps -ef | grep $run_user | grep memcached | grep -v grep | awk '{print($2)}')

for pid in $pidlist

do

kill -9 $pid

if [ $? -ne 0 ]; then

return 1

fi

done

RETVAL=$?

echo

[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog

}


# See how we were called.

case "$1" in

start)

start

;;

stop)

stop

;;

restart)

stop

start

;;

*)

echo "Usage: $0 {start|stop|restart|status}"

exit 1

esac

exit $RETVAL

设置脚本可被执行:

[root@memcache ~]# chmod +x /etc/init.d/memcached 

[root@memcache ~]# chkconfig --add memcached

[root@memcache ~]# chkconfig memcached on

说明:

shell脚本中return的作用

1)终止一个函数. 

2)return命令允许带一个整型参数, 这个整数将作为函数的"退出状态

码"返回给调用这个函数的脚本, 并且这个整数也被赋值给变量$?.

3)命令格式:return value

5、配置nginx.conf文件(在nginx主机操作)

配置内容如下:

user www www;

worker_processes  4;

worker_cpu_affinity 0001 0010 0100 1000;

error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;


pid        logs/nginx.pid;


events {

use epoll;

    worker_connections  65535;

multi_accept on;

}


http {

include       mime.types;

    default_type  application/octet-stream;


    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';


    #access_log  logs/access.log  main;


sendfile        on;

tcp_nopush     on;

    keepalive_timeout  65;

tcp_nodelay on;

client_header_buffer_size 4k;

open_file_cache max=102400 inactive=20s;

    open_file_cache_valid 30s;

    open_file_cache_min_uses 1;

    client_header_timeout 15;

    client_body_timeout 15;

reset_timedout_connection on;

    send_timeout 15;

server_tokens off;

client_max_body_size 10m;


    fastcgi_connect_timeout     600;

    fastcgi_send_timeout 600;

    fastcgi_read_timeout 600;

fastcgi_buffer_size 64k;

    fastcgi_buffers     4 64k;

fastcgi_busy_buffers_size 128k;

fastcgi_temp_file_write_size 128k;

    fastcgi_temp_path /usr/local/nginx1.10/nginx_tmp;

fastcgi_intercept_errors on;

    fastcgi_cache_path /usr/local/nginx1.10/fastcgi_cache levels=1:2 keys_zone=cache_fastcgi:128m inactive=1d max_size=10g;


gzip on;

    gzip_min_length  2k;

    gzip_buffers     4 32k;

    gzip_http_version 1.1;

    gzip_comp_level 6;

    gzip_types  text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;

gzip_vary on;

gzip_proxied any;

server {

listen       80;

        server_name  www.benet.com;


        #charset koi8-r;


        #access_log  logs/host.access.log  main;


location ~* ^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {

valid_referers none blocked  www.benet.com benet.com;

if ($invalid_referer) {

                #return 302  http://www.benet.com/img/nolink.jpg;

return 404;

break;

             }

access_log off;

        }

location / {

root   html;

index  index.php index.html index.htm;

        }

location ~* \.(ico|jpe?g|gif|png|bmp|swf|flv)$ {

expires 30d;

            #log_not_found off;

access_log off;

        }


location ~* \.(js|css)$ {

expires 7d;

log_not_found off;

access_log off;

        }      


location = /(favicon.ico|roboots.txt) {

access_log off;

log_not_found off;

        }

location /status {

stub_status on;

        }

location ~ .*\.(php|php5)?$ {

root html;

            fastcgi_pass 127.0.0.1:9000;

            fastcgi_index index.php;

include fastcgi.conf;

            fastcgi_cache cache_fastcgi;

            fastcgi_cache_valid 200 302 1h;

            fastcgi_cache_valid 301 1d;

fastcgi_cache_valid any 1m;

            fastcgi_cache_min_uses 1;

fastcgi_cache_use_stale error timeout invalid_header http_500;

            fastcgi_cache_key http://$host$request_uri;

        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html

        #

        error_page   500 502 503 504  /50x.html;

location = /50x.html {

root   html;

        }

   }

}

重启nginx服务

生成一个php测试页

[root@www memcache-3.0.8]# cat /usr/local/nginx1.10/html/test1.php 

<?php

phpinfo();

?>

使用浏览器访问test1.php测试页

这时候PHP是没有memcache的信息

6、memcache客户端(在php服务器操作):

memcache分为服务端和客户端。服务端用来存放缓存,客户端用来操作缓存。

安装php扩展库(phpmemcache)。

安装PHP Memcache扩展:

可以使用php自带的pecl安装程序

# /usr/local/php5.6/bin/pecl install memcache

也可以从源码安装,他是生成php的扩展库文件memcache.so。

安装memcache扩展库

[root@www ~]# tar zxf memcache-3.0.8.tgz 

[root@www ~]# cd memcache-3.0.8/

[root@www memcache-3.0.8]# /usr/local/php5.6/bin/phpize

[root@wwwmemcache-3.0.8]#./configure --enable-memcache --with-php-config=/usr/local/php5.6/bin/php-config

[root@www memcache-3.0.8]# make&& make install

安装完后会有类似这样的提示:

Installing shared extensions:     /usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/

把这个记住,然后修改php.ini

添加一行

extension=/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/memcache.so

重启php-fpm服务

[root@www memcache-3.0.8]# service  php-fpm restart

Gracefully shutting down php-fpm .done

Starting php-fpm  done

测试:

检查php扩展是否正确安装

1、[root@www html]# /usr/local/php5.6/bin/php -m

命令行执行php -m 查询结果中是否有memcache项

2、创建phpinfo()页面,查询session项下面的Registered save handlers值中是否有memcache项

浏览器访问test1.php

这时候可以查到memcache的信息。


测试代码:

[root@www ~]# cat /usr/local/nginx1.10/html/test2.php 

<?php

$memcache = new Memcache;

$memcache->connect('192.168.31.250', 11211) or die ("Could not connect");

$version = $memcache->getVersion();

echo "Server's version: ".$version."<br/>";

$tmp_object = new stdClass;

$tmp_object->str_attr = 'test';

$tmp_object->int_attr = 123;

$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");

echo "Store data in the cache (data will expire in 10 seconds)<br/>";

$get_result = $memcache->get('key');

echo "Data from the cache:<br/>";

var_dump($get_result);

?>

浏览器访问test2.php

解释

使用memcache实现session共享

配置php.ini中的Sessionmemcache方式。

session.save_handler= memcache

session.save_path= "tcp://192.168.31.250:11211?persistent=1&weight=1&timeout=1&retry_interval=15"

注:

session.save_handler设置session的储存方式为memcache。默认以文件方式存取session数据,如果想要使用自定义的处理来存取session数据,比如memcache方式则修为session.save_handler = memcache

session.save_path设置session储存的位置,多台memcache用逗号隔开

使用多个 memcached server 时用逗号”,”隔开,可以带额外的参数”persistent”、”weight”、”timeout”、”retry_interval”等等,
类似这样的:"tcp://host:port?persistent=1&weight=2,tcp://host2:port2"

memcache实现session共享也可以在某个一个应用中设置: 
ini_set("session.save_handler", "memcache"); 
ini_set("session.save_path", "tcp://192.168.0.9:11211"); 

ini_set()只对当前php页面有效,并且不会去修改php.ini文件本身,也不会影响其他php页面。

测试memcache可用性

重启php-fpm

web服务器上新建//usr/local/nginx1.10/html/memcache.php文件。内容如

<?php

session_start();

if (!isset($_SESSION['session_time']))

{

 $_SESSION['session_time'] = time();

}

echo"session_time:".$_SESSION['session_time']."<br />";

echo"now_time:".time()."<br />";

echo"session_id:".session_id()."<br />";

?>

访问网址http://192.168.31.141/memcache.php可以查看session_time是否都是为memcache中的Session,同时可以在不同的服务器上修改不同的标识查看是否为不同的服务器上的。

查看时间 session


可以直接用sessionid 去 memcached 里查询一下:

[root@www html]# telnet 192.168.31.250 11211

Trying 192.168.31.250...

Connected to 192.168.31.250.

Escape character is '^]'.

get ffaqe5b1oar311n3cn5q9co5g6

VALUE ffaqe5b1oar311n3cn5q9co5g6 0 26

session_time|i:1479134997;

得到session_time|i:1479134997;这样的结果,说明session 正常工作 

默认memcache会监听11221端口,如果想清空服务器上memecache的缓存,一般使用的是:

[root@memcache ~]# telnet 192.168.31.250 11211

Trying 192.168.31.250...

Connected to 192.168.31.250.

Escape character is '^]'.

flush_all

OK

同样也可以使用:

[root@memcache ~]# echo "flush_all" | nc 192.168.31.250 11211

OK

使用flush_all 后并不是删除memcache上的key,而是置为过期

memcache安全配置

因为memcache不进行权限控制,因此需要通过iptables将memcache仅开放个web服务器。

7、测试memcache缓存数据库数据

在Mysql服务器上创建测试表

mysql> create database testdb1;

Query OK, 1 row affected (0.00 sec)


mysql> use testdb1;

Database changed

mysql> create table test1(id int not null auto_increment,name varchar(20) default null,primary key (id)) engine=innodb auto_increment=1 default charset=utf8;

Query OK, 0 rows affected (0.03 sec)


mysql> insert into test1(name) values ('tom1'),('tom2'),('tom3'),('tom4'),('tom5');

Query OK, 5 rows affected (0.01 sec)

Records: 5  Duplicates: 0  Warnings: 0


mysql> select * from test1;

+----+------+

| id | name |

+----+------+

|  1 | tom1 |

|  2 | tom2 |

|  3 | tom3 |

|  4 | tom4 |

|  5 | tom5 |

+----+------+

5 rows in set (0.00 sec)

测试

下面就是测试的工作了,这里有个php脚本,用于测试memcache是否缓存数据成功

需要为这个脚本添加一个只读的数据库用户,命令格式

mysql> grant select on testdb1.* to user@'%' identified by '123456';

Query OK, 0 rows affected, 1 warning (0.00 sec)

在web服务器上创建测试脚本内容如下:

[root@www html]# cat /usr/local/nginx1.10/html/test_db.php 

<?php

$memcachehost = '192.168.31.250';

$memcacheport = 11211;

$memcachelife = 60;

$memcache = new Memcache;

$memcache->connect($memcachehost,$memcacheport) or die ("Could not connect");

$query="select * from test1 limit 10";

$key=md5($query);

if(!$memcache->get($key))

{

                $conn=mysql_connect("192.168.31.225","user","123456");

                mysql_select_db(testdb1);

                $result=mysql_query($query);

while ($row=mysql_fetch_assoc($result))

                {

                        $arr[]=$row;

                }

                $f = 'mysql';

                $memcache->add($key,serialize($arr),0,30);

                $data = $arr ;

}

else{

        $f = 'memcache';

        $data_mem=$memcache->get($key);

        $data = unserialize($data_mem);

}

echo $f;

echo "<br>";

echo "$key";

echo "<br>";

//print_r($data);

foreach($data as $a)

{

echo "number is <b><font color=#FF0000>$a[id]</font></b>";

echo "<br>";

echo "name is <b><font color=#FF0000>$a[name]</font></b>";

echo "<br>";

}

?>

访问页面测试

查看出mysql的数据

开肉会显示是mysql取出,还是memcache服务器取出

如果出现mysql表示memcached中没有内容,需要memcached从数据库中取得

再刷新页面,如果有memcache标志表示这次的数据是从memcached中取得的。

memcached有个缓存时间默认是1分钟,过了一分钟后,memcached需要重新从数据库中取得数据

查看 Memcached 缓存情况

我们需要使用 telnet 命令查看

[root@memcache ~]# telnet 192.168.31.250 11211

Trying 192.168.31.250...

Connected to 192.168.31.250.

Escape character is '^]'.

stats

STAT pid 1681                    //Memcached 进程的ID

STAT uptime 8429                //进程运行时间

STAT time 1479142306             //当前时间

STAT version 1.4.33                // Memcached 版本

STAT libevent 2.0.22-stable

STAT pointer_size 64

STAT rusage_user 1.218430

STAT rusage_system 1.449512

STAT curr_connections 5

STAT total_connections 32

STAT connection_structures 10

STAT reserved_fds 20

STAT cmd_get 25//总共获取数据的次数(等于 get_hits + get_misses )

STAT cmd_set 19 //总共设置数据的次数

STAT cmd_flush 4

STAT cmd_touch 0

STAT get_hits 15//命中了多少次数据,也就是从 Memcached 缓存中成功获取数据的次数

STAT get_misses 10//没有命中的次数

STAT get_expired 3

STAT get_flushed 1

STAT delete_misses 0

STAT delete_hits 0

STAT incr_misses 2

STAT incr_hits 2

STAT decr_misses 0

STAT decr_hits 0

STAT cas_misses 0

STAT cas_hits 0

STAT cas_badval 0

STAT touch_hits 0

STAT touch_misses 0

STAT auth_cmds 0

STAT auth_errors 0

STAT bytes_read 3370

STAT bytes_written 15710

STAT limit_maxbytes 2147483648//总的存储大小,默认为 64M

STAT accepting_conns 1

STAT listen_disabled_num 0

STAT time_in_listen_disabled_us 0

STAT threads 4

STAT conn_yields 0

STAT hash_power_level 16

STAT hash_bytes 524288

STAT hash_is_expanding 0

STAT malloc_fails 0

STAT log_worker_dropped 0

STAT log_worker_written 0

STAT log_watcher_skipped 0

STAT log_watcher_sent 0

STAT bytes 584//当前所用存储大小

STAT curr_items 3

STAT total_items 17

STAT expired_unfetched 2

STAT evicted_unfetched 0

STAT evictions 0

STAT reclaimed 4

STAT crawler_reclaimed 0

STAT crawler_items_checked 0

STAT lrutail_reflocked 0

END

命中率= get_hits/ cmd_get