zoukankan      html  css  js  c++  java
  • Redis之二----企业级nosql数据库应用与实战-redis的主从和高可用集群

    redis高可用与集群

    虽然Redis可以实现单机的数据持久化,但无论是RDB也好或者AOF也好,都解决不了单点宕机问题,即一旦redis服务器本身出现系统故障、硬件故障等问题后, 就会直接造成数据的丢失 因此需要使用另外的技术来 解决单点问题 。

    配置reids主从:

    主备模式:可以实现 Redis数据的跨主机备份。

    程序端连接到高可用负载的VIP,然后连接到负载服务器设置的Redis后端real server,此模式不需要在程序里面配置Redis服务器的真实IP地址当后期Redis服务器IP地址,发生变更只需要更改redis相应的后端real server即可,可避免更改程序中的IP地址设置。

    Redis Slave也要开启持久化并设置和master同样的连接密码, 因为后期slave会有提升为master的可能Slave 端切换 master 同步后会丢失之前的所有数据。

    一旦某个 S lave 成为 一个 master 的 slave Redis Slave 服务会 清空 当前 redis 服务器 上的所有数据 并将master 的数据导入到自己的内存,但是 断开 同步关系后不会删除当前已经同步过的数据。

    实战一:redis 主从复制的实现

    原理架构图:

    主从复制过程:

    Redis 支持主从复制 分为全量同步和增量同步 首次同步是全量同步,主从同步可以让从服务器从主服务器备份数据,而且从服务器还可与有从服务器,即另外一台 redis 服务器可以从一台从服务器进行数据同步,

    redis 的主从同步是非阻塞的,其收到从服务器的 sync(2.8 版本之前是 PSYNC) 命令会fork一个子进程在后台执行 bgsave 命令,并将新写入的数据写入到一个缓冲区里面, bgsave 执行完成之后并生成的将 RDB 文件发送给客户端,

    客户端将收到后的 RDB 文件载入自己的内存,然后主 redis将缓冲区的内容在全部发送给从 redis ,之后的同步从服务器会发送一个 off set 的位置 等同于 MySQL的 binlog 的位置 给主服务器,

    主服务器检查后位置没有错误将此位置之后的数据包括写在缓冲区的积压数据发送给 redis 从服务器,从服务器将主服务器发送的挤压数据写入内存,这样一次完整的数据同步,再之后再同步的时候从服务器只要发送当前的 offset 位 置给主服务器,然后主服务器根据响应的位置将之后的数据发送给从服务器保存到其内存即可。

    Redis全量复制一般发生在 Slave 初始化阶段,这时 Slave 需要将 Master 上的所有数据都复制一份。具体步骤如下:

    1)从服务器连接主服务 器,发送 SYNC 命令;

    2)主服务器接收到 SYNC 命名后,开始执行 BGSAVE 命令生成 RDB 快照 文件并使用缓冲区记录此后执行的所有写命令;

    3)主服务器 BGSAVE 执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;

    4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照

    5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令

    6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令

    7)后期同步会先发送自己slave_repl_offset位置 只 同步新增加的数据,不再全量同步 。

    环境准备

    机器名称

    IP配置

    服务角色

    redis-master

    192.168.37.7

    redis主

    redis-slave1

    192.168.37.17

    redis从

    redis-slave2

    192.168.30.27

    redis从

    1、在所有redis服务器上修改以下配置

     vim  /apps/redis/etc/redis.conf

    bind 192.168.37.7   #监听地址(各自写各自的IP,推荐写0.0.0.0,监听所有地址)
    requirepass 123456  #登陆redis的密码
    daemonize yes   #后台守护进程运行
    masterauth 123456   #如果设置了访问认证就需要设定此项。

    2、在redis从服务器上配置slave配置 

     (1)源码编译安装redis,然后将配置文件复制一份:

    cp  /apps/redis/etc/redis.conf{,.bak}

     (2)修改从服务器的配置文件

       vim  /apps/redis/etc/redis.conf 

    ### REPLICATION ###  在这一段配置
    slaveof 192.168.37.7 6379  #监听主服务器的IP地址和端口
    下边保持默认就好,需要的自己修改
    masterauth  123456   #如果设置了访问认证就需要设定此项。
    slave-serve-stale-data yes   #当slave与master连接断开或者slave正处于同步状态时,如果slave收到请求允许响应,no表示返回错误。
    slave-read-only yes   #slave节点是否为只读。
    slave-priority 100   #设定此节点的优先级,是否优先被同步。
    

     (3)将第二个从服务器进行设置,监听主服务器的IP地址。

    ### REPLICATION ###  在这一段配置
    slaveof 192.168.37.7 6379  最好监听主服务器的地址192.168.37.7 6379
    下边保持默认就好,需要的自己修改
    masterauth  123456   #如果设置了访问认证就需要设定此项。
    slave-serve-stale-data yes   #当slave与master连接断开或者slave正处于同步状态时,如果slave收到请求允许响应,no表示返回错误。
    slave-read-only yes   #slave节点是否为只读。
    slave-priority 100   #设定此节点的优先级,是否优先被同步。

    3、开始测试效果

      1、在主redis服务器上查看创建的键值。

      2、查看从redis服务器上的键值对,此时已经被同步过来。

     3、主从同步日志成功

     4、查看主从节点关系,已经确认,从节点为开启状态,并监控主服务器的IP地址和端口:

       127.0.0.1:6379> info replication 

    高级配置(根据自己需要设置)

    (1)一个RDB文件从master端传到slave端,分为两种情况:

    ① 支持disk:master端将RDB file写到disk,稍后再传送到slave端;

    ② 无磁盘diskless:master端直接将RDB file传到slave socket,不需要与disk进行交互。

    无磁盘diskless 方式适合磁盘读写速度慢但网络带宽非常高的环境。

    (2)设置

    vim /apps/redis/etc/redis.conf

    repl-diskless-sync no   #默认不使用diskless同步方式
    repl-diskless-sync-delay 5   #无磁盘diskless方式在进行数据传递之前会有一个时间的延迟,以便slave端能够进行到待传送的目标队列中,这个时间默认是5秒
    repl-ping-slave-period 10   #slave端向server端发送pings的时间区间设置,默认为10秒
    repl-timeout 60   #设置超时时间
    min-slaves-to-write 3   #主节点仅允许其能够通信的从节点数量大于等于此处的值时接受写操作;
    min-slaves-max-lag 10   #从节点延迟时长超出此处指定的时长时,主节点会拒绝写入操作;
    repl-backlog-ttl 3600  如果一段时间后没有slave连接到master,则 backlog size的内存将会被释放。如果值为0,则表示永远不释放这部份内存。
    

    实战二:Sentinel(哨兵)实现Redis的高可用性

    原理及架构图

    a)原理

      Sentinel(哨兵)是Redis的高可用性(HA)解决方案,由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的服务器进行下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替下线的主服务器继续处理命令请求。

      Redis提供的sentinel(哨兵)机制,通过sentinel模式启动redis后,自动监控master/slave的运行状态,基本原理是:心跳机制+投票裁决

    ① 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

     提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

    ③ 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

    b)架构流程图

    (1)正常的主从服务

    (2)sentinel 监控到主redis 下线

    (3)由优先级升级新主

    (4)旧主修复,作为从redis,新主照常工作

    1、环境准备

    机器名称

    IP配置

    服务角色

    备注

    redis-master

    192.168.37.7

    redis主

    开启sentinel

    redis-slave1

    192.168.37.17

    redis从

    开启sentinel

    redis-slave2

    192.168.37.27

    redis从

    开启sentinel

      

    2、按照上实验实现主从

    (1)打开所有机器上的redis 服务

      redis-server /apps/redis/etc/redis.conf

    (2)在主上登录查询主从关系,确实主从已经实现

     redis-cli -h 192.168.37.7

    192.168.30.107:6379> info Replication

     

     3、在三个主机上分别配置sentinel 哨兵

     1、在主从三个redis服务器上都配置sentinel哨兵,三个主机的哨兵配置文件相同,只需要在主服务器上修改相关配置,直接使用scp命令复制到其他主机上即可。

     vim /apps/redis/etc/sentinel.conf

    bind 0.0.0.0
    port 26379
    daemonize yes
    logfile "/var/log/redis/sentinel_26379.log" # 源码编译redis,指定log文件路径,方便观察主从复制与哨兵监控过程。
    sentinel monitor mymaster 192.168.37.7 6379 2    #法定人数限制 quorum )),即有几个slave认为masterdown了就进行故障转移,此处比较重要,如果有三个哨兵就写2,有四个哨兵就写3,IP地址指向主服务器的即可
    sentinel auth-pass mymaster 123456   #验证master登陆密码
    sentinel down-after-milliseconds mymaster 30000  #SDOWN 主观下线的时间
    sentinel parallel-syncs mymaster 1 #发生故障转移时候同时向新master同步数据的slave数量数字越小总同步时间越长
    sentinel failover-timeout mymaster 180000 #所有slaves指向新的master所需的超时时间
    

      4、三台主机都启动redis和sentinel哨兵服务

    [root@centos7etc]#redis-server /apps/redis/etc/redis.conf 
    [root@centos7etc]#redis-sentinel  /apps/redis/etc/sentinel.conf 
    

     启动的服务最好保存到启动服务脚本中,设置为开机启动,避免主机重启,服务无法启动问题。

    [root@cenots27~]#vim /etc/rc.d/rc.local  写入本地启动服务脚本中
    redis-server /apps/redis/etc/redis.conf
    redis-sentinel  /apps/redis/etc/sentinel.conf
    [root@cenots27~]#chmod +x /etc/rc.d/rc.local  加上执行权限

      此时在第三台从服务器上观察日志,可以很清楚看到启动过程:

     5、开始模拟宕机主redis服务器

    [root@centos7etc]#ps -ef |grep redis
    root       8766      1  0 21:43 ?        00:00:01 redis-server 0.0.0.0:6379
    root       8880      1  0 21:51 ?        00:00:00 redis-sentinel 0.0.0.0:26379 [sentinel]
    root       8886   7374  0 21:52 pts/0    00:00:00 grep --color=auto redis
    [root@centos7etc]#kill -9 8766
    

     6、此时可以在第三台日志跟踪中看到主服务器宕机 

     slave-priority 100 #复制集群中,主节点故障时,sentinel应用场景中的主节点选举时使用的优先级;数字越小优先级越高,但0表示不参与选举;当优先级一样时,随机选举。

     7、在新升上去的主服务器上查看其他主机的slave状态

    8、由于旧主宕机,需要修复,此时需要将旧主变为从 

    [root@centos7etc]#vim /apps/redis/etc/redis.conf  
    slaveof 192.168.37.17 6379   将旧主的IP地址指向新主的IP地址
    masterauth 12345
    

     启动redis服务,观察此时新主slave状态。

    redis-server  /apps/redis/etc/redis.conf  启动redis服务

     

    实战三:redis 集群cluster 及主从复制模型的实现(6台服务器)

    原理及架构图

    背景:

    在哨兵 sentinel 机制中,可以解决 redis 高可用的问题 即当 master 故障后 可以 自动将 slave 提升为master 从而可以保证 redis 服务的正常使用,但是无法解决 redis 单机写入的 瓶颈 问题 即单机的 redis
    写入性能受限于单机的 内存 大小、 并发 数量、 网卡速率等因素 ,因 此 redis 官方在 redis 3.0 版本之后推出了无中心架构的 redis cluster 机制, 在无中心 的 redis 集群汇中,其每个节点保存当前节点数据和
    整个集群状态,每个节点都和其他所有节点连接 特点如下:

    1、所有 Redis 节点 使用 PING 机制 互联

    2、集群中某个节点的失效是整个集群中超过半数的节点监测都失效才算真正的失效。

    3、客户端不需要proxy即可直接连接redis应用 程序需要 写 全部的redis服务器 IP 。

    4、redis cluster 把 所有的 redis node 映射 到 0 16383 个 槽位 slot 上 读写 需要到 指定 的 redis node上进行操作,
    因此有多少个 reids node 相当于 red is 并发 扩展了多少倍。

    5、Redis cluste r 预先分配 16384 个 slot 槽位,当需要在 redis 集群中写入一个 key value 的时候 ,会使用 CRC16 ( mod 16384 之后 的值,
    决定将 key 写入值哪一个槽位从而决定写入哪一个 Redis 节点上 从而有效解决单机瓶颈 。

    a)原理

    (1)前提背景:如何解决redis横向扩展的问题----redis集群实现方式

    (2)介绍redis 集群

    ① Redis 集群是一个提供在多个Redis间节点间共享数据的程序集

    ② 优势:

      自动分割数据到不同的节点上。

      整个集群的部分节点失败或者不可达的情况下能够继续处理命令。

    ③ 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节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.

    (3)能实现横向扩展的原理

      每个redis 节点之间,都会有自己内部的连通机制,能知道每个数据在哪个节点的hash槽中。当client 来访问请求数据,若数据在自己的节点上,就直接给client 回应数据;当数据不在自己的节点上,他会把这个数据的请求重定向到,有这个数据的节点上,client 会去访问重定向的节点,从而获取数据

    (4)加入主从复制模型的原因

      每一个节点都有一个自己的从redis,保持集群的高可用;若一个节点的机器宕机,会有它的从顶替工作。

    b)架构实例

    c)过程分析

    ① client 访问redis2 机器,假如要取A数据

    ② redis2 发现自己没有A数据,通过自己内部机制,发现A数据在redis1 上

    ③ redis2 发指令,把client 的请求重定向到 redis1 机器上

    ④ client 访问redis1 ,取得A数据

    创建 redis cluster 集群的前提:

    1. 每个redis node节点采用相同的硬件配置、相同的密码。

    2. 每个节点必须开启的参数。

    cluster enabled yes # 必须开启集群状态, 开启后 redis 进程会有 cluster 显示。
    cluster config file nodes 6380.conf # 此文件有redis cluster集群自动创建和维护,不需要任何手动操作。

    3. 所有redis服务器必须没有任何数据。

    4 先启动为单机redis且没有任何key value。

    1、环境准备

    机器名称

    IP配置

    服务角色

    redis-master-cluster1

    192.168.37.7

    主服务器1

    redis-master-cluster2

    192.168.37.17

    主服务器2

    redis-master-cluster3

    192.168.37.27

    主服务器3

    redis-slave-cluster1

    192.168.37.37

    从服务器

    redis-slave-cluster2

    192.168.37.47

    从服务器

    redis-slave-cluster3

    192.168.37.57

    从服务器

    2、开启6个机器的集群配置文件

    1、创建redis配置文件存放位置

    [root@rs2redis]#mkdir /apps/redis/{etc,data,logs,run}
    

    2、将6个redis配置文件都进行修改

    vim  /apps/redis/etc/redis.conf(源码编译配置文件)

    bind 0.0.0.0   #监听所有地址
    port 6379   #监听的端口号
    daemonize yes   #后台守护方式开启服务
    logfile "/apps/redis/logs/redis_6379.log" 配置log日志存放路径
    pidfile /apps/redis/run/redis_6379.pid  配置pid存放路径
    dir /apps/redis/data   配置数据存放路径
    dbfilename dump_6379.rdb   数据名称
    requirepass 123456   配置redis登陆密码
    
    ### REDIS CLUSTER  ###   集群段
    cluster-enabled yes   #开启集群
    cluster-config-file nodes-6379.conf    #集群的配置文件
    cluster-node-timeout 15000    #请求超时 默认15秒,可自行设置
    appendonly yes    #aof日志开启,有需要就开启,它会每次写操作都记录一条日志
    masterauth "123456" #配置验证redis密码

    3、启动六个主机的redis服务

    [root@rs2redis]#redis-server  /apps/redis/etc/redis.conf

    3、源码编译ruby包(在任意一个集群编译即可):

    官网下载路径:http://www.ruby-lang.org/en/downloads/

    1、安装依赖的包。

    [root@centos17src]#yum install "development tools"  安装开发包
    [root@centos17src]#yum install  openssl-devel openssl  -y  安装加密包
    [root@centos17src]#yum install zlib zlib-devel -y  安装依赖包
    

     2、下载ruby包,并进行源码编译。  

    [root@centos17src]#rz
    [root@centos17src]#tar -xvf ruby-2.5.5.tar.gz 解压文件
    [root@centos17src]#cd ruby-2.5.5/  切换到目录下
    [root@centos17src]#./configure  开始配置
    [root@centos17src]#make -j2 && make install  编译安装
    [root@centos17src]#gem install redis
    

      3、创建redis-trib.rb软链接

    [root@centos17src]#ln -s /usr/local/src/redis-4.0.14/src/redis-trib.rb /usr/bin  创建软链接
    [root@centos17src]#redis-trib.rb 
    Usage: redis-trib <command> <options> <arguments ...>
    
      create          host1:port1 ... hostN:portN
                      --replicas <arg>
      check           host:port
      info            host:port
      fix             host:port
                      --timeout <arg>
      reshard         host:port
                      --from <arg>
                      --to <arg>
                      --slots <arg>
                      --yes
                      --timeout <arg>
                      --pipeline <arg>
      rebalance       host:port
                      --weight <arg>
                      --auto-weights
                      --use-empty-masters
                      --timeout <arg>
                      --simulate
                      --pipeline <arg>
                      --threshold <arg>
      add-node        new_host:new_port existing_host:existing_port
                      --slave
                      --master-id <arg>
      del-node        host:port node_id
      set-timeout     host:port milliseconds
      call            host:port command arg arg .. arg
      import          host:port
                      --from <arg>
                      --copy
                      --replace
      help            (show this help)
    
    For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

    编译完成后需要修改gems客户端配置文件,加入密码,为了能访问加密后的redis服务,密码和redis服务一致。

    [root@rs2redis]#vim /usr/local/lib/ruby/gems/2.5.0/gems/redis-4.1.3/lib/redis/client.rb  注意修改redis版本

      

    第一种报错:ruby 安装redis报错

    [root@localhost tools]# gem install redis
    ERROR: Loading command: install (LoadError)
     cannot load such file -- zlib
    ERROR: While executing gem ... (NoMethodError)
        undefined method `invoke_with_build_args' for nil:NilClass

    解决办法:

    yum -y install zlib-devel
    进入ruby源码文件夹,安装ruby自身提供的zlib包
    cd ruby-2.5.1/ext/zlib
    ruby ./extconf.rb
    make
    make install

     第二种报错:ruby 安装redis报错

    make: *** No rule to make target `/include/ruby.h', needed by `zlib.o'. Stop. 

    解决办法:

    vim /usr/local/src/ruby-2.5.1/ext/zlib/Makefile
    #zlib.o: $(top_srcdir)/include/ruby.h #把这一行替换成下面一行
    zlib.o: ../../include/ruby.h

     第三种报错:在源码编译安装ruby过程中会出现报错信息:

    [root@centos17zlib]#gem install redis
    ERROR:  While executing gem ... (Gem::Exception)
        Unable to require openssl, install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources
    

    解决办法:

    1. yum install openssl-devel -y
    
    2. 在ruby安装包/root/ruby-2.4.1/ext/openssl,执行ruby ./extconf.rb
    
    3.执行make,若出现make: *** No rule to make target `/include/ruby.h', needed by `ossl.o'.  Stop.;在Makefile顶部中的增加  top_srcdir = ../..
    
    4.执行make && make install
    

     在openssl/Mfile配置文件中添加内容:

    [root@centos17openssl]#vim /usr/local/src/ruby-2.5.5/ext/openssl/Makefile   
    

     

    4、开始用redis-trib.rb分配槽位,创建主从集群服务关系

    [root@rs2redis]#redis-trib.rb  create --replicas 1 192.168.37.7:6379  192.168.37.17:6379  192.168.37.27:6379  192.168.37.37:6379  192.168.37.47:6379  192.168.37.57:6379
    >>> Creating cluster
    >>> Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    192.168.37.7:6379
    192.168.37.17:6379
    192.168.37.27:6379
    Adding replica 192.168.37.47:6379 to 192.168.37.7:6379
    Adding replica 192.168.37.57:6379 to 192.168.37.17:6379
    Adding replica 192.168.37.37:6379 to 192.168.37.27:6379
    M: df86bca3b6d59894cb89cff7b9454271e974874b 192.168.37.7:6379
       slots:0-5460 (5461 slots) master
    M: c723bea0038cf2f20e3a75124c117bc0ff2f3347 192.168.37.17:6379
       slots:5461-10922 (5462 slots) master
    M: bdfe6741fe3de7803f7227f3c22c557c0043b713 192.168.37.27:6379
       slots:10923-16383 (5461 slots) master
    S: 3c4fbbd8048444e105789b1984907619786094c8 192.168.37.37:6379
       replicates bdfe6741fe3de7803f7227f3c22c557c0043b713
    S: 4fce7ec3e9c6bc06ae3ec285cf466abd84576d00 192.168.37.47:6379
       replicates df86bca3b6d59894cb89cff7b9454271e974874b
    S: 5f3bcdc39903ba3db09288b328207af2451daec5 192.168.37.57:6379
       replicates c723bea0038cf2f20e3a75124c117bc0ff2f3347
    Can I set the above configuration? (type 'yes' to accept): yes  输入yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join..
    >>> Performing Cluster Check (using node 192.168.37.7:6379)
    M: df86bca3b6d59894cb89cff7b9454271e974874b 192.168.37.7:6379
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    S: 4fce7ec3e9c6bc06ae3ec285cf466abd84576d00 192.168.37.47:6379
       slots: (0 slots) slave
       replicates df86bca3b6d59894cb89cff7b9454271e974874b
    S: 5f3bcdc39903ba3db09288b328207af2451daec5 192.168.37.57:6379
       slots: (0 slots) slave
       replicates c723bea0038cf2f20e3a75124c117bc0ff2f3347
    M: c723bea0038cf2f20e3a75124c117bc0ff2f3347 192.168.37.17:6379
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    M: bdfe6741fe3de7803f7227f3c22c557c0043b713 192.168.37.27:6379
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    S: 3c4fbbd8048444e105789b1984907619786094c8 192.168.37.37:6379
       slots: (0 slots) slave
       replicates bdfe6741fe3de7803f7227f3c22c557c0043b713
    [OK] All nodes agree about slots configuration.  所有节点槽位分配完成
    >>> Check for open slots...  检查打开的槽位
    >>> Check slots coverage...   检查插槽覆盖范围
    [OK] All 16384 slots covered.   所有餐位分配完成

     

     注意:如果创建失败,最大的原因可能是没有配置ruby客户端的密码,还要就是每个redis服务器里边有数据,如果有数据,可以进行以下操作,然后重新启动redis服务器即可。

    [root@centos17apps]#redis-cli -a 123456
    Warning: Using a password with '-a' option on the command line interface may not be safe.
    127.0.0.1:6379> flushall
    OK
    127.0.0.1:6379> cluster reset
    OK
    127.0.0.1:6379> 
    

     

      5、查看三对redis服务器的主从关系

     查看主从关系通过登录redis-cli,可看到三对主从对应关系:

    192.168.37.7(主)-------> 192.168.37.47(从)

    192.168.37.17(主)------> 192.168.37.57(从)

    192.168.37.27(主)------->192.168.37.37(从)

     6、测试主从效果

     1、在192.168.37.7主服务器上创建键值对

     

     2、在192.168.37.47服务器上查看同步的数据,此时从服务器上没有读写的权限

     

     7、演示主master服务器宕机,然后查看从服务器角色是否可以接管

     1、杀死192.168.37.7的redis主服务器

     

     2、查看此时192.168.37.47是否可以接管成为主服务器

    查看日志:tail -f /apps/redis/logs/redis_6379.log,可以看到此时从服务已经同步为主服务器。

      当再启动192.168.37.7服务器时,此时就成为从服务器(slave状态)。

    实战四:redis 集群cluster 及主从复制模型的实现(3台服务器,生产中足够)

    实现原理:当我们此时只有三台服务器去搭建redis高可用集群时,需要有主从同步功能,且三台服务器的主从服务器对应关系不在一个主机,避免服务器故障,导致主从服务器都出现问题不能访问。

    因此,要在不同主机上配置主从服务器同步,当主服务器宕机后,从服务器接管主服务器的的任务,继续进行运行。

    1、环境准备

    机器名称

    IP配置

    服务角色

    redis-master-cluster1

    192.168.37.7:6379

    主服务器1

    redis-master-cluster2

    192.168.37.17:6379

    主服务器2

    redis-master-cluster3

    192.168.37.27:6379

    主服务器3

    redis-slave-cluster1

    192.168.37.7:6380

    从服务器2

    redis-slave-cluster2

    192.168.37.17:6380

    从服务器3

    redis-slave-cluster3

    192.168.37.27:6380

    从服务器1

    2、开启配置3个源码编译的redis 主服务器,启用集群功能

    (1)将不同的数据存在在新建的目录下

    [root@rs2apps]#mkdir /apps/redis/{etc,data,logs.run}

    (2)修改配置文件,端口默认为6379,在三台主机上都配置集群服务,打开集群功能。

      vim  /apps/redis/etc/redis.conf

    bind 0.0.0.0   #监听所有地址
    port 6379   #监听的端口号
    daemonize yes   #后台守护方式开启服务
    logfile "/apps/redis/logs/redis_6379.log" 配置log日志存放路径
    pidfile /apps/redis/run/redis_6379.pid  配置pid存放路径
    dir /apps/redis/data   配置数据存放路径
    dbfilename dump_6379.rdb   数据名称
    requirepass 123456   配置redis登陆密码
    
    ### REDIS CLUSTER  ###   集群段
    cluster-enabled yes   #开启集群
    cluster-config-file nodes-6379.conf    #集群的配置文件,首次启动自动生成,有两个主机监听端口,就修改两个不同后缀
    cluster-node-timeout 15000    #请求超时 默认15秒,可自行设置
    appendonly yes    #aof日志开启,有需要就开启,它会每次写操作都记录一条日志
    masterauth "123456" #配置验证redis密码

    创建存放redis的日志、数据及pid文件

    [root@centos7 ~]# mkdir /apps/redis/{run,logs,data}  -p
    [root@centos7 ~]# chown -R redis.redis  /apps/redis   # 将权限进行修改,否则无法启动redis服务。

    (3)创建三个6380端口的服务器,并在三个服务器上分别创建一个存放从服务器log、数据、pid文件及配置文件的目录

    [root@rs2redis6380]#mkdir /apps/redis6380/{etc,logs,run,data}  -p
    [root@rs2redis6380]# chown -R redis.redis /apps/redis6380 # 修改目录权限
    [root@rs2redis6380]#cp /apps/redis/etc/redis.conf  /apps/redis6380/etc/redis.conf

    (4)修改三个新创建的端口为6380的服务器,设置都一致:可以在vim编辑模式下进行全局替换":%s/6379/6380/g"

     vim /apps/redis6380/etc/redis.conf

    bind 0.0.0.0   #监听所有地址
    port 6380   #监听的端口号
    daemonize yes   #后台守护方式开启服务
    logfile "/apps/redis/logs/redis_6380.log" 配置log日志存放路径
    pidfile /apps/redis/run/redis_6380.pid  配置pid存放路径
    dir /apps/redis/data   配置数据存放路径
    dbfilename dump_6380.rdb   数据名称
    requirepass 123456   配置redis登陆密码
    
    ### REDIS CLUSTER  ###   集群段
    cluster-enabled yes   #开启集群
    cluster-config-file nodes-6380.conf    #集群的配置文件,首次启动自动生成,有两个主机监听端口,就修改两个不同后缀
    cluster-node-timeout 15000    #请求超时 默认15秒,可自行设置
    appendonly yes    #aof日志开启,有需要就开启,它会每次写操作都记录一条日志
    masterauth "123456" #配置验证redis密码

    (5)启动六个主机的redis服务器

    [root@rs2redis6380]#redis-server /apps/redis/etc/redis.conf 
    [root@rs2redis6380]#redis-server /apps/redis6380/etc/redis.conf 

     最好将启动服务写入到本地脚本中,避免主机宕机后无法启动服务

    [root@cenots27~]#vim /etc/rc.d/rc.local  写入本地启动服务脚本中
    redis-server /apps/redis/etc/redis.conf
    redis-server  /apps/redis6380/etc/redis.conf
    
    [root@cenots27~]#chmod +x /etc/rc.d/rc.local  加上执行权限
    

    3、源码编译ruby包(在任意一个redis集群编译即可):

    官网下载路径:http://www.ruby-lang.org/en/downloads/

    1、安装依赖的包。

    [root@centos17src]#yum install "development tools"  安装开发包
    [root@centos17src]#yum install  openssl-devel openssl  -y  安装加密包
    [root@centos17src]#yum install zlib zlib-devel -y  安装依赖包
    

     2、下载ruby包,并进行源码编译。  

    [root@centos17src]#rz
    [root@centos17src]#tar -xvf ruby-2.5.5.tar.gz 解压文件
    [root@centos17src]#cd ruby-2.5.5/  切换到目录下
    [root@centos17src]#./configure  开始配置
    [root@centos17src]#make -j2 && make install  编译安装
    [root@centos17src]#gem install redis
    

      3、创建redis-trib.rb软链接和验证编译后的ruby是否可以正常使用

    [root@centos17src]#ln -s /usr/local/src/redis-4.0.14/src/redis-trib.rb /usr/bin  创建软链接
    [root@centos17src]#redis-trib.rb   # 验证编译之后的命令是否可用,如果有帮助文档显示,说明可以使用
    Usage: redis-trib <command> <options> <arguments ...>
    
      create          host1:port1 ... hostN:portN
                      --replicas <arg>
      check           host:port
      info            host:port
      fix             host:port
                      --timeout <arg>
      reshard         host:port
                      --from <arg>
                      --to <arg>
                      --slots <arg>
                      --yes
                      --timeout <arg>
                      --pipeline <arg>
      rebalance       host:port
                      --weight <arg>
                      --auto-weights
                      --use-empty-masters
                      --timeout <arg>
                      --simulate
                      --pipeline <arg>
                      --threshold <arg>
      add-node        new_host:new_port existing_host:existing_port
                      --slave
                      --master-id <arg>
      del-node        host:port node_id
      set-timeout     host:port milliseconds
      call            host:port command arg arg .. arg
      import          host:port
                      --from <arg>
                      --copy
                      --replace
      help            (show this help)
    
    For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

    编译完成后需要修改gems客户端配置文件,加入密码,为了能访问加密后的redis服务,密码和redis服务一致。

    [root@rs2redis]#vim /usr/local/lib/ruby/gems/2.5.0/gems/redis-4.1.3/lib/redis/client.rb  注意修改redis版本

     

    第一种报错:ruby 安装redis报错

    [root@localhost tools]# gem install redis
    ERROR: Loading command: install (LoadError)
     cannot load such file -- zlib
    ERROR: While executing gem ... (NoMethodError)
        undefined method `invoke_with_build_args' for nil:NilClass

    解决办法:

    yum -y install zlib-devel
    进入ruby源码文件夹,安装ruby自身提供的zlib包
    cd ruby-2.5.1/ext/zlib
    ruby ./extconf.rb
    make
    make install

     第二种报错:ruby 安装redis报错

    make: *** No rule to make target `/include/ruby.h', needed by `zlib.o'. Stop. 

    解决办法:

    vim /usr/local/src/ruby-2.5.1/ext/zlib/Makefile
    #zlib.o: $(top_srcdir)/include/ruby.h #把这一行替换成下面一行
    zlib.o: ../../include/ruby.h

     第三种报错:在源码编译安装ruby过程中会出现报错信息:

    [root@centos17zlib]#gem install redis
    ERROR:  While executing gem ... (Gem::Exception)
        Unable to require openssl, install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources
    

    解决办法:

    1. yum install openssl-devel -y
    
    2. 在ruby安装包/root/ruby-2.4.1/ext/openssl,执行ruby ./extconf.rb
    
    3.执行make,若出现make: *** No rule to make target `/include/ruby.h', needed by `ossl.o'.  Stop.;在Makefile顶部中的增加  top_srcdir = ../..
    
    4.执行make && make install
    

     在openssl/Mfile配置文件中添加内容:

    [root@centos17openssl]#vim /usr/local/src/ruby-2.5.5/ext/openssl/Makefile   
    

    4、创建三主三从集群服务

     注意:前面三个IP地址默认是创建的主服务器,后面三个对应的是从服务器

    [root@rs2redis6380]#redis-trib.rb  create --replicas 1  192.168.37.7:6379  192.168.37.17:6379  192.168.37.27:6379  192.168.37.7:6380  192.168.37.17:6380  192.168.37.27:6380
    >>> Creating cluster
    >>> Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    192.168.37.7:6379
    192.168.37.17:6379
    192.168.37.27:6379
    Adding replica 192.168.37.17:6380 to 192.168.37.7:6379
    Adding replica 192.168.37.27:6380 to 192.168.37.17:6379
    Adding replica 192.168.37.7:6380 to 192.168.37.27:6379
    M: df86bca3b6d59894cb89cff7b9454271e974874b 192.168.37.7:6379
       slots:0-5460 (5461 slots) master
    M: c723bea0038cf2f20e3a75124c117bc0ff2f3347 192.168.37.17:6379
       slots:5461-10922 (5462 slots) master
    M: 203b931272d0c313f1fec283410c318953035757 192.168.37.27:6379
       slots:10923-16383 (5461 slots) master
    S: 7f1bc39e92ea982c0914eca469589eb60f99ae5b 192.168.37.7:6380
       replicates 203b931272d0c313f1fec283410c318953035757
    S: 56c599c944045419ccd4d6f73a38fd4b53292795 192.168.37.17:6380
       replicates df86bca3b6d59894cb89cff7b9454271e974874b
    S: 37ed98ec914c40dabb8db5d493fd178a60456ca7 192.168.37.27:6380
       replicates c723bea0038cf2f20e3a75124c117bc0ff2f3347
    Can I set the above configuration? (type 'yes' to accept): yes
    >>> Nodes configuration updated
    >>> Assign a different config epoch to each node
    >>> Sending CLUSTER MEET messages to join the cluster
    Waiting for the cluster to join......
    >>> Performing Cluster Check (using node 192.168.37.7:6379)
    M: df86bca3b6d59894cb89cff7b9454271e974874b 192.168.37.7:6379
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    S: 56c599c944045419ccd4d6f73a38fd4b53292795 192.168.37.17:6380
       slots: (0 slots) slave
       replicates df86bca3b6d59894cb89cff7b9454271e974874b
    M: 203b931272d0c313f1fec283410c318953035757 192.168.37.27:6379
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    S: 7f1bc39e92ea982c0914eca469589eb60f99ae5b 192.168.37.7:6380
       slots: (0 slots) slave
       replicates 203b931272d0c313f1fec283410c318953035757
    S: 37ed98ec914c40dabb8db5d493fd178a60456ca7 192.168.37.27:6380
       slots: (0 slots) slave
       replicates c723bea0038cf2f20e3a75124c117bc0ff2f3347
    M: c723bea0038cf2f20e3a75124c117bc0ff2f3347 192.168.37.17:6379
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    

    5、查看此时高可用集群的对应关系 

    由下图可以看出:

    192.168.37.27(主)------> 192.168.37.7(从)

    192.168.37.7(主)-------->192.168.37.17(从)

    192.168.37.17(主)-------> 192.168.37.27(从)

     也可以直接在每个服务器6379端口登陆查看:7(主)--->17(从)

    在17上查看:17(主)---->27(从)

     在27上查看27(主)------>7(从)

     注意:修改配置文件后,主从服务器交叉对应,避免存在服务器宕机,主从服务器都在一个主机上导致不能提供服务。

    7、启动三个从redis服务器

    [root@rs2redis6380]#redis-server /apps/redis6380/etc/redis.conf    启动三个从服务器
    

    8、验证主从复制效果

     在192.168.37.7主服务器上创建一个key2文件

     在17的端口为6380的从服务器能查看到此key2的名称,但是不能查看到内容,并且也不能写入数据

     9、演示宕机过程,查看从服务器是否可以接管主服务器的服务变为主服务器

      (1)宕机192.168.37.7的6380端口的服务器

      (2)此时192.168.37.17的6380端口从服务器变为主服务器

     (3)当再次启动192.168.37.7端口为6379的redis服务器,此时旧主服务器就变成从服务器。

      

     

     



      

  • 相关阅读:
    javajava.lang.reflect.Array
    基于annotation的spring注入
    jquery插件
    spring的注入方式
    jqueryajax
    javascript基础
    xml基础
    js 获取FCKeditor 值
    TSQL 解析xml
    Linq
  • 原文地址:https://www.cnblogs.com/struggle-1216/p/12121104.html
Copyright © 2011-2022 走看看