Linux数据库管理——day12——Redis数据库集群、Ruby软件简析

部署redis集群

   1. 将redis部署进入集群
      1.1 修改主配置文件/etc/redis/6379.conf

sed -i 's/# cluster-enabled/cluster-enabled/' /etc/redis/6379.conf
sed -i '/cluster-node-timeout/ccluster-node-timeout 5000' /etc/redis/6379.conf
sed -i 's/# cluster-config-file/cluster-config-file/' /etc/redis/6379.conf

      1.2 重新启动数据库,检查端口,会出现两个端口:
          一个是自己设定的,用于给客户端访问;
          一个是自动创建的,这个端口是集群间进行连接的端口,

/etc/init.d/redis_6379  restart
netstat -ntlup | grep redis
tcp        0      0 172.25.10.110:6379       0.0.0.0:*               LISTEN      2901/redis-server 1 
tcp        0      0 172.25.10.110:16379      0.0.0.0:*               LISTEN      2901/redis-server 1 


   2. 选择一个服务器作为管理服务器,安装管理集群软件Ruby

yum -y install ruby rubygems
rpm -ivh ruby-devel-2.0.0.648-30.el7.x86_64.rpm 
gem install redis-3.2.1.gem

   3. 创建集群
        先检查一下命令,如果能查看到帮助信息,就说明redis命令正常

redis源码包解压目录/src/redis-trib.rb help
redis-trib.rb create --replicas 从库个数 集群中的数据库IP:端口(所有的都写上,空格隔开)
# 然后如果执行成功,回答yes即可
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
# 这里出现的就是主库信息

Adding replica 从库IP:端口号 to 对应主库IP:端口号
# 这会按照配置的要求出现主从关系

Can I set the above configuration? (type 'yes' to accept): yes

# 这里会再次出现集群信息

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# 显示创建成功

   3. 检查集群

redis-cli -h 数据库IP -p 端口号 -a 密码 cluster info
# 查看简介,主要查看状态,以及集群中各个节点个数
cluster_state:ok
cluster_known_nodes:个数

redis-cli -h 数据库IP -p 端口号 -a 密码 cluster nodes
# 查看里面的节点详细信息

redis源码包解压目录/src/redis-trib.rb check 管理服务器IP:端口号
# 显示主从关系
>>> Performing Cluster Check (using node 192.168.4.51:6351)

M: 469b44972ac8d1cd5e121a8d5d3291478741b57d 172.25.10.110:6379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
# 这里第一行由三个组成,(M代表主库  S代表从库), 然后一长段字符串就是ID号 最后是IP和端口号
# 第二行括号中就是哈希编号的个数,可以理解为存储的变量个数
# 第三行指代的是

S: eb67516a15b2d2fd806592d5d47f5a15f861b942 172.25.10.112:6381
   slots: (0 slots) slave
   replicates 528332b300ffd84456188c0562954d19cfe5ec49
# 这里第三行指代的就是该从库的主库的ID号

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

   注意:
      1. 集群中必须有3个主库 而选项 replicas 则是指定一个主库有几个从库,也就是说至少有 3*(1+replicas参数) 个redis数据库才能创建集群
      2. 如果想把一个或多个节点,创建或者加入到集群中,必须确保新加入集群的数据库中没有任何数据,如果想保留,可以先拷贝出来,再删除、重启动服务,这样才能加入集群
      3. 所有操作,必须用-c进去集群,不写就是单独进入某个数据库,但是因为集群配置还在,导致数据存储读取还是会根据哈希算法来,这样就有可能存失败或者读失败
      4. 生成集群的时候,会有着一句话 All 16384 slots covered 返回出来,这代表创建量多少个编号,编号范围0-16383,学名hash slot,它会根据主库个数,平均非配给每个主库,然后在存储数据的时候,变量名根据哈希算法计算得到一个0-16383的编号,然后根据这个编号,找寻存放的位置,查询的时候也是根据变量名进行哈希运算,得到一个编号,因为算法相同,所以这个编号和存的时候会一模一样,到时候就可以根据编号找到存的数据库的位置,从而实现查找。
         举例解释: 加入现在有默认的3个主库信息,那么第一个主库内存的编号范围是0-5461,第二个是 5462-10922 ,第三个是 10923-16383 ,然后存了一个变量,这时候会根据crc16算法计算得到一个数和16384取余,得到的值假如为6666,我们发现这个编号在第二个主库的编号范围内,就会把数据存到第二个主库中,查询的时候,根据变两名,算法计算得到的编号还会是6666,这样就可以了解到,数据存在第二个主库中,这样就可以前往第二个主库查数据。


   负载均衡测试
      客户端访问(注意要加上 -c 选项,不然是访问的独立的数据库服务器,加上 -c 才是访问集群)

redis-cli -c -h 集群中任意一个服务器IP -p 端口号(不能是数据库集群间使用的端口)

172.25.10.110:6379> set test good
-> Redirected to slot [7785] located at 172.25.10.111:6380
OK
172.25.10.111:6380> set test2 good2
-> Redirected to slot [7785] located at 172.25.10.110:6379
OK
172.25.10.110:6379> get test
-> Redirected to slot [11786] located at 172.25.10.111:6380
"good"

      测试后我们会发现,存储的时候,是根据哈希算法计算后按照一定规律存在某个主库内,然后自动同步到对应从库;而读取的时候,会再次根据哈希算法计算确认存放在哪个数据库,如果查询的变量不在当前库中,会自动切换到指定库,并返回值
      这样就实现了数据读写负载均衡,每个服务器都负责了一部分的数据存储

    高可用
       创建中,我们每个主库都配置了一个从库,目的就是数据备份,而且Ruby会在主库down机后,自动让其从库成为主库,继续提供服务,不会因为任何一个单点故障而致使集群崩溃,而且那个down机的主库恢复后,会自动加入集群,并且自动同步新主库中的数据,并成为其从库
       举例解释: 假设集群中数据库A是主库,数据库B是其从库,当A出问题,服务停止后,Ruby会自动让数据库B成为主库,并把A中所有的哈希编号转移到B中,从而继续提供读写服务,当A恢复后,会自动加入集群并同步B中的数据,成为B的从库。
       但是,如果一个有哈希编号的主库,没有从库,那么当其down机,集群会即刻崩溃,所以一般一个主库后面会有2个主库,当工程师发现,一个有问题的时候,高可用依然存在,非常安全,只需要迅速恢复,集群即可恢复如初


管理集群
   使用的命令是 redis源码包解压目录/src/redis-trib.rb
      命令格式基本都是:  redis-trib.rb 选项 集群中任意一个主机IP:端口

    0. 查看当前集群结构

redis-trib.rb check 集群中任意一个主机IP:端口

    1. 如何添加一个主库节点
      1.0 停止预备加入集群的redis服务,然后删除/var/lib/redis/6379/下的文件,然后重新启动服务
      1.1 添加新的节点(这时候节点内没有一个哈希编号,也就是说,可以连接,但是不能存任意数据)

redis-trib.rb add-node 准备添加到主库中的服务器IP:端口  集群中任意一个主机IP:端口

      1.2 重新分配hash编号(这样新加入的主库才能存数据)

redis-trib.rb reshard 集群中任意一个主机IP:端口
>>> Performing Cluster Check (using node 172.25.10.110:6379)

# 这里会显示所有库的信息

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 预计分配给新加入的库的hash编号数(可以拿16384/当前库个数得到一个平均值)
What is the receiving node ID? 新添加的库的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.

# 如果想哈希编号从所有主库里面等分出来,这里填写all
Source node #1:all

# 如果只想从某个或者某几个库里面抽取部分哈希编号,就填写主库ID号
Source node #1:选择抽取的主库ID号
Source node #2:选择抽取的主库ID2号
Source node #3:done   (如果只想从这几个库里面抽取,就写done结束)

# 然后会列出所有将被转移的哈希编号,在这之后回答yes开始转移

Do you want to proceed with the proposed reshard plan (yes/no)? yes

    2. 如何添加一个从库节点
      2.0 停止预备加入集群的redis服务,然后删除/var/lib/redis/6379/下的文件,然后重新启动服务
      2.1 加入节点即可

redis-trib.rb add-node  --slave --master-id 主库ID值(注意不是IP) 新添加的IP:端口号 集群中任意一个主机IP:端口
# 可以不写 --master-id 指定主库,这样默认是给从库数量最少的那个库

    3. 如何删除一个从库节点
       3.1 先用管理服务器,把该从库节点删除集群

redis-trib.rb del-node 集群中任意一个主机IP:端口 被删除库的ID号

       3.2 前往被移除的从库服务器,删除从库中的节点配置文件/var/lib/redis/6379/nodes-6379.conf,但是最好不要删除/var/lib/redis/6379/dump.rdb,这里面存储的就是数据信息

       3.3 修改主配置文件 /etc/redis/6379.conf 将集群相关配置注释掉

sed -i 's/^cluster/# cluster/' /etc/redis/6379.conf

     4. 如何删除主库节点
        4.1 移除预备删除的主库的哈希编号

redis-trib.rb reshard 集群中任意一个主机IP:端口

>>> Performing Cluster Check (using node 192.168.4.51:6351)

# 这里会显示所有库的信息

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 这里写预备删除的库的哈希编号个数
What is the receiving node ID? 必须选择一个库接受这些哈希编号,这里写这个库的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:预备删除的主库的ID号
Source node #2:done

        4.2 删除节点(下面就和删除从库操作相同)

redis-trib.rb del-node  集群中任意一个主机IP:端口 被删除库的ID号

     5. 将已经被退出集群的数据库,重新添加回去
        起始和添加没有什么区别,不过因为要把数据库中原来写的集群配置删除,而保留数据信息,所以有点不同
        5.1 删除记录在数据库中的集群配置文件,然后重启服务

rm -f /var/lib/redis/6379/nodes-6379.conf 
redis-cli  -h 192.168.4.57 -p 6357 cluster reset

        5.2 加入集群


总结

    1. 数据库Ruby集群结构,共设置量16384个哈希编号,每个主库都有属于自己的哈希编号,变量存储读取都会进行哈希运算得到哈希编号从而了解自己应该存在哪里,或者去哪里读取数据。并且会自动处理负载均衡和高可用。

    2. 集群工作过程:
       存: 将变量名根据哈希算法计算得到一个哈希编号,然后查看这个哈希编号编号归属于哪个数据库中,然后就把数据存到该库下
       读: 将变量名根据哈希算法计算得到一个哈希编号,然后查看这个哈希编号编号归属于哪个数据库中,然后到该库下查找数据

    3. 添加新的库信息:
        3.1. 删除/var/lib/redis/6379/nodes-6379.conf(名字可能不一样,具体看自己的配置文件)
        3.2. 用命令将数据库加入到集群中
        3.3. 如果是主库调整一下哈希编号

    4. 移除一个库:
        4.1 如果是主库就移除所有哈希编号
        4.2 用命令从集群中移除数据库
        4.3 删除/var/lib/redis/6379/nodes-6379.conf 并修改 /etc/redis/6379.conf 中的配置


详细解析:
    1. 如果主库有哈希编号,那么其及其从库能否正常工作就关系到集群架构;相反,如果主库没有哈希编号,那么其及其从库down机就不会影响集群,也就是说集群能否正常工作取决于是不是所有的哈希编号都能被查看到

    2. 如果一个主库的哈希编号全部给了另外一个主库,那么该主库的从库也会成为另外一个主库的从库,而且还有一个特殊情况:
       假设主库A其哈希编号从0-100,其从库为B;主库C哈希列表为200-300,其从库为D;这时候加入把C的哈希编号全部给A,这时候B、D都将成为A的从库,然后我们把A中0-100的哈希编号转给C,神奇的事情就会发生,A的从库成为D,而C的从库就变成了D。

    3. 如果主库中哈希编号被全部移走会失去从库,但只要从获取它哈希数据的主库中获取一个哈希编号,从库就会回来。
       举个例子:初始情况和上面一样,如果A的哈希编号被B取走,这时候A会失去自己的从库,这时候如果A获取B的0-100内的一个哈希编号,那么C就会成为A的从库,如果A获取200-300中的一个哈希编号,那么D就会成为A的从库

报错信息分析
    可能集群出现故障,数据无法读取 , 可能服务器不在集群中
(error) CLUSTERDOWN The cluster is down

    选择加入集群的库中/var/lib/redis/6379/存在nodes-6379.conf配置,所以要删除该文件重启服务
[ERR] Node 172.25.10.110:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.    

    当创建集群的时候,数据库服务器不够必须的个数,就会报错
*** ERROR: Invalid configuration for cluster creation.
*** Redis Cluster requires at least 3 master nodes.
*** This is not possible with 1 nodes and 1 replicas per node.
*** At least 6 nodes are required.


 

猜你喜欢

转载自blog.csdn.net/Yu1543376365/article/details/83572928