Redis集群配置(创建集群,添加节点,redis结合mysql,数据同步)

一. Redis集群介绍

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

  2. Redis 集群的数据分片

Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么
节点 A 包含 0 到 5500号哈希槽.
节点 B 包含5501 到 11000 号哈希槽.
节点 C 包含11001 到 16384号哈希槽.
这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群redis集群配置

二. redis集群配置
server1上安装了redis,先关闭之前的redis

[root@server1 ~]# /etc/init.d/redis_6379 stop
  1. 新建目录,编辑配置文件

      [root@server1 ~]# mkdir /usr/local/rediscluster
     
     [root@server1 rediscluster]# mkdir 700{1..6}
     [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
     #查看进程
     ps ax
     
      1332 ?        Ssl    0:00 redis-server *:7001 [cluster]
      [root@server1 7001]# redis-cli -p 7001
     127.0.0.1:7001> info
     
     #Cluster
     cluster_enabled:1	##集群激活
     
     #同理配置7002~7006,并启动
    

在这里插入图片描述

  1. 拷贝ruby脚本

     [root@server1 src]# pwd
     /root/redis-5.0.3/src
     [root@server1 src]# cp redis-trib.rb /usr/local/bin/
     [root@server1 src]# yum install -y ruby
    

3.创建集群

[root@server1 ~]# 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
在这里插入图片描述

#查看集群信息
[root@server1 ~]# redis-cli --cluster info 127.0.0.1:7001
	##输入其他端口也可以,但是必须输一个端口

在这里插入图片描述

  1. 测试存储信息

     [root@server1 ~]# redis-cli -c -p 7001
     127.0.0.1:7001> get name
     -> Redirected to slot [5798] located at 127.0.0.1:7002
     (nil)
     127.0.0.1:7002> set name douluo
     OK
     127.0.0.1:7002> get name 
     "douluo"
     127.0.0.1:7002> quit
     [root@server1 ~]# redis-cli -c -p 7005
     127.0.0.1:7005> get name
     -> Redirected to slot [5798] located at 127.0.0.1:7002
     "douluo"			#在任意节点都可以获取到信息,但是都会跳转到7002
     127.0.0.1:7002> quit
    

##挂掉7002,key还会保存在7004上

三. redis添加新的节点
1.添加节点
server1上已经有6个节点

cd /usr/local/rediscluster
[root@server1 rediscluster]# cp 7001/redis.conf 7007/
[root@server1 rediscluster]# cp 7001/redis.conf 7008/

[root@server1 7007]# redis-server redis.conf
[root@server1 7008]# redis-server redis.conf

[root@server1 7008]# redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7001	
##添加节点

在这里插入图片描述
2.查看节点信息

[root@server1 7008]# redis-cli -c -p 7007
127.0.0.1:7007> cluster nodes	##查看节点信息

在这里插入图片描述
发现7007没有哈希槽

尽管新节点没有包含任何哈希槽, 但它仍然是一个主节点, 所以在集群需要将某个从节点升级为新的主节点时, 这个新节点不会被选中,所以要添加一个slave

[root@server1 ~]# redis-cli --cluster add-node 127.0.0.1:7008 127.0.0.1:7007 --cluster-slave --cluster-master-id 7d3fb70a5e9d098977cc873c3aad6433e2b064b0  
 ##master的id
[root@server1 ~]# redis-cli --cluster info 127.0.0.1:7001	##查看集群信息

在这里插入图片描述

  1. 为新节点分配哈希槽
    reshard分配不均等,可能导致数据不同步

     [root@server1 ~]# redis-cli --cluster reshard 127.0.0.1:7007
     How many slots do you want to move (from 1 to 16384)? 300	##随便分配一点
     
     What is the receiving node ID? b9ee016d45dde6a0067dd3e19139f1044a621d77	##接收哈希槽的节点ID
     
     Please enter all the source node IDs.
     Type ‘all’ to use all the nodes as source nodes for the hash slots.
     Type ‘done’ once you entered all the source nodes IDs.
     Source node #1: all
     #从所有节点获取哈希槽
     [root@server1 ~]# redis-cli --cluster check 127.0.0.1:7001	##检查可以看到已经分配哈希槽
    

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

[root@server1 ~]# redis-cli --cluster rebalance --cluster-threshold 1 --cluster-use-empty-masters 127.0.0.1:7001	##均分哈希槽
[root@server1 ~]# redis-cli --cluster check 127.0.0.1:7001
##查看数据[root@server1 ~]# redis-cli -c -p 7008

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查询数据成功,新节点添加完成

四. redis结合mysql

数据访问流程:client -> app -> redis -> mysql -> redis -> client
客户端用app访问,先在redis里读数据,速度快,redis没有才去mysql读,读完保存在redis里,然后返回客户端,下次获取数据回更快

1.server1上配置nginx和php

##首先在server1配置好nginx.修改配置文件
location / {
root html;
index index.php index.html index.htm;
}

1

...

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
###安装启动php-fpm
在这里插入图片描述
yum install -y *

  1. server2上配置redis

     /etc/init.d/redis_6379 restart 
     #删除原来的key
     [root@server2 ~]# redis-cli 
     127.0.0.1:6379> get name
     "dd"
     127.0.0.1:6379> DEL name
     (integer) 1
     127.0.0.1:6379> get name
     (nil)
    
  2. server3配置数据库
    ##开启server3,关闭原来的mysql

     [root@server3 ~]# rpm -qa | grep mysql
     mysql-community-libs-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-common-5.7.24-1.el7.x86_64
     mysql-community-client-5.7.24-1.el7.x86_64
     mysql-community-libs-compat-5.7.24-1.el7.x86_64
    

##卸载原来的mysql

[root@server3 ~]# rpm -e `rpm -qa | grep mysql` --nodeps

#安装mariadb,这里试验用这个就行

[root@server3 ~]# yum install -y mariadb-server

#清除原来数据目录里的内容

[root@server3 ~]# cd /var/lib/mysql
[root@server3 mysql]# rm -fr *

#启动mariadb

[root@server3 mysql]# systemctl start mariadb

#安全初始化

[root@server3 ~]# mysql_secure_installation	##这里密码可以设置为简单的,如redhat

#登录数据库,授权用户

MariaDB [(none)]> create database test;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> grant all on test.* to redis@'%' identified by 'redhat';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
  1. 给server3数据库test库导入信息
    cat 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 -predhat < test.sql
  1. 修改server1的默认发布页

     [root@server1 ~]# mv test.php /usr/local/nginx/html/
     [root@server1 html]# mv test.php index.php
    

我们设置nginx默认访问index.php

[root@server1 ~]# cd /usr/local/nginx/html/
[root@server1 html]# cat index.php

<?php
        $redis = new Redis();				##连接server2的redis
        $redis->connect('172.25.61.2',6379) or die ("could net connect redis server");
  #      $query = "select * from test limit 9";
        $query = "select * from test";
        for ($key = 1; $key < 10; $key++)
        {
                if (!$redis->get($key))
                {									##连接server3的mysql
                        $connect = mysql_connect('172.25.61.3','redis','redhat');
                        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>";
        }
?>

6.测试

#浏览器访问测试
172.25.61.1
可以看到导入的数据
在这里插入图片描述
#但是刷新一次后,可以看到后面就从redis读取数据
在这里插入图片描述
这个时候有个问题,如果此时mysql数据发生变更,redis会同步吗?

在server3上

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

变更后发现,redis里没有变,浏览器也看不到变化,但是在redis里做的变化能看到

127.0.0.1:6379> set 2 redhat
OK

刷新浏览器,看到变化,这样显然不合理

五. 配置gearmand(myaql数据变化,redis数据同步)

  1. server1上启的gearmand

    [root@server1 ~]# systemctl start gearmand ##之前已经安装过

  2. server3
    在这里插入图片描述

     unzip lib_mysqludf_json-master.zip
     在server3上解压lib_mysqludf_json-master.zip
    

#安装mariadb-devel

[root@server3 lib_mysqludf_json-master]# yum install -y mariadb-devel.x86_64

#编译模块(文档上有)

[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c

#将模块放到mysql插件目录

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

#在server3上查看

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

#注册udf函数

MariaDB [(none)]> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';

#安装插件管理gearman的分布式队列
在这里插入图片描述

[root@server3 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz

#先安装libgearman,从server1上scp

[root@server3 ~]# yum install -y libevent-devel-2.0.21-4.el7.x86_64.rpm libgearman-

#编译安装gearman插件

[root@server3 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/ --with-mysql

[root@server3 gearman-mysql-udf-0.6]# make && make install

#注册udf函数

mysql -p

MariaDB [(none)]> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';


MariaDB [(none)]> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';

##查看函数

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)

##指定gman服务信息

MariaDB [(none)]> SELECT gman_servers_set('172.25.61.1:4730');

##编写mysql触发器

[root@server3 ~]# cat 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 -p < test.sql

##查看触发器

MariaDB [(none)]> SHOW TRIGGERS FROM test;
  1. server1
    ##编写gman的worker端

      [root@server1 redis]# cp worker.php /usr/local/
      [root@server1 redis]# cd /usr/local/
     
      cat worker.php 
     <?php
     $worker = new GearmanWorker();
     $worker->addServer();
     $worker->addFunction('syncToRedis', 'syncToRedis');
      
     $redis = new Redis();
     $redis->connect('127.0.61.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. 测试,修改数据库内容
    ##修改数据库内容

     MariaDB [test]> update test set name='redhat' where id=2;
    

##在redis上查看

127.0.0.1:6379> get 2
"redhat"

##页面查看,数据同步
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值