redis笔记3 redis集群(千峰教育)

------------恢复内容开始------------

一. 主从架构

 原因: 单机版redis存在读写瓶颈, 单机版redis只能承受11万/s的读和8w/s的写. 

 主从架构: 多台tomcat对应3台以及以上redis,其中一台可读写, 其他的节点只读. 

         1.1配置文件准备:

            (1)docker-compose.yml文件(以 3个redis库, 一个主库,两个从库为例)

    • 三个redis他们的containner_name和ports都不一样
    • 从库需要设置links,指向主库名, 
    • 从库之间不能通信, 主从库之间可以
# redis主从架构的docker-compose.yml
version: '3.1'
services: 
  redis1:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis1
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7000:6379
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis2:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis2
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7001:6379
    volumes:
      - ./conf/redis2.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis3:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis3
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7002:6379
    volumes:
      - ./conf/redis3.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]

     (2) redis2.conf和redis3.conf的设置:从节点指定master节点 通过master可以找到容器, 通过6379可以找到容器内部端口号

replicaof master 6379

      1.2  创建步骤:

  •  在/opt下创建docker_redis_master_slave目录 
  • 在docker_redis_master_slave目录下vi docker-compose.yml文件, 即上面准备的文件
  • 在指示的数据卷映射中创建conf目录, 并创建 redis2.conf, redis1.conf redis3.conf作为三个库的配置文件
  • 在 redis2.conf, redis3.conf两文件中指明master 
  • 命令docker-compose up -d启动,
volumes:
      - ./conf/redis2.conf:/usr/local/redis/redis.conf       

 主从通信的实验: 进入redis库后, 可以通过info命令查看库信息, 其中有role属性, 

第一张图的主节点可以存取数据, 而第二张图片的从节点只能取数据, 不能存.

    

 二. 哨兵架构

         原因: 主从架构存在缺陷: (单点故障问题)当master节点宕机后, 主从架构就瘫痪了, 从节点无法跟master通信

           哨兵结构:

    • 每个redis容器里都有一个哨兵,
    • 各容器内的redis服务和各自的哨兵可以互相通信
    • 所有哨兵之间可以互相通信
    • 当master宕机后, 看守它的哨兵会向其他哨兵发出信号, 
    • 所有哨兵通过投票, 在剩余正常运行的slave中选出一个作为master继续运行

 

 哨兵的配置文件

# 哨兵需要后台启动
daemonize yes
# 主节点指定Master节点的ip和端口号
sentinel monitor master localhost 6379 2
# 从节点指定Master节点的ip和端口号
sentinel monitor master master 6379 2
# 哨兵每隔多少秒监听一次redis架构
sentinel down-after-milliseconds master 1000

     设置哨兵的conf:

      (1)在conf目录下, vi 3个sentinel文件, 并写上述配置文件(主从节点需要各自去注释别人的)

      

      (2) 在redis-config.yml里添加数据卷, 可以在容器中使用哨兵的配置:

        - ./conf/sentinel1.conf:/data/sentinel.conf

      (3)在每个容器内部(注意是容器内部)启用哨兵: redis-sentinel sentinel.conf(因为data里有sentinel.conf,做过映射)

         

        在master节点上 , 可以写操作

        

       然后停掉master: docker stop 容器id 

       

      分别进入两个slave容器, 发现其中一个变成了master.

三.redis集群

      redis主从架构解决了效率问题, 哨兵架构解决了单点故障问题.

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

      集群特点: 

  • redis集群是无中心的, 不像主从和哨兵那样, 有个master.
  • 乒乓机制:  每个节点都相互发消息
  • 投票机制: 当乒乓机制回应异常, 就采取投票, 谁的票多就表明谁宕机,集群节点的数量必须是 2n+1个节点.
  • redis的集群采用hash槽来存数据, 所以可以动态扩充. 默认有16384个哈希槽, 存数据时, 通过hash算法, 将key存到相应的hash槽中.
  • 每个redis节点, 都维护着一定数量的hash槽. 
  • 每一个节点后面, 都跟着一个从节点, 和该节点的数据同步. 防止节点宕机
    redis cluster 为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉

现在我们是三个主节点分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。那么,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:

  • 节点A覆盖0-5460;

  • 节点B覆盖5461-10922;

  • 节点C覆盖10923-16383.

    获取数据:
    如果存入一个值,按照redis cluster哈希槽的算法: CRC16('key')384 = 6782。 那么就会把这个key 的存储分配到 B 上了。同样,当我连接(A,B,C)任何一个节点想获取'key'这个key时,也会这样的算法,然后内部跳转到B节点上获取数据

    新增一个主节点:
    新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到D上,我会在接下来的实践中实验。大致就会变成这样:

  • 节点A覆盖1365-5460

  • 节点B覆盖6827-10922

  • 节点C覆盖12288-16383

  • 节点D覆盖0-1364,5461-6826,10923-12287

同样删除一个节点也是类似,移动完成后就可以删除这个节点了。

上面那个例子里, 集群有ABC三个主节点, 如果这3个节点都没有加入从节点,如果B挂掉了,我们就无法访问整个集群了。A和C的slot也无法访问。

所以我们在集群建立的时候,一定要为每个主节点都添加了从节点, 比如像这样, 集群包含主节点A、B、C, 以及从节点A1、B1、C1, 那么即使B挂掉系统也可以继续正确工作。

B1节点替代了B节点,所以Redis集群将会选择B1节点作为新的主节点,集群将会继续正确地提供服务。 当B重新开启后,它就会变成B1的从节点。

不过需要注意,如果节点B和B1同时挂了,Redis集群就无法继续正确地提供服务了。

3.2搭建redis集群

     如果搭建3个主节点, 并且每个节点都有一个从节点, 那么总共需要搭建6个节点

    (1) 准备docker-compose.yml文件和6个redisx.conf配置文件

     docker-compose.yml文件
# redis集群
version: '3.1'
services: 
  redis1:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis1
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7001:7001
      - 17001:17001
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis2:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis2
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7002:7002
      - 17002:17002
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis3:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis3
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7003:7003
      - 17003:17003
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]   
  redis4:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis4
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7004:7004
      - 17004:17004
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis5:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis5
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7005:7005
      - 17005:17005
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis6:
    image: daocloud.io/library/redis:5.0.7
    container_name: redis6
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports: 
      - 7006:7006
      - 17006:17006
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]

6个redis.conf文件(每个文件都以redis1.conf redis2.conf....并改下端口为7001, 7002...)

# redis.conf 
# 指定redis端口
port 7001
# 开启redis集群
cluster-enabled yes
# 集群信息的文件
cluster-config-file nodes-7001.conf
# 集群的对外ip地址
cluster-announce-ip 192.168.43.173
# 集群的对外端口
cluster-announce-port 7001
# 集群的对外总线
cluster-announce-bus-port 17001
     (2) 在opt/下创建docker_redis_cluster, 编写docker-compose.yml文件,  并创建conf目录和6个redis.conf文件
       

      (3)启动6个redis容器

   
     (4) 进入任意一个容器内, 通过命令来创建集群
       redis-cli --cluster create ip:端口号 ... --cluster-replicas 从节点数量 
        注意: 该才做就会显示master和slave, 并且分配slots; 下图0-5460 被分配到7001....
(5)通过redis-cli -h  -p  -c操作redis; -c表示可以切换redis节点.

              

        (5)java连接redis集群, 

         new  JedisCluster(参数是一个hostandpot的集合)

             

 
 
原文地址:https://www.cnblogs.com/dangdanghepingping/p/14293962.html