• 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的集合)

                 

     
     
  • 相关阅读:
    Flink window机制
    用上帝视角来看待组件的设计模式
    npm和package.json那些不为常人所知的小秘密
    四步走查智能硬件异常Case
    PorterDuffXfermode 图像混合技术在漫画APP中的应用
    发布流程进化史
    新手入门Sqlalchemy
    OpenResty 最佳实践 (2)
    更新数据库触发器
    删除约束名字段名
  • 原文地址:https://www.cnblogs.com/dangdanghepingping/p/14293962.html
Copyright © 2020-2023  润新知