运维项目实训—基于Redis缓存数据库实现lnmp架构高速访问

一、Redis作mysql缓存服务器

redis 是一个高性能的 key-value 数据库。

1.redis 的出现,很大程度弥补了memcached 这类 key-value 存储的不足(只能存入内存).

2.它支持的数据类型比memcache多,包括了 Python,Ruby,Erlang,PHP 客户端…

3.Redis 的所有数据都是保存在内存中,两种同步模式

    A>半持久化模式:RDB(全量同步)

            i>RDB是Redis默认同步方式

            ii>不定期的通过异步方式保存到磁盘上,快照最终结果( 快照二进制文件为dump.rdb)

            iii>在恢复大数据集时的速度比 AOF 的恢复速度要快。

    B>全持久化模式:(增量同步)

            i>把每一次数据变化都写入到一个 append only file(aof)里面.

            ii>没有RDB同步的快,但采用了高并发机制,对系统内存要求高.

            iii>使用方式

                #appendfsync always实时同步

                appendfsync everysec每秒同步(推荐使用)

                # appendfsync no

    一般两种模式结合使用.

4.只保证最终数据一致性,适用于微博粉丝,秒杀,抢红包等场景,微博粉丝数量,一会儿加一减一的,要是这么微量但高频率的变化,每次都要写到数据库里,那数据库的负担就太重了。

详细配置如下:
实验环境:rhel6.5
server1:172.25.51.1(php)
server2:172.25.51.2(mysql)
server3:172.25.51.3(redis缓存)

实验步骤:

1.安装php的redis扩展

[root@server1 ~]# cd redis/
[root@server1 redis]# yum install -y php-*

这里写图片描述

[root@server1 redis]# cd /etc/php-fpm.d
[root@server1 php-fpm.d]# id nginx
uid=498(nginx) gid=499(nginx) groups=499(nginx)
[root@server1 php-fpm.d]# vim www.conf 
 39 user = nginx
 41 group = nginx
[root@server1 php-fpm.d]# vim /etc/php.ini 
 946 date.timezone = Asia/Shanghai     ##时区
[root@server1 php-fpm.d]# /etc/init.d/php-fpm start

这里写图片描述

2.安装并配置nginx

[root@server1 redis]# rpm -ivh nginx-1.8.0-1.el6.ngx.x86_64.rpm 
[root@server1 ~]# cd /etc/nginx/conf.d/
[root@server1 conf.d]# vim default.conf
 10         index  index.php index.html index.htm;

 30     location ~ \.php$ {
 31         root           html;
 32         fastcgi_pass   127.0.0.1:9000;
 33         fastcgi_index  index.php;
 34         fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;
 35         include        fastcgi_params;
 36     }
[root@server1 conf.d]# /etc/init.d/nginx start

这里写图片描述
这里写图片描述

[root@server1 conf.d]# cd /usr/share/nginx/html/
[root@server1 html]# vim index.php
<?php
phpinfo()
?>
[root@server1 conf.d]# /etc/init.d/nginx reload

物理机访问172.25.51.1
这里写图片描述

3.创建php测试页

[root@server1 ~]# cd redis/
[root@server1 redis]# cp test.php /usr/share/nginx/html/
[root@server1 redis]# cd /usr/share/nginx/html/
[root@server1 html]# vim test.php 
  3         $redis->connect('172.25.51.3',6379) or die ("could net connect redis server");
 10                         $connect = mysql_connect('172.25.51.2','redis','westos');

这里写图片描述
这里写图片描述
4.添加php支持的redis

[root@server1 ~]# cd redis/
[root@server1 redis]# unzip phpredis-master.zip 
[root@server1 redis]# cd phpredis-master
[root@server1 phpredis-master]# phpize
[root@server1 phpredis-master]# ./configure
[root@server1 phpredis-master]# make
[root@server1 phpredis-master]# make install
[root@server1 ~]# cd /etc/php.d/
[root@server1 php.d]# cp mysql.ini redis.ini
[root@server1 php.d]# vim redis.ini
extension=redis.so                             #加载 redis 模块
[root@server1 php.d]# /etc/init.d/php-fpm reload
[root@server1 php.d]# php -m|grep redis
redis

这里写图片描述
5.配置mysql

[root@server1 redis]# scp test.sql server2:
[root@server2 ~]# rpm -qa|grep mysql;
mysql-community-common-5.7.17-1.el6.x86_64
mysql-community-client-5.7.17-1.el6.x86_64
mysql-community-libs-compat-5.7.17-1.el6.x86_64
mysql-community-libs-5.7.17-1.el6.x86_64
mysql-community-server-5.7.17-1.el6.x86_64
mha4mysql-node-0.56-0.el6.noarch
[root@server2 ~]# rpm -e `rpm -qa|grep mysql` --nodeps  ##无依赖性
[root@server2 ~]# rpm -qa|grep mysql;
[root@server2 ~]# cd /var/lib/mysql/
[root@server2 mysql]# rm -fr *
[root@server2 ~]# yum install -y mysql-server
[root@server2 ~]# /etc/init.d/mysqld start
[root@server2 ~]# ls
test.sql
[root@server2 ~]# mysql < test.sql 
mysql> grant all on test.* to redis@'%' identified by 'westos';

这里写图片描述

测试:访问172.25.51.1/test.php

1.php默认从redis索取数据,第一次redis无缓存,则php从数据库索取数据
这里写图片描述
2.将数据库server2节点内容更新并删除节点,则php从数据库索取数据
节点内容更新

mysql> use test;
mysql> update test set name='westos' where id=1;

redis的master主机删除节点内容

[root@server3 ~]# redis-cli 
127.0.0.1:6379> del 1
(integer) 1
127.0.0.1:6379> get 1
(nil)

刷新页面,再次访问172.25.51.1/test.php
这里写图片描述


以上redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情况。

二、mysql和redis触发数据同步

mysql 触发器+gearman+php.worker

接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。
因为mysql和redis数据格式不同,不能实现直接同步,所以将MySQL数据首先放入Gearman中,然后通过一个自己编写的PHP+Gearman+Worker,将数据同步到Redis。


Gearman 是一个支持分布式的任务分发框架:

Gearman Job Server: Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。

Gearman Client:可以理解为任务的请求者。

Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行.

Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。

大致流程:

1)下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。

2)修改表,插入表就相当于直接下发任务。

3)再通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式

4)再通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中

5)最后通过redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新。

详细配置如下:
1.php装载gearman插件
[root@server1 ~]# cd redis/
[root@server1 redis]# yum install -y gearmand-1.1.8-2.el6.x86_64.rpm libgearman-* libevent-* 
[root@server1 redis]# /etc/init.d/gearmand start

这里写图片描述

[root@server1 redis]# tar zxf gearman-1.1.2.tgz 
[root@server1 redis]# cd gearman-1.1.2
[root@server1 gearman-1.1.2]# phpize
[root@server1 gearman-1.1.2]# ./configure
[root@server1 gearman-1.1.2]# make && make install
[root@server1 gearman-1.1.2]# cd /etc/php.d
[root@server1 php.d]# cp redis.ini gearman.ini
[root@server1 php.d]# vim gearman.ini 
extension=gearman.so
[root@server1 php.d]# /etc/init.d/php-fpm reload
gearman
mysql
redis

这里写图片描述


[root@server1 redis]# vim worker.php 
 7 $redis->connect('172.25.51.3', 6379);     ##master的ip
[root@server1 redis]# cp worker.php /usr/local/
[root@server1 redis]# nohup php /usr/local/worker.php &

这里写图片描述

2.将server1的部分安装包拷贝给server2
[root@server1 redis]# scp lib_mysqludf_json-master.zip gearman-mysql-udf-0.6.tar.gz server2:
[root@server1 redis]# scp libevent-* server2:
[root@server1 redis]# scp libgearman-* server2:
3.生成lib_mysqludf_json.so模块
[root@server2 ~]# yum install -y mysql-devel
[root@server2 ~]# yum install -y gcc
[root@server2 ~]# unzip lib_mysqludf_json-master.zip 
[root@server2 ~]# cd lib_mysqludf_json-master
[root@server2 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
[root@server2 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
4.注册 json 函数
[root@server2 ~]# mysql
mysql> show global variables like 'plugin_dir';
mysql> create function json_object returns string soname 'lib_mysqludf_json.so';
mysql> select * from mysql.func;

这里写图片描述

5.注册UDF函数
[root@server2 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz 
[root@server2 ~]# cd gearman-mysql-udf-0.6
[root@server2 ~]# yum install -y libgearman-*
[root@server2 ~]# yum install libevent-* -y
[root@server2 ~]# cd gearman-mysql-udf-0.6
[root@server2 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/
[root@server2 gearman-mysql-udf-0.6]# make
[root@server2 gearman-mysql-udf-0.6]# make install
[root@server2 gearman-mysql-udf-0.6]# cd /usr/lib64/mysql/plugin/
[root@server2 plugin]# ll libgearman_mysql_udf.so
lrwxrwxrwx 1 root root 29 Jul 11 15:50 libgearman_mysql_udf.so -> libgearman_mysql_udf.so.0.0.0
[root@server2 ~]# mysql
mysql> create function gman_do_background returns string soname 'libgearman_mysql_udf.so';
mysql> create function gman_servers_set returns string soname 'libgearman_mysql_udf.so';
mysql> select * from mysql.func;

这里写图片描述

6.指定 gearman 的服务信息
mysql> select gman_servers_set('172.25.51.1:4730');

这里写图片描述

7.编写 mysql 触发器
[root@server2 ~]# vim test.sql   
[root@server2 ~]# mysql < test.sql 

这里写图片描述

8.查看触发器
[root@server2 ~]# mysql
mysql> show triggers from test;

这里写图片描述

测试:Server2
mysql> update test set name='redhat' where id=1;

这里写图片描述

mysql> update test set name='test1' where id=1;

这里写图片描述

猜你喜欢

转载自blog.csdn.net/hannah_zh/article/details/81006684