TT Bigdata TT Bigdata
首页
  • 部署专题

    • 常规安装
    • 一键部署
  • 组件安装

    • 常规&高可用
  • 版本专题

    • 更新说明
  • Ambari-Env

    • 环境准备
    • 开始使用
  • 组件编译

    • 专区—Ambari
    • 专区—Bigtop
  • 报错解决

    • 专区—Ambari
    • 专区—Bigtop
  • 其他技巧

    • Maven镜像加速
    • Gradle镜像加速
    • Bower镜像加速
    • 虚拟环境思路
    • R环境安装+一键安装脚本
    • Ivy配置私有镜像仓库
    • Node.js 多版本共存方案
    • Ambari Web本地启动
    • Npm镜像加速
    • PostgreSQL快速安装
    • Temurin JDK 23快速安装
  • 成神之路

    • 专区—Ambari
    • 专区—Bigtop
  • 集成案例

    • Redis集成教学
    • Dolphin集成教学
    • Doris集成教学
    • 持续整理...
  • 模板代码

    • 各类组件
    • 通用模板
  • 国产化&其他系统

    • Centos系列
    • Kylin系列
    • OpenEuler系列
    • Rocky系列
    • Ubuntu系列
  • 生产调优

    • 组件调优指南
    • 1v1指导调优
  • 定制开发

    • 组件版本定制
    • 样式风格定制
  • 蓝图愿景
  • 技术支持
  • 合作共建
GitHub (opens new window)

JaneTTR

数据酿造智慧,每一滴都是沉淀!
首页
  • 部署专题

    • 常规安装
    • 一键部署
  • 组件安装

    • 常规&高可用
  • 版本专题

    • 更新说明
  • Ambari-Env

    • 环境准备
    • 开始使用
  • 组件编译

    • 专区—Ambari
    • 专区—Bigtop
  • 报错解决

    • 专区—Ambari
    • 专区—Bigtop
  • 其他技巧

    • Maven镜像加速
    • Gradle镜像加速
    • Bower镜像加速
    • 虚拟环境思路
    • R环境安装+一键安装脚本
    • Ivy配置私有镜像仓库
    • Node.js 多版本共存方案
    • Ambari Web本地启动
    • Npm镜像加速
    • PostgreSQL快速安装
    • Temurin JDK 23快速安装
  • 成神之路

    • 专区—Ambari
    • 专区—Bigtop
  • 集成案例

    • Redis集成教学
    • Dolphin集成教学
    • Doris集成教学
    • 持续整理...
  • 模板代码

    • 各类组件
    • 通用模板
  • 国产化&其他系统

    • Centos系列
    • Kylin系列
    • OpenEuler系列
    • Rocky系列
    • Ubuntu系列
  • 生产调优

    • 组件调优指南
    • 1v1指导调优
  • 定制开发

    • 组件版本定制
    • 样式风格定制
  • 蓝图愿景
  • 技术支持
  • 合作共建
GitHub (opens new window)
  • 方法论

    • 自顶向下——基于方法论下的Redis集成[一]
    • 自顶向下——基于方法论下的Redis集成[二]
    • 自顶向下——基于方法论下的Redis集成[三]
    • 自顶向下——基于方法论下的Redis集成[四]
    • 自顶向下——基于方法论下的Redis集成[五]
    • 安装过程日志逆向理解[一]
    • 安装过程日志逆向理解[二]
    • 安装过程日志逆向理解[三]
    • Redis-Cluster模式设计[一]
    • Redis-Cluster模式设计[二]
      • 2. Ambari 中的 Redis 高可用设计元素
        • 2.1 主从组件的分割与布局
        • 2.1.1 节点分布表
        • 2.1.2 反亲和性设计
        • 2.2 主从组件的启动与管理
        • 2.2.1 Redis Master 的启动逻辑
        • 2.2.2 Redis Slave 的启动逻辑
        • 2.2.3 集群初始化与扩展逻辑
        • 2.3 动态扩展与缩容
        • 2.3.1 动态扩展
        • 2.3.2 动态缩容
  • 代码生命周期-metainfo

  • 架构剖析

  • UI样式

  • GOD-Ambari
  • 方法论
JaneTTR
2025-05-31
目录

Redis-Cluster模式设计[二]

# 2. Ambari 中的 Redis 高可用设计元素

Ambari 对 Redis 集群的高可用运维做了系统性的集成,通过自动化脚本与节点反亲和策略,实现主从分离、分布式容错和集群弹性扩缩容。下面结合表格、代码和设计要点进行逐步拆解。

# 2.1 主从组件的分割与布局

Redis 的高可用核心,在于 Master 与 Slave 角色的合理分布。Ambari 通过自动化分配策略,确保主从节点物理隔离,极大提升集群容灾能力。

# 2.1.1 节点分布表

节点名称 角色 端口 哈希槽分配 职责 数据复制关系
Node 1 Master 1 6379 0-5461 负责哈希槽 0-5461 数据 复制到 Slave 3 (Node 3)
Node 1 Slave 1 6380 5462-10922 复制 Master 2 (Node 2) 数据
Node 2 Master 2 6379 5462-10922 负责哈希槽 5462-10922 数据 复制到 Slave 1 (Node 1)
Node 2 Slave 2 6380 10923-16383 复制 Master 3 (Node 3) 数据
Node 3 Master 3 6379 10923-16383 负责哈希槽 10923-16383 数据 复制到 Slave 2 (Node 2)
Node 3 Slave 3 6380 0-5461 复制 Master 1 (Node 1) 数据

笔记

Master 和 Slave 通过交叉分布,互为容灾,消除了单节点故障的隐患 高可用。

Redis分布式主从拓扑

# 2.1.2 反亲和性设计

在集群自动化部署时,Ambari 内部会调用如 get_assigned_master 方法,确保 Slave 节点总是绑定到不同的物理主机上,避免“同命运”故障:

def get_assigned_master(self, params):
    master_hosts = params.redis_master_hosts
    Logger.info("Available Master nodes: {0}".format(master_hosts))

    current_slave_index = int(params.redis_port) % len(master_hosts)
    assigned_master_index = (current_slave_index + 1) % len(master_hosts)
    assigned_master = master_hosts[assigned_master_index]

    Logger.info(format("Assigning Slave on port {params.redis_port} to Master {assigned_master}"))
    return assigned_master
1
2
3
4
5
6
7
8
9
10

提示

这种主从跨机绑定方式,有效规避了主从同物理节点带来的整体失效风险,确保了每一次故障切换的独立性和安全性。

# 2.2 主从组件的启动与管理

Ambari 将 Redis Master 和 Slave 的生命周期管理彻底解耦,分别以独立脚本完成配置、启动、监控和故障恢复,方便按需维护和弹性扩展。

# 2.2.1 Redis Master 的启动逻辑

def start(self, env):
    import params
    self.configure(env)
    Logger.info(format("Starting Redis Master on port {redis_port}"))
    Execute(format(
        "{client_bin}/redis-server /etc/redis/redis.conf --cluster-config-file /etc/redis/cluster_master.conf --pidfile {master_redis_pid_file}"),
        user=params.redis_user)
1
2
3
4
5
6
7

笔记

Master 主要承担数据处理和哈希槽分配,不参与 Slave 的生命周期管理。

# 2.2.2 Redis Slave 的启动逻辑

def start(self, env):
    import params
    self.configure(env)

    slave_port = int(params.redis_port) + 1
    Logger.info(format("Starting Redis Slave on port {slave_port}"))

    Execute(format(
        "{client_bin}/redis-server /etc/redis/redis.conf --port {slave_port} --cluster-config-file /etc/redis/cluster_slave.conf --pidfile {slave_redis_pid_file}"),
        user=params.redis_user)

    self.initialize_or_expand_cluster(params)
1
2
3
4
5
6
7
8
9
10
11
12
  • Slave 启动后,会根据当前集群状态自动决定是初始化集群,还是扩容加入现有主节点。

# 2.2.3 集群初始化与扩展逻辑

initialize_or_expand_cluster 方法根据集群现状动态决策,自动化处理 Master 初始化和 Slave 加入:

def initialize_or_expand_cluster(self, params):
    retries = 5
    retry_delay = 10

    for attempt in range(retries):
        code, output = shell.call(
            format("{client_bin}/redis-cli -p {params.redis_port} -a {redis_password} cluster nodes"),
            user=params.redis_user)

        if code == 0 and len(output.splitlines()) > 1:
            Logger.info("Cluster is already initialized. Proceeding with slave addition.")
            self.add_slave_to_master(params)
            return
        elif len(output.splitlines()) == 1:
            Logger.info("Cluster is not initialized. Initializing Redis Cluster with master nodes and assigning slots.")
            self.initialize_cluster_and_assign_slots(params)
            return
        else:
            Logger.warning("Cluster is not initialized (attempt {}/{}).".format(attempt + 1, retries))
            time.sleep(retry_delay)

    Logger.error("Cluster could not be initialized after retries.")
    raise Exception("Cluster in an inconsistent state.")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

注意

集群状态判断与自动化容错,极大减少了人工运维成本,同时也避免了节点状态“悬空”或孤岛问题。

# 2.3 动态扩展与缩容

# 2.3.1 动态扩展

扩容时,只需新启动 Master/Slave 角色节点,Slave 通过 add_slave_to_master 方法智能挂载到合适主节点,无需手动分配:

def add_slave_to_master(self, params):
    slave_port = int(params.redis_port) + 1
    master_host = self.get_assigned_master(params)

    if self.is_slave_already_in_cluster(params, slave_port):
        Logger.info(format("Redis Slave {params.hostname}:{slave_port} is already part of the cluster, skipping addition."))
        return

    Execute(format(
        "{client_bin}/redis-cli --cluster add-node {params.hostname}:{slave_port} {master_host}:{params.redis_port} --cluster-slave -a {redis_password}"),
        user=params.redis_user)

    Logger.info("Slave node added to the cluster as a replica of master {master_host}. No need to rebalance slots.")
1
2
3
4
5
6
7
8
9
10
11
12
13

提示

动态扩容过程全自动,无需重启业务,对线上服务“无感知”热扩容。

# 2.3.2 动态缩容

缩容则结合 Redis reshard 工具,先迁移哈希槽再下线节点,保证业务平滑、数据均衡,不影响整体读写可用性。

#Redis#Ambari#高可用#集群运维
Redis-Cluster模式设计[一]
加载原理深度剖析[一]

← Redis-Cluster模式设计[一] 加载原理深度剖析[一]→

最近更新
01
Pandoc 缺失导致 SparkR 构建失败
06-08
02
Cyrus SASL/GSASL 缺失解决
06-07
03
Hadoop_3.3.4 编译实战 1.0.0+
06-06
更多文章>
Theme by Vdoing | Copyright © 2017-2025 JaneTTR | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式