近况

明天还剩最后一点redis视频了,看完就整理好笔记放在github上,然后就要准备学习nginx了
6月份的任务有很多,例如:

  • spring,mybatis源码应该看看
  • 老师弄的项目得跟着做,听说涉及到了zookeeper,dubbo,nginx等等
  • 计算机网络需要学习
  • 前端JS,vue,这部分是我6月份主要学习的内容
  • 多线程,JVM更加底层的内容,一些数据结构算法,打算实习的时候可以再学习,这部分比较耗时间
搭建集群

无中心化集群指的是,集群中的所有redis服务器都能作为请求的入口,当请求来到不合适的redis服务器时
该服务器会将请求转发给其他redis服务器,减少并发的压力。

  • 什么是集群
    redis集群实现了对redis的水平扩容,即启动n个redis节点,将整个数据库分布存储在这n个节点中,
    每个结点存储总数据的1/n,redis集群通过分区来提供一定程度的可用性:即使集群中有一部分节点失效
    或者无法进行通信,集群也可以继续处理命令请求。

  • 在上一个例子,一主二从基础之上进行搭建

    • 删除三份rdb文件,该文件默认在/var/lib/redis目录下

    • 修改自定义的redis6379.conf文件,上个例子中,该文件在/redisFile目录下

      #原文件内容如下:
      include /redisFile/redis.conf
      pidfile "/var/run/redis/redis6379.pid"
      port 6379
      dbfilename "dump6379.rdb"
      # Generated by CONFIG REWRITE
      daemonize yes
      always-show-logo yes
      logfile "/var/log/redis/redis-server.log"
      save 900 1
      save 300 10
      save 60 10000
      user default on nopass ~* +@all
      #rdb file location
      dir "/var/lib/redis"
      replicaof 127.0.0.1 6381
      
      #修改成以下内容:
      include /redisFile/redis.conf
      pidfile "/var/run/redis/redis6379.pid"
      port 6379
      dbfilename "dump6379.rdb"
      cluster-enabled yes #打开集群模式
      cluster-config-file nodes-6379.conf #设置节点配置文件名
      cluster-node-timeout 15000 #设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换
    • 修改好后,复制该文件到同一目录下/redisFile,命名为:redis6380.conf,redis6381.conf
      redis6382.conf,redis6383.conf,redis6384.conf,一共6台redis进程配制文件。
      因为搭建集群最少需要6台redis服务器,本次集群实验配置3主3从,端号是6379,6380,6381,6382,
      6383,6384,其中6379-6381作为主机,6382-6384作为从机,复制后,将各个文件中的内容全部修改成
      各自的端口号和文件名,修改各自端口号及文件名有快捷方式:例如编辑进入6380.conf

      输入":%s/6379/6380",即可将6380.conf文件中6379字符替换成6380
    • 全部修改完毕之后,然后修改/redisFile/redis.conf文件,这个文件是拷贝自redis的配置文件
      修改其中参数为:protected-mode no,即将redis保护模式关闭,另外如果有哨兵进程在运行
      需要杀掉哨兵进程sentinel

    • 一切准备完毕后,根据我们6个配置文件启动6台redis服务器

      #如果使用apt命令安装redis,使用如下命令
      redis-server /redisFile/redis6379.conf
      redis-server /redisFile/redis6380.conf
      redis-server /redisFile/redis6381.conf
      ...
      
      #如果使用下载解压编译方式安装redis,需要进入redis/src目录下使用如下命令
      ./redis-server /redisFile/redis6379.conf
      ./redis-server /redisFile/redis6380.conf
      ./redis-server /redisFile/redis6381.conf
      ...
      
      成功启动6台服务后,会在/var/lib/redis/目录下会生成各自的nodes-63xx.conf
      没有配置集群之前,这个目录放着三台redis服务器的rdb文件。
      
      #查看6台redis服务器情况
      root@keyi:/redisFile# ps -ef | grep redis
    • 接下来将6台redis服务器合成一个redis集群,使用如下命令

      #使用apt方式,使用解压编译方式需要进入redis/src目录下执行
      redis-cli --cluster create --cluster-replicas 1 45.32.124.62:6379 
      45.32.124.62:6380 45.32.124.62:6381 45.32.124.62:6382 45.32.124.62:6383 
      45.32.124.62:6384
      
      #合成时会问你是否采用redis设置的主从配置,即3组主从,每台主机一台从机,输入yes确定
      
      #注意:
      1)不要直接复制以上命令,直接复制有换行符,在linux系统上粘贴有问题
      2)--cluster create 表示创建集群的方式
      3)--cluster-replicas 1 表示使用最简单的集群方式,3台主机,每台主机1台从机,一共6台
      4)后面是6台redis服务器的ip地址和端口号,ip地址不能填本地地址127.0.0.1,而是真实linux的ip地址
      5)本次实验使用redis6,如果是redis低版本,则需要ruby环境,高版本redis已经集成了ruby环境
    • 测试集群

      1)以前配置一主二从,使用测试客户端连接redis时,通过redis-cli -p 6379命令连接主机
          现在集群方式就不一样了,通过redis-cli -c -p 6379命令连接集群中redis服务器,
          -c 表示采用集群策略连接,连接后,在任意redis测试客户端上添加数据都会自动切换到相应的写主机。
          即:当我连接到某个从机,进行add操作时,集群会自动将请求交给其他主机进行处理。
      2)连接到测试客户端后,通过cluster nodes命令查看集群信息
          root@keyi:~# redis-cli -c -p 6379
          127.0.0.1:6379> cluster nodes
  • redis集群如何分配这6个节点
    一个集群至少要有三个主节点,选项 –cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点
    分配原则:尽量保证每个主数据库运行在不同的ip地址,每个从库和主库不在一个ip地址上。

  • 什么是slots?

    • 定义

      1. slots指的是插槽的意思,一个redis集群包含16384个插槽(0-16383),数据库中的每个键都属于这16384个插槽的其中一个
      2. 集群使用公式CRC16(key)%16384来计算键key属于哪个槽,其中CRC16(key)语句用于计算键key的CRC16校验和,这种方式很像使用hash函数计算
      3. 集群中的每个主节点负责处理一部分插槽,例如主机1负责0-5460,主机2负责5461-10922,
        主机3负责10923-16383,当在主机1保存数据时,redis会计算key值,计算出该数据位于哪一个
        插槽,如果该数据不属于本主机负责的插槽,就会将请求转交给负责该插槽的主机,
        让其他处理进行保存处理。
    • 注意:使用集群后,不能再使用mset,mget命令进行多键操作,可以通过{}来定义组的概念,
      从而使key中{}内相同的键值对放到同一个slot中去,其实就是根据组指定的数值进行计算属于哪一个插槽

      127.0.0.1:6379> mset name{keyi} wanyi age{keyi} 22
      -> Redirected to slot [14360] located at 45.32.124.62:6381
      OK
      45.32.124.62:6381> mget name{keyi} age{keyi}
      1) "wanyi"
      2) "22"
    • 计算集群中,key值属于哪一个插槽

      45.32.124.62:6381> cluster keyslot name
      (integer) 5798
      45.32.124.62:6381> cluster keyslot name
      (integer) 5798
      45.32.124.62:6381> cluster keyslot keyi
      (integer) 14360
    • 计算某个插槽中有几个key,有几个键,注意每个主机只能看到自己负责的插槽中的数据

      45.32.124.62:6381> cluster countkeysinslot 14360
      (integer) 2
    • 返回插槽中key值,14360是指定的插槽,10是指定返回的数量

      45.32.124.62:6381> cluster getkeysinslot 14360 10
      1) "age{keyi}"
      2) "name{keyi}"
  • 故障恢复

    • 如果主节点下线,从节点能否自动升为主节点?注意:15秒超时
      答:可以,如果某个主机宕机后,则属于该主机的从机就会变成新主机,
      当原主机恢复后,就变成新主机的从机
    • 主节点恢复后,主从关系会如何?
      主节点回来后变成从机
    • 如果所有某一段插槽的主从节点都宕机(某个主机和属于它的从机都宕机了),redis服务是否还能继续?
      不一定,如果某个主机和属于它的从机都宕机了,而且redis.conf中的参数cluster-require-full-coverage
      为yes那么整个集群都挂掉,如果该参数值是no,那么属于该主机负责的插槽全都不能使用,
      也无法存储。
  • 注意:即使连接的不是主机,集群会自动切换主机存储,主机写,从机读,无中心化主从集群,
    无论从哪台主机写数据,其他主机都能读到数据,
    例如尽管当前6379redis进程是从机,但还是可以接收请求,将请求转发给其他主机处理

    127.0.0.1:6379> set money 100
    -> Redirected to slot [11921] located at 45.32.124.62:6381
    OK
  • 使用集群的好处与不足
    好处:实现扩容,分摊压力,无中心化配置相对简单
    不足:多键操作是不被支持的,多键的redis事务是不被支持的,lua脚本不被支持