3. Redis集群

1 单机、单节点、单实例通用问题

  1. 单点故障
  2. 容量有限
  3. 压力(来自连接数、cpu)

2 解决方案:AKF拆分原则

  1. 可扩展艺术一书中提供的设计微服务时的原则之一,是将大规模系统拆分成多个小规模系统时,所应该遵守的原则。遵守该原则可以解决大规模系统的容量、性能、模块数量增长带来的系统复杂度等问题。防止系统设计的不合理导致需要将系统进行反复地重构
2.1 基于X轴的拆分
  1. 全量,镜像复制,用于解决单点故障问题

  2. 会引发数据一致性的问题,也就是几台节点数据可能不一致

  3. 一致性问题解决方案

    1. 强一致性

      1. 客户端写入A后,A不返回结果,而是继续向B和C写入,同时A阻塞,等B、C都写完,再由B、C将成功的消息返回给A,A再返回客户端。ABC一台机器写入失败就全部失败
      2. 成本太高,基本无法达到,因为如果B写入太慢,会导致整个交易变慢
      3. 会破坏可用性,因为如果数据没写进去,整个服务就不能再正常使用了
      4. 基于X轴拆分,本来就是为了解决可用性,结果强一致性还影响了可用性

      在这里插入图片描述

    2. 弱一致性:可能导致数据丢失

      在这里插入图片描述

    3. 最终一致性:最终的数据是一致的,过程中有可能取到不一致的数据

      1. 在A和B、C间加一个消息中间件,例如kafka,A和kafka之间同步阻塞,kafka和BC间异步
      2. 要求kafka必须可靠(集群模式)、响应速度够快
      3. 最终B、C中数据一定可以和A一致,叫做最终一致性
      4. 但如果对于主从集群,当client访问到了B和C,还是可能取到与A不一致数据,比如B、C还在同步kafka中数据时被访问

      在这里插入图片描述

  4. 集群的模式

    1. 主从:主负责读写,从只负责读。即读写分离
    2. 主备:备机不提供服务
  5. 高可用性的解决方案:指当主机宕机后,如何能够快速的由备机接管,目的是替代人,之前的keepalived就是这种技术

    1. 可以使用一个程序监控主和从

    2. 但如果是一个程序,就又涉及到了单点故障问题,即一旦这个监控程序故障,当主机宕机,仍然无法切换到备机

    3. 因此这个程序也应是一个集群

      在这里插入图片描述

    4. 如果这个监控程序也是有主有从,就又会产生单点故障,因此该程序是使用投票的方式来运行,即监控程序的集群中,必须有n/2+1个监控程序认为主机宕机,才算是真正宕机

    5. 因为如果不够n/2+1,会导致可能n/2个监控认为主机宕机,剩下n/2认为主机正常,造成脑裂,也就是网络分区。即不同网络下系统状态不一致

    6. 一般集群中的监控程序节点数是奇数台,因为一个集群中有5台还是6台,效果是一样的,都只能最多允许两个节点故障,而台数越多,故障的机器数越多,且购买成本越高

    7. 监控程序之间是需要知道对方状态的,这样监控程序才能判断出谁和自己状态相同,从而判断当达到一定数量监控程序和自己监控结果相同,进而决定下一步对主如何处理

  6. 此时单点故障问题可以解决,读的压力也被分散,但写的压力还没有被分散,也无法解决容量问题

2.2 基于Y轴的拆分
  1. 按不同的业务功能,进行拆分,不同的业务跑不同的redis。在mysql中称为分库
2.3 基于Z轴的拆分
  1. 按数据进行拆分,例如1-100000跑第一套redis,100000-200000放在第二套redis

3 Redis的主从复制

  1. 是redis采用的基于X轴拆分的具体方案

  2. redis默认使用的是异步复制,也就是弱一致性,这是为了保证redis快的特点。而且是主从集群,主可以提供读写,从只能提供读

  3. 主机称为master,从机称为replica,意思是复制品

  4. 实验

    #1. 建立test目录,复制配置文件进来,配置文件中关闭后台运行、日志、aof、rdb文件路径
    cp /etc/redis/6379.conf /root/test/6379.conf
    #2. 建立三个配置文件,6379、6380、6381
    #3. 删除持久化目录中内容,防止内容被自动加载
    cd /var/lib/redis/6379
    rm -rf *
    #4. 关闭之前启动的redis实例,按新配置文件启动三个redis实例
    service redis_6379 stop
    redis-server /root/test/6379.conf
    redis-server /root/test/6380.conf
    redis-server /root/test/6381.conf
    #5. 客户端连接6380和6381,并执行命令让他们成为6379的replica
    redis-cli -p 6380
    #redis5.0之前使用slaveof命令
    replicaof 127.0.0.1 6379
    #6. 此时观察6379中日志,发现它触发bgsave,产生rdb文件,然后将这个rdb文件传送到6380的rdb路径下。而6380中,会先执行flushall清空自身数据,然后加载6379传输过来的的rdb文件
    #7. 此时客户端连接6380,能读到之前客户端向6379写入的数据,尝试写入6380会报错,默认为主从模式,从不允许写
    #8. 可以使用如下命令在启动时,就作为从进行启动,同时需要设定其master是谁。如果6380宕机,使用如下命令重启6379就不会再生成rdb文件,而是使用原来6380宕机时最后保留的rdb文件进行恢复,并在这基础上追加增量数据
    redis-server /root/test/6380.conf --replicaof 127.0.0.1 6379
    #9. 但如果用aof的模式启动,此时6379又会产生rdb文件。这是因为使用aof模式启动后,6380不再从rdb文件恢复,而是从aof文件恢复,而redis现在版本中,aof文件中并没有其追随master的id号,因此虽然6380之前产生了aof文件,但6380并不知道现在追随的6379,是不是之前产生aof文件的那个master,因此不能直接在当前留存aof文件基础上去追加增量数据。而rdb文件中有master的id号,这样6380就知道自己路径下的rdb文件是6379某个时点的数据,因此只要在此基础上进行追加即可
    redis-server /root/test/6380.conf --replicaof 127.0.0.1 6379 --appendonly yes
    #10. 当master宕机,replica仍然可以查询,但无法写入,可以手动将6380切换为master,再让其他replica追随6380,这样6380就会产生rdb文件并传送给它的replica。注意master上会记录replica都有谁
    #6380客户端执行
    REPLICAOF no one
    #6381客户端执行
    REPLICAOF 127.0.0.1 6380
    
  5. 配置文件

    ################################# REPLICATION #################################
    
    # 配置追随的master的ip和port
    # replicaof <masterip> <masterport>
    
    # 如果master设置了密码保护,需要配置密码
    # masterauth <master-password>
    
    # master将rdb文件发送给replica时,需要将rdb文件传输到replica的rdb目录中,而rdb传输需要一定时间,该参数表示这段时间内,replica是否还提供对外服务,no表示必须同步完,变成最新状态的数据才能提供查询
    replica-serve-stale-data yes
    
    # replica是否启用只读模式,也就是无法写入
    replica-read-only yes
    
    # 连接master时,master产生的rdb文件,是否不必放到master的磁盘上,而直接通过socket传送给replica,no表示必须先落磁盘
    repl-diskless-sync no
    
    # master中会维护一个队列,存放近期的操作,当replica宕机后,恢复时,会发送给master一个偏移量offset,master判断如果这个偏移量并没有超过自己维护的队列的范围,就不会重新生成rdb文件,replica直接使用本地rdb恢复,然后master只将宕机到恢复这段期间,队列中对应的数据发送给replica进行增量的恢复。该参数就用于控制这个队列的大小
    # repl-backlog-size 1mb
    
    # 至少保证有3个健康的replica,master才允许继续进行写操作,该值默认为0,表示无论replica状态如何不影响主机写入,实际上该参数的目的是尽量让一致性向强一致性靠拢
    # 延迟小于10的replica才被认为是健康的
    # min-replicas-to-write 3
    # min-replicas-max-lag 10
    

4 Redis的高可用

  1. redis通过哨兵Sentinel来实现高可用,即Sentinel可以可以替代人工,进行监控、提醒、故障转移

  2. 使用Sentinel的两种启动方式

    1. redis-sentinel
    2. redis-server /path/to/sentinel.conf --sentinel
  3. 哨兵模式下,使用客户端API连接redis时,应该连接哨兵集群,而不是直连master

  4. 实验

    #1. 参照redis主目录下的sentinel.conf,在/root/test下建立3个哨兵的配置文件,26379.conf、26380.conf、26381.conf
    #哨兵占用的端口号
    port 26379
    #指定哨兵监控的集群中master为127.0.0.1 6379,且投票的权重值为2,即至少有2个哨兵认为主机宕机才会进行切换。因为一套哨兵可以监控多套主从复制集群,因此此处可以设置监听多个master
    sentinel monitor mymaster 127.0.0.1 6379 2
    #2. 启动三个redis实例,6379为主,6380和6381为从
    redis-server ./6379.conf
    redis-server ./6380.conf --replicaof 127.0.0.1 6379
    redis-server ./6381.conf --replicaof 127.0.0.1 6379
    #3. 启动26379这个哨兵
    	#1. 在之前配置的$REDIS_HOME/bin目录中,虽然有redis-sentinel命令,该命令和redis源文件中的src下的redis-sentinel命令不同,前者是一个指向redis-server命令的链接
    	#2. 也就是说redis将redis-sentinel的功能集成在了redis-server中,只需要使用--sentinel参数就可以告诉redis-server命令,当前不是要启动一个redis实例,而是要启动一个哨兵实例
    	#3. 发现该哨兵马上发现了master的两个replica进程,哨兵称其为slave(奴隶)。这是因为master知道有哪些replica,哨兵监控master,因此也能知道有哪些replica
    	#4. 然后哨兵在master上发布并订阅名为"__sentinel__:hello"的频道,这样当其他哨兵启动后,也会发布订阅该频道,这样一个哨兵就能知道其他哨兵的地址和端口了
    	#5. 我们可以通过psubscribe *监听redis上所有发布订阅的消息,发现26379一直在__sentinel__:hello频道发布自身的id、ip、port
    redis-server ./26379.conf --sentinel
    #4. 接下来启动26380这个哨兵,查看26379控制台会发现26379已经发现了26380的加入,并获取到了26380的id、ip、port等信息。这就是上面描述的"监控程序之间是需要知道对方状态的"
    #5. 当master宕机,几个哨兵会反复确定master状态,直到确定master确实已经宕机,几个哨兵投票推选出6381替代原有的master,然后在6381设置REPLICAOF no one,在6380和6379上设置REPLICAOF 127.0.0.1 6381
    #6. 同时哨兵的配置文件中监控的master的ip和port也会变为6381的ip和端口
    

5 Redis的分区

  1. 可以让Redis管理更大的内存
  2. 提升Redis计算能力、扩充Redis的网络带宽
5.1 数据分区的方式
5.1.1 根据业务逻辑拆分
  1. 客户端根据不同的业务场景,将数据存入不同redis中,读取时也根据不同业务场景,去访问不同的redis
  2. 相当于基于Y轴的拆分

在这里插入图片描述

5.1.2 根据数据进行拆分
  1. 相当于基于Z轴的拆分
5.1.2.1 modula
  1. 计算key的hash值,然后用hash值模上redis节点数,从而决定数据应该放到哪台redis实例中
  2. 会影响分布式下的扩展性。例如原本2个节点扩展为6个节点因,如果原来数据10对2取模,因此放在第一台节点上,但现在客户端在获取10时,需要对6取模,判断该数据会放在第4台节点上,但去第4台节点上获取时发现获取不到
  3. 哈希算法本质上就是是一种映射算法,即无论给定哪个字符串都能经过映射算法得到一个等宽的其他值。hash、crc、fnv、md5都是映射算法
    在这里插入图片描述
5.1.2.2 random
  1. 随机将数据写入服务端,但会造成读的时候不知道从哪读,只适合特定场景
    在这里插入图片描述
5.1.2.3 kemata
  1. 一致性哈希算法
    1. 先规划一个哈希环,环中每个点对应0到2^32范围内的一个整数
    2. 将服务器节点的ip经过哈希计算,然后用其哈希值对2^32取模,得到的结果对应圆上的一点,称为物理点
    3. 当数据传入,对key也进行相同的哈希计算,然后用其哈希值对2^32取模,得到的结果也对应圆上一个点,在圆上找到比该值大的最小的物理点,将该key放到这个物理点对应的服务器节点上存放
    4. 此时如果新增一个服务器节点node3,不影响查询key的哈希值在node3到node2之间的数据,但会影响查询key的哈希值在node01到node03之间的所有数据,因为按新的规则,查询他们时,会到node03中查询,但其实他们在node02上
      在这里插入图片描述
  2. 优点
    1. 相比modula,不会造成数据全局洗牌,确实可以分担其他节点压力
  3. 缺点
    1. 新增节点会造成一部分数据不能命中
    2. 缓存无法命中,就会造成击穿,一部分数据压到mysql中
  4. 解决方案
    1. 每次取大于key的哈希值的最小的两个物理点,但增加节点变多后,仍然会造成击穿
    2. 因此这种方案更倾向作为缓存而不是作为数据库用
      1. 可以对各个节点设置lru、lfu等清理策略,保证失效数据被及时清理
      2. 同时一旦发现缓存击穿,及时将该数据放入到新节点中进行缓存
  5. 虚拟节点
    1. 只用node01、node02、node03的ip去进行哈希计算,只能得到三个物理点,很容易造成数据倾斜,比如数据都恰好存放在node01中
    2. 因此可以为node01和node02都加上几个虚拟节点,比如1-10,然后根据ip和虚拟节点值一起进行哈希计算,这样每台服务器就都能得到10个物理点,从而解决数据倾斜问题
5.2 分区的实现
  1. 客户端分区:客户端掌握modula、random、kemata等算法,可以决定数据会被存储到哪个redis节点的算法
  2. 代理分区:客户端将请求发送给代理服,然后代理决定去哪个节点写数据或者读数据。twemproxy、codis、predixy都属于代理服务器
  3. 查询路由:客户端随机地请求任意一个redis实例,然后由Redis将请求转发给正确的Redis节点。Redis Cluster实现了一种混合形式的查询路由,但并不是直接将请求从一个redis节点转发到另一个redis节点,而是在客户端的帮助下直接redirected到正确的redis节点
5.3 Redis的分区实现
5.3.1 支持一致性哈希的客户端
  1. 客户端掌握一致性哈希算法,决定将数据发送给具体哪台服务器
  2. 缺点
    1. 一台客户端假如会启用n个线程,而每个线程如果使用1个redis连接,那么每台客户端就会对每台redis服务器产生n个连接,如果该redis服务器上连接着m台客户端,就会产生m*n个连接
    2. 而连接本身是需要成本的,因为无论长连接还是短连接,都需要经历3次握手、4次分手,大量的连接会导致redis服务器性能降低
    3. 所有客户端中都需要持有一致性哈希算法,对客户端要求较高
5.3.2 Twemproxy
  1. 可以在客户端与redis服务端之间加一个代理服务器,并将modula、kemata、random等逻辑放在代理服务器上
    1. 由于代理服务器只负责接收客户端请求而不进行处理,因此它可以承受更大量的连接
    2. 由于代理服务器不存放数据、无状态,因此代理服务器数量是可以随意扩展的
    3. 同时由于代理服务器的存在,客户端不必再支持modula、kemata、random等算法
      在这里插入图片描述
  2. 当一台代理服务器无法承受住所有客户端连接时,可以增加代理服务器数量,并使用lvs和keepalive技术,为代理服务器进一步分担压力。无论企业后面技术多么复杂,对于客户端都是透明的
    1. lvs是4层的,不持有连接,所以不会由于连接而造成压力
    2. lvs是单机的有单点故障隐患,因此需要为其提供一台备用机,并使用keepalived技术,保证其高可用
      在这里插入图片描述
5.3.3 Redis 集群(cluster)
  1. 对于modula或kemata这两种模式,一旦增加节点,缓存的迁移非常费劲,正常来说,以modula为例,需要将缓存中所有数据拿出来,按新服务器个数取模,重新将所有数据分配到不同的服务器上,计算量非常大
  2. 因此redis设计了槽位的概念,redis上有16384个哈希槽,最开始就将数据的哈希值按16383进行取模,得到0-16383之间的值,分别映射到两台服务器上,例如node01负责0-5460槽位上的数据,node02负责5461-10922槽位上的数据,node03负责10923-16383,这样,当新增节点,可以将槽位进行迁移,将他们上的槽位各取一部分分配给新节点
  3. Redis集群:客户端随机地请求任意一个redis实例,该实例判断客户端执行的命令涉及的数据是否在自己持有的槽位中,如果有直接从自身取,如果没有,从自己记录的所有槽位与实例的映射关系中,找到这个槽位在哪个实例中,然后将客户端连接重定向到该实例上,并执行命令
5.4 分区引发的问题
  1. 无法实现聚合、事务等功能,聚合操作需要redis访问所有实例,影响速度,而redis本质是快,因此不支持。而多个命令可能会发送到不同机器上,因此无法实现事务
  2. redis的集群提供了补偿方案,可以指定哈希标签(hash tag),例如{},redis只会对{}中内容进行哈希计算,这样客户端可以将想要实现聚合或事务的key,设置为类似{ooxx}k1、{ooxx}k2的形式,这样他们就一定会放在同一台实例中,也就可以支持聚合和事务了

6 实际操作

6.1 twemproxy
  1. 安装

    #1. 在soft中克隆twitter/twemproxy项目
    git clone https://github.com/twitter/twemproxy.git
    #2. 如果执行失败
    yum update nss
    #3. 安装automake和libtool工具,下面用到的configure命令需要autoconf、automake、libtool这三个安装包,而autoconf在centos中自带但版本过低
    yum install automake libtool
    #4. 查看当前仓库中autoconf工具支持的最高版本
    yum search autoconf
    #5. 发现系统自带仓库的版本不够用,需要引入阿里的epel仓库。进入https://developer.aliyun.com/mirror/网页,点开epel标签,复制epel(RHEL 6)下记录的RHEL6如何获取该仓库的命令并执行
    wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
    #6. 执行后系统中/etc/yum.repos.d目录下多了一个指向阿里仓库的文件epel.repo。之前使用的CentOS-Base.repo指向的是red hat社区自己的仓库
    #7. 清理缓存的仓库,这样yum就能找到新仓库
    yum clean all
    #8. 再次查找autoconf最新版本,发现叫做autoconf268
    yum search autoconf
    #9. 下载autoconf268
    yum install autoconf268
    #10. 进入twemproxy主目录执行autoreconf268命令生成configure命令
    autoreconf268 -fvi
    #11. 使用生成的configure命令进行配置
    ./configure --enable-debug=full
    #12. 在twemproxy主目录执行make命令,可以在src目录下生成nutcracker程序
    make
    #13. 让twemproxy作为系统服务启动,将脚本拷贝到/etc/init.d中
    cp /root/twemproxy/twemproxy/scripts/nutcracker.init /etc/init.d/twemproxy
    #14. 为/etc/init.d/twemproxy赋予执行权限
    chmod +x twemproxy
    
  2. 配置文件

    #1. 查看twemproxy脚本,查看里面需要/etc/nutcracker/nutcracker.yml文件,同时需要用到nutcracker命令
    	#1. 将/root/twemproxy/twemproxy/conf中所有配置文件拷贝到/etc/nutcracker目录中
    	#2. 在path中引入nutcracker,由于path中包括/usr/bin,所以可以直接将nutcracker拷贝到/usr/bin中即可,此时输入nut,然后按tab就能补全该命令了,说明确实放入了path中
    #2. 进一步修改/etc/nutcracker/nutcracker.yml配置文件
    	#a. 默认有alpha和beta等多组配置,这是因为twemproxy可以为多套redis主从提供代理服务,这里我们配置一组就可以了,因此只保留alpha
    alpha:
      listen: 127.0.0.1:22121
      hash: fnv1a_64
      distribution: ketama
      auto_eject_hosts: true
      redis: true
      server_retry_timeout: 2000
      server_failure_limit: 1
      servers:
      #b. 1表示权重,权重越大,数据被放入的概率越大
       - 127.0.0.1:6379:1
       - 127.0.0.1:6380:1
    
  3. 实验

    #1. 手动执行redis-server启动服务时,会使用当前目录作为数据的持久化目录,也就是存放rdb文件的目录,因此此处建立/test/data/6379和6380两个文件夹,在其内分别手工启动两个redis服务
    redis-server --port 6379
    #2. 应该检查所有启动的redis进程,都杀掉,防止对实验有影响
    redis-cli -p 6380 shutdowm
    service redis_6379 stop
    #3. 启动twemproxy,service中的这个名称需要和/etc/init.d中的一致
    service twemproxy start
    #4. 此时客户端就可以连twemproxy这个代理,而不用直接连redis实例
    redis-cli -p 22121
    #5. 聚合、watch、multi等命令执行报错
    keys *
    #6. 写入数据后,使用客户端分别直连6379和6380,发现只有6380中有新的key,因为twemproxy根据上面设定的算法将key放入到了6380,set 1 1234123时候,会放入6379
    redis-cli -p 6379
    
6.2 predixy
  1. predixy需要c++11编译器,centos6没有这个编译器,很难补全,因此直接从github下载编译好的程序

  2. 进入https://github.com/joyieldInc/predixy,点击releases,复制predixy-1.0.5-bin-amd64-linux.tar.gz的连接地址

  3. 安装

    mkdir predixy 
    cd predixy
    wget https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz
    tar xf predixy-1.0.5-bin-amd64-linux.tar.gz
    
  4. 配置文件

    #1. conf路径下的predixy.conf
    #a. 打开
    Bind 127.0.0.1:7617
    #b. 引入sentinel.conf这个配置文件,注意这个配置文件不是redis中的那个,而是predixy中的
    # Include cluster.conf
    #c. 配置文件中支持引入哨兵的配置文件,通过哨兵predixy就能知道谁是master谁是replica
    Include sentinel.conf
    # Include try.conf
    
    #2. sentinel.conf
    	#1. 
    SentinelServerPool {
        Databases 16
        Hash crc16
        #设置HashTag为{}
        HashTag "{}"
        Distribution modula
        MasterReadPriority 60
        StaticSlaveReadPriority 50
        DynamicSlaveReadPriority 50
        RefreshInterval 1
        ServerTimeout 1
        ServerFailureLimit 10
        ServerRetryTimeout 1
        KeepAlive 120
        Sentinels {
        		#配置哨兵的地址
            + 127.0.0.1:26379
            + 127.0.0.1:26380
            + 127.0.0.1:26381
        }
        #一组哨兵可以监控多套主从复制结构,也就是会监控多个master,因此这多个master分为多个组,predixy会根据不同算法将数据分配到这两套主从复制结构中
        #该名称必须为redis的哨兵配置文件中定义的master的别名
        Group ooxx {
        }
        Group xxoo {
        }
    }
    
    #3. vi操作补充
    #a. ':'表示进入末行模式,'.'表示当前光标所在位置,'$'表示最后一行,','表示从哪到哪,y为复制,回车后就复制从当前光标位置到最后一行的所有数据
    :.,$y
    #b. 's'表示替换,此处表示将光标位置到文件最后的所有内容中的#替换为空
    :.,$s/#//
    #c. 删除当前光标后面2行内容
    2dd
    #d. 删除当前光标下面所有行
    dG
    
  5. 实验

    #1. 修改redis哨兵配置文件/root/test下的26379.conf、26380.conf、26381.conf。哨兵会监控两套主从结构,主机分别为36379和46379,哨兵为26379-26381
    port 26379
    sentinel monitor ooxx 127.0.0.1 36379 2
    sentinel monitor xxoo 127.0.0.1 46379 2
    #2. 先启动三台哨兵
    redis-server 26379.conf --sentinel
    redis-server 26380.conf --sentinel
    redis-server 26381.conf --sentinel
    #3. 启两套主从复制集群,在test目录中,建立四个目录36379、36380、46379、46380
    redis-server --port 36379
    redis-server --port 36380 --replicaof 127.0.0.1 36379
    #4. 进入predixy的bin目录中,启动perdixy
    ./predixy ../conf/predixy.conf
    #5. 连接predixy
    redis-cli -p 7617
    #6. 单独连两台master,发现k1和k2被放入了不同的master中
    #7. 发现{oo}k1、{oo}k2,放入了同一个master中
    set {oo}k1 kjfkjd
    set {oo}k2 kjfkjd
    #8. keys *、watch {oo}k1等命令还是无法执行
    #9. 删除predixy配置文件中ooxx组,那么即使哨兵监控了多套主从复制结构,数据也无法写入,重启predixy后,predixy会判断当前只连接了一套主从结构,就又开启了聚合、事务等操作,因此又能使用watch k1了,开启事务也没问题
    
6.3 redis cluster
  1. Redis4.0以前需要使用ruby启动reids集群,新版本使用redis自己的命令即可

  2. 使用/root/redis-5.0.5/utils/create-cluster/create-cluster命令完成集群操作

    #1. README中有集群的详细操作方法
    #2. 查看create-cluster脚本,其中NODES=6表示会启动6个redis实例,REPLICAS=1表示一个master有一个replica,也就是6个redis实例会构成6/(1+REPLICAS)=3套主从结构
    #3. 启动集群,通过打印可以看出6个redis实例被启动,端口号从30001到30006
    ./create-cluster start
    #4. 将6个redis实例配置成3套主从结构,30001-30003被设置为master,并为每套主从结构分配槽位(slots),根据提示输入yes
    ./create-cluster create
    #5. 随意连接到一个实例上
    redis-cli -p 30001
    #6. 命令执行失败,提示需要连接到30003上才能完成key的创建,此时不会自动路由到30003
    set k1 123456
    #7. 使用-c连接到任意一个实例上
    redis-cli -c -p 30001
    #8. 命令执行成功,会显示先自动路由到了12706槽位对应的30003机器上,然后才执行了set k1 123456命令,并且执行成功。此时客户端自动连到了30003上,再输命令已经是在30003上输入了
    set k1 123456
    #9. 命令执行成功,会先路由到k1所在的30003,然后执行watch k1命令,multi开启事务也没问题,此时set k2 123456,又被路由到了30001上。此时执行exec会报错,因为30001上没开启过multi
    watch k1
    multi
    set k2 123456
    exec
    #10. 可以利用hash tag保证都存放在同一个节点上,这样就不会发生自动路由,执行exec也就不会报错。其他客户端如果在这中间连入不会导致当前连接被自动路由,所以只要客户端对事务中所有key都是用hash tag,那么就不会由于自动路由导致事务失败
    set {oo}k1 123456
    watch {oo}k1
    multi
    set {oo}k2 123456
    get {oo}k3
    exec
    #11. 结束集群
    ./create-cluster stop
    #12. 该命令所在文件夹下会产生一堆配置文件、日志、持久化文件等内容,可以使用如下命令全量删除
    ./create-cluster clean
    
  3. 使用redis-cli --cluster进行集群操作

    #1. 查看集群操作帮助文档
    redis-cli --cluster help
    #2. 该命令其实是将已启动的几个redis实例组成一个集群,且如果某redis实例是为了被组成集群而启动,在配置文件中需要开启cluster-enabled yes,否则无法组成集群。此处为了方便启动6个redis实例,还是调用./create-cluster start启动redis实例,然后调用下面命令将他们分配槽位,设定主从关系,组成cluster。之前./create-cluster create只能将自身服务器上的几个redis实例组成cluster,无法将不同ip不同端口下的实例组成cluster
    redis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1
    #3. 启动客户端连接这个集群,连接的实例不是master也能连接成功
    redis-cli -c -p 30001
    #4. 移动数据,也是随机连接到cluster中哪台实例都可以,也可以连接到replica
    	#a. 提示你想移动多少槽位,从1-16384,此处输入2000
    	#b. 提示想移动到的节点的ID,节点的ID在create命令和当前reshard命令的输出中都有记录,此处必须输入master的ID
    	#c. 输入移出节点的ID号,回车后可以再选一个节点,如果不需要了输入done
    	#d. 按提示输入yes
    	#e. 具体移动哪号槽位是无法控制的
    redis-cli --cluster reshard 127.0.0.1 30001
    #5. 查看集群的相关信息,命令后面的端口可以是master的也可以是replica的,此时发现每个master上的slots数量不再相同
    redis-cli --cluster info 127.0.0.1:30001
    #6. 查看每个master具体拥有哪些槽位
    redis-cli --cluster check 127.0.0.1:30001
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值