redis做mysql的缓存前移(lnmp架构下)

  • client -> app -> redis -> mysql(如果在redis找不到再访问mysql) -> redis -> client
    实验环境:
    server1-------->php,nginx服务
    server2-------->redis的master端
    server3-------->mysql

配置:

  • server1配置
  1. 安装软件包,整个实验所需的包我都已经下载好了,现在全都安装。
[root@server1 ~]# killall redis-server	#如果做过其他redis实验,需要先停掉
[root@server1 ~]# cd rhel7/
[root@server1 rhel7]# ls
gearmand-1.1.12-18.el7.x86_64.rpm
libevent-devel-2.0.21-4.el7.x86_64.rpm
libgearman-1.1.12-18.el7.x86_64.rpm
libgearman-devel-1.1.12-18.el7.x86_64.rpm
libzip-0.10.1-8.el7.x86_64.rpm
openssl-1.0.2k-16.el7.x86_64.rpm
openssl-libs-1.0.2k-16.el7.x86_64.rpm
php-cli-5.4.16-46.el7.x86_64.rpm
php-common-5.4.16-46.el7.x86_64.rpm
php-fpm-5.4.16-46.el7.x86_64.rpm
php-mysql-5.4.16-46.el7.x86_64.rpm
php-pdo-5.4.16-46.el7.x86_64.rpm
php-pecl-gearman-1.1.2-1.el7.x86_64.rpm
php-pecl-igbinary-1.2.1-1.el7.x86_64.rpm
php-pecl-redis-2.2.8-1.el7.x86_64.rpm
php-process-5.4.16-46.el7.x86_64.rpm
php-xml-5.4.16-46.el7.x86_64.rpm
[root@server1 rhel7]# yum install -y *
  1. 开启php,并查看端口
[root@server1 nginx-1.16.0]# systemctl start php-fpm
  1. 安装nginx

安装过程本文不再讲解了,可参考https://blog.csdn.net/weixin_43273168/article/details/89668619

  • 更改配置文件
[root@server1 nginx-1.16.0]# vim /usr/local/nginx/conf/nginx.conf

        location / {
            root   html;
            index  index.php index.html index.htm;	#添加index.php
        }
        
        #打开php模块
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi.conf;
        }
  • 检测脚本是否正确,并开启nginx
[root@server1 nginx-1.16.0]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server1 nginx-1.16.0]# /usr/local/nginx/sbin/nginx 
  • 测试
    在这里插入图片描述
    端口正常
    在这里插入图片描述
    访问到nginx的默认页面,nginx服务正常
  1. 将写好的php测试页放在 /usr/local/nginx/html/
[root@server1 html]# ls
50x.html  index.html  index.php
[root@server1 html]# vim index.php 
<?php
        $redis = new Redis();
        $redis->connect('172.25.254.2',6379) or die ("could net connect redis server");	#指向redis
  #      $query = "select * from test limit 9";
        $query = "select * from test";
        for ($key = 1; $key < 10; $key++)
        {
                if (!$redis->get($key))
                {
                        $connect = mysql_connect('172.25.254.3','redis','westos');	#指向mysql
                        mysql_select_db(test);
                        $result = mysql_query($query);
                        //如果没有找到$key,就将该查询sql的结果缓存到redis
                        while ($row = mysql_fetch_assoc($result))
                        {
                                $redis->set($row['id'],$row['name']);
                        }
                        $myserver = 'mysql';
                        break;
                }
                else
                {
                        $myserver = "redis";
                        $data[$key] = $redis->get($key);
                }
        }

        echo $myserver;
        echo "<br>";
        for ($key = 1; $key < 10; $key++)
        {
                echo "number is <b><font color=#FF0000>$key</font></b>";
                                                                                                                                    1,1           Top
                echo "<br>";

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

                echo "<br>";
        }
?>            

再次访问nginx服务器(显示没有redis server,是因为我们还没有配置))
在这里插入图片描述

  • server2配置redis master
  1. 下载安装包,并解压,编译安装
[root@server2 ~]# ls
redis-5.0.3.tar.gz
[root@server2 ~]# tar zxf redis-5.0.3.tar.gz 
[root@server2 ~]# cd redis-5.0.3
[root@server2 redis-5.0.3]# yum install gcc -y
[root@server2 redis-5.0.3]# make && make install
[root@server2 redis-5.0.3]# cd utils/
[root@server2 utils]# ./install_server.sh 

此时netstat -antlp会出现6379端口
在这里插入图片描述
2. 编辑配置文件

[root@server2 utils]# vim /etc/redis/6379.conf
  70 bind 0.0.0.0    
[root@server2 utils]# /etc/init.d/redis_6379 start
  • server3 配置mysql
  1. 实验数据比较简单,所以安装系统自带的mariadb就可以了。
[root@server3 ~]# yum install mariadb-server -y
[root@server3 ~]# systemctl start mariadb
[root@server3 ~]# mysql_secure_installation
测试需求,我们登录mysql数据库建立test库

在这里插入图片描述

  1. 创建授权用户,并刷洗授权表
[root@server3 ~]# mysql -p
Enter password: 
MariaDB [(none)]> grant all on test.*  to redis@'%' identified by 'westos';
MariaDB [(none)]>  flush privileges;
  1. 导入测试库
[root@server3 ~]# vim test.sql 
use test;
CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9');

#DELIMITER $$
#CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN
#    SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
#  END$$
#DELIMITER ;
~               
[root@server3 ~]# mysql -pwestos < test.sql 
  • 测试
    浏览器访问nginx服务器
    第一次访问是从mysql中找数据
    在这里插入图片描述
    第二次访问就是从redis中读取数据了
    在这里插入图片描述

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

那么我们该如何实现将mysql端修改的数据及时更新到redis端呢?所以接下来就要通过 mysql 触发器将改变的数据同步到 redis
中。

配置 gearman 实现数据同步

Gearman介绍:

  • Gearman 是一个支持分布式的任务分发框架:
  • Gearman Job Server:Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。
  • Gearman Client:可以理解为任务的请求者。
  • Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。

大致流程:

  • 下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。修改表,插入表就相当于直接下发任务。然后通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式,然后在通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中,最后通过redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新。

配置过程

  • mysql (client) -> gearmand:4730(job server) -> worker(php/python/java)
  • client
  1. 安装 lib_mysqludf_json
[root@server3 ~]# unzip lib_mysqludf_json-master.zip 
[root@server3 lib_mysqludf_json-master]# yum install gcc mariadb-devel -y
[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

[root@server3 lib_mysqludf_json-master]# cd /usr/lib64/mysql/
[root@server3 mysql]# ls
INFO_BIN  libmysqlclient_r.so  libmysqlclient.so.18      mysqlbug      plugin
INFO_SRC  libmysqlclient.so    libmysqlclient.so.18.0.0  mysql_config
[root@server3 ~]# cp lib_mysqludf_json-master/lib_mysqludf_json.so /usr/lib64/mysql/plugin/
  1. 安装 gearman 软件包,并安装 php 的 gearman 扩展
[root@server3 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz 
[root@server3 ~]# yum install -y libevent-devel-2.0.21-4.el7.x86_64.rpm libgearman-1.1.12-18.el7.x86_64.rpm libgearman-devel-1.1.12-18.el7.x86_64.rpm 
[root@server3 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/ --with-mysql 
[root@server3 gearman-mysql-udf-0.6]# make 
[root@server3 gearman-mysql-udf-0.6]# make install

查看 mysql 的模块目录
在这里插入图片描述
3. 注册 UDF 函数

  • 注册json函数
    在这里插入图片描述
  • 注册 UDF 函数
MariaDB [(none)]> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)

##查看函数
MariaDB [(none)]> select * from mysql.func; 
+--------------------+-----+-------------------------+----------+
| name               | ret | dl                      | type     |
+--------------------+-----+-------------------------+----------+
| json_object        |   0 | lib_mysqludf_json.so    | function |
| gman_do_background |   0 | libgearman_mysql_udf.so | function |
| gman_servers_set   |   0 | libgearman_mysql_udf.so | function |
+--------------------+-----+-------------------------+----------+
3 rows in set (0.00 sec)

##指定 gearman 的服务信息
MariaDB [(none)]> SELECT gman_servers_set('172.25.254.1:4730'); 
+---------------------------------------+
| gman_servers_set('172.25.254.1:4730') |
+---------------------------------------+
| 172.25.254.1:4730                     |
+---------------------------------------+
  1. 编写 mysql 触发器(根据实际情况编写)
[root@server3 ~]# vim test.sql
use test;
DELIMITER $$
CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN
    SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`)); 
  END$$
DELIMITER ;
[root@server3 ~]# mysql -pwestos < test.sql
  • 查看触发器
    在这里插入图片描述
  • worker
  1. 打开gearmand
[root@server1 rhel7]# systemctl start gearmand
[root@server1 rhel7]# netstat -antlp

在这里插入图片描述
6. 编写 gearman 的 worker 端

[root@server1 ~]# vim /usr/local/worker.php 
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');

$redis = new Redis();
$redis->connect('172.25.254.2', 6379);

while($worker->work());
function syncToRedis($job)
{
        global $redis;
        $workString = $job->workload();
        $work = json_decode($workString);
        if(!isset($work->id)){
                return false;
        }
        $redis->set($work->id, $work->name);
}
?>
  • 后台运行 worker
[root@server1 ~]# nohup php /usr/local/worker.php &> /dev/null &
[1] 5605
  • 测试
  • 更新数据库信息
    在这里插入图片描述
  • redis端查看
    在这里插入图片描述
  • 浏览器查看
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43273168/article/details/90209911