利用Gearman使redis做mysql 的缓存服务器(lnmp架构)

秒杀系统,先存储在内存中,等高峰过去之后,在将数据存入数据库中

实验环境

server3(172.25.34.4)安装nginx PHP
server4(172.25.34.5)安装Redis
server5(172.25.34.6)安装mariadb

redis结合lnmp架构做mysql 的缓存服务器

server3:

上篇实验中的集群节点服务都关掉

[root@server3 nginx-1.17.4]# killall redis-server 

安装nginx:

[root@server3 ~]# tar zxf nginx-1.17.4.tar.gz 
[root@server3 ~]# cd nginx-1.17.4
[root@server3 nginx-1.17.4]# ls
auto     CHANGES.ru  configure  html     man     src
CHANGES  conf        contrib    LICENSE  README
[root@server3 nginx-1.17.4]# vi auto/cc/gcc
# debug
#CFLAGS="$CFLAGS -g"
[root@server3 nginx-1.17.4]# yum install pcre-devel  zlib-devel -y
[root@server3 nginx-1.17.4]# ./configure  --prefix=/usr/local/nginx
[root@server3 rhel7]# make && make install

安装php

[root@server3 ~]# cd rhel7
[root@server3 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@server3 rhel7]# yum install * -y

编辑nginx的配置文件

root@server3 rhel7]# cd
[root@server3 ~]# cd nginx-1.17.4/conf
[root@server3 conf]# vi nginx.conf 
 2 user  nginx nginx;
 43         location / {
     44             root   html;
     45             index  index.php index.html index.htm;
     46         }
  65         location ~ \.php$ {
     66             root           html;
     67             fastcgi_pass   127.0.0.1:9000;
     68             fastcgi_index  index.php;
     69         #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
     70             include        fastcgi.conf;
     71         }
[root@server1 conf]# /usr/local/nginx/sbin/nginx -t
[root@server3 conf]# useradd nginx

开启nginx php 查看端口

[root@server3 conf]# /usr/local/nginx/sbin/nginx
[root@server3 conf]# systemctl start php-fpm
[root@server3 conf]# netstat -antuple
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          31086      7842/nginx: master  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          14167      629/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      0          15356      874/master          
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      0          31245      7850/php-fpm: maste 
[root@server3 ~]# ls
gearman-mysql-udf-0.6.tar.gz  nginx-1.17.4         redis-5.0.3.tar.gz  test.php
lib_mysqludf_json-master.zip  nginx-1.17.4.tar.gz  rhel6 Redis.pdf     test.sql
mysql                         redis-5.0.3          rhel7               worker.php
[root@server3 ~]# mv test.php /usr/local/nginx/html/
[root@server3 ~]# cd /usr/local/nginx/html/
[root@server3 html]# ls
50x.html  index.html  test.php
[root@server3 html]# mv test.php index.php
[root@server3 html]# vi index.php 
1 <?php
  2         $redis = new Redis();
  3         $redis->connect('172.25.34.5',6379) or die ("could net connect redis     server");   ##指向redis
  4   #      $query = "select * from test limit 9";
  5         $query = "select * from test";
  6         for ($key = 1; $key < 10; $key++)
  7         {
  8                 if (!$redis->get($key))
  9                 {
 10                         $connect = mysql_connect('172.25.34.6','redis','west    os');   ##指向数据库

server4:

安装redis

下载安装包,并解压
[root@server4 ~]# ls
redis-5.0.3.tar.gz
[root@server4 ~]# tar zxf redis-5.0.3.tar.gz 

安装依赖包,并编译安装
[root@server4 ~]# cd redis-5.0.3
[root@server4 redis-5.0.3]# yum install gcc -y
[root@server4 redis-5.0.3]# make && make install


执行redis安装脚本
[root@server2 redis-5.0.3]# cd utils/
[root@server2 utils]# ./install_server.sh 

此时netstat -antlp会出现6379端口

编辑配置文件

[root@server2 utils]# vim /etc/redis/6379.conf
  70 bind 0.0.0.0    
[root@server2 utils]# /etc/init.d/redis_6379 start

server5:

配置mysql端

安装rhel7.3自带数据库即可

如果之前安装过mysql数据库,先卸载数据库
[root@server5 ~]# rpm -aq | grep mysql
mysql-community-common-5.7.24-1.el7.x86_64
mysql-community-client-5.7.24-1.el7.x86_64
mysql-community-server-5.7.24-1.el7.x86_64
mha4mysql-node-0.58-0.el7.centos.noarch
mysql-community-libs-5.7.24-1.el7.x86_64
mysql-community-libs-compat-5.7.24-1.el7.x86_64
[root@server5 ~]# rpm -e `rpm -aq | grep mysql` --nodeps ##清除mysql数据库
warning: /etc/my.cnf saved as /etc/my.cnf.rpmsave

安装mariadb
[root@server5 utils]# yum install mariadb-server -y
[root@server5 mysql]# systemctl start mariadb
[root@server5 mysql]# mysql_secure_installation 
MariaDB [(none)]> create database test;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> grant all on test.* to redis@'%' identified by 'westos';
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> flush privileges;
Query OK, 0 rows affected (0.00 sec)


[root@server5 ~]# cd redis
[root@server5 redis]# ls
gearman-mysql-udf-0.6.tar.gz  redis-5.0.3.tar.gz  rhel7     test.sql
lib_mysqludf_json-master.zip  rhel6 Redis.pdf     test.php  worker.php
[root@server5 redis]# 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@server5 redis]# mysql -pwestos < test.sql 导入测试库


[root@server5 ~]# mysql -p
MariaDB [(none)]> grant all on test.*  to redis@'%' identified by 'westos'; ##授权用户
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [test]> select * from test;
+----+-------+
| id | name  |
+----+-------+
|  1 | test1 |
|  2 | test2 |
|  3 | test3 |
|  4 | test4 |
|  5 | test5 |
|  6 | test6 |
|  7 | test7 |
|  8 | test8 |
|  9 | test9 |
+----+-------+

测试

浏览器访问

在这里插入图片描述
刷新
在这里插入图片描述
第一次访问到的是数据库mariadb中的数据,然后刷新后是redis

server4:

[root@server4 ~]# redis-cli
127.0.0.1:6379> get 1
"test1"

如何同步数据修改

server5:

MariaDB [(none)]> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [test]> update test set name='westos' where id=1; #修改数据
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [test]> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | westos |
|  2 | test2  |
|  3 | test3  |
|  4 | test4  |
|  5 | test5  |
|  6 | test6  |
|  7 | test7  |
|  8 | test8  |
|  9 | test9  |
+----+--------+
9 rows in set (0.00 sec)

server4:

查看Redis数据库上存储的数据发现并未改变

[root@server4 ~]# redis-cli
127.0.0.1:6379> get 1
"test1"

在mysql端修改的数据没有进行同步,说明数据是在redis端取得

到这里,我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情况。
那么我们该如何实现将mysql端修改的数据及时更新到redis端呢?所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中

配置 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)

server5:

安装 lib_mysqludf_json

[root@server5 redis]# ls
gearman-mysql-udf-0.6.tar.gz  redis-5.0.3.tar.gz  rhel7     test.sql
lib_mysqludf_json-master.zip  rhel6 Redis.pdf     test.php  worker.php
[root@server5 redis]# unzip lib_mysqludf_json-master.zip 
Archive:  lib_mysqludf_json-master.zip
37f851c808c4161beb4d5e535771dc0c59c82de6
   creating: lib_mysqludf_json-master/
  inflating: lib_mysqludf_json-master/README.md  
  inflating: lib_mysqludf_json-master/lib_mysqludf_json.c  
  inflating: lib_mysqludf_json-master/lib_mysqludf_json.html  
  inflating: lib_mysqludf_json-master/lib_mysqludf_json.so  
  inflating: lib_mysqludf_json-master/lib_mysqludf_json.sql  


[root@server5 redis]# cd lib_mysqludf_json-master
[root@server5 lib_mysqludf_json-master]# ls
lib_mysqludf_json.c     lib_mysqludf_json.so   README.md
lib_mysqludf_json.html  lib_mysqludf_json.sql
[root@server5 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

[root@server5 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/


安装 gearman 软件包,并.安装 php 的 gearman 扩展

[root@server5 lib_mysqludf_json-master]# cd ..
[root@server5 redis]# ls
gearman-mysql-udf-0.6.tar.gz  redis-5.0.3.tar.gz  test.php
lib_mysqludf_json-master      rhel6 Redis.pdf     test.sql
lib_mysqludf_json-master.zip  rhel7               worker.php
[root@server5 redis]# tar zxf gearman-mysql-udf-0.6.tar.gz 
[root@server5 redis]# cd gearman-mysql-udf-0.6
[root@server5 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@server5 rhel7]# yum install libevent-devel-2.0.21-4.el7.x86_64.rpm libgearman-*


[root@server5 redis]# cd ../gearman-mysql-udf-0.6
[root@server5 gearman-mysql-udf-0.6]# ./configure  --libdir=/usr/lib64/mysql/plugin/ --with-mysql
[root@server5 gearman-mysql-udf-0.6]# make && make install

[root@server3 ~]# mysql -p 
MariaDB [(none)]> CREATE FUNCTION gman_do_background RETURNS STRING SONAME
    -> 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.01 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.19.1:4730');   
+--------------------------------------+
| gman_servers_set('172.25.19.1:4730') |
+--------------------------------------+
| 172.25.19.1:4730                     |
+--------------------------------------+
1 row in set (0.02 sec)

编写 mysql 触发器(根据实际情况编写)

[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 

查看触发器

MariaDB [(none)]> SHOW TRIGGERS FROM test;

在这里插入图片描述

server3:

[root@server3 ~]# ls
gearman-mysql-udf-0.6.tar.gz  nginx-1.17.4.tar.gz  rhel7
lib_mysqludf_json-master.zip  redis-5.0.3          test.sql
mysql                         redis-5.0.3.tar.gz   worker.php
nginx-1.17.4                  rhel6 Redis.pdf
[root@server3 ~]# cp worker.php /usr/local/
[root@server3 ~]# cd /usr/local
[root@server3 local]# ls
bin  games    lib    libexec  rediscluster  share  worker.php
etc  include  lib64  nginx    sbin          src
[root@server3 local]# vi worker.php 
 1 <?php
      2 $worker = new GearmanWorker();
      3 $worker->addServer();
      4 $worker->addFunction('syncToRedis', 'syncToRedis');
      5 
      6 $redis = new Redis();
      7 $redis->connect('172.25.34.5', 6379); ##改
      8 
      9 while($worker->work());
     10 function syncToRedis($job)
     11 {
     12         global $redis;
     13         $workString = $job->workload();
     14         $work = json_decode($workString);
     15         if(!isset($work->id)){
     16                 return false;
     17         }
     18         $redis->set($work->id, $work->name);
     19 }
     20 ?>

[root@server3 local]# nohup php /usr/local/worker.php  &> /dev/null &
[1] 7929
[root@server3 local]# systemctl start gearmand ##打开gearmand
[1]+  Exit 255                nohup php /usr/local/worker.php &>/dev/null
[root@server3 local]# netstat -antuple
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          31086      7842/nginx: master  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          14167      629/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      0          15356      874/master          
tcp        0      0 0.0.0.0:4730            0.0.0.0:*   ##4370gearman的端口            LISTEN      99

测试:

server5:

更新数据库信息

MariaDB [test]> update test set name='sm' where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [test]> select * from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | sm     |
|  2 | test2  |
|  3 | test3  |
|  4 | test4  |
|  5 | test5  |
|  6 | test6  |
|  7 | test7  |
|  8 | test8  |
|  9 | test9  |
+----+--------+
9 rows in set (0.00 sec)

server4:

127.0.0.1:6379> get 1
"sm"
127.0.0.1:6379> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值