redis集群_redis集群搭建 - CSDN
精华内容
参与话题
  • 理解Redis集群

    千次阅读 多人点赞 2018-04-10 09:53:51
    一、什么是Redis集群 Redis 集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis 实现, 集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset)。 Redis 集群中不存在中心...

    一、什么是Redis集群

    Redis 集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis 实现, 集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset)。

    Redis 集群中不存在中心(central)节点或者代理(proxy)节点, 集群的其中一个主要设计目标是达到线性可扩展性(linear scalability)。

    Redis 集群提供了一种运行 Redis 的方式,其中数据在多个 Redis 节点间自动分区。Redis 集群还在分区期间提供一定程度的可用性,即在实际情况下能够在某些节点发生故障或无法通信时继续运行。但是,如果发生较大故障(例如,大多数主站不可用时),集群会停止运行。

    二、Redis集群模型

    70

    1):所有的节点通过服务通道直接相连,各个节点之间通过二进制协议优化传输的速度和带宽。

    2):客户端与节点之间通过 ascii 协议进行通信

    3):客户端与节点直连,不需要中间 Proxy 层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

    4):尽管这些节点彼此相连,功能相同,但是仍然分为两种节点:master 和 slave。

    三、各个节点之间都传递了什么信息

    70

    通过上面的图我们可以知道各个节点之间通过 PING-PONG 机制通信,下面是一段关于 PING-PONG 机制的会话”内容”。

    节点M:PING,嘿,朋友你好吗?我是 XYZ 哈希槽的 master ,配置信息是 FF89X1JK。

    节点N:PONG,我很好朋友,我也是 XYZ 哈希槽的 master ,配置信息是 FF89X1JK。

    节点M:我这里有一些关于我最近收到的其他节点的信息 ,A 节点回复了我的 PING 消息,我认为 A 节点是正常的。B 没有回应我的消息,我猜它现在可能出问题了,但是我需要一些 ACK(Acknowledgement) 消息来确认。

    节点N:我也想给你分享一些关于其它节点的信息,C 和 D 节点在指定的时间内回应了我, 我认为它们都是正常的,但是 B 也没有回应我,我觉得它现在可能已经挂掉了。

    每个节点会向集群中的其他节点发送节点状态信息,如果某个节点挂掉停止了服务,那么会执行投票容错机制,关于这个机制,会在下面讲到。

    四、Hash 槽

    70
    Redis 集群不使用一致的散列,而是一种不同的分片形式,其中每个键在概念上都是我们称之为散列槽的一部分,目的是使数据均匀的存储在诸多节点中。这点类似于 HashMap 中的桶(bucket)。

    Redis 集群中有 16384 个散列槽,为了计算给定密钥的散列槽,Redis 对 key 采用 CRC16 算法,以下是负责将键映射到槽的算法:

    slot = crc16(key) mod NUMER_SLOTS

    例如,你可能有3个节点,其中一个集群:

    • 节点 A 包含从0到5500的散列槽。
    • 节点 B 包含从 5501 到 11000 的散列槽。
    • 节点 C 包含 从11001 到16383 的散列槽。

    Hash 槽可以轻松地添加和删除集群中的节点。例如,如果我想添加一个新节点 D,我需要将节点 A,B,C 中的一些散列槽移动到 D。同样,如果我想从节点 A 中删除节点 A,可以只移动由 A 服务的散列槽到 B 和 C。当节点 A 为空时,可以将它从群集中彻底删除。

    五、容错

    70

    • 集群中的节点不断的 PING 其他的节点,当一个节点向另一个节点发送 PING 命令, 但是目标节点未能在给定的时限内回复, 那么发送命令的节点会将目标节点标记为 PFAIL(possible failure,可能已失效)。

    • 当节点接收到其他节点发来的信息时, 它会记下那些被其他节点标记为失效的节点。 这被称为失效报告(failure report)。

    • 如果节点已经将某个节点标记为 PFAIL , 并且根据节点所收到的失效报告显式, 集群中的大部分其他主节点也认为那个节点进入了失效状态, 那么节点会将那个失效节点的状态标记为 FAIL 。

    • 一旦某个节点被标记为 FAIL , 关于这个节点已失效的信息就会被广播到整个集群, 所有接收到这条信息的节点都会将失效节点标记为 FAIL 。

    简单来说, 一个节点要将另一个节点标记为失效, 必须先询问其他节点的意见, 并且得到大部分主节点的同意才行。

    • 如果被标记为 FAIL 的是从节点, 那么当这个节点重新上线时, FAIL 标记就会被移除。 一个从节点是否处于 FAIL 状态, 决定了这个从节点在有需要时能否被提升为主节点。

    • 如果一个主节点被打上 FAIL 标记之后, 经过了节点超时时限的四倍时间, 再加上十秒钟之后, 针对这个主节点的槽的故障转移操作仍未完成, 并且这个主节点已经重新上线的话, 那么移除对这个节点的 FAIL 标记。在不符合上面的条件后,一旦某个主节点进入 FAIL 状态, 如果这个主节点有一个或多个从节点存在, 那么其中一个从节点会被升级为新的主节点, 而其他从节点则会开始对这个新的主节点进行复制。

    参考资料:
    https://redis.io/topics/cluster-tutorial
    https://redis.io/presentation/Redis_Cluster.pdf
    http://doc.redisfans.com/topic/cluster-spec.html

    展开全文
  • Redis集群详解

    万次阅读 多人点赞 2019-05-10 13:56:46
    Redis集群详解 Redis有三种集群模式,分别是: * 主从模式 * Sentinel模式 * Cluster模式 三种集群模式各有特点,关于Redis介绍可以参考这里:NoSQL(二)——Redis Redis官网:https://redis.io/ ,最新版本5.0.4...

    Redis集群详解

    Redis有三种集群模式,分别是:

    * 主从模式
    
    * Sentinel模式
    
    * Cluster模式
    

    三种集群模式各有特点,关于Redis介绍可以参考这里:NoSQL(二)——Redis

    Redis官网:https://redis.io/ ,最新版本5.0.4


    主从模式

    主从模式介绍

    主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。

    其中主从复制有如下特点:

    * 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库
    
    * 从数据库一般都是只读的,并且接收主数据库同步过来的数据
    
    * 一个master可以拥有多个slave,但是一个slave只能对应一个master
    
    * slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来
    
    * master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务
    
    * master挂了以后,不会在slave节点中重新选一个master
    

    工作机制:

    当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。

    复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。

    安全设置:

    当master节点设置密码后,

    客户端访问master需要密码
    
    启动slave需要密码,在配置文件中配置即可
    
    客户端访问slave不需要密码
    

    缺点:

    从上面可以看出,master节点在主从模式中唯一,若master挂掉,则redis无法对外提供写服务。

    主从模式搭建

    • 环境准备:
    master节点                  192.168.30.128
    
    slave节点                   192.168.30.129
    
    slave节点                   192.168.30.130
    
    • 全部下载安装:
    # cd /software
    
    # wget http://download.redis.io/releases/redis-5.0.4.tar.gz
    
    # tar zxf redis-5.0.4.tar.gz && mv redis-5.0.4/ /usr/local/redis
    
    # cd /usr/local/redis && make && make install
    
    # echo $?
    0
    
    • 全部配置成服务:

    服务文件

    # vim /usr/lib/systemd/system/redis.service
    
    [Unit]
    Description=Redis persistent key-value database
    After=network.target
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    ExecStart=/usr/local/bin/redis-server /usr/local/redis/redis.conf --supervised systemd
    ExecStop=/usr/libexec/redis-shutdown
    Type=notify
    User=redis
    Group=redis
    RuntimeDirectory=redis
    RuntimeDirectoryMode=0755
    
    [Install]
    WantedBy=multi-user.target
    

    shutdown脚本

    # vim /usr/libexec/redis-shutdown
    
    #!/bin/bash
    #
    # Wrapper to close properly redis and sentinel
    test x"$REDIS_DEBUG" != x && set -x
    
    REDIS_CLI=/usr/local/bin/redis-cli
    
    # Retrieve service name
    SERVICE_NAME="$1"
    if [ -z "$SERVICE_NAME" ]; then
       SERVICE_NAME=redis
    fi
    
    # Get the proper config file based on service name
    CONFIG_FILE="/usr/local/redis/$SERVICE_NAME.conf"
    
    # Use awk to retrieve host, port from config file
    HOST=`awk '/^[[:blank:]]*bind/ { print $2 }' $CONFIG_FILE | tail -n1`
    PORT=`awk '/^[[:blank:]]*port/ { print $2 }' $CONFIG_FILE | tail -n1`
    PASS=`awk '/^[[:blank:]]*requirepass/ { print $2 }' $CONFIG_FILE | tail -n1`
    SOCK=`awk '/^[[:blank:]]*unixsocket\s/ { print $2 }' $CONFIG_FILE | tail -n1`
    
    # Just in case, use default host, port
    HOST=${HOST:-127.0.0.1}
    if [ "$SERVICE_NAME" = redis ]; then
        PORT=${PORT:-6379}
    else
        PORT=${PORT:-26739}
    fi
    
    # Setup additional parameters
    # e.g password-protected redis instances
    [ -z "$PASS"  ] || ADDITIONAL_PARAMS="-a $PASS"
    
    # shutdown the service properly
    if [ -e "$SOCK" ] ; then
            $REDIS_CLI -s $SOCK $ADDITIONAL_PARAMS shutdown
    else
            $REDIS_CLI -h $HOST -p $PORT $ADDITIONAL_PARAMS shutdown
    fi
    
    # chmod +x /usr/libexec/redis-shutdown
    
    # useradd -s /sbin/nologin redis
    
    # chown -R redis:redis /usr/local/redis
    
    # chown -R reids:redis /data/redis
    
    # yum install -y bash-completion && source /etc/profile                 #命令补全
    
    # systemctl daemon-reload
    
    # systemctl enable redis
    
    • 修改配置:

    192.168.30.128

    # mkdir -p /data/redis
    
    # vim /usr/local/redis/redis.conf
    
    bind 192.168.30.128               #监听ip,多个ip用空格分隔
    daemonize yes               #允许后台启动
    logfile "/usr/local/redis/redis.log"                #日志路径
    dir /data/redis                 #数据库备份文件存放目录
    masterauth 123456               #slave连接master密码,master可省略
    requirepass 123456              #设置master连接密码,slave可省略
    
    appendonly yes                  #在/data/redis/目录生成appendonly.aof文件,将每一次写操作请求都追加到appendonly.aof 文件中
    
    # echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf
    
    # sysctl -p
    

    192.168.30.129

    # mkdir -p /data/redis
    
    # vim /usr/local/redis/redis.conf
    
    bind 192.168.30.129
    daemonize yes
    logfile "/usr/local/redis/redis.log"
    dir /data/redis
    replicaof 192.168.30.128 6379
    masterauth 123456
    requirepass 123456
    appendonly yes
    
    # echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf
    
    # sysctl -p
    

    192.168.30.130

    # mkdir -p /data/redis
    
    # vim /usr/local/redis/redis.conf
    
    bind 192.168.30.130
    daemonize yes
    logfile "/usr/local/redis/redis.log"
    dir /data/redis
    replicaof 192.168.30.128 6379
    masterauth 123456
    requirepass 123456
    appendonly yes
    
    # echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf
    
    # sysctl -p
    
    • 全部启动redis:
    # systemctl start redis
    
    • 查看集群状态:
    # redis-cli -h 192.168.30.128 -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    
    192.168.30.128:6379> info replication
    # Replication
    role:master
    connected_slaves:2
    slave0:ip=192.168.30.129,port=6379,state=online,offset=168,lag=1
    slave1:ip=192.168.30.130,port=6379,state=online,offset=168,lag=1
    master_replid:fb4941e02d5032ad74c6e2383211fc58963dbe90
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:168
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:168
    
    # redis-cli -h 192.168.30.129 -a 123456 info replication
    
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    # Replication
    role:slave
    master_host:192.168.30.128
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:1
    master_sync_in_progress:0
    slave_repl_offset:196
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:fb4941e02d5032ad74c6e2383211fc58963dbe90
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:196
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:196
    
    • 数据演示:
    192.168.30.128:6379> keys *
    (empty list or set)
    
    192.168.30.128:6379> set key1 100
    OK
    
    192.168.30.128:6379> set key2 lzx
    OK
    
    192.168.30.128:6379> keys *
    1) "key1"
    2) "key2"
    
    # redis-cli -h 192.168.30.129 -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    
    192.168.30.129:6379> keys *
    1) "key2"
    2) "key1"
    
    192.168.30.129:6379> CONFIG GET dir
    1) "dir"
    2) "/data/redis"
    
    192.168.30.129:6379> CONFIG GET dbfilename
    1) "dbfilename"
    2) "dump.rdb"
    
    192.168.30.129:6379> get key1
    "100"
    
    192.168.30.129:6379> get key2
    "lzx"
    
    192.168.30.129:6379> set key3 aaa
    (error) READONLY You can't write against a read only replica.
    
    # redis-cli -h 192.168.30.130 -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    
    192.168.30.130:6379> keys *
    1) "key2"
    2) "key1"
    
    192.168.30.130:6379> CONFIG GET dir
    1) "dir"
    2) "/data/redis"
    
    192.168.30.130:6379> CONFIG GET dbfilename
    1) "dbfilename"
    2) "dump.rdb"
    
    192.168.30.130:6379> get key1
    "100"
    
    192.168.30.130:6379> get key2
    "lzx"
    
    192.168.30.130:6379> set key3 aaa
    (error) READONLY You can't write against a read only replica.
    

    可以看到,在master节点写入的数据,很快就同步到slave节点上,而且在slave节点上无法写入数据。


    Sentinel模式

    Sentinel模式介绍

    主从模式的弊端就是不具备高可用性,当master挂掉以后,Redis将不能再对外提供写入操作,因此sentinel应运而生。

    sentinel中文含义为哨兵,顾名思义,它的作用就是监控redis集群的运行状况,特点如下:

    * sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义
    
    * 当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master
    
    * 当master重新启动后,它将不再是master而是做为slave接收新的master的同步数据
    
    * sentinel因为也是一个进程有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群
    
    * 多sentinel配置的时候,sentinel之间也会自动监控
    
    * 当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中,不需要担心
    
    * 一个sentinel或sentinel集群可以管理多个主从Redis,多个sentinel也可以监控同一个redis
    
    * sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也挂了
    

    工作机制:

    * 每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令 
    
    * 如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被sentinel标记为主观下线。 
    
    * 如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态
    
    * 当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态, 则master会被标记为客观下线 
    
    * 在一般情况下, 每个sentinel会以每 10 秒一次的频率向它已知的所有master,slave发送 INFO 命令 
    
    * 当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送 INFO 命令的频率会从 10 秒一次改为 1 秒一次 
    
    * 若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;
      若master重新向sentinel的 PING 命令返回有效回复,master的主观下线状态就会被移除
    

    当使用sentinel模式的时候,客户端就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。

    Sentinel模式搭建

    • 环境准备:
    master节点              192.168.30.128          sentinel端口:26379
    
    slave节点               192.168.30.129          sentinel端口:26379
    
    slave节点               192.168.30.130          sentinel端口:26379
    
    • 修改配置:

    前面已经下载安装了redis,这里省略,直接修改sentinel配置文件。

    192.168.30.128

    # vim /usr/local/redis/sentinel.conf
    
    daemonize yes
    logfile "/usr/local/redis/sentinel.log"
    dir "/usr/local/redis/sentinel"                 #sentinel工作目录
    sentinel monitor mymaster 192.168.30.128 6379 2                 #判断master失效至少需要2个sentinel同意,建议设置为n/2+1,n为sentinel个数
    sentinel auth-pass mymaster 123456
    sentinel down-after-milliseconds mymaster 30000                 #判断master主观下线时间,默认30s
    

    这里需要注意,sentinel auth-pass mymaster 123456需要配置在sentinel monitor mymaster 192.168.30.128 6379 2下面,否则启动报错:

    # /usr/local/bin/redis-sentinel /usr/local/redis/sentinel.conf
    
    *** FATAL CONFIG FILE ERROR ***
    Reading the configuration file, at line 104
    >>> 'sentinel auth-pass mymaster 123456'
    No such master with specified name.
    
    • 全部启动sentinel:
    # mkdir /usr/local/redis/sentinel && chown -R redis:redis /usr/local/redis
    
    # /usr/local/bin/redis-sentinel /usr/local/redis/sentinel.conf
    
    • 任一主机查看日志:
    # tail -f /usr/local/redis/sentinel.log
    
    21574:X 09 May 2019 15:32:04.298 # Sentinel ID is 30c417116a8edbab09708037366c4a7471beb770
    21574:X 09 May 2019 15:32:04.298 # +monitor master mymaster 192.168.30.128 6379 quorum 2
    21574:X 09 May 2019 15:32:04.299 * +slave slave 192.168.30.129:6379 192.168.30.129 6379 @ mymaster 192.168.30.128 6379
    21574:X 09 May 2019 15:32:04.300 * +slave slave 192.168.30.130:6379 192.168.30.130 6379 @ mymaster 192.168.30.128 6379
    21574:X 09 May 2019 15:32:16.347 * +sentinel sentinel 79b8d61626afd4d059fb5a6a63393e9a1374e78f 192.168.30.129 26379 @ mymaster 192.168.30.128 6379
    21574:X 09 May 2019 15:32:31.584 * +sentinel sentinel d7b429dcba792103ef0d80827dd0910bd9284d21 192.168.30.130 26379 @ mymaster 192.168.30.128 6379
    

    Sentinel模式下的几个事件:

    ·       +reset-master :主服务器已被重置。
    
    ·       +slave :一个新的从服务器已经被 Sentinel 识别并关联。
    
    ·       +failover-state-reconf-slaves :故障转移状态切换到了 reconf-slaves 状态。
    
    ·       +failover-detected :另一个 Sentinel 开始了一次故障转移操作,或者一个从服务器转换成了主服务器。
    
    ·       +slave-reconf-sent :领头(leader)的 Sentinel 向实例发送了 [SLAVEOF](/commands/slaveof.html) 命令,为实例设置新的主服务器。
    
    ·       +slave-reconf-inprog :实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。
    
    ·       +slave-reconf-done :从服务器已经成功完成对新主服务器的同步。
    
    ·       -dup-sentinel :对给定主服务器进行监视的一个或多个 Sentinel 已经因为重复出现而被移除 —— 当 Sentinel 实例重启的时候,就会出现这种情况。
    
    ·       +sentinel :一个监视给定主服务器的新 Sentinel 已经被识别并添加。
    
    ·       +sdown :给定的实例现在处于主观下线状态。
    
    ·       -sdown :给定的实例已经不再处于主观下线状态。
    
    ·       +odown :给定的实例现在处于客观下线状态。
    
    ·       -odown :给定的实例已经不再处于客观下线状态。
    
    ·       +new-epoch :当前的纪元(epoch)已经被更新。
    
    ·       +try-failover :一个新的故障迁移操作正在执行中,等待被大多数 Sentinel 选中(waiting to be elected by the majority)。
    
    ·       +elected-leader :赢得指定纪元的选举,可以进行故障迁移操作了。
    
    ·       +failover-state-select-slave :故障转移操作现在处于 select-slave 状态 —— Sentinel 正在寻找可以升级为主服务器的从服务器。
    
    ·       no-good-slave :Sentinel 操作未能找到适合进行升级的从服务器。Sentinel 会在一段时间之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。
    
    ·       selected-slave :Sentinel 顺利找到适合进行升级的从服务器。
    
    ·       failover-state-send-slaveof-noone :Sentinel 正在将指定的从服务器升级为主服务器,等待升级功能完成。
    
    ·       failover-end-for-timeout :故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器(slaves will eventually be configured to replicate with the new master anyway)。
    
    ·       failover-end :故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。
    
    ·       +switch-master :配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息。
    
    ·       +tilt :进入 tilt 模式。
    
    ·       -tilt :退出 tilt 模式。
    
    • master宕机演示:

    192.168.30.128

    # systemctl stop redis
    
    # tail -f /usr/local/redis/sentinel.log
    
    22428:X 09 May 2019 15:51:29.287 # +sdown master mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:29.371 # +odown master mymaster 192.168.30.128 6379 #quorum 2/2
    22428:X 09 May 2019 15:51:29.371 # +new-epoch 1
    22428:X 09 May 2019 15:51:29.371 # +try-failover master mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:29.385 # +vote-for-leader 30c417116a8edbab09708037366c4a7471beb770 1
    22428:X 09 May 2019 15:51:29.403 # d7b429dcba792103ef0d80827dd0910bd9284d21 voted for 30c417116a8edbab09708037366c4a7471beb770 1
    22428:X 09 May 2019 15:51:29.408 # 79b8d61626afd4d059fb5a6a63393e9a1374e78f voted for 30c417116a8edbab09708037366c4a7471beb770 1
    22428:X 09 May 2019 15:51:29.451 # +elected-leader master mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:29.451 # +failover-state-select-slave master mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:29.528 # +selected-slave slave 192.168.30.129:6379 192.168.30.129 6379 @ mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:29.528 * +failover-state-send-slaveof-noone slave 192.168.30.129:6379 192.168.30.129 6379 @ mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:29.594 * +failover-state-wait-promotion slave 192.168.30.129:6379 192.168.30.129 6379 @ mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:30.190 # +promoted-slave slave 192.168.30.129:6379 192.168.30.129 6379 @ mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:30.190 # +failover-state-reconf-slaves master mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:30.258 * +slave-reconf-sent slave 192.168.30.130:6379 192.168.30.130 6379 @ mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:30.511 # -odown master mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:31.233 * +slave-reconf-inprog slave 192.168.30.130:6379 192.168.30.130 6379 @ mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:31.233 * +slave-reconf-done slave 192.168.30.130:6379 192.168.30.130 6379 @ mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:31.297 # +failover-end master mymaster 192.168.30.128 6379
    22428:X 09 May 2019 15:51:31.297 # +switch-master mymaster 192.168.30.128 6379 192.168.30.129 6379
    22428:X 09 May 2019 15:51:31.298 * +slave slave 192.168.30.130:6379 192.168.30.130 6379 @ mymaster 192.168.30.129 6379
    22428:X 09 May 2019 15:51:31.298 * +slave slave 192.168.30.128:6379 192.168.30.128 6379 @ mymaster 192.168.30.129 6379
    22428:X 09 May 2019 15:52:31.307 # +sdown slave 192.168.30.128:6379 192.168.30.128 6379 @ mymaster 192.168.30.129 6379
    

    从日志中可以看到,master已经从192.168.30.128转移到192.168.30.129上

    192.168.30.129上查看集群信息

    # /usr/local/bin/redis-cli -h 192.168.30.129 -p 6379 -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    
    192.168.30.129:6379> info replication
    # Replication
    role:master
    connected_slaves:1
    slave0:ip=192.168.30.130,port=6379,state=online,offset=291039,lag=1
    master_replid:757aff269236ed2707ba584a86a40716c1c76d74
    master_replid2:47a862fc0ff20362be29096ecdcca6d432070ee9
    master_repl_offset:291182
    second_repl_offset:248123
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:1
    repl_backlog_histlen:291182
    
    192.168.30.129:6379> set key4 linux
    OK
    

    当前集群中只有一个slave——192.168.30.130,master是192.168.30.129,且192.168.30.129具有写权限。

    192.168.30.130上查看redis的配置文件也可以看到replicaof 192.168.30.129 6379,这是sentinel在选举master是做的修改。

    重新把192.168.30.128上进程启动

    # systemctl start redis
    
    # tail -f /usr/local/redis/sentinel.log
    
    22428:X 09 May 2019 15:51:31.297 # +switch-master mymaster 192.168.30.128 6379 192.168.30.129 6379
    22428:X 09 May 2019 15:51:31.298 * +slave slave 192.168.30.130:6379 192.168.30.130 6379 @ mymaster 192.168.30.129 6379
    22428:X 09 May 2019 15:51:31.298 * +slave slave 192.168.30.128:6379 192.168.30.128 6379 @ mymaster 192.168.30.129 6379
    22428:X 09 May 2019 15:52:31.307 # +sdown slave 192.168.30.128:6379 192.168.30.128 6379 @ mymaster 192.168.30.129 6379
    22428:X 09 May 2019 16:01:24.872 # -sdown slave 192.168.30.128:6379 192.168.30.128 6379 @ mymaster 192.168.30.129 6379
    

    查看集群信息

    # /usr/local/bin/redis-cli -h 192.168.30.128 -p 6379 -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    
    192.168.30.128:6379> info replication
    # Replication
    role:slave
    master_host:192.168.30.129
    master_port:6379
    master_link_status:up
    master_last_io_seconds_ago:0
    master_sync_in_progress:0
    slave_repl_offset:514774
    slave_priority:100
    slave_read_only:1
    connected_slaves:0
    master_replid:757aff269236ed2707ba584a86a40716c1c76d74
    master_replid2:0000000000000000000000000000000000000000
    master_repl_offset:514774
    second_repl_offset:-1
    repl_backlog_active:1
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:376528
    repl_backlog_histlen:138247
    
    192.168.30.128:6379> get key4
    "linux"
    
    192.168.30.128:6379> set key5
    (error) ERR wrong number of arguments for 'set' command
    

    即使192.168.30.128重新启动redis服务,也是作为slave加入redis集群,192.168.30.129仍然是master。


    Cluster模式

    Cluster模式介绍

    sentinel模式基本可以满足一般生产的需求,具备高可用性。但是当数据量过大到一台服务器存放不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候需要对存储的数据进行分片,将数据存储到多个Redis实例中。cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。

    cluster可以说是sentinel和主从模式的结合体,通过cluster可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。

    使用集群,只需要将redis配置文件中的cluster-enable配置打开即可。每个集群中至少需要三个主数据库才能正常运行,新增节点非常方便。

    cluster集群特点:

    * 多个redis节点网络互联,数据共享
    
    * 所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用
    
    * 不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,
      并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为
      
    * 支持在线增加、删除节点
    
    * 客户端可以连接任何一个主节点进行读写
    

    Cluster模式搭建

    • 环境准备:
    三台机器,分别开启两个redis服务(端口)
    
    192.168.30.128              端口:7001,7002
    
    192.168.30.129              端口:7003,7004
    
    192.168.30.130              端口:7005,7006
    
    • 修改配置文件:

    192.168.30.128

    # mkdir /usr/local/redis/cluster
    
    # cp /usr/local/redis/redis.conf /usr/local/redis/cluster/redis_7001.conf
    
    # cp /usr/local/redis/redis.conf /usr/local/redis/cluster/redis_7002.conf
    
    # chown -R redis:redis /usr/local/redis
    
    # mkdir -p /data/redis/cluster/{redis_7001,redis_7002} && chown -R redis:redis /data/redis
    
    # vim /usr/local/redis/cluster/redis_7001.conf
    
    bind 192.168.30.128
    port 7001
    daemonize yes
    pidfile "/var/run/redis_7001.pid"
    logfile "/usr/local/redis/cluster/redis_7001.log"
    dir "/data/redis/cluster/redis_7001"
    #replicaof 192.168.30.129 6379
    masterauth 123456
    requirepass 123456
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes_7001.conf
    cluster-node-timeout 15000
    
    # vim /usr/local/redis/cluster/redis_7002.conf
    
    bind 192.168.30.128
    port 7002
    daemonize yes
    pidfile "/var/run/redis_7002.pid"
    logfile "/usr/local/redis/cluster/redis_7002.log"
    dir "/data/redis/cluster/redis_7002"
    #replicaof 192.168.30.129 6379
    masterauth "123456"
    requirepass "123456"
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes_7002.conf
    cluster-node-timeout 15000
    

    其它两台机器配置与192.168.30.128一致,此处省略

    • 启动redis服务:
    # redis-server /usr/local/redis/cluster/redis_7001.conf
    
    # tail -f /usr/local/redis/cluster/redis_7001.log
    
    # redis-server /usr/local/redis/cluster/redis_7002.conf
    
    # tail -f /usr/local/redis/cluster/redis_7002.log
    

    其它两台机器启动与192.168.30.128一致,此处省略

    • 安装ruby并创建集群(低版本):

    如果redis版本比较低,则需要安装ruby。任选一台机器安装ruby即可

    # yum -y groupinstall "Development Tools"
    
    # yum install -y gdbm-devel libdb4-devel libffi-devel libyaml libyaml-devel ncurses-devel openssl-devel readline-devel tcl-devel
    
    # mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
    
    # wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz -P ~/rpmbuild/SOURCES
    
    # wget http://raw.githubusercontent.com/tjinjin/automate-ruby-rpm/master/ruby22x.spec -P ~/rpmbuild/SPECS
    
    # rpmbuild -bb ~/rpmbuild/SPECS/ruby22x.spec
    
    # rpm -ivh ~/rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.x86_64.rpm
    
    # gem install redis                 #目的是安装这个,用于配置集群
    
    # cp /usr/local/redis/src/redis-trib.rb /usr/bin/
    
    # redis-trib.rb create --replicas 1 192.168.30.128:7001 192.168.30.128:7002 192.168.30.129:7003 192.168.30.129:7004 192.168.30.130:7005 192.168.30.130:7006
    
    • 创建集群:

    我这里是redis5.0.4,所以不需要安装ruby,直接创建集群即可

    # redis-cli -a 123456 --cluster create 192.168.30.128:7001 192.168.30.128:7002 192.168.30.129:7003 192.168.30.129:7004 192.168.30.130:7005 192.168.30.130:7006 --cluster-replicas 1
    
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    >>> Performing hash slots allocation on 6 nodes...
    Master[0] -> Slots 0 - 5460
    Master[1] -> Slots 5461 - 10922
    Master[2] -> Slots 10923 - 16383
    Adding replica 192.168.30.129:7004 to 192.168.30.128:7001
    Adding replica 192.168.30.130:7006 to 192.168.30.129:7003
    Adding replica 192.168.30.128:7002 to 192.168.30.130:7005
    M: 80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001
       slots:[0-5460] (5461 slots) master
    S: b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002
       replicates 6788453ee9a8d7f72b1d45a9093838efd0e501f1
    M: 4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003
       slots:[5461-10922] (5462 slots) master
    S: b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004
       replicates 80c80a3f3e33872c047a8328ad579b9bea001ad8
    M: 6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005
       slots:[10923-16383] (5461 slots) master
    S: 277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006
       replicates 4d74ec66e898bf09006dac86d4928f9fad81f373
    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
    

    可以看到,

    192.168.30.128:7001是master,它的slave是192.168.30.129:7004;
    
    192.168.30.129:7003是master,它的slave是192.168.30.130:7006;
    
    192.168.30.130:7005是master,它的slave是192.168.30.128:7002
    

    自动生成nodes.conf文件:

    # ls /data/redis/cluster/redis_7001/
    appendonly.aof  dump.rdb  nodes-7001.conf
    
    # vim /data/redis/cluster/redis_7001/nodes-7001.conf 
    
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557454406312 5 connected 10923-16383
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557454407000 6 connected
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557454408371 5 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 myself,master - 0 1557454406000 1 connected 0-5460
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557454407366 4 connected
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557454407000 3 connected 5461-10922
    vars currentEpoch 6 lastVoteEpoch 0
    

    集群操作

    • 登录集群:
    # redis-cli -c -h 192.168.30.128 -p 7001 -a 123456                  # -c,使用集群方式登录
    
    • 查看集群信息:
    192.168.30.128:7001> 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:6
    cluster_my_epoch:1
    cluster_stats_messages_ping_sent:580
    cluster_stats_messages_pong_sent:551
    cluster_stats_messages_sent:1131
    cluster_stats_messages_ping_received:546
    cluster_stats_messages_pong_received:580
    cluster_stats_messages_meet_received:5
    cluster_stats_messages_received:1131
    
    • 列出节点信息:
    192.168.30.128:7001> CLUSTER NODES                  #列出节点信息
    
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557455176000 5 connected 10923-16383
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557455174000 6 connected
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557455175000 5 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 myself,master - 0 1557455175000 1 connected 0-5460
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557455174989 4 connected
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557455175995 3 connected 5461-10922
    

    这里与nodes.conf文件内容相同

    • 写入数据:
    192.168.30.128:7001> set key111 aaa
    -> Redirected to slot [13680] located at 192.168.30.130:7005                #说明数据到了192.168.30.130:7005上
    OK
    
    192.168.30.130:7005> set key222 bbb
    -> Redirected to slot [2320] located at 192.168.30.128:7001                 #说明数据到了192.168.30.128:7001上
    OK
    
    192.168.30.128:7001> set key333 ccc
    -> Redirected to slot [7472] located at 192.168.30.129:7003                 #说明数据到了192.168.30.129:7003上
    OK
    
    192.168.30.129:7003> get key111
    -> Redirected to slot [13680] located at 192.168.30.130:7005
    "aaa"
    
    192.168.30.130:7005> get key333
    -> Redirected to slot [7472] located at 192.168.30.129:7003
    "ccc"
    
    192.168.30.129:7003> 
    

    可以看出redis cluster集群是去中心化的,每个节点都是平等的,连接哪个节点都可以获取和设置数据。

    当然,平等指的是master节点,因为slave节点根本不提供服务,只是作为对应master节点的一个备份。

    • 增加节点:

    192.168.30.129上增加一节点:

    # cp /usr/local/redis/cluster/redis_7003.conf /usr/local/redis/cluster/redis_7007.conf
    
    # vim /usr/local/redis/cluster/redis_7007.conf
    
    bind 192.168.30.129
    port 7007
    daemonize yes
    pidfile "/var/run/redis_7007.pid"
    logfile "/usr/local/redis/cluster/redis_7007.log"
    dir "/data/redis/cluster/redis_7007"
    #replicaof 192.168.30.129 6379
    masterauth "123456"
    requirepass "123456"
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes_7007.conf
    cluster-node-timeout 15000
    
    # mkdir /data/redis/cluster/redis_7007
    
    # chown -R redis:redis /usr/local/redis && chown -R redis:redis /data/redis
    
    # redis-server /usr/local/redis/cluster/redis_7007.conf 
    

    192.168.30.130上增加一节点:

    # cp /usr/local/redis/cluster/redis_7005.conf /usr/local/redis/cluster/redis_7008.conf
    
    # vim /usr/local/redis/cluster/redis_7007.conf
    
    bind 192.168.30.130
    port 7008
    daemonize yes
    pidfile "/var/run/redis_7008.pid"
    logfile "/usr/local/redis/cluster/redis_7008.log"
    dir "/data/redis/cluster/redis_7008"
    #replicaof 192.168.30.130 6379
    masterauth "123456"
    requirepass "123456"
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes_7008.conf
    cluster-node-timeout 15000
    
    # mkdir /data/redis/cluster/redis_7008
    
    # chown -R redis:redis /usr/local/redis && chown -R redis:redis /data/redis
    
    # redis-server /usr/local/redis/cluster/redis_7008.conf 
    

    集群中增加节点:

    192.168.30.129:7003> CLUSTER MEET 192.168.30.129 7007
    OK
    
    192.168.30.129:7003> CLUSTER NODES
    
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 myself,master - 0 1557457361000 3 connected 5461-10922
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 master - 0 1557457364746 1 connected 0-5460
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557457362000 6 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557457363000 4 connected
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557457362000 5 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557457362729 0 connected
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557457363739 5 connected 10923-16383
    
    192.168.30.129:7003> CLUSTER MEET 192.168.30.130 7008
    OK
    
    192.168.30.129:7003> CLUSTER NODES
    
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 myself,master - 0 1557457489000 3 connected 5461-10922
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 master - 0 1557457489000 1 connected 0-5460
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557457489000 6 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557457488000 4 connected
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557457489472 5 connected
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 master - 0 1557457489259 0 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557457489000 0 connected
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557457490475 5 connected 10923-16383
    

    可以看到,新增的节点都是以master身份加入集群的

    • 更换节点身份:

    将新增的192.168.30.130:7008节点身份改为192.168.30.129:7007的slave

    # redis-cli -c -h 192.168.30.130 -p 7008 -a 123456 cluster replicate e51ab166bc0f33026887bcf8eba0dff3d5b0bf14
    

    cluster replicate后面跟node_id,更改对应节点身份。也可以登入集群更改

    # redis-cli -c -h 192.168.30.130 -p 7008 -a 123456
    
    192.168.30.130:7008> CLUSTER REPLICATE e51ab166bc0f33026887bcf8eba0dff3d5b0bf14
    OK
    
    192.168.30.130:7008> CLUSTER NODES
    
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557458316881 3 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 master - 0 1557458314864 1 connected 0-5460
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557458316000 3 connected 5461-10922
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557458315872 5 connected 10923-16383
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557458317890 5 connected
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 myself,slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557458315000 7 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557458315000 1 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557458314000 0 connected
    

    查看相应的nodes.conf文件,可以发现有更改,它记录当前集群的节点信息

    # cat /data/redis/cluster/redis_7001/nodes-7001.conf
    
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557458236169 7 connected
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557458235000 5 connected 10923-16383
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557458234103 6 connected
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557458235129 5 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 myself,master - 0 1557458234000 1 connected 0-5460
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557458236000 4 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557458236000 0 connected
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557458233089 3 connected 5461-10922
    vars currentEpoch 7 lastVoteEpoch 0
    
    • 删除节点:
    192.168.30.130:7008> CLUSTER FORGET 1a1c7f02fce87530bd5abdfc98df1cffce4f1767
    (error) ERR I tried hard but I can't forget myself...               #无法删除登录节点
    
    192.168.30.130:7008> CLUSTER FORGET e51ab166bc0f33026887bcf8eba0dff3d5b0bf14
    (error) ERR Can't forget my master!                 #不能删除自己的master节点
    
    192.168.30.130:7008> CLUSTER FORGET 6788453ee9a8d7f72b1d45a9093838efd0e501f1
    OK              #可以删除其它的master节点
    
    192.168.30.130:7008> CLUSTER NODES
    
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557458887328 3 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 master - 0 1557458887000 1 connected 0-5460
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557458886000 3 connected 5461-10922
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave - 0 1557458888351 5 connected
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 myself,slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557458885000 7 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557458883289 1 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557458885310 0 connected
    
    192.168.30.130:7008> CLUSTER FORGET b4d3eb411a7355d4767c6c23b4df69fa183ef8bc
    OK              #可以删除其它的slave节点
    
    192.168.30.130:7008> CLUSTER NODES
    
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557459031397 3 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 master - 0 1557459032407 1 connected 0-5460
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557459035434 3 connected 5461-10922
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557459034000 5 connected 10923-16383
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 myself,slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557459032000 7 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557459034000 1 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557459034427 0 connected
    
    • 保存配置:
    192.168.30.130:7008> CLUSTER SAVECONFIG                 #将节点配置信息保存到硬盘
    OK
     
    # cat /data/redis/cluster/redis_7001/nodes-7001.conf
    
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557458236169 7 connected
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557458235000 5 connected 10923-16383
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557458234103 6 connected
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557458235129 5 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 myself,master - 0 1557458234000 1 connected 0-5460
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557458236000 4 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557458236000 0 connected
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557458233089 3 connected 5461-10922
    vars currentEpoch 7 lastVoteEpoch 0
    
    # redis-cli -c -h 192.168.30.130 -p 7008 -a 123456
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    
    192.168.30.130:7008> CLUSTER NODES
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557459500741 3 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 master - 0 1557459500000 1 connected 0-5460
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557459501000 3 connected 5461-10922
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557459500000 5 connected 10923-16383
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557459499737 5 connected
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 myself,slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557459499000 7 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 slave 80c80a3f3e33872c047a8328ad579b9bea001ad8 0 1557459501750 1 connected
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557459498000 0 connected
    

    可以看到,之前删除的节点又恢复了,这是因为对应的配置文件没有删除,执行CLUSTER SAVECONFIG恢复。

    • 模拟master节点挂掉:

    192.168.30.128

    # netstat -lntp |grep 7001
    tcp        0      0 192.168.30.128:17001    0.0.0.0:*               LISTEN      6701/redis-server 1 
    tcp        0      0 192.168.30.128:7001     0.0.0.0:*               LISTEN      6701/redis-server 1 
    
    # kill 6701
    
    192.168.30.130:7008> CLUSTER NODES
    
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557461178000 3 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 master,fail - 1557460950483 1557460947145 1 disconnected
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557461174922 3 connected 5461-10922
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557461181003 5 connected 10923-16383
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557461179993 5 connected
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 myself,slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557461176000 7 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 master - 0 1557461178981 8 connected 0-5460
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557461179000 0 connected
    

    对应7001的一行可以看到,master fail,状态为disconnected;而对应7004的一行,slave已经变成master。

    • 重新启动7001节点:
    # redis-server /usr/local/redis/cluster/redis_7001.conf
    
    192.168.30.130:7008> CLUSTER NODES
    
    277daeb8660d5273b7c3e05c263f861ed5f17b92 192.168.30.130:7006@17006 slave 4d74ec66e898bf09006dac86d4928f9fad81f373 0 1557461307000 3 connected
    80c80a3f3e33872c047a8328ad579b9bea001ad8 192.168.30.128:7001@17001 slave b6331cbc986794237c83ed2d5c30777c1551546e 0 1557461305441 8 connected
    4d74ec66e898bf09006dac86d4928f9fad81f373 192.168.30.129:7003@17003 master - 0 1557461307962 3 connected 5461-10922
    6788453ee9a8d7f72b1d45a9093838efd0e501f1 192.168.30.130:7005@17005 master - 0 1557461304935 5 connected 10923-16383
    b4d3eb411a7355d4767c6c23b4df69fa183ef8bc 192.168.30.128:7002@17002 slave 6788453ee9a8d7f72b1d45a9093838efd0e501f1 0 1557461306000 5 connected
    1a1c7f02fce87530bd5abdfc98df1cffce4f1767 192.168.30.130:7008@17008 myself,slave e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 0 1557461305000 7 connected
    b6331cbc986794237c83ed2d5c30777c1551546e 192.168.30.129:7004@17004 master - 0 1557461308972 8 connected 0-5460
    e51ab166bc0f33026887bcf8eba0dff3d5b0bf14 192.168.30.129:7007@17007 master - 0 1557461307000 0 connected
    

    可以看到,7001节点启动后为slave节点,并且是7004的slave节点。即master节点如果挂掉,它的slave节点变为新master节点继续对外提供服务,而原来的master节点如果重启,则变为新master节点的slave节点。

    另外,如果这里是拿7007节点做测试的话,会发现7008节点并不会切换,这是因为7007节点上根本没数据。集群数据被分为三份,采用哈希槽 (hash slot)的方式来分配16384个slot的话,它们三个节点分别承担的slot 区间是:

    节点7004覆盖0-5460
    节点7003覆盖5461-10922
    节点7005覆盖10923-16383
    

    更多参考:

    Redis集群常用命令

    展开全文
  • redis详解、哨兵模式、集群模式

    万次阅读 2019-02-21 16:37:20
    redis 安装 安装步骤: 1、下载获得redis-3.2.5.tar.gz后将它放入我们的Linux目录/opt 2、解压命令:tar -zxvf redis-3.2.5.tar.gz 3、解压完成后进入目录:cd redis-3.2.5 4、在redis-3.2.5目录下执行make命令 运行...

    redis 安装

    安装步骤:

    1、下载获得redis-3.2.5.tar.gz后将它放入我们的Linux目录/opt
    2、解压命令:tar -zxvf redis-3.2.5.tar.gz
    3、解压完成后进入目录:cd redis-3.2.5
    4、在redis-3.2.5目录下执行make命令
    运行make命令时出现故障意出现的错误解析:gcc:命令未找到
    能上网:
    yum install gcc
    yum install gcc-c++
    不能上网:
    将资料中的rpmgcc目录复制到Linux的opt目录中
    进入opt目录中的rpmgcc目录执行命令:rpm -Uvh *.rpm --nodeps --force

    然后使用gcc –v和g++ -v查看gcc和g++版本,会看到详细的版本信息,然后
    离线环境下安装GCC和GCC-C++就完成了。
    5、在redis-3.2.5目录下再次执行make命令
    Jemalloc/jemalloc.h:没有那个文件
    解决方案:运行make distclean之后再 make
    6、在redis-3.2.5目录下再次执行make命令在这里插入图片描述

    查看默认安装目录:usr/local/bin

    Redis-benchmark:性能测试工具,可以在自己本子运行,看看自己本子性能如何(服务启动起来后执行)
    Redis-check-aof:修复有问题的AOF文件,持久化
    Redis-check-dump:修复有问题的dump.rdb文件
    Redis-sentinel:Redis集群使用,哨兵
    redis-server:Redis服务器启动命令
    redis-cli:客户端,操作入口
    在这里插入图片描述

    启动

    1、备份redis.conf:拷贝一份redis.conf到其他目录

    在这里插入图片描述

    2、修改redis.conf文件将里面的daemonize no 改成 yes,让服务在后台启动
    在这里插入图片描述
    3、启动命令:执行 redis-server /myredis/redis.conf

    在这里插入图片描述

    4、用客户端访问: redis-cli
    5、测试验证: ping

    在这里插入图片描述

    Redis的Java客户端Jedis

    Jedis所需要的jar包

    Commons-pool-1.6.jar
    Jedis-2.1.0.jar
    

    idea连接虚拟机的Redis的注意事项

    禁用Linux的防火墙:
    临时禁用:service iptables stop
    关闭开机自启:chkconfig iptables off
    redis.conf中注释掉bind 127.0.0.1(61行) ,然后 protect-mode(80行)设置为 no。

    在这里插入图片描述
    在这里插入图片描述

    Jedis测试连通性

    在这里插入图片描述

    Redis事务

    Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
    Redis事务的主要作用就是串联多个命令防止别的命令插队
    Multi、Exec、discard
    从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,至到输入Exec后,Redis会将之前的命令队列中的命令依次执行。
    组队的过程中可以通过discard来放弃组队。

    在这里插入图片描述

    事务的错误处理
    组队中某个命令出现了报告错误,执行时整个的所有队列会都会被取消。
    在这里插入图片描述

    如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。
    在这里插入图片描述
    悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
    乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。
    在这里插入图片描述

    Redis的持久化

    Redis 提供了2个不同形式的持久化方式。
    RDB (Redis DataBase)
    AOF (Append Of File)

    RDB

    在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
    Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
    关于fork
    在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,Linux中引入了“写时复制技术”,一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
    rdb的保存的文件
    在redis.conf中配置文件名称,默认为dump.rdb
    在这里插入图片描述
    rdb文件的保存路径,也可以修改。默认为Redis启动时命令行所在的目录下
    在这里插入图片描述
    rdb的保存策略
    在这里插入图片描述

    手动保存快照
    命令save: 只管保存,其它不管,全部阻塞
    save vs bgsave

    stop-writes-on-bgsave-error yes
    

    当Redis无法写入磁盘的话,直接关掉Redis的写操作

    rdbcompression yes
    

    进行rdb保存时,将文件压缩

    rdbchecksum yes
    

    在存储快照后,还可以让Redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
    rdb的备份
    先通过config get dir 查询rdb文件的目录
    将*.rdb的文件拷贝到别的地方
    rdb的恢复
    关闭Redis
    先把备份的文件拷贝到工作目录下
    启动Redis, 备份数据会直接加载
    rdb的优点
    节省磁盘空间
    恢复速度快
    rdb的缺点
    虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
    在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。

    AOF

    以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

    AOF默认不开启,需要手动在配置文件中配置
    在这里插入图片描述

    可以在redis.conf中配置文件名称,默认为 appendonly.aof

    在这里插入图片描述

    AOF文件的保存路径,同RDB的路径一致。
    AOF和RDB同时开启,redis 听aof的
    AOF文件故障备份
    AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。
    AOF文件故障恢复
    如遇到AOF文件损坏,可通过

    redis-check-aof --fix appendonly.aof 进行恢复
    AOF同步频率设置
    始终同步,每次Redis的写入都会立刻记入日志
    每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
    把不主动进行同步,把同步时机交给操作系统。
    在这里插入图片描述
    Rewrite
    AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof。
    Redis如何实现重写?
    AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
    何时重写
    重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。
    在这里插入图片描述

    系统载入时或者上次重写完毕时,Redis会记录此时AOF大小,设为base_size,如果Redis的AOF当前大小>= base_size +base_size*100% (默认)且当前大小>=64mb(默认)的情况下,Redis会对AOF进行重写。
    AOF的优点
    备份机制更稳健,丢失数据概率更低。
    可读的日志文本,通过操作AOF稳健,可以处理误操作。
    AOF的缺点
    比起RDB占用更多的磁盘空间。
    恢复备份速度要慢。
    每次读写都同步的话,有一定的性能压力。
    存在个别Bug,造成恢复不能。
    用哪个好
    官方推荐两个都启用。
    如果对数据不敏感,可以选单独用RDB。
    不建议单独用 AOF,因为可能会出现Bug。
    如果只是做纯内存缓存,可以都不用。

    Redis的主从复制

    主从复制,就是主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主
    用处
    读写分离,性能扩展
    容灾快速恢复
    配从(服务器)不配主(服务器)
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    启动3台redis服务
    在这里插入图片描述

    info replication
    打印主从复制的相关信息
    slaveof
    成为某个实例的从服务器

    在这里插入图片描述

    在这里插入图片描述
    一主二仆模式演示
    复制原理
    每次从机联通后,都会给主机发送sync指令
    主机立刻进行存盘操作,发送RDB文件,给从机
    从机收到RDB文件后,进行全盘加载
    之后每次主机的写操作,都会立刻发送给从机,从机执行相同的命令
    薪火相传
    上一个slave可以是下一个slave的Master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险。
    用 slaveof
    中途变更转向:会清除之前的数据,重新建立拷贝最新的
    风险是一旦某个slave宕机,后面的slave都没法备份
    反客为主
    当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。。
    用 slaveof no one 将从机变为主机。
    在这里插入图片描述

    哨兵模式(sentinel)
    反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库.

    配置哨兵
    调整为一主二仆模式
    自定义的/myredis目录下新建sentinel.conf文件
    在配置文件中填写内容:

    sentinel  monitor  mymaster  127.0.0.1  6379  1
    

    其中mymaster为监控对象起的服务器名称, 1 为 至少有多少个哨兵同意迁移的数量。

    在这里插入图片描述

    启动哨兵

    执行redis-sentinel /myredis/sentinel.conf

    在这里插入图片描述

    现在我将6379 shutdown 然后在将6379连上,发现 主机为6381 从机为6379、6380
    在这里插入图片描述

    哨兵模式搭建完毕,下面来搞集群

    redis的集群

    Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。

    Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
    1、安装ruby环境
    能上网:
    执行yum install ruby
    执行yum install rubygems
    不能上网:
    cd /run/media/root/CentOS 7 x86_64/Packages(路径跟centos6不同) 获取右图rpm包
    拷贝到/opt/rpmruby/目录下,并cd到此目录
    执行:rpm -Uvh *.rpm --nodeps --force
    按照依赖安装各个rpm包
    2、拷贝redis-3.2.0.gem到/opt目录下
    3、执行在opt目录下执行 gem install --local redis-3.2.0.gem
    在这里插入图片描述
    制作6个实例,6379,6380,6381,6389,6390,6391.conf
    cluster-enabled yes 打开集群模式
    cluster-config-file nodes-6379.conf 设定节点配置文件名
    cluster-node-timeout 15000 设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。
    在这里插入图片描述

    复制6份
    在这里插入图片描述

    并且改端口(每个都要改)
    在这里插入图片描述

    在这里插入图片描述

    将六个节点合成一个集群
    组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常。
    在这里插入图片描述

    在这里插入图片描述

    合体:
    cd /opt/redis-3.2.5/src

    ./redis-trib.rb create --replicas 1 192.168.1.101:6379 192.168.1.101:6380 192.168.1.101:6381 192.168.1.101:6389 192.168.1.101:6390 192.168.1.101:6391
    

    在这里插入图片描述

    在这里插入图片描述

    合体成功
    在这里插入图片描述

    通过 cluster nodes 命令查看集群信息
    redis cluster 如何分配这六个节点?
    一个集群至少要有三个主节点。
    选项 --replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
    分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。
    什么是slots?
    一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
    集群中的每个节点负责处理一部分插槽。 举个例子, 如果一个集群可以有主节点, 其中:
    节点 A 负责处理 0 号至 5500 号插槽。
    节点 B 负责处理 5501 号至 11000 号插槽。
    节点 C 负责处理 11001 号至 16383 号插槽。
    如果主节点下线?从节点能否自动升为主节点?
    主节点恢复后,主从关系会如何?
    如果所有某一段插槽的主从节点都宕掉,redis服务是否还能继续?
    redis.conf中的参数 cluster-require-full-coverage

    集群的Jedis开发

    public class JedisClusterTest {
    
      public static void main(String[] args) {
     
         Set<HostAndPort> set =new HashSet<HostAndPort>();
         set.add(new HostAndPort("192.168.1.101",6379));
         JedisCluster jedisCluster=new JedisCluster(set);
    
         jedisCluster.set("k1", "v1");
         System.out.println(jedisCluster.get("k1"));
      }
    
    }
    

    Redis 集群提供了以下好处:
    实现扩容
    分摊压力
    无中心配置相对简单
    Redis 集群的不足:
    多键操作是不被支持的
    多键的Redis事务是不被支持的。lua脚本不被支持。
    由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。

    展开全文
  • Redis集群搭建【超详细】

    万次阅读 2019-08-05 17:00:25
    一、基本环境 首先我们需要使用VMware配置几个虚拟机,我们需要安装VMWare然后 下载自己的linux镜像文件,在虚拟机上安装linux系统, vm15和centos7下载传送门 提取码: lvb5 。我使用的是centos7 64, ...

    一、基本环境

    首先我们需要使用VMware配置几个虚拟机,我们需要安装VMWare然后 下载自己的linux镜像文件,在虚拟机上安装linux系统,

    vm15和centos7下载传送门   提取码: lvb5 。我使用的是centos7 64

    大致步骤可以根据其他博客将第一台虚机的系统安装成功,然后直接clone这台机器就可以了,然后需要修改ip。

     

     二、准备相关软件安装包

    在这里我们需要准备 redis-3.0.7.tar.gz  如果需要搭建其他集群请自行准备,上面的链接中还提供了zookeeper的文件。

    三、开始

    1、我们启动好虚拟机后,首先需要确保各个之间可以ping 通。

    2、我们使用xshell工具连我自己的这几台服务器。

    配置大致如上图,配置参数如下图。

    3、cd /root/software 进入到我们software目录下 我们可以使用wget http://download.redis.io/releases/redis-3.0.7.tar.gz 下载 ,也可以使用xshell 提供的文件传输工具将我们的离线文件上传至software下:

    目录如上。

    进入到 redis-3.0.7目录下 使用如下命令

    4、编译并安装

     cd redis-3.2.4

     make && make install

    5、 将 redis-trib.rb 复制到 /usr/local/bin 目录下

    cd src
    cp redis-trib.rb /usr/local/bin/

    6、创建redis节点(在/root/software/redis-3.0.7 下创建redis_cluster 目录)

    mkdir redis_cluster


    7、创建节点目录并将redis.conf文件复制到节点目录下

    mkdir 7000 7001 7002    (创建节点目录)

    cp redis.conf redis_cluster/7000
    cp redis.conf redis_cluster/7001
    cp redis.conf redis_cluster/7002

    复制配置文件

    8、修改配置文件

    port  7000                                        //端口7000,7002,7003        
    bind 本机ip                                       //改为其他节点机器可访问的ip 可以使用ifconfig查看一下
    daemonize    yes                               //redis后台运行
    appendonly  yes                           //aof日志开启  有需要就开启,它会每次写操作都记录一条日志
    pidfile  /var/run/redis_7000.pid          //pidfile文件对应7000,7001,7002
    cluster-enabled  yes                           //开启集群  
    cluster-config-file  nodes_7000.conf   //集群的配置  配置文件首次启动自动生成 7000,7001,7002
    cluster-node-timeout  15000                //请求超时  默认15秒,可自行修改
    

    操作之后在另外一台机器重复该操作。

    9、启动各个节点

    第一台机器上执行
    redis-server redis_cluster/7000/redis.conf
    redis-server redis_cluster/7001/redis.conf
    redis-server redis_cluster/7002/redis.conf
     
    另外一台机器上执行
    redis-server redis_cluster/7003/redis.conf
    redis-server redis_cluster/7004/redis.conf
    redis-server redis_cluster/7005/redis.conf

    10、检查启动情况

    ps -ef | grep redis

    netstat -tnlp | grep redis

    注意红色部分是总线ip稍后会给我们埋坑

    11、创建集群之前准备

    redis-trib.rb使用ruby实现的所以在执行集群创建命令之前我们需要安装ruby。

    启动命令:

    redis-trib.rb  create  --replicas  1  192.168.255.128:7003   192.168.255.128:7004   192.168.255.128:7005  192.168.255.3:7000  192.168.255.3:7001  192.168.255.3:7002  

    不安装的话会出现下图结果:

    所以我们需要使用如下命令安装redis接口:

    gem install redis

    我们看到上图提示说需要redis的version 大于 2.3.0 。

    这是因为我之前使用 yum -y install ruby ruby-devel rubygems rpm-build 安装的了ruby 但是安装的版本是2.0.0的。

    我们可以使用RVM来对ruby进行环境的管理和切换,而RVM需要通过CRUL来进行下载。

    12 安装CRUL

    使用命令    yum install curl

     13、使用curl安装rvm

    命令: curl -L get.rvm.io | bash -s stable

    14、使用key进行RVM的安装

    source ~/.bashrc

    source ~/.bash_profile

    执行上述命令使环境变量生效。

    使用source让当前shell读入路径为" /usr/local/rvm/scripts/rvm "(路径可以自定义)的shell文件并依次执行文件中的所有语句,并重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录

    15、安装需要的ruby版本

    rvm install 2.4.6

    16、检查版本,移除旧版本,check新版本

    rvm use 2.4.6 #启用新版本

    rvm remove 2.0.0  # 移除旧版本

    ruby -v #检查当前使用的版本号

    17、然后继续redis接口安装(gem install redis

    18、现在可以执行redis集群启动命令

    redis-trib.rb  create  --replicas  1  192.168.255.128:7003   192.168.255.128:7004   192.168.255.128:7005  192.168.255.3:7000  192.168.255.3:7001  192.168.255.3:7002  

    执行命令时出现下面的错误。

    [ERR] Sorry, can't connect to node 192.168.255.3:7000

    这个错误的原因是我们之前配置的所有节点都没有进行对外开放所以无法链接。

    firewall-cmd --zone=public --add-port=7003/tcp --permanent 
    firewall-cmd --zone=public --add-port=7004/tcp --permanent 
    firewall-cmd --zone=public --add-port=7005/tcp --permanent 
    firewall-cmd --reload
    firewall-cmd --zone=public --add-port=7000/tcp --permanent 
    firewall-cmd --zone=public --add-port=7001/tcp --permanent 
    firewall-cmd --zone=public --add-port=7002/tcp --permanent 
    firewall-cmd --reload
    

    在两台机器上分别执行上述命令开发端口。这里我们修改的是firewall防火墙。

    此时执行会出现如下图的情况:

    后面的点会一直点一下一直等待中。

    这是因为我们只是开放了客户端节点的端口,没有开放集群总线的端口,总线端口就是客户端端口+10000,上面我们提到重点注意的

    19、在iptables中开发所有端口

    我们使用命令

    cd /etc/sysconfig/可以使用vi iptables 先查看一下 目前只是开放了 22 端口。

    iptables -A INPUT -p tcp --dport 17001 -j ACCEPT
    iptables -A INPUT -p tcp --dport 17002 -j ACCEPT
    iptables -A INPUT -p tcp --dport 17000 -j ACCEPT
    iptables -A INPUT -p tcp --dport 7001 -j ACCEPT
    iptables -A INPUT -p tcp --dport 7002 -j ACCEPT
    iptables -A INPUT -p tcp --dport 7000 -j ACCEPT
    
    service iptables save #保存文件
    iptables -L -n #查看哪些端口开放了
    
    -----------------------------------------------
    iptables -A INPUT -p tcp --dport 17003 -j ACCEPT
    iptables -A INPUT -p tcp --dport 17004 -j ACCEPT
    iptables -A INPUT -p tcp --dport 17005 -j ACCEPT
    iptables -A INPUT -p tcp --dport 7003 -j ACCEPT
    iptables -A INPUT -p tcp --dport 7004 -j ACCEPT
    iptables -A INPUT -p tcp --dport 7005 -j ACCEPT
    service iptables save #保存文件
    iptables -L -n #查看哪些端口开放了

    20、此时再次执行集群启动命令

    [ERR] Node xxxxx is not empty. Either the node already knows other nodes (check with CLUSTER NODES) 

    会提示我们node节点不空,这是因为我们之前在执行redis集群启动命令的时候虽然一直等待,但是相关节点配置数据以及数据文件都已经生成。我们需要进入到我们的redis解压目录下删除掉图中红色的数据文件:

    执行rm ****  然后选择y

    最后我们再次执行集群启动命令成功:

    21 测试集群效果:

    在Xshell中新开一个窗口 如下图,使用7002的节点进行设值操作传递到7003主。(如图 03、04 00 都是主)

    set redis cluster

    接下来我们能在另外一台机器上链接05从节点,进行取值操作 get redis

    集群功能测试成功。至此redis集群搭建测试成功。

    展开全文
  • redis集群搭建(非常详细,适合新手)

    万次阅读 多人点赞 2018-10-09 11:46:59
    redis集群搭建 在开始redis集群搭建之前,我们先简单回顾一下redis单机版的搭建过程 下载redis压缩包,然后解压压缩文件; 进入到解压缩后的redis文件目录(此时可以看到Makefile文件),编译redis源文件; 把编译...
  • Redis几种集群模式

    万次阅读 2018-11-28 14:22:16
    现在越来越多的项目都会利用到redis,多实例redis服务比单实例要复杂的多,这里面涉及到定位、容错、扩容等技术问题。我们常用sharding技术来对此进行管理,其集群...Redis官方 Cluster集群模式(服务端sharding)...
  • 标签:software sts crc root second oca res netstat 直接  介绍安装环境与版本 用两台虚拟机模拟6个节点...redis 采用 redis-3.2.4 版本。 两台虚拟机都是 CentOS ,一台 CentOS6.5 (IP:192.168.31.2...
  • Redis集群模式

    千次阅读 2018-03-19 15:13:07
    此文由多处转载,自行组织,水平有限,有错误,望大家指正。 现在越来越多的项目都会利用到redis,多实例redis服务比单实例要...Redis官方 Cluster集群模式(服务端sharding) Jedis sharding集群(客户端shardin...
  • 但是每个slave的数据和master中的数据是一致的,如果我们想要在redis中存放更多的数据,就需要redis cluster了。如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机足够了。一个...
  • redis cluster(5)- redis集群原理

    万次阅读 2020-06-29 13:52:05
    Redis集群设计总体架构 在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和...
  • redis集群检查集群状态和添加密码

    万次阅读 2018-06-05 08:16:18
    1.查看集群状态cd /root/install/redis/cluster-test/xxx/src./redis-cli -c -p 端口号 -h IP地址cluster info2.修改密码cd /root/install/redis/cluster-test/xxx/src./redis-cli -c -p 端口号 -h IP地址config set...
  • redis集群)清空缓存

    万次阅读 2018-04-16 09:27:32
    清空集群的缓解只要清空其中一个而已,其他的节点会同步flushall-清空所有数据库的缓存flushdb-清空当前数据库的缓存
  • 1、停掉所有redis服务 ps aux | grep redis kill -9 [进程号] 2、删除掉截图中的文件 3、重新启动redis服务 redis-server [redis配置文件] redis启动不懂的请移步:...4、重新构建redis集群 r...
  • 查看redis集群信息

    万次阅读 2019-04-04 10:40:04
    注:ip为安装redis的那台服务器(集群中...查看redis中存的数据 1.ssh root@ip 2.Password: password 3.keys * 4.type key 5.hkeys key 6.hget key field 1.集群状态 redis-cli -h ip -p 9379 -a password cluster in...
  • 进入命令行: ./redis-cli -h ip -p port 查看集群节点 cluster info 查看key对应的slot cluster keyslot key 查看slot和节点的对应关系 cluster slots
  • redis集群中,一个节点宕掉后,怎么修复,让它恢复到集群中?
  • redis集群清除数据

    千次阅读 2019-03-12 17:38:14
    redis中数据存储比较多,需要进行清理。我们首先用命令查看集群的主从情况。 例如我有三台机器,每台机器上启动俩个节点。说明:7000是端口号 redis-cli -p 7000 -h 192.168.1.147 cluster nodes 连接到每个...
  • 六台机器搭建RedisCluster分布式集群

    万次阅读 2018-07-11 18:02:20
    一、RedisCluster结构二、redis Cluster集群搭建1、修改redis.conf中需要更改的配置bind 改成当前ipcluster-enabled yes #允许redis集群cluster-config-file nodes-6379.conf #集群配置文件cluster-node-timeout ...
  •  redis从3.0版本后引入了令人兴奋的cluster集群模式,相信很多人都尝试过了,在高兴之余却发现redis官方的cluster对于java客户端的jedis支持却不是很好,至少目前的版本cluster是不支持直接使用pipeline操作,找了...
  • Redis集群的关闭、启动、重启等相关指令

    万次阅读 热门讨论 2020-02-27 00:39:33
    目录 关闭 启动 重启 (保留原有集群的)重启 (删除原有集群的)重启 ...集群相关指令 ... 查看集群相关指令 ... 查看集群状态信息 ... 查看集群节点信息 ... 直接kill -9 ${进程号}即可(若想一次kill掉...# 查看redis进程 ps...
1 2 3 4 5 ... 20
收藏数 136,450
精华内容 54,580
关键字:

redis集群