zoukankan      html  css  js  c++  java
  • Docker环境搭建Redis4.0 Cluster

    个人学习笔记,谢绝转载!!!

    原文:https://www.cnblogs.com/wshenjin/p/15296600.html


    配置三个redis实例:

    # cluster
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 15000
    

    启动三个Redis实例6001 6002 6003:

    docker run -tid 
        --network=net_192.168.1 
        --ip=192.168.1.11 
        -p 6001:6001 
        -p 16001:16001 
        --name redis_cluster_node01 redis-4.0.14
    
    docker run -tid 
        --network=net_192.168.1 
        --ip=192.168.1.12 
        -p 6002:6002 
        -p 16002:16002 
        --name redis_cluster_node02 redis-4.0.14
    
    docker run -tid 
       --network=net_192.168.1 
       --ip=192.168.1.13 
       -p 6003:6003 
       -p 16003:16003 
       --name redis_cluster_node03 redis-4.0.14
    

    创建集群:

    [root@ ]# redis-trib.rb create 192.168.1.11:6001 192.168.1.12:6002 192.168.1.13:6003
    >>> Creating cluster
    >>> Performing hash slots allocation on 3 nodes...
    Using 3 masters:
    192.168.1.11:6001
    192.168.1.12:6002
    192.168.1.13:6003
    M: 468b51d1918e82ad6ca81b3772e469be1000e23f 192.168.1.11:6001
       slots:0-5460 (5461 slots) master
    M: e91829ab91203f38f37de7114e82ba5883dcff3c 192.168.1.12:6002
       slots:5461-10922 (5462 slots) master
    M: 6dce80e6cc8a8e6863165087581496409f7e73ad 192.168.1.13:6003
       slots:10923-16383 (5461 slots) master
    Can I set the above configuration? (type 'yes' to accept): yes
    

    此时的Redis Cluster集群正常的,却无法对外部网络提供业务。
    这是因为,Cluster节点需要告诉客户端或其他节点连接自己的IP和端口。默认情况下,Redis会自动检测自己的IP和PORT,告诉客户端或其他节点。而在Docker环境中,如果使用的不是host网络模式,在容器内部的IP和PORT都是隔离的,那么外部客户端和其他节点无法通过节点公布的IP和PORT建立连接。

    1.1.1.1:6012> CLUSTER NODES
    6dce80e6cc8a8e6863165087581496409f7e73ad 192.168.1.13:6001@16001 master - 0 1631788081031 3 connected 10923-16383
    468b51d1918e82ad6ca81b3772e469be1000e23f 192.168.1.11:6001@16001 master - 0 1631788082034 1 connected 0-5460
    e91829ab91203f38f37de7114e82ba5883dcff3c 192.168.1.12:6001@16001 myself,master - 0 1631788079000 2 connected 5461-10922
    1.1.1.1:6012> get mkey02897
    -> Redirected to slot [15915] located at 192.168.1.13:6001
    Could not connect to Redis at 192.168.1.13:6001: Connection timed out
    

    从Redis4.0开始,Cluster将兼容NAT和Docker, 如下配置:

    cluster-announce-ip:        要宣布的IP地址。
    cluster-announce-port:      要宣布的数据端口。
    cluster-announce-bus-port:  要宣布的集群总线端口
    
    ##每个节点都要配置
    192.168.1.11:6001> config set cluster-announce-bus-port 16001
    OK
    192.168.1.11:6001> config set cluster-announce-port 6001
    OK
    192.168.1.11:6001> config set cluster-announce-ip 1.1.1.1
    OK
    

    配置了以后,Redis节点会将配置中的这些IP和PORT告知客户端或其他节点,而这些IP和PORT是通过Docker转发到容器内的临时IP和PORT的。

    配置后的效果:

    1.1.1.1:6001> CLUSTER NODES
    6dce80e6cc8a8e6863165087581496409f7e73ad 1.1.1.1:6001@16003 master - 0 1631788348900 3 connected 10923-16383
    468b51d1918e82ad6ca81b3772e469be1000e23f 1.1.1.1:6002@16002 master - 0 1631788349904 1 connected 0-5460
    e91829ab91203f38f37de7114e82ba5883dcff3c 1.1.1.1:6001@16001 myself,master - 0 1631788346000 2 connected 5461-10922
    1.1.1.1:6012> get mkey02897
    -> Redirected to slot [15915] located at 1.1.1.1:6003
    "__ac268adff36ba00140264436b7436b749a"
    

    这里有个BUG,集群的内部通讯也是走了cluster-announce-ip + cluster-announce-bus-port,这点就有点那啥了。

    不过我们可以改为用hosts的方式:通过hosts,客户端的连接走hosts(外部IP) + cluster-announce-port进行访问,集群内部hosts(内部IP) + cluster-announce-bus-port进行互通。

    修改配置:

    cluster-announce-ip node01         ##对外宣布的hosts
    cluster-announce-port 6001         ##对外宣布的端口,即映射后的端口
    cluster-announce-bus-port 16001    ##集群总线端口,这里不需要映射后的端口,用默认的,因为集群通过hosts在各个实例之间直连
    

    重新启动三个redis实例:6001 6002 6003,启动时添加hosts:

    --add-host node01:192.168.1.11 --add-host node02:192.168.1.12 --add-host node03:192.168.1.13
    

    效果:

    node01:6001> cluster nodes
    761bc6ec25b6b517ddb55fd420a13172442a1a52 node03:6003@16003 master - 0 1632295362318 3 connected 10923-16383
    2ae875f786de16d211fed7ffda07180c09de7982 node02:6002@16002 master - 0 1632295363322 2 connected 5461-10922
    e395b2fe7e7c256d6f1d4028c0d4f1068127ab6d node01:6001@16001 myself,master - 0 1632295360000 1 connected 0-5460
    

    这样,客户端就可以直接使用hosts+映射后的端口连接集群的任意实例,而集群内部通过hosts+总线端口进行通讯。

    这里有个说明:redis-trib.rb工具好像对hosts的支持不太友好无法创建集群,因此可以先创建好集群,再使用动态修改参数或者重启实例的方式调整cluster-announce-ip。
    5.0开始的版本redis-cli自带cluster集群管理功能应该会解决这个问题。

    学习参考:https://www.jianshu.com/p/57aac41e26e8

  • 相关阅读:
    OpenGL入门学习
    linux下安装sqlite3
    SQLite 之 C#版 System.Data.SQLite 使用
    .net程序运行流程
    一种简单,轻量,灵活的C#对象转Json对象的方案
    C# 获取Windows系统:Cpu使用率,内存使用率,Mac地址,磁盘使用率
    WPF中选择文件及文件夹
    要想创业成功,千万不能在这十个方面走弯路
    [译]Quartz.Net 框架 教程(中文版)2.2.x 之第三课 更多关于Jobs和JobDetails
    [译]Quartz 框架 教程(中文版)2.2.x 之第二课 Quartz API,Jobs和Triggers简介
  • 原文地址:https://www.cnblogs.com/wshenjin/p/15296600.html
Copyright © 2011-2022 走看看