• Docker 搭建Redis 集群之路


    前言

    搞技术就是动手,动手再动手,实践出真知,毕竟最终是要解决问题的呢,废话不多讲,开搞,主要是为了记录一下,毕竟过程还是有点艰辛呢
    
    • 1

    需求(target)

    1. Windows 电脑 装一个虚拟机
    2. 用虚拟机构造Linux 系统
    3. 下载Docker 搭建Redis 集群
    4. 代码交互集群

    过关斩将

    1. 检查电脑是否开启虚拟话化
    2. VMware 或者 VirtualBox 等虚拟机软件
    以VirtualBox 为例 (根据个人喜好)
    1. 进入官网:
           https://www.virtualbox.org/ 
    2. 下载对应版本的压缩包文件:
      ![virtualbox](https://img-blog.csdnimg.cn/c489543054784b50bdaa6807a4a2d462.png)
    
    • 1
    • 2
    • 3
    • 4

    3.安装 (选择合适的物理盘)
    4. 验证
    icon
    界面

    快速搭建Linux(使用镜像)

    1.使用vagrant
    2.官网:
    https://www.vagrantup.com/downloads
    https://app.vagrantup.com/boxes/search
    vagrant download
    boxes serarch
    3. 安装 (电脑会自动重启)
    4. 验证
    win + R cmd 黑窗口 vagrant -v
    有版本号 ,ok
    cmd

    5.构建Linux
    1. vagrant box list (看看可使用的box 列表)
    2. vagrant init boxName
    例 vagrant init centos-7
    会在安装的对应目录下生成一个

    Vagrantfileboxname
    3. vagrant up (启动并创建Linux)
    有时挺快,大部分时间会失败,因为是国外服务器,如果20分钟还没好就不等了
    国内镜像:
    https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box

    4.vagrant box add E:\myLinux\CentOS-7.box --name centos-7 (加入box)
    4. vargrant ssh (连接)
    5. 可以 使用黑窗口 也可以使用xshell
    computer

    xshell

    下载docker image

    1.卸载之前版本  
      sudo yum remove -y docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-selinux \
                      docker-engine-selinux \
                      docker-engine
    				  
    2. 安装需要的依赖包:
      sudo yum install -y yum-utils
    
    3. 配置阿里镜像
      sudo yum-config-manager \
        --add-repo \
        https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
    
    4. 更新安装docker 容器
    sudo yum install docker-ce docker-ce-cli containerd.io
    
    5. docker -v
    
    6.sudo systemctl start docker   
       如果报错:
        Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
     更改文件类型:   
     mv daemon.json daemon.conf
    6.查看docker 镜像:  sudo docker images       
    7. 设置开机自启:sudo systemctl enable docker
    8. 由于权限问题 命令前加 sudo  或者直接使用 root 账户 :su root
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    redis 集群搭建(3主3从)

    1.docker search redis   
    2.docker pull redis     (默认拉去最新的)
    3. 创建虚拟网卡
        创建虚拟网卡,主要是用于redis-cluster能于外界进行网络通信,一般常用桥接模式。
        docker network create myrediscluster
    
     4. 查看Docker 网卡信息
        docker network ls
    	
     5.	查看dockerr网络详细信息
         docker network inspect myrediscluster
    	
     6、补充(删除网卡信息、帮助命令)
       docker network rm myrediscluster #删除网卡命令 多个中间 空格隔开
        docker network --help #显示可带参数等	
    	
     7.	编写配置文件
        此处用到了一点 shlle 编程中 的一些命令,让我们操作更加便利
    	for port in $(seq 6390 6395); 
    do 
    mkdir -p /mydata/rediscluster/node-${port}/conf
    touch /mydata/rediscluster/node-${port}/conf/redis.conf
    cat  << EOF > /mydata/rediscluster/node-${port}/conf/redis.conf
    port ${port}
    requirepass 1234
    bind 0.0.0.0
    protected-mode no
    daemonize no
    appendonly yes
    cluster-enabled yes 
    cluster-config-file nodes.conf
    cluster-announce-ip 192.168.56.10
    cluster-node-timeout 18000
    cluster-announce-port ${port}
    cluster-announce-bus-port 1${port}
    EOF
    done
    
    8. 启动:
       for port in $(seq 6390 6395); \
    do \docker run -it -d -p ${port}:${port} -p 1${port}:1${port} \--privileged=true -v /mydata/rediscluster/node-${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \--privileged=true -v /mydata/rediscluster/node-${port}/data:/data \--restart always --name redis-${port} --net myrediscluster \--sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf
    done
    
    9. 进入容器:
    docker exec -it redis-6392 /bin/bash
    10. 创建集群:
    redis-cli  -a 1234 --cluster create 192.168.56.10:6390 192.168.56.10:6391 192.168.56.10:6392 192.168.56.10:6393 192.168.56.10:6394 192.168.56.10:6395   --cluster-replicas 1
    
    11. 先停止运行,再删除(重新来)
       for port in $(seq 6390 6395); 
    do 
    docker stop redis-${port}
    done	
    
    
    for port in $(seq 6390 6395); 
    do 
    docker rm redis-${port}
    done
    
    12. 命令解释:
      port:节点端口;
    requirepass:设置密码,访问时需要验证
    protected-mode:保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
    daemonize:是否以守护线程的方式启动(后台启动),默认 no;
    appendonly:是否开启 AOF 持久化模式,默认 no;
    cluster-enabled:是否开启集群模式,默认 no;
    cluster-config-file:集群节点信息文件;
    cluster-node-timeout:集群节点连接超时时间;
    cluster-announce-ip:集群节点 IP (对外通讯的地址 或者配置 docker 宿主机地址)
    cluster-announce-port:集群节点映射端口;
    cluster-announce-bus-port:集群节点总线端口。
    启动:
    -it:交互
    -d:后台运行,容器启动完成后打印容器
    –privileged:是否让docker 应用容器 获取宿主机root权限(特殊权限--p :端口映射
    -v:文件挂载
    –sysctl参数来设置系统参数,通过这些参数来调整系统性能
    –restart always:在容器退出时总是重启容器
    –name:给容器取名
    –net myrediscluster:使用我们创建的虚拟网卡(想详细了解,可以去看看Docker 网络方面知识)	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    问题&图片展示

    上面搭建成功就可以操作了
    success

    问题

    p1 : Waiting for the cluster to join
    Waiting for the  cluster  to join
    p2: 拒绝连接拒绝连接p3: MOVED (-c 使用集群模式访问)
    在这里插入图片描述p4:
    [ERR] Node 172.18.0.2:6392 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

    上面问题根源都是IP 地址的问题
    ifconfig
    mycomputer
    ip addr
    vm ip info
    docker inspect redis-6395 | grep IP (docker image ip info)
    image ip
    ping
    ping

    代码连接

    1. 依赖
           <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>3.7.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
                <version>2.11.1</version>
            </dependency>
    
    2. 单节点demo
      import redis.clients.jedis.HostAndPort;
    import redis.clients.jedis.Jedis;
    /**
     * @className RedisSingletonDemo
     * @description:
     * @date 2023/9/1 16:36
     * @created by windBird
     */
    public class RedisSingletonDemo {
        public static void main(String[] args) {
            Jedis jedis = new Jedis(new HostAndPort("192.168.56.10",6379));
            jedis.set("redisSingleton","我通了");
            System.out.println(jedis.get("redisSingleton"));
        }
    }
    
    3. 集群:
     import redis.clients.jedis.HostAndPort;
    import redis.clients.jedis.JedisCluster;
    import redis.clients.jedis.JedisPoolConfig;
    import java.util.LinkedHashSet;
    import java.util.Set;
    
    /**
     * @className RedisDemo
     * @description:
     * @date 2023/8/14 22:50
     * @created by windBird
     */
    public class RedisDemo {
        public static void main(String[] args) {
            JedisCluster cluster =null;
            try {
                Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
                //一般选用slaveof从IP+端口进行增删改查,不用master
                nodes.add(new HostAndPort("192.168.56.10", 6390));
                nodes.add(new HostAndPort("192.168.56.10", 6391));
                nodes.add(new HostAndPort("192.168.56.10", 6392));
                nodes.add(new HostAndPort("192.168.56.10", 6393));
                nodes.add(new HostAndPort("192.168.56.10", 6394));
                nodes.add(new HostAndPort("192.168.56.10", 6395));
                // Jedis连接池配置
                JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                // 最大空闲连接数, 默认8个
                jedisPoolConfig.setMaxIdle(100);
                // 最大连接数, 默认8个
                jedisPoolConfig.setMaxTotal(500);
                //最小空闲连接数, 默认0
                jedisPoolConfig.setMinIdle(0);
                // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
                jedisPoolConfig.setMaxWaitMillis(-1); // 设置2秒
                //对拿到的connection进行validateObject校验
                jedisPoolConfig.setTestOnBorrow(true);
                //未设置auth Password
               // JedisCluster jedis = new JedisCluster(nodes, jedisPoolConfig);
                //设置auth Password
               JedisCluster jedis = new JedisCluster(nodes,20000,3000,10,"1234", new JedisPoolConfig());
                System.out.println(jedis.get("weather"));
                jedis.set("name","sugar");
                jedis.set("address","china");
                System.out.println(jedis.exists("name"));
                System.out.println(jedis.get("name"));
                System.out.println(jedis.get("address"));
            }catch(Exception e) {
                e.printStackTrace();
            }finally {
                if(null !=cluster)
                    cluster.close();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    timeout
    docker ps -a
    docker restart redis (CONTAINER ID 或者 names)
    restart

    在这里插入图片描述
    集群超时
    cluster timeout批量重启cluster nodes
    for port in ( s e q 63906395 ) ; d o d o c k e r r e s t a r t r e d i s − (seq 6390 6395); do docker restart redis- (seq63906395);dodockerrestartredis{port}
    done

    cluster restart

    cluster go
    重新设值:
    docker exec -it redis-6392 /bin/bash
    redis-cli -c -a 1234 -h 192.168.56.10 -p 6392

    vm ok

    ok

    心动不如行动,来试试呗
  • 相关阅读:
    JAVA编程规范之异常处理
    为什么选择虚拟展会展览?了解虚拟展会展览的应用领域
    Go语言map并发安全,互斥锁和读写锁谁更优?
    Kubernetes(K8s):未来云原生应用的引擎
    大一C语言入门到底怎么学
    5分钟学会 gRPC
    怎么快速入门一种编程语言
    UE4创建一个角色类
    AI人体行为分析:玩手机/打电话/摔倒/攀爬/扭打检测及TSINGSEE场景解决方案
    京东获取商品历史价格信息 API
  • 原文地址:https://blog.csdn.net/WindwirdBird/article/details/132724176