zoukankan      html  css  js  c++  java
  • Docker部署Redis集群-小白入门

    前言

    阅读本文需要具备docker、docker-compose、redis等前置知识储备。

    centos版本:

    cat /etc/redhat-release
    
    CentOS Linux release 7.8.2003 (Core)
    

    redis版本:

    redis-server -v
    
    Redis server v=6.0.8 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=75cef67090587c6
    

    redis集群

    Redis集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。

    Redis主从模式可以读写分离;
    Redis哨兵模式可以实现高可用的读写分离;
    Redis集群模式则是在高可用的读写分离的基础上再加上了数据分片。

    以上只是个人对于Redis三种模式功能上总结,实际上集群模式的数据存储和故障转移机制和哨兵模式并不一样。

    部署

    目录结构

    本文采用如下目录结构:

    .
    |-- 7000.conf
    |-- 7001.conf
    |-- 7002.conf
    |-- data
    `-- docker-compose.yml
    
    

    redis配置

    准备三个redis配置文件,端口分别是7000、7001和7002

    7000.conf

    # 监听端口
    port 7000
    
    # 设定密码认证
    requirepass 123456
    
    # 开启集群配置
    cluster-enabled yes
    # 设定了保存节点配置文件的路径,无需人为修改,Redis集群在启动时创建
    cluster-config-file nodes.conf
    # 节点连接超时配置
    cluster-node-timeout 5000
    appendonly yes
    

    7001.conf

    # 监听端口
    port 7001
    
    # 设定密码认证
    requirepass 123456
    
    # 开启集群配置
    cluster-enabled yes
    # 设定了保存节点配置文件的路径,无需人为修改,Redis集群在启动时创建
    cluster-config-file nodes.conf
    # 节点连接超时配置
    cluster-node-timeout 5000
    appendonly yes
    

    7002.conf

    # 监听端口
    port 7002
    
    # 设定密码认证
    requirepass 123456
    
    # 开启集群配置
    cluster-enabled yes
    # 设定了保存节点配置文件的路径,无需人为修改,Redis集群在启动时创建
    cluster-config-file nodes.conf
    # 节点连接超时配置
    cluster-node-timeout 5000
    appendonly yes
    

    docker-compose配置

    用docker-compose来统一管理容器
    docker-compose.yml

    ---
    
    version: '3'
    
    services:
      # 7000的容器
      node-1:
        image: redis
        container_name: node-1
        restart: always
        # 为了规避Docker中端口映射可能带来的问题
        # 这里选择使用host网络
        network_mode: host
        # 指定时区,保证容器内时间正确
        environment:
          TZ: "Asia/Shanghai"
        volumes:
          # 映射配置文件和数据目录
          - ./7000.conf:/usr/local/etc/redis/redis.conf
          - ./data/7000:/data
        sysctls:
          # 必要的内核参数
          net.core.somaxconn: '511'
        command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
      # 7001的容器
      node-2:
        image: redis
        container_name: node-2
        restart: always
        network_mode: host
        environment:
          TZ: "Asia/Shanghai"
        volumes:
          - ./7001.conf:/usr/local/etc/redis/redis.conf
          - ./data/7001:/data
        sysctls:
          net.core.somaxconn: '511'
        command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
      # 7002的容器
      node-3:
        image: redis
        container_name: node-3
        restart: always
        network_mode: host
        environment:
          TZ: "Asia/Shanghai"
        volumes:
          - ./7002.conf:/usr/local/etc/redis/redis.conf
          - ./data/7002:/data
        sysctls:
          net.core.somaxconn: '511'
        command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
    

    启动、坑

    后台启动

    docker-compose up -d
    

    docker-compose up -d

    节点连接

    这个时候实际上每个节点都是运行一个独立的集群当中,在7000节点中执行cluster nodes命令:
    cluster nodes
    可以看到当前集群中只有7000节点自己。所以需要把他们连接起来,融合到一个集群中,使用cluster meet命令可以完成这个工作:

    cluster meet 127.0.0.1 7001
    cluster meet 127.0.0.1 7002
    

    再次查看cluster nodes
    cluster nodes
    这就可以看到三个节点了

    需要注意的是,这里虽然redis-server只用到了7000,7001和7002这三个端口,但实际上还会使用到17000,17001和17002三个端口,我就是因为redis部署在云端,安全组没有放开17000~17002这三个端口,所以在节点连接这里一直握手失败。

    槽位指派

    Redis集群通过分片的方式来保存数据库中的键值对:集群的整个数据库被分为16384个槽(slot),数据库中的每个键都属于这16384个槽的其中一个,集群中的每个节点可以处理0个或最多16384个槽。
    当数据库中的16384个槽都有节点在处理时,集群处于上线状态(ok);相反地,如果数据库中有任何一个槽没有得到处理,那么集群处于下线状态(fail)。

    下线状态
    参照书上的方法进行槽位指派:
    image.png
    于是我进行了如下各种命令组合的尝试:

    cluster addslots 0..5000
    cluster addslots 0...5000
    cluster addslots 0 .. 5000
    cluster addslots 0 ... 5000
    cluster addslots {0..5000}
    cluster addslots {0...5000}
    

    都没有成功~,期待有大佬能教教我

    折中方案

    由于使用下面这些命令都不能正确执行:

    cluster addslots 0..5000
    cluster addslots 0...5000
    cluster addslots 0 .. 5000
    cluster addslots 0 ... 5000
    cluster addslots {0..5000}
    cluster addslots {0...5000}
    .........
    感到绝望
    

    不得已写了个python脚本用于槽位分配

    # -*- coding: utf-8 -*-
    import redis
    
    if __name__ == '__main__':
        ip = input("请输入IP:")
        port = int(input("请输入端口:"))
        password = input("请输入密码:")
        start_slot = int(input("请输入开始槽位号:"))
        end_slot = int(input("请输入结束槽位号:"))
    
        # 拿到redis客户端实例
        r = redis.Redis(host=ip, port=port, password=password)
    
        expect_num = end_slot - start_slot
        actual_num = 0
        for x in range(start_slot, end_slot + 1):
            try:
                result = r.execute_command("cluster addslots " + str(x))
                if result == b'OK':
                    actual_num += 1
            except redis.exceptions.ResponseError as e:
                print("执行 cluster addslots " + str(x) + " 失败!")
    
        if expect_num == actual_num:
            print("所有槽位分配成功")
        else:
            print("部分槽位分配失败")
    

    集群状态

    脚本执行成功以后再查看集群状态:
    cluster info
    可以看到,集群状态已经是上线状态了

    再看看槽位分配情况:
    cluster slots

    和我们预期结果一致

    7000: 0~5000
    7001: 5001~ 10000
    7002: 10001~16383
    

    参考文章

    槽指派
    Redis 集群教程

  • 相关阅读:
    springmvc介绍
    mybatis中的动态sql应用
    mybatis中表的关联
    mybatis分页
    聚类评估指标系列(二):准确率和F值
    混淆矩阵,准确率,召回率,F-score,PR曲线,ROC曲线,AUC
    聚类评估指标系列(一):标准化互信息NMI计算步骤及其Python实现
    numpy.where() 用法详解
    互信息Mutual Information
    转:Prewitt算子、Sobel算子、canny算子、Lapacian算子
  • 原文地址:https://www.cnblogs.com/alinainai/p/14098719.html
Copyright © 2011-2022 走看看