Redis集群,利用Gearman做mysql 的缓存服务器(lnmp架构)

Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。Redis集群并不支持处理多个keys的命令,因为这需要
在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.
Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令.
Redis 集群的优势:
自动分割数据到不同的节点上。
整个集群的部分节点失败或者不可达的情况下能够继续处理命令。

一。redis集群的搭建

1.将之前做的redis关掉,然后依次解决日志出现的警告信息

[root@server1 redis]# /etc/init.d/redis_6379 stop
[root@server1 redis]# sysctl -w vm.overcommit_memory=1
vm.overcommit_memory = 1

2.搭建集群环境使用7001到7006搭建六个集群节点

[root@server1 ~]# mkdir /usr/local/rediscluster
[root@server1 ~]# cd /usr/local/rediscluster/
[root@server1 rediscluster]# mkdir 700{1..6}
[root@server1 rediscluster]# ls
7001  7002  7003  7004  7005  7006

3.每个节点的目录在里边写配置文件redis.conf

[root@server1 rediscluster]# cd 7001/
[root@server1 7001]# vim redis.conf
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout  5000
appendonly yes
pidfile "/usr/local/rediscluster/7001/redis.pid"
logfile "/usr/local/rediscluster/7001/redis.log"
daemonize yes
dir "/usr/local/rediscluster/7001"

[root@server1 7001]# redis-server redis.conf 
  • 此时查看端口7001已经打开
    在这里插入图片描述
    ps ax,进程也已经开启
    在这里插入图片描述

4.把7001配置好的文件直接发送到每个目录中,进行相应的改变即可

[root@server1 7001]# cp redis.conf  ../7002/
[root@server1 7001]# cp redis.conf  ../7003/
[root@server1 7001]# cp redis.conf  ../7004/
[root@server1 7001]# cp redis.conf  ../7005/
[root@server1 7001]# cp redis.conf  ../7006/   
[root@server1 rediscluster]# cd 7002
[root@server1 7002]# vim redis.conf 
port 7002
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout  5000
appendonly yes
pidfile "/usr/local/rediscluster/7002/redis.pid"
logfile "/usr/local/rediscluster/7002/redis.log"
daemonize yes
dir "/usr/local/rediscluster/7002"
[root@server1 7002]# redis-server redis.conf 

在这里插入图片描述
5.ps ax查看到6个端口的进程已经开启
在这里插入图片描述
6.创建集群

[root@server1 redis-5.0.3]# redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006

在这里插入图片描述
在这里插入图片描述
测试:
1.测试查看集群节点对应关系
[root@server1 redis-5.0.3]# redis-cli --cluster info 127.0.0.1:7001
在这里插入图片描述
7001,7002,7003是master,分别对应的slave是7004,7005,7006

[root@server1 redis-5.0.3]# redis-cli -c -p 7001
127.0.0.1:7001> info

在这里插入图片描述
2.无中心检测
在这里插入图片描述
在这里插入图片描述
3.将一个master(7002)宕掉,对应的master(7005)会接替

[root@server1 redis-5.0.3]# redis-cli -c -p 7002
127.0.0.1:7002> SHUTDOWN
not connected> 

在这里插入图片描述
如果再把slave宕掉,整个集群就不能用了

[root@server1 ~]# redis-cli -c -p 7005
127.0.0.1:7005> SHUTDOWN
not connected> 

在这里插入图片描述
在这里插入图片描述
恢复集群:
1.重新加载7002,和7005的配置文件

[root@server1 ~]# cd /usr/local/rediscluster/
[root@server1 rediscluster]# cd 7005
[root@server1 7005]# redis-server redis.conf 
[root@server1 7005]# cd ..
[root@server1 rediscluster]# cd 7002
[root@server1 7002]# redis-server redis.conf 
[root@server1 7002]# 

2.查看
在这里插入图片描述
给集群中添加节点
1.先创建两个新的节点

[root@server1 ~]# cd /usr/local/rediscluster/
[root@server1 rediscluster]# mkdir 7007
[root@server1 rediscluster]# mkdir 7008
[root@server1 rediscluster]# cd 7007/
[root@server1 7007]# cp ../7001/redis.conf  .
[root@server1 7007]# 
[root@server1 7007]# vim redis.conf 
port 7007
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout  5000
appendonly yes
pidfile "/usr/local/rediscluster/7007/redis.pid"
logfile "/usr/local/rediscluster/7007/redis.log"
daemonize yes
dir "/usr/local/rediscluster/7007"
[root@server1 7007]# redis-server redis.conf

在这里插入图片描述
ps ax查看

在这里插入图片描述
2.添加节点7007(master的添加方法)

[root@server1 7007]# redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7001

在这里插入图片描述
再次查看节点7007已经添加进去

redis-cli --cluster check 127.0.0.1:7001

在这里插入图片描述
3. 添加节点7008(slave的添加方法,master为7007)

[root@server1 7007]# redis-cli --cluster add-node --cluster-slave
--cluster-master-id 28ebcd99186f035713c67b4cbb3330b554b18954 127.0.0.1:7008 127.0.0.1:7007

在这里插入图片描述
再次检查,7008节点添加成功

[root@server1 7007]# redis-cli --cluster check 127.0.0.1:7001

在这里插入图片描述

给新的节点(7007)中添加哈希槽
[root@server1 7007]# redis-cli --cluster reshard --cluster-from all --cluster-to 54fb91ba168445aff9aa147362a24a5d1b709341 --cluster-slots 300 --cluster-yes 127.0.0.1:7001

##54fb91ba168445aff9aa147362a24a5d1b709341 是7007的id,在上图中可以看到
从所有节点中向7007分配300个哈希槽
在这里插入图片描述
再次检查

[root@server1 7007]# redis-cli --cluster check 127.0.0.1:7001

在这里插入图片描述
均匀分配哈希槽

 [root@server1 7007]# redis-cli --cluster rebalance --cluster-threshold 1 --cluster-use-empty-masters 127.0.0.1:7001

在这里插入图片描述
再次检查

[root@server1 7007]# redis-cli --cluster check 127.0.0.1:7001

在这里插入图片描述

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

client -> app -> redis -> mysql(如果在redis找不到再访问mysql) -> redis -> client

主机名 			IP 				服务
server1 	172.25.26.1 	php,nginx
server2 	172.25.26.2 	redis的master端
server3 	172.24.26.3 	mysql

1.将刚才实验中的集群节点服务都关掉
[root@server1 7007]# killall redis-server
2.安装如下安装包
[root@server1 rhel7]# yum install * -y
在这里插入图片描述
3. 安装nginx:
安装需要的依赖工具

[root@server1 ~]# yum install gcc pcre-devel zlib-devel -y
解压
[root@server1 ~]# tar zxf nginx-1.16.0.tar.gz 
编译安装前关闭debug日志
[root@server1 ~]# cd nginx-1.16.0
[root@server1 nginx-1.16.0]# vim auto/cc/gcc  
171 # debug
172 #CFLAGS="$CFLAGS -g"      ##注释掉(关闭debug日志)
进入解压目录,进行编译安装
[root@server1 nginx-1.16.0]# ./configure --prefix=/usr/local/nginx
[root@server1 nginx-1.16.0]# make
[root@server1 nginx-1.16.0]# make install

编辑配置文件:

[root@server1 conf]# vim /usr/local/nginx       (编译时设定的编译目录)
 43         location / {
 44             root   html;
 45             index  index.php index.html index.htm;   ##添加index.php
 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 }

检测脚本是否正确,并开启nginx

[root@server1 conf]# /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 conf]# /usr/local/nginx/sbin/nginx 

开启php,并查看端口

[root@server1 conf]# systemctl start php-fpm
[root@server1 conf]# netstat -antlp

在这里插入图片描述
此时在浏览器输入:http://172.25.26.1/测试查看
在这里插入图片描述
5.将写好的php测试页放在 /usr/local/nginx/html/

[root@server1 conf]# cd /usr/local/nginx/html/
[root@server1 html]# vim index.php 
<?php
        $redis = new Redis();
        $redis->connect('172.25.26.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.26.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>";
 
                echo "<br>";
 
                echo "name is <b><font color=#FF0000>$data[$key]</font></b>";
 
                echo "<br>";
        }
?>

此时浏览器输入:http://172.25.26.1/(显示没有redis server,是因为我们还没有配置)
在这里插入图片描述

6.在server2上配置一个redis(master)
下载安装包,并解压

[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

执行redis安装脚本

[root@server2 redis-5.0.3]# cd utils/
[root@server2 utils]# ./install_server.sh 

此时netstat -antlp会出现6379端口
在这里插入图片描述
7.配置mysql端
安装rhel7.3自带数据库即可

[root@server3 utils]# /etc/init.d/redis_6379 stop
[root@server3 utils]# yum install mariadb-server -y

[root@server3 ~]# systemctl start mariadb
[root@server3 ~]# mysql_secure_installation   ##初始化
##初始化步骤不再赘述,修改密码,注意不用删除test库,如果没有test,则新建一个

在这里插入图片描述
创建授权用户,并刷新授权表

[root@server3 ~]# 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)

导入测试库

[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 

8.测试
浏览器再次访问http://172.25.26.1/
在这里插入图片描述
再刷新几次
在这里插入图片描述

在redis端查看
在这里插入图片描述
如果在mysql端修改了数据
在这里插入图片描述
在redis端,也修改一个数据
在这里插入图片描述

刷新浏览器
发现在redis端修改的数据已经同步了,而在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)

mysql端

[root@server3 ~]# ls
gearman-mysql-udf-0.6.tar.gz  redis-5.0.3         test.sql
lib_mysqludf_json-master.zip  redis-5.0.3.tar.gz
[root@server3 ~]# yum install unzip -y


[root@server3 ~]# unzip lib_mysqludf_json-master.zip 
[root@server3 ~]# cd  lib_mysqludf_json-master
[root@server3 lib_mysqludf_json-master]# yum install gcc -y

[root@server3 lib_mysqludf_json-master]# yum install 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/

安装 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 的模块目录

[root@server3 ~]# mysql -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 17
Server version: 5.5.52-MariaDB MariaDB Server

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show global variables like 'plugin_dir';
+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| plugin_dir    | /usr/lib64/mysql/plugin/ |
+---------------+--------------------------+

注册 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)]> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
Query OK, 0 rows affected (0.00 sec)

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


##指定 gearman 的服务信息
MariaDB [(none)]> SELECT gman_servers_set('172.25.26.1:4730');
+--------------------------------------+
| gman_servers_set('172.25.26.1:4730') |
+--------------------------------------+
| 172.25.26.1:4730                     |
+--------------------------------------+

在这里插入图片描述

查看触发器

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

在这里插入图片描述
worker端
1.打开gearmand

[root@server1 rhel7]# systemctl start gearmand
[root@server1 rhel7]# netstat -antlp

在这里插入图片描述
2. 编写 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.26.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] 18940

测试:
1.更新数据库信息
在这里插入图片描述
2.查看 redis,数据更新了
在这里插入图片描述
3.浏览器也显示数据更新了
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值