LNMP部署+memcache缓存服务器
LNMP部署+memcache缓存服务器
- MemCache 简介
MemCache 是一个自由、源码开放、高性能、分布式的分布式内存对象缓存系统,用于动态 Web 应用以减轻数据库的负载。它通过在内存中缓存数据和对象来减少读取数据库的次数, 从而提高了网站访问的速度。 MemCaChe 是一个存储键值对的 HashMap,在内存中对任意 的数据(比如字符串、对象等)所使用的 key-value 存储,数据可以来自数据库调用、API 调用,或者页面渲染的结果。MemCache 设计理念就是小而强大,它简单的设计促进了快速 部署、易于开发并解决面对大规模的数据缓存的许多难题,而所开放的 API 使得 MemCache 能用于 Java、C/C++/C#、Perl、Python、PHP、Ruby 等大部分流行的程序语言。 另外,说一下为什么会有 Memcache 和 memcached 两种名称?其实 Memcache 是这个项目 的名称,而 memcached 是它服务器端的主程序文件名
MemCache 的官方网站为 http://memcached.org/
MemCache 一次写缓存的流程:
- 应用程序输入需要写缓存的数据
- API 将 Key 输入路由算法模块,路由算法根据 Key 和 MemCache 集群服务器列表得到一 台服务器编号
- 由服务器编号得到 MemCache 及其的 ip 地址和端口号
- API 调用通信模块和指定编号的服务器通信,将数据写入该服务器,完成一次分布式缓 存的写操作
路由算法:
- 余数算法
简单的路由算法可以使用余数 Hash:用服务器数目和缓存数据 KEY 的 hash 值相除,余数为服务器列表下标编号,假如某个 str 对应的 HashCode 是 52、服务器的数目是 3,取余数得到 1, str 对应节点 Node1,所以路由算法把 str 路由到 Node1 服务器上。由于 HashCode 随机性比 较强,所以使用余数 Hash 路由算法就可以保证缓存数据在整个 MemCache 服务器集群中有 比较均衡的分布。
- 一致性算法
一致性 Hash 算法通过一个叫做一致性 Hash 环的数据结构实现 Key 到缓存服务器的 Hash 映 射
MemCache实现原理:
1、访问数据的速度比传统的关系型数据库要快,因为 Oracle、MySQL 这些传统的关系型数 据库为了保持数据的持久性,数据存放在硬盘中,IO 操作速度慢
2、MemCache 的数据存放在内存中同时意味着只要 MemCache 重启了,数据就会消失
3、既然 MemCache 的数据存放在内存中,那么势必受到机器位数的限制,32 位机器最多只 能使用 2GB 的内存空间,64 位机器可以认为没有上限
Memcache 的工作流程:
- 检查客户端的请求数据是否在 memcached 中,如果有,直接把请求数据返回,不再对数 据库进行任何操作,路径操作为①②③⑦
- 如果请求的数据不在 memcached 中,就去查数据库,把从数据库中获取的数据返回给客 户端,同时把数据缓存一份到 memcached 中(memcached 客户端不负责,需要程序明确实 现),路径操作为①②④⑤⑦⑥。
- 每次更新数据库的同时更新 memcached 中的数据,保证一致性。
- 当分配给 memcached 内存空间用完之后,会使用 LRU(Least Recently Used,最近最少使 用)策略加上到期失效策略,失效数据首先被替换,然后再替换掉最近未使用的数据。
Memcached 特征:
协议简单
基于 libevent 事件处理
内置的内存管理方式
分布式
- centos+nginx+php+memcache+mysql
实验环境:
OS:CentOS Linux release 7.3.1611 (Core)
nginx:nginx-1.14.0.tar.gz
192.168.1.10
PHP+memcache:php-5.6.27.tar.gz+memcache-3.0.8.tgz
192.168.1.20
Memcached: memcached-1.4.33.tar.gz
192.168.1.30
Mysql: mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz
192.168.1.40
1)安装nginx
解决依赖关系:
[[email protected] ~]# yum -y install openssl-devel pcre-devel
解压并编译安装:
[[email protected] ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src/
[[email protected] ~]# cd /usr/src/nginx-1.14.0/
[[email protected] nginx-1.14.0]# ./configure --prefix=/usr/local/nginx1.14 --user=nginx --group=nginx
[[email protected] nginx-1.14.0]# make && make install
优化并启动nginx:
[[email protected] ~]# useradd nginx -s /sbin/nologin -M
[[email protected] ~]# ln -s /usr/local/nginx1.14/sbin/nginx /usr/local/sbin/
[[email protected] ~]# nginx
[[email protected] ~]# netstat -anput | grep 80
2)安装php
安装libmcrypt:
[[email protected] ~]# tar zxf libmcrypt-2.5.7.tar.gz -C /usr/src/
[[email protected] ~]# cd /usr/src/libmcrypt-2.5.7/
[[email protected] libmcrypt-2.5.7]# ./configure --prefix=/usr/local/libmcrypt && make && make install
解决依赖关系:
[[email protected] ~]# yum -y install libxml2-devel libcurl-devel openssl-devel bzip2-devel
解压并编译安装php:
[[email protected] ~]# tar zxf php-5.6.27.tar.gz -C /usr/src/
[[email protected] ~]# cd /usr/src/php-5.6.27/
[[email protected] php-5.6.27]# ./configure --prefix=/usr/local/php5.6 --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-openssl --enable-fpm --enable-sockets --enable-sysvshm --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --with-mhash --with-mcrypt=/usr/local/libmcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2 --enable-maintainer-zts
[[email protected] php-5.6.27]# make && make install
优化并启动php:
[[email protected] php-5.6.27]# cp php.ini-production /etc/php.ini
[[email protected] php-5.6.27]# cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
[[email protected] php-5.6.27]# chmod +x /etc/init.d/php-fpm
[[email protected] php-5.6.27]# chkconfig --add php-fpm
[[email protected] php-5.6.27]# chkconfig php-fpm on
[[email protected] etc]# ln -s /usr/local/php5.6/bin/* /usr/local/bin/
[[email protected] php-5.6.27]# cd /usr/local/php5.6/etc/
[[email protected] etc]# cp php-fpm.conf.default php-fpm.conf
编辑配置文件:
[[email protected] etc]# vim php-fpm.conf
修改如下:
listen = 127.0.0.1:9000--- listen = 0.0.0.0:9000
pm.max_children = 5-- pm.max_children = 300
pm.start_servers = 2-- pm.start_servers = 5
pm.min_spare_servers = 1-- pm.min_spare_servers = 5
pm.max_spare_servers = 3-- pm.max_spare_servers = 35
启动:
[[email protected] etc]# /etc/init.d/php-fpm start
[[email protected] etc]# netstat -anput | grep 9000
3)安装MySQL
使用脚本一键安装:
[[email protected] ~]# sh mysql.sh
4)配置nginx配置文件:
[[email protected] ~]# vim /usr/local/nginx1.14/conf/nginx.conf
去掉注释,并进行修改:
location ~ \.php$ {
root /var/www/html;
fastcgi_pass 192.168.1.20:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
重启nginx:
[[email protected] ~]# nginx -s reload
在php主机上生成一个php测试页:
[[email protected] ~]# mkdir -p /var/www/html
[[email protected] ~]# vim /var/www/html/index.php
<?php
phpinfo();
?>
浏览器访问测试页:
5)安装memcached服务端
安装libevent-2.0.22-stable.tar.gz:
[[email protected] ~]# tar zxf libevent-2.0.22-stable.tar.gz -C /usr/src/
[[email protected] ~]# cd /usr/src/libevent-2.0.22-stable/
[[email protected] libevent-2.0.22-stable]# ./configure && make && make install
安装memcached:
[[email protected] ~]# tar zxf memcached-1.4.33.tar.gz -C /usr/src/
[[email protected] ~]# cd /usr/src/memcached-1.4.33/
[[email protected] memcached-1.4.33]# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local
[[email protected] memcached-1.4.33]# make && make install
检测是否安装成功:
[[email protected] memcached-1.4.33]# ls /usr/local/memcached/bin/memcached
/usr/local/memcached/bin/memcached
优化:
[[email protected] ~]# ln -s /usr/local/memcached/bin/memcached /usr/local/bin/
启动服务:
[[email protected] ~]# memcached -d -m 2048 -l 192.168.1.30 -p 11211 -c 10240 -P /usr/local/memcached/memcached.pid -u root
[[email protected] ~]# netstat -anput | grep 11211
6)安装memcache客户端
memcache 分为服务端和客户端。服务端用来存放缓存,客户端用来操作缓存
[[email protected] ~]# tar zxf memcache-3.0.8.tgz -C /usr/src/
[[email protected] ~]# cd /usr/src/memcache-3.0.8/
[[email protected] memcache-3.0.8]# phpize //使用phpize生成./configure
[[email protected] memcache-3.0.8]# ./configure --enable-memcache --with-php-config=/usr/local/php5.6/bin/php-config
[[email protected] memcache-3.0.8]# make && make install
安装完成后会有提示:
Installing shared extensions: /usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/
将这个添加到php.ini文件的最后一行:
[[email protected] memcache-3.0.8]# vim /etc/php.ini
extension=/usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/memcache.so
重启php:
[[email protected] memcache-3.0.8]# /etc/init.d/php-fpm restart
7)测试:
[[email protected] ~]# vim /var/www/html/test1.php
代码如下:
<?php
$memcache = new Memcache;
$memcache->connect('192.168.1.30', 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);
?>
浏览器访问测试页面:
8)使用 memcache 实现 session 共享(在php主机上操作)
[[email protected] ~]# vim /etc/php.ini
在最后一行写入:
session.save_handler = memcache
session.save_path = "tcp://192.168.1.30:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
测试memcache可用性:
创建测试页:
[[email protected] ~]# vim /var/www/html/test2.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 />";
?>
重启php-fpm:
[[email protected] ~]# /etc/init.d/php-fpm restart
浏览器访问:
根据这个session,在memcached里查询:
安装telnet:(在memcached主机上操作)
[[email protected] ~]# yum -y install telnet
[[email protected] ~]# telnet 192.168.1.30 11211
get hkqo3n53tqcq6sa7v92dk130a5
quit退出
9)memcache服务连接mysql,并测试缓存数据库数据
[[email protected] ~]# mysql -uroot -p
mysql> grant all on *.* to [email protected]'192.168.1.%' identified by '123.com';
mysql> create database testdb1;
mysql> use testdb1;
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;
mysql> insert into test1(name) values ('tom1'),('tom2'),('tom3'),('tom4'),('tom5');
mysql> select * from test1;
在php主机上创建测试脚本文件,测试memcache是否缓存成功:
[[email protected] ~]# vim /var/www/html/test_db.php
脚本内容如下:
<?php
$memcachehost = '192.168.1.30';
$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.1.40","test","123.com");
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 表示 memcached 中没有内容
第二次访问:memcache 标志表示这次的数据是从 memcached 中取得的
查看缓存情况:
[[email protected] ~]# telnet 192.168.1.30 11211
输入stats就能看到
quit退出