• Redis系列1-redis主从、哨兵模式、集群模式搭建


    Redis作为一款开源的、高性能的键值对存储。支持主从复制,并通过哨兵模式(sentinel)提高了高可用性,以及集群(Redis Cluster)模式保证了高并发性。

    一、redis主从

    Redis本身提供数据持久化的功能(两种方式:RDB和AOF),把数据保存到磁盘上,保证了即使服务器重启的情况下也不会造成数据丢失。由于数据是保存在一台服务器上的,如果由于某些原因导致系统硬盘损坏,也会导致数据丢失。鉴于这种情况,一般的做法是把数据备份到不同的服务器上,即使有一台服务器出现故障,其它服务器也可以提供服务。

    Redis提供了一主(master)多从(slave)数据库的方式来进行数据的备份。一个主数据库可以有多个从数据库,一个从数据库只能有一个主数据库。一般情况下,主数据是可读写的,从数据只能读,并且从数据库同步主数据库新增的数据。

    Redis主从是一种备份关系,主数据库写入数据,同步到从数据库。如果主数据损坏了,从数据库可以作为主数据库继续提供服务。

    下面就来搭建一个一主二从的主从复制环境。演示环境是在一台centos 7服务器上模拟的,真实环境需要把主从服务器放置在不同的服务器上。

    1.创建3个redis服务,对应的端口分别是6001,6002,6003,其中6001作为主库,6002,6003作为6001的从库(备份库)

    在当前目录新增3个目录,名称以端口命名:

    mkdir 6001 6002 6003
    2.配置主从关系

    配置主从关系有两种方式,一种是通过修改redis.conf配置文件,另一种是通过命令修改相应配置项。把redis.conf文件分别复制到对应的目录下

    • 修改redis.conf

    主库配置:

    cd ./6001 
    vim redis.conf //redis.conf 主库主要配置项 
    ​
    bind 192.168.80.129//本机IP地址 
    port 6001 
    requirepass 123456 //设置密码 
    masterauth 123456 //链接主库密码

    从库配置(以6002端口为例,6003修改相应端口即可):

    cd ./6002 
    vim redis.conf 
    ​
    bind 192.168.80.129 
    port 6002 
    requirepass 123456 
    masterauth 123456 //连接主库的密码 对应主库中
    requirepass slaveof 192.168.80.129 6001//主库 ip 端口
    • 命令方式更改主从配置

    //分别修改3个redis服务的端口和ip
    6001:
    bind 192.168.80.129
    port 6001
    6002:
    bind 192.168.80.129
    port 6002
    6003:
    bind 192.168.80.129
    port 6003
    //开启redis服务
    ./redis-server ./6001/redis.conf
    ./redis-server ./6002/redis.conf
    ./redis-server ./6003/redis.conf
    //使用redis-cli连接6002
    ./redis-cli -h 192.168.80.129 -p 6002 -a 123456
    192.168.80.129:6002> slaveof 192.168.80.129 6001
    OK
    192.168.80.129:6002> config set masterauth 123456
    OK
    192.168.80.129:6002> info replication
    # Replication
    role:slave
    master_host:192.168.80.129
    master_port:6001
    master_link_status:up
    master_last_io_seconds_ago:1
    master_sync_in_progress:0
    slave_repl_offset:28
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:131038188755eea59eb4a84de0e2702c977a438b
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:28
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:28
    //查看6001
    192.168.80.129:6001> info replication
    # Replication
    role:master
    connected_slaves:1
    slave0:ip=192.168.80.129,port=6002,state=online,offset=42,lag=1
    master_replid:131038188755eea59eb4a84de0e2702c977a438b
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:42
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:42

    可以看到6002已经是6001的从服务了,按照6002配置6003为6001的从服务器,查询6001的状态:

    192.168.80.129:6001> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=192.168.80.129,port=6002,state=online,offset=1022,lag=1
    slave1:ip=192.168.80.129,port=6003,state=online,offset=1022,lag=0
    master_replid:131038188755eea59eb4a84de0e2702c977a438b
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:1022
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:1022

    有2个从服务器6002,6003

    >>>测试

    通过第二步已经成功创建了一主二从的主从复制环境,主服务是可读写的,从服务是只读的。

    在6002上是禁止写入的:

    192.168.80.129:6003> set name 123
    (error) READONLY You can't write against a read only slave.

    在6001上写入数据:

    192.168.80.129:6001> set name test
    OK

    在6002上查看数据已经同步到6002从数据库上:

    192.168.80.129:6002> get name
    "test"

    到这里,一个主从复制、读写分离的环境就完成了,主服务器负责写入,从服务器服务读取。然而如果主服务器由于某种原因down掉的话,整个服务就没有办法写入,需要运维人员手动恢复主数据库后才能正常提供服务。下面哨兵模式的登场就有效的解决了主服务down掉人工介入的问题。

    二、Redis哨兵(sentinel)

    设置Redis主从后,如果主数据断开后,需要人工手动设置一个从数据库提升为主数据库继续提供服务,然而这种人工介入的方式,需要耗费一定的时间。为了实现此过程的自动化,Redis提供了哨兵模式(sentinel)。哨兵负责监控主从数据的运行状态,如果检测到主数据库出现异常,就自动选择一个从数据库升级为主数据库。

    哨兵保证Redis的高可用性(HA),保证特殊故障后能够自动切换,如果主库异常,自动推选出一个从库作为新的主库继续提供服务。

    下面让我们在主从模式的基础上,添加哨兵机制,主库down掉后,推选出一个从库作为新的主库,继续提供服务。

    1.将sentinel.conf配置文件复制到目录下,修改相应配置:
    vim sentinel.conf
    //修改如下配置项
    port 16001
    sentinel monitor mymaster 192.168.80.129 6001 1
    sentinel auth-pass mymaster 123456
    2.开启哨兵
    ./redis-sentinel ./sentinel.conf
    //显示如下信息,启动成功,自动检测到6001下的从服务器
    120502:X 18 Apr 11:26:35.565 # Sentinel ID is 0676c2efd784d10801da4e51f17a35ddb2018e54
    120502:X 18 Apr 11:26:35.565 # +monitor master mymaster 192.168.80.129 6001 quorum 1
    120502:X 18 Apr 11:26:35.566 * +slave slave 192.168.80.129:6002 192.168.80.129 6002 @ mymaster 192.168.80.129 6001
    120502:X 18 Apr 11:26:35.567 * +slave slave 192.168.80.129:6003 192.168.80.129 6003 @ mymaster 192.168.80.129 6001

    哨兵启动成功后,模拟6001down掉,查看服务状态:

    ./redis-cli -h 192.168.80.129 -p 6001 -a 6001 shutdown //或是直接kill id
    //查看哨兵服务日志,如下:成功将6003提升为主库
    120502:X 18 Apr 11:30:20.478 # +switch-master mymaster 192.168.80.129 6001 192.168.80.129 6003
    120502:X 18 Apr 11:30:20.478 * +slave slave 192.168.80.129:6002 192.168.80.129 6002 @ mymaster 192.168.80.129 6003
    120502:X 18 Apr 11:30:20.478 * +slave slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003//使用redis-cli连接6003,查看信息如下:6003做为新的主库,6002为其从库
    192.168.80.129:6003> info replication
    # Replication
    role:master
    connected_slaves:1
    slave0:ip=192.168.80.129,port=6002,state=online,offset=26318,lag=0
    master_replid:2902c22b9c0c34000c9b3af52dbd812242774a90
    master_replid2:695a9c210b17f18e6fc39503b28af3ee341bae2c
    master_repl_offset:26461
    second_repl_offset:15804
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:26461

    重新开启6001服务,6001会成为6003主库的从库:

    ./redis-server ./6001/redis.conf
    //哨兵输入如下信息,6001成功成为6003的从库
    120502:X 18 Apr 11:44:16.161 # +sdown slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003
    120502:X 18 Apr 11:46:46.411 * +reboot slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003
    120502:X 18 Apr 11:46:46.467 # -sdown slave 192.168.80.129:6001 192.168.80.129 6001 @ mymaster 192.168.80.129 6003//查看6003的信息,拥有6001,6002两个从服务:
    192.168.80.129:6003> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=192.168.80.129,port=6002,state=online,offset=89380,lag=1
    slave1:ip=192.168.80.129,port=6001,state=online,offset=89380,lag=1
    master_replid:2902c22b9c0c34000c9b3af52dbd812242774a90
    master_replid2:695a9c210b17f18e6fc39503b28af3ee341bae2c
    master_repl_offset:89380
    second_repl_offset:15804
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:89380

    三、Redis集群(cluster)

    虽然Redis提供了主从备份、哨兵模式自动切换主从数据库。但是每个Redis实例是全量存储的,存储的都是完整的数据。这就造成了单个Redis并发有限,并且导致内存占用太大,rdb文件文件过大,从很大的rdb文件中同步恢复数据会很慢。Redis集群模式出现就解决了这个问题,采用分布式存储,最大化的使用内存。Redis集群共有16384个哈希槽(slot),每个Redis节点都会分配一部分slot,通过CRC(16)校验后16384取模,得到给定key的哈希槽,就把对应的可以存储在相应的节点上。

    Redis集群保证了高并发性,同时集群导致了数据的分散,不同的key存放到不同的槽中。

    下面使用Redis自带的redis-trib.rb工具来逐步搭建Redis Cluster。实战环境需要把redis部署在不同的服务器上,我们演示是在一台centos 7服务器上,用不同的端口来进行部署。由于Redis集群中至少需要3个主节点,每个主节点至少一个从节点(备份),所以需要创建6个节点:

    创建6个文件夹,分别命名为:7001,7002,7003,7004,7005,7006

    mkdir 7001 7002 7003 7004 7005 7006
    1、添加配置信息

    把redis.conf配置文件复制到对应的6个文件夹中,并按如下内容配置:

    以7001为例,其它文件内参考如下项修改相应的端口:

    bind 192.168.80.129 //配置本机ip
    port 7001 //配置端口
    daemonize yes //以守护进程方式启动
    pidfile /var/run/redis_7001.pid
    dbfilename dump7001.rdb
    masterauth 123456 //访问主机密码
    requirepass 123456 //访问本实例密码
    appendonly yes //开启aof
    appendfilename "appendonly7001.aof"
    cluster-enabled yes //开启集群模式
    cluster-config-file nodes-7001.conf
    2、编写启动、停止服务脚本:

    启动脚本,命名:start-server.sh

    ./redis-server ./7001/redis.conf
    ./redis-server ./7002/redis.conf
    ./redis-server ./7003/redis.conf
    ./redis-server ./7004/redis.conf
    ./redis-server ./7005/redis.conf
    ./redis-server ./7006/redis.conf

    停止脚本,命名:stop-server.sh

    ./redis-cli -c -h 192.168.80.129 -c 7001 -a 123456 shutdown
    ./redis-cli -c -h 192.168.80.129 -c 7002 -a 123456 shutdown
    ./redis-cli -c -h 192.168.80.129 -c 7003 -a 123456 shutdown
    ./redis-cli -c -h 192.168.80.129 -c 7004 -a 123456 shutdown
    ./redis-cli -c -h 192.168.80.129 -c 7005 -a 123456 shutdown
    ./redis-cli -c -h 192.168.80.129 -c 7006 -a 123456 shutdown

    保存之后,需要设置可执行权限:

    chmod +x start-server.sh 
    chmod +x stop-server.sh
    3、安装redis-trib.rb工具所需环境

    由于redis-trib.rb是使用ruby语言编写的,在使用工具创建集群前,需要安装对应的依赖环境。

    yum install ruby 
    yum install rubygems 
    gem install redis

    创建集群

    ./start-server.sh //开启redis实例
     ps -ef|grep redis //查看redis的状态
     root     120202      1  0 09:35 ?        00:00:26 ./redis-server 192.168.80.129:7005 [cluster]
     root     122327      1  0 09:06 ?        00:00:29 ./redis-server 192.168.80.129:7002 [cluster]
     root     122332      1  0 09:06 ?        00:00:29 ./redis-server 192.168.80.129:7003 [cluster]
     root     122337      1  0 09:06 ?        00:00:28 ./redis-server 192.168.80.129:7004 [cluster]
     root     122350      1  0 09:06 ?        00:00:29 ./redis-server 192.168.80.129:7006 [cluster]
    ​
     ./redis-trib.rb create --replicas 1 192.168.80.129:7001 192.168.80.129:7002 192.168.80.129:7003 192.168.80.129:7004 192.168.80.129:7005 192.168.80.129:7006
     

    使用create命令创建集群,--replicas 1参数表示为每个主服务器分配1个从服务器。

    在redis.conf配置文件中我们设置了requirepass,需要修改/usr/local/rvm/gems/ruby-2.5.3/gems/redis-4.1.0/lib/redis/client.rb文件中password

    DEFAULTS = {
          :url => lambda { ENV["REDIS_URL"] },
          :scheme => "redis",
          :host => "127.0.0.1",
          :port => 6379,
          :path => nil,
          :timeout => 5.0,
          :password => 123456,
          :db => 0,
          :driver => nil,
          :id => nil,
          :tcp_keepalive => 0,
          :reconnect_attempts => 1,
          :reconnect_delay => 0,
          :reconnect_delay_max => 0.5,
          :inherit_socket => false
        }

    创建成功后,随便连接一个redis实例,查看集群所有节点信息:

    ./redis-cli -c -h 192.168.80.129 -p 7001 -a 123456
    cluster nodes
    4b25a13040b72063c124194afdd2498d9bdf9ad5 192.168.80.129:7006@17006 slave 01eb67ca03f468254ae44774ee8923da318a4bce 0 1555485726804 6 connected
    b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 192.168.80.129:7003@17003 master - 0 1555485726000 3 connected 10923-16383
    53af35146e22456897920e02c696323b8fe29c55 192.168.80.129:7004@17004 slave b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 0 1555485725000 4 connected
    7f7041c5ef11f5165c7d913596243ca142826907 192.168.80.129:7001@17001 myself,master - 0 1555485726000 8 connected 0-5460
    01eb67ca03f468254ae44774ee8923da318a4bce 192.168.80.129:7002@17002 master - 0 1555485725000 2 connected 5461-10922
    bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 192.168.80.129:7005@17005 slave 7f7041c5ef11f5165c7d913596243ca1428

    从上面信息可以看出,三个主库(7001,7002,7003),三个从库(7004,7005,7006)。三个主库分配的slot分别是:

    70010-5460
    
    70025461-10922
    
    700310923-16383

    结束7001主库,查看集群所有节点状态:

    92.168.80.129:7002> cluster nodes
    b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 192.168.80.129:7003@17003 master - 0 1555488472000 3 connected 10923-16383
    bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 192.168.80.129:7005@17005 master - 0 1555488474017 9 connected 0-5460
    53af35146e22456897920e02c696323b8fe29c55 192.168.80.129:7004@17004 slave b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 0 1555488473000 4 connected
    01eb67ca03f468254ae44774ee8923da318a4bce 192.168.80.129:7002@17002 myself,master - 0 1555488470000 2 connected 5461-10922
    4b25a13040b72063c124194afdd2498d9bdf9ad5 192.168.80.129:7006@17006 slave 01eb67ca03f468254ae44774ee8923da318a4bce 0 1555488473006 6 connected
    7f7041c5ef11f5165c7d913596243ca142826907 192.168.80.129:7001@17001 master,fail - 1555488452052 1555488450000 8 disconnected

    其中7001的状态已经是fail,7005已升级为主库继续提供服务。显然redis cluster本身就集成了主从备份和哨兵模式,主数据库down掉后,从服务器自动被推选为新的主服务器,查看集群状态如下:

    192.168.80.129:7002> cluster info
    cluster_state:ok
    cluster_slots_assigned:16384
    cluster_slots_ok:16384
    cluster_slots_pfail:0
    cluster_slots_fail:0
    cluster_known_nodes:6
    cluster_size:3
    cluster_current_epoch:8
    cluster_my_epoch:2
    cluster_stats_messages_ping_sent:33577
    cluster_stats_messages_pong_sent:25592
    cluster_stats_messages_meet_sent:4
    cluster_stats_messages_fail_sent:8
    cluster_stats_messages_auth-ack_sent:2
    cluster_stats_messages_sent:59183
    cluster_stats_messages_ping_received:25590
    cluster_stats_messages_pong_received:24893
    cluster_stats_messages_meet_received:2
    cluster_stats_messages_fail_received:2
    cluster_stats_messages_publish_received:278
    cluster_stats_messages_auth-req_received:2
    cluster_stats_messages_received:50767

    再次启动7001,7001已成为7005的从库

    [root@localhost cluster]# ./redis-server ./7001/redis.conf
    60511:C 17 Apr 16:10:44.760 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    60511:C 17 Apr 16:10:44.760 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=60511, just started
    60511:C 17 Apr 16:10:44.760 # Configuration loaded
    [root@localhost cluster]# ./redis-cli -c -h 192.168.80.129 -p 7001 -a 123456
    Warning: Using a password with '-a' option on the command line interface may not be safe.
    192.168.80.129:7001> cluster nodes
    7f7041c5ef11f5165c7d913596243ca142826907 192.168.80.129:7001@17001 myself,slave bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 0 1555488653000 8 connected
    bcd17fb8c3ae4e20ce2b1edc82c8e235475dcf0f 192.168.80.129:7005@17005 master - 0 1555488657756 9 connected 0-5460
    53af35146e22456897920e02c696323b8fe29c55 192.168.80.129:7004@17004 slave b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 0 1555488653732 4 connected
    b9fc41ff7cf22b3b7b066883f4f0dae6c0552114 192.168.80.129:7003@17003 master - 0 1555488656752 3 connected 10923-16383
    4b25a13040b72063c124194afdd2498d9bdf9ad5 192.168.80.129:7006@17006 slave 01eb67ca03f468254ae44774ee8923da318a4bce 0 1555488655743 6 connected
    01eb67ca03f468254ae44774ee8923da318a4bce 192.168.80.129:7002@17002 master - 0 1555488656000 2 connected 5461-10922

    PS:如果有一个主数据库异常后,没有从数据库可以恢复,整个集群就会down掉。

    本小节主要简单的介绍下redis集群的搭建,以及模拟一个主机down掉之后从机自动切换成主机的过程,更多有关redis集群内容会单独的章节进行分析总结。

  • 相关阅读:
    使用hibernate利用实体类生成表和利用表生成实体类
    多线程循环打印ABC
    maven在整合springmvc+hibernate运行时遇到的一些问题
    checkbox属性获取
    glib中关于线程池的一个实例
    阅读英文文献总结的专业词汇
    网络流分类领域牛人
    锐捷s3550千兆交换机配置端口镜像
    转载Wireshark过滤语法
    DispatcherServlet处理流程
  • 原文地址:https://www.cnblogs.com/alsbingo/p/13040738.html
Copyright © 2020-2023  润新知