LNMP static and dynamic separation && memcache cache server

Bowen outline:
a, MemCache Profile

  • 1, agreement
  • 2, event processing
  • 3, storage
  • 4, communication distribution formula
  • 5, memcached application scenarios
  • 6, memcached application workflow
  • 7, the consistency of memcached Hash algorithm
    II deployment LNMP static and dynamic separation && memcache cache server
  • 1, environment preparation
  • 2, Nginx server deployment
  • 3, the deployment of PHP server
  • 4, MySQL database deployment
  • 5, Memcached server deployment
  • 6, deploy memcache client
  • 7, using memcache achieve shared session
  • 8, test memcached caching database

A, MemCache Profile

MemCache is a free, open-source, high-performance, distributed, distributed memory object caching system, used for dynamic Web applications in order to reduce the load on the database. It is to reduce the number of database read by caching data and objects in memory, thereby increasing the speed of the site visit. MemCaChe is a key-value pairs stored in the HashMap, data (such as strings, objects, etc.) to any memory used in the key-value store, data may be invoked from the database, the API calls, or page rendering results. MemCache design philosophy is small but powerful, its simple design facilitate rapid deployment, ease of development and solve the many problems facing large-scale data cache, and the open API makes MemCache for Java, C / C ++ / C #, Perl , Python, PHP, Ruby, and most popular programming language.
In addition, talk about why there Memcache and memcached two kind of names? In fact, Memcache is the name of the project (also the name of it when a client), but it is memcached server-side main program file name.

memcached is a key / value system, the system MySQL is much simpler, although MySQL also has a cache, but the SQL database of the resolution that is cost performance, query slower than memcached, another MySQL cache designed to be more complicated, because to consider the transaction log relative, storage engine modules, its performance is not good memcached.

memcached only do one thing, simple and efficient, stronger than MySQL in the cache, it should be easy to understand.

memcached distributed cache server as a high-speed operation, has the following characteristics:

  • Agreement simple;
  • Based on the libevent event processing;
  • Built-in memory storage;
  • memcached distributed not communicate with each other.

1, agreement

memcached client communications server does not use the XML format, and use a simple line of text-based protocol.
Therefore, the data can also be stored in memcached on through telnet, to obtain data.

2, event processing

libevent is a library, it will be Linux's epoll, BSD-like operating systems such as event handling kqueue packaged into a unified interface. Even if the number of connections to the server increases, the performance can also play a O (1) is. memcached use the libevent library, it can play its high performance on Linux, BSD, Solaris and other operating systems.

3, storage

To improve performance, the data stored in memcached memcached are stored in the built-in memory storage space. Since the data exists only in memory, thus restart memcached, restart the operating system will cause all data disappear. Further, the content capacity after reaching the predetermined value, it is automatically deleted without the use of the cache based on LRU (Least Recently Used) algorithm. memcached server to cache itself is designed, and therefore did not give much thought to the issue of permanent data.

4, communication distribution formula

Although memcached is "distributed" cache server, but the server is not distributed function. Each memcached not communicate with each other to share information. So, how distributed it? It all depends on the implementation of the client.

5, memcached application scenarios

1) front-end cache database applications: it complicated to share the pressure data, when the data is updated, the program can notify cache update
2) session shared session shared memory

6, memcached application workflow

It is a memory cache, the data can be read in the cache memory by way of the API, when the user needs to read data, memcached will first access the cache if the cache data is directly returned to the front end of the application, if no, forwarded to the back end server, then the server returns data to the user in addition, it will update the data to memcached caching.

If the actual production environment, the cache server need to restart (or off), then the data in the cache will be lost, this time to replace the server will be expanded concurrent pressure may lead to the introduction of server downtime also followed, not to provide services, so when our deal flow is as follows:
first, load balancing application from the WEB stopped in the - - -> make load balancing does not forward the data to the WEB - -> then start the cache server - - - -> through the database program initialized to the contents of the cache server - - - -> then enabled web applications - - - -> restart the database server

7, memcached consistency Hash Algorithm

Consistency Key Hash algorithm by a data structure called a ring of consistency Hash Hash mapping to the cache server. Briefly, consistent hashing the hash value of the entire space into a virtual ring (the cycloalkyl ring is called Hash consistency), the hypothesis space as a space hash function H 0 to 2 ^ 32 1 (i.e., a hash value is a 32-bit unsigned integer), the entire hash space is as follows:

LNMP static and dynamic separation && memcache cache server

The next step for each server using a hash calculation H, specifically using the IP address or host name as a key server, so that each machine can determine its position on the upper ring of the hash, and is clockwise arrangement, where we assume that the three memcache node position calculated as follows:

LNMP static and dynamic separation && memcache cache server

Next, using the same algorithm to calculate a hash value h of the data, and thereby determine the position of the ring on the hash data. If we have data A, B, C, D, 4 objects, after hashing the following positions:

LNMP static and dynamic separation && memcache cache server

根据一致性哈希算法,数据 A 就被绑定到了 server01 上,D 被绑定到了 server02 上,B、C在 server03 上,是按照顺时针找最近服务节点方法。

这样得到的哈希环调度方法,有很高的容错性和可扩展性:
假设 server03 宕机:

LNMP static and dynamic separation && memcache cache server

可以看到此时 C、B 会受到影响,将 B、C 节点被重定位到 Server01。一般的,在一致性哈希算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。
考虑另外一种情况,如果我们在系统中增加一台服务器 Memcached Server 04:

LNMP static and dynamic separation && memcache cache server
此时 A、D、C 不受影响,只有 B 需要重定位到新的 Server04。一般的,在一致性哈希算法中,如果增加一台服务器,则受影响的数据仅仅是新服务器到其环空间中前一台服务器(即顺着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。

综上所述,一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。
一致性哈希的缺点:在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜问题。我们可以采用增加虚拟节点的方式解决。
更重要的是,集群中缓存服务器节点越多,增加/减少节点带来的影响越小,很好理解。换句话说,随着集群规模的增大,继续命中原有缓存数据的概率会越来越大,虽然仍然有小部分数据缓存在服务器中不能被读到,但是这个比例足够小,即使访问数据库,也不会对数据库造成致命的负载压力。

二、部署LNMP动静分离&&memcache缓存服务器

1、环境准备

LNMP static and dynamic separation && memcache cache server

下载我提供的源码包,并将对应的源码包上传至各个服务器。

2、部署Nginx服务器

[root@nginx ~]# yum -y erase httpd     #卸载自带的httpd服务
[root@nginx ~]# yum -y install openssl-devel pcre-devel    #安装所需依赖
[root@nginx ~]# cd /usr/src
[root@nginx src]# rz           #上传Nginx源码包
[root@nginx src]# tar zxf nginx-1.14.0.tar.gz
[root@nginx src]# cd nginx-1.14.0/
[root@nginx nginx-1.14.0]# ./configure --prefix=/usr/local/nginx --user=www --group=www && make && make install
#进行编译安装
[root@nginx nginx-1.14.0]# useradd -M -s /sbin/nologin www   #创建运行用户
[root@nginx nginx-1.14.0]# ln -sf /usr/local/nginx/sbin/nginx /usr/local/sbin/    #对命令做软链接
[root@nginx nginx-1.14.0]# nginx     #启动Nginx服务
[root@nginx nginx-1.14.0]# netstat -anput | grep 80     #确定80端口在监听
#以下是配置nginx与PHP服务器关联
[root@nginx nginx-1.14.0]# cd /usr/local/nginx/conf/
[root@nginx conf]# vim nginx.conf   #编辑主配置文件
#在server{  }字段中添加以下内容
        location ~ \.php$ {            root           /var/www/html;      #指定PHP服务器的网页存放路径   
            fastcgi_pass   192.168.20.3:9000;    #指定PHP服务器监听端口
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi.conf;
        }
#更改完成后,保存退出即可
[root@nginx conf]# nginx -s reload      #重启使更改生效

3、部署PHP服务器

[root@php ~]# rz    #上传源码包libmcrypt及php-5.6.27
[root@php ~]# tar zxf libmcrypt-2.5.7.tar.gz -C /usr/src    #解包
[root@php ~]# tar zxf php-5.6.27.tar.gz -C /usr/src    #解包
[root@php ~]# yum -y install libxml2-devel openssl-devel bzip2-devel    #安装依赖
[root@php ~]# cd /usr/src/libmcrypt-2.5.7       #切换至解压后的路径
[root@php libmcrypt-2.5.7]# ./configure --prefix=/usr/local/libmcrypt && make && make install
#编辑安装
[root@php libmcrypt-2.5.7]# cd ../php-5.6.27/       #进入PHP源码包解压后的路径
[root@php 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 && make && make install
#编译安装PHP
#接下来为调整PHP的配置文件及控制服务的启停
[root@php php-5.6.27]# cp php.ini-production /etc/php.ini    #复制源码中中提供的PHP配置文件
[root@php php-5.6.27]# cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm   #复制其服务控制脚本文件
[root@php php-5.6.27]# chmod +x /etc/init.d/php-fpm    #赋予执行权限
[root@php php-5.6.27]# chkconfig --add php-fpm    #添加为系统服务,以便支持systemctl管理
[root@php php-5.6.27]# chkconfig php-fpm on   #开启
[root@php php-5.6.27]# cp /usr/local/php5.6/etc/php-fpm.conf.default /usr/local/php5.6/etc/php-fpm.conf
#复制php-fpm提供的默认配置文件并编辑它
[root@php php-5.6.27]# vim /usr/local/php5.6/etc/php-fpm.conf     #修改一下,进行优化
listen = 192.168.20.3:9000    #监听地址是本机的IP9000端口
pm.max_children = 50         #最大启动的进程数
pm.start_servers = 5          #初始启动进程数
pm.min_spare_servers = 5     #最小空闲进程
pm.max_spare_servers = 35     #最大空闲进程
#修改完成后,保存退出即可
[root@php php-5.6.27]# systemctl start php-fpm    #启动PHP服务
[root@php php-5.6.27]# netstat -anput | grep php-fpm     #确认其9000端口已启动
[root@php ~]# mkdir -p /var/www/html        #创建其网页存放目录,须和nginx服务器的网页存放路径一样
[root@php php-5.6.27]# vim /var/www/html/index.php     #编写PHP测试页面
<?php
phpinfo();
?>
[root@php php-5.6.27]# vim /var/www/html/index1.php     #连接数据库的测试脚本

<?php
$link=mysqli_connect('192.168.20.5','ljz','pwd@123');
if($link) echo "恭喜你,数据库连接成功!!!"; else echo "connect shibai";
mysqli_close($link);
?>

至此,即可访问Nginx服务器的80端口来查看php服务器上定义的两个网页文件(在访问连接数据库的脚本文件时,需要先部署数据库,并创建用来连接的用户):

访问index.php,看到以下页面说明php运行正常:
LNMP static and dynamic separation && memcache cache server

访问index1.php,看到以下页面,说明LNMP之间的协调工作没有问题(我在访问下面的地址前,已经部署了MySQL数据库,并且创建了相应的用户):

LNMP static and dynamic separation && memcache cache server

4、部署MySQL数据库

我这里部署一个简易的MySQL数据库,提供测试功能即可。

[root@mysql ~]# rz
#上传我提供的mysql.sh脚本文件及mysql-5.7.22-linux.....源码包
[root@mysql ~]# sh mysql.sh              #执行mysql.sh脚本,执行后,需要等待较长时间
Starting MySQL... SUCCESS!    #当出现此提示信息时,则表示MySQL部署成功
mysql: [Warning] Using a password on the command line interface can be insecure.
#安装MySQL成功后,默认的数据库root密码为123
[root@mysql ~]# mysql -uroot -p123    #登录MySQL数据库
mysql> create database bbs;
mysql> grant all on bbs.* to ljz@"192.168.20.%" identified by 'pwwd@123';

5、部署Memcached服务器

[root@mamcache ~]# cd /usr/src       #切换至指定目录
[root@mamcache src]# rz             #上传所需源码包
[root@mamcache src]# ls       #就是上传以下的后面两个源码包
debug  kernels  libevent-2.0.22-stable.tar.gz  memcached-1.4.33.tar.gz
[root@mamcache src]# tar zxf libevent-2.0.22-stable.tar.gz       #解包
[root@mamcache src]# tar zxf memcached-1.4.33.tar.gz       #解包
[root@mamcache src]# cd libevent-2.0.22-stable/     #切换至解压后的目录
[root@mamcache libevent-2.0.22-stable]# ./configure && make && make install     #编译安装
[root@mamcache libevent-2.0.22-stable]# cd ../memcached-1.4.33/    #切换至memcached目录
[root@mamcache memcached-1.4.33]# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/local && make && make install
#编译安装
[root@mamcache ~]# ls /usr/local/memcached/bin/memcached          #确认该命令已安装
/usr/local/memcached/bin/memcached
[root@mamcache ~]# ln -sf /usr/local/memcached/bin/memcached /usr/local/bin/    #对命令做软链接
[root@memcache memcached-1.4.33]# memcached -d -m 1024 -l 192.168.20.4 -p 11211 -u root -c 10240 -P /usr/local/memcached/memcached.pid
#启动memcached服务,上述启动参数说明如下:
# -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@mamcache ~]# netstat -anput | grep 11211         #确定TCP及udp端口在监听

6、部署memcache客户端(返回到PHP服务器进行配置)

[root@php ~]# cd /usr/src
[root@php src]# rz   #上传memcache-3.0.8.tgz源码包
[root@php src]# tar zxf memcache-3.0.8.tgz     #解包
[root@php src]# cd memcache-3.0.8/     #进入解压后的目录
[root@php memcache-3.0.8]# /usr/local/php5.6/bin/phpize    #生成该命令,以便生成configure文件
#若在执行上述命令时报错,则需要执行“yun -y install autoconf "安装提示的autoconf包。
[root@php memcache-3.0.8]#  ./configure --enable-memcache --with-php-config=/usr/local/php5.6/bin/php-config && make && make install
#上述命令执行后,会显示memcache.so存放的路径
[root@php memcache-3.0.8]# vim /etc/php.ini   #编辑主配置文件
#在配置文件末尾添加上述内容,以便指定memcache.so文件的存放路径
extension = /usr/local/php5.6/lib/php/extensions/no-debug-zts-20131226/memcache.so
[root@php memcache-3.0.8]# systemctl restart php-fpm   #重启php服务,使更改生效
[root@php memcache-3.0.8]# cd /var/www/html/
[root@php html]# vim test3.php       #编写测试文件

<?php
$memcache = new Memcache;
$memcache->connect('192.168.20.4', 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, 600) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 600 seconds)<br/>";
$get_result = $memcache->get('key');
echo "Data from the cache:<br/>";
var_dump($get_result);
?>
#编辑完成后,保存退出即可,此测试脚本是显示memcached的版本
#并且向里面插入了一个缓存时间为600秒的键值对“test=123”,其ID为“key”

客户端访问编辑的test3.php文件,会看到以下内容:
LNMP static and dynamic separation && memcache cache server

在memcached服务器上安装Telnet命令,并登陆缓存库,查看是否可以得到其键值对(以下操作在memcached服务器上进行操作):

[root@memcache ~]# yum -y install telnet           #安装Telnet命令
[root@memcache ~]# telnet 192.168.20.4 11211    #登陆到memcached的11211端口
get key         #查询ID为“key”的键值对,可以看到我们测试脚本写入的“test=123”
VALUE key 1 66
O:8:"stdClass":2:{s:8:"str_attr";s:4:"test";s:8:"int_attr";i:123;}
END
#在进行上面的get验证时,需要将test3.php文件中插入的键值对的保存时间值改大一些
#或者重新访问一下,以免缓存失效,查询不到

至此,LNMP动静分离&&memcache缓存服务器已经基本部署完成,接下来,配置PHP与memcached服务器沟通保存session会话

7、使用 memcache 实现 session 共享(在PHP服务器进行以下操作)

接下来实现PHP与memcached服务器沟通保存session会话。

[root@php ~]# vim /etc/php.ini      #在配置文件末尾添加下面内容
ession.save_handler = memcache
session.save_path = "tcp://192.168.20.4:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
#注上面写入的内容解释如下:
# session.save_handler:设置 session 的储存方式为 memcache 。
#默认以文件方式存取 session数据。
#session.save_path: 设置 session 储存的位置
#使用多个 memcached server 时用逗号”,”隔开,
#可以带额外的参数”persistent”、”weight”、”timeout”、”retry_interval”等等,
#类似这样的:"tcp://host:port?persistent=1&weight=2,tcp://host2:port2"。
[root@php html]# systemctl restart php-fpm     #重启使更改生效
[root@php html]# 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 />";
?>
#编写完成后,保存退出即可

客户端访问编写的test2.php测试文件,如下:

LNMP static and dynamic separation && memcache cache server

同样,使用Telnet命令在memcached服务器上进行查询其session_id的值,如下:

[root@memcache ~]# telnet 192.168.20.4 11211     #登录缓存监听的端口
get naapo2eet2d9s4to4mt7hchnr1            #执行get命令
VALUE naapo2eet2d9s4to4mt7hchnr1 0 26
session_time|i:1572450021;
#可以看到,查询到的session_time和我们网页访问到的值是一样的,说明其被缓存了

8、测试memcached缓存数据库

在MySQL数据库上创建用于测试的表(所有操作都在MySQL数据库上)如下:

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;
#创建表,共两列,分别是ID号和姓名
mysql> insert into test1(name) values ('tom1'),('tom2'),('tom3'),('tom4'),('tom5');
#向表中插入测试数据
mysql> select * from test1;   #确定插入的数据
+----+------+
| id | name |
+----+------+
|  1 | tom1 |
|  2 | tom2 |
|  3 | tom3 |
|  4 | tom4 |
|  5 | tom5 |
+----+------+
5 rows in set (0.00 sec)
mysql> desc test1;         #可以执行此语句查看test1的表结构
mysql> grant select on testdb1.* to user@'%' identified by 'pwd@123';
#对test1表创建一个只读的数据库用户,用于接下来的测试

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

在PHP服务器上编写以下测试文件:

客户端访问用于测试的脚本文件,第一次访问的页面如下:
LNMP static and dynamic separation && memcache cache server

客户端刷新后,会看到以下页面:

LNMP static and dynamic separation && memcache cache server

在查询到的缓存过期前,可以在memcache上通过get 获取到对应的缓存数据,如下(在memcache服务器上进行操作):

[root@memcache ~]# telnet 192.168.20.4 11211     #登录缓存监听的端口
get d8c961e9895ba4b463841924dbcefc2b       #执行get命令
VALUE d8c961e9895ba4b463841924dbcefc2b 0 251
a:5:{i:0;a:2:{s:2:"id";s:1:"1";s:4:"name";s:4:"tom1";}i:1;a:2:{s:2:"id";s:1:"2";s:4:"name";s:4:"tom2";}i:2;a:2:{s:2:"id";s:1:"3";s:4:"name";s:4:"tom3";}i:3;a:2:{s:2:"id";s:1:"4";s:4:"name";s:4:"tom4";}i:4;a:2:{s:2:"id";s:1:"5";s:4:"name";s:4:"tom5";}}

———————— 本文至此结束,感谢阅读 ————————

Guess you like

Origin blog.51cto.com/14154700/2446652