K8S如何部署ZooKeeper以及如何进行ZooKeeper的平滑替换

news2024/10/1 19:32:26

2.png

前言

在之前的章节中,我们已经成功地将Dubbo项目迁移到了云环境。在这个过程中,我们选择了单机ZooKeeper作为注册中心。接下来,我们将探讨如何将单机ZooKeeper部署到云端,以及在上云过程中可能遇到的问题及解决方案。

ZooKeeper是一个开源的分布式协调服务,由Apache软件基金会开发。它主要用于实现分布式系统中的配置管理、命名服务、分布式同步和组服务等,是一个功能强大、高性能、高可用性和可扩展性的分布式协调服务,广泛应用于各种分布式系统和微服务架构中。ZooKeeper的主要特点如下:

  • 高可用性:ZooKeeper通过在集群中选举领导者来确保系统的可用性。当领导者不可用时,其他服务器可以自动选举出新的领导者,从而保证了系统的持续运行。

  • 数据一致性:ZooKeeper使用一种称为“原子广播”的数据同步机制,确保所有节点上的数据保持一致。这对于需要高度一致性的分布式应用(如金融交易系统)非常重要。

  • 高性能:ZooKeeper具有低延迟和高吞吐量的特点,适用于处理大量并发请求。它使用了多种优化技术,如内存管理和多线程,以提高性能。

  • 可扩展性:ZooKeeper支持水平扩展,可以通过增加服务器节点来提高系统的容量。此外,ZooKeeper还提供了负载均衡功能,可以根据服务器的负载情况自动分配客户端请求。

  • 灵活性:ZooKeeper提供了丰富的API和工具,方便开发者进行集成和定制。同时,它还支持多种编程语言,如Java、C++、Python等。

ZooKeeper的云端迁移

由于我们还有一些Dubbo服务并未部署在Kubernetes集群内,因此我们需要在Zookeeper中采用NodePort方式来暴露相关端口。这样一来,外部的Dubbo服务便可以通过访问Zookeeper节点的IP地址和NodePort号来建立连接,从而实现对其他Dubbo服务的访问。

在之前的文章中,我们提到了我们的Dubbo版本为2.7.22。因此,在查阅了Dubbo官方文档中关于Dubbo版本与ZooKeeper版本之间的依赖关系后,我们选择的ZooKeeper官方镜像为zookeeper:3.4.9

Dubbo版本与ZooKeeper版本关系

基于以上的历史原因,我们最终的部署文件如下所示:

apiVersion: v1
kind: Service
metadata:
  name: zookeeper
  namespace: your-namespace
spec:
  selector:
    app: zookeeper
  type: NodePort
  ports:
    - name: client
      port: 2181
      targetPort: 2181
      nodePort: 30000
    - name: follower
      port: 2888
      targetPort: 2888
      nodePort: 30001
    - name: leader
      port: 3888
      targetPort: 3888
      nodePort: 30002
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: zookeeper
  namespace: your-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zookeeper
  template:
    metadata:
      labels:
        app: zookeeper
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: project.node
                    operator: In
                    values:
                      - your-namespace
      containers:
        - name: zookeeper
          image: zookeeper:3.4.9
          imagePullPolicy: IfNotPresent
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          ports:
            - containerPort: 2181
            - containerPort: 2888
            - containerPort: 3888
          volumeMounts:
            - name: data
              mountPath: /data
      volumes:
        - name: data
          hostPath:
            path: /var/lib/docker/zookeeper

在这个配置文件中,我们使用了一个名为zookeeper的Deployment来部署单机ZooKeeper,并使用了一个名为zookeeper的Service来暴露端口。Service的类型被设置为NodePort,这样可以在集群外部链接ZooKeeper。Service的选择器指定了要暴露的Pod,这里使用了一个名为zookeeper的标签。Service的端口被设置为2181、2888和3888,分别对应ZooKeeper的客户端端口、跟随者端口和领导者端口。targetPort字段指定了要转发到Pod的端口,这里使用了相同的端口号。nodePort字段指定了要暴露的端口号,这里分别使用了30000、30001和30002端口。我们将/data目录挂载到了宿主机的/var/lib/docker/zookeeper目录。这个目录用于存储ZooKeeper的数据和日志。

启动一个Dubbo服务,我们使用刚刚部署的Zookeeper作为注册中心。同时,我们也部署了一个Dubbo-Admin,它同样链接到刚刚部署的Zookeeper上。登录到Dubbo-Admin前端页面,我们发现服务已经成功注册。至此,Zookeeper已成功迁移到云端。

2.png

ZooKeeper的平滑迁移

根据上述步骤,我们已经成功部署了一个可用的单机ZooKeeper。那么,如何将线上存量服务在不停机的情况下优雅的平滑迁移过来呢?

其实,在Dubbo官方文档中,已经给了我们答案:多注册中心地址不聚合

Dubbo 注册中心和服务是独立配置的,通常开发者不用设置服务和注册中心组件之间的关联关系,Dubbo 框架会将自动执行以下动作:

  • 对于所有的 Service 服务,向所有全局默认注册中心注册服务地址。
  • 对于所有的 Reference 服务,从所有全局默认注册中心订阅服务地址。
<dubbo:registry id="one" address="zookeeper://127.0.0.1:9090" />
<dubbo:registry id="two" address="zookeeper://127.0.0.2:9010" />

因此,当我们配置如上所示独立配置的注册中心组件时,Dubbo会将所有的Service服务同时注册到这两个ZooKeeper上,并且所有的Reference服务也会同时订阅这两个ZooKeeper。地址列表在消费端默认是完全隔离的,负载均衡选址要经过两步:

  1. 注册中心集群间选址,选定一个集群
  2. 注册中心集群内选址,在集群内进行地址筛选

1.png

注册中心集群间选址策略有如下几种:

  • 随机默认策略,每次请求都随机的分配到一个注册中心集群。随机的过程中会有可用性检查,即每个集群要确保至少有一个地址可用才有可能被选到。

  • preferred 优先:如果有注册中心集群配置了 preferred="true",则所有流量都会被路由到这个集群。

    <dubbo:registry id="one" address="zookeeper://127.0.0.1:9090" preferred="true"/>
    <dubbo:registry id="two" address="zookeeper://127.0.0.2:9010" />
    
  • weighted:基于权重的随机负载均衡,以下集群间会有大概 10:1 的流量分布。

    <dubbo:registry id="one" address="zookeeper://127.0.0.1:9090" weight="100"/>
    <dubbo:registry id="two" address="zookeeper://127.0.0.2:9010" weight="10"/>
    
  • 同 zone 优先:根据 Invocation 中带的流量参数或者在当前节点通过 context 上下文设置的参数,流量会被精确的引导到对应的集群。

    <dubbo:registry id="one" address="zookeeper://127.0.0.1:9090" zone="one"/>
    <dubbo:registry id="two" address="zookeeper://127.0.0.2:9010" zone="two"/>
    
    RpcContext.getContext().setAttachment("registry_zone", "one");
    

在这里,我们采用默认的随机策略,因为在随机的过程中会有可用性检查,这确保了我们的消费者服务始终能够连接到可用的提供者服务,为我们不停机迁移提供了基础。

接下来,我们需要对代码进行修改,具体操作如下:

  • dubbo.xml:

    • 删除以下部分:

      <!-- zookeeper注册中心 -->
      <dubbo:registry address="${dubbox.registry.address}"/>
      
    • 新增以下部分:

      <!-- 老zookeeper注册中心 -->
      <dubbo:registry id="oldZkRegistry" address="${dubbox.registry.address}"/>
      <!-- 新k8s上zk注册中心 -->
      <dubbo:registry id="newZkRegistry" address="${dubbox.registry.address.new}"/>
      
  • 配置文件:在配置文件中,新增以下配置:

    # 新k8s上zk注册中心地址,ip为宿主机的ip,端口为nodeport暴露的client的端口
    dubbox.registry.address.new = zookeeper://xx.xx.xx.xx:30000
    
    

在经过改造后,我们的服务将同时注册到新的和旧的ZooKeeper上,这就相当于我们搭建了一个ZooKeeper集群。当所有的存量服务都完成改造并成功部署上线后,我们还需要对我们的代码进行进一步的改造。具体的步骤如下:

  • dubbo.xml:

    • 删除以下部分:

      <!-- 老zookeeper注册中心 -->
      <dubbo:registry id="oldZkRegistry" address="${dubbox.registry.address}"/>
      <!-- 新k8s上zk注册中心 -->
      <dubbo:registry id="newZkRegistry" address="${dubbox.registry.address.new}"/>
      
      
    • 新增以下部分:

      <!-- 新k8s上zk注册中心 -->
      <dubbo:registry address="${dubbox.registry.address.new}"/>
      
      
  • 配置文件:在配置文件中,删除以下配置:

    # 老zk注册中心地址
    dubbox.registry.address = zookeeper://xx.xx.xx.xx:2181
    
    

当我们的存量服务全部经过改造并成功部署上线后,我们的老ZooKeeper才能够进行停机下线。至此,ZooKeeper的平滑替换便顺利完成了。

小结

经过以上的阐述,我们可以明确地认识到,在决定ZooKeeper的部署版本时,我们需要进行深入细致的分析,充分考虑外部环境因素的影响,例如Duboo版本之间的兼容性问题。为了确保ZooKeeper的平稳迁移并维持服务的连续性,我们需要采取一系列策略,如逐步升级、严格的功能测试和版本兼容性检查等。要在生产环境中实现ZooKeeper的平滑迁移并保持服务不间断,这将需要投入大量的时间和精力。因此,在我们正式上线生产环境之前,必须进行详尽的规划,全面预见未来可能出现的情况,以最大程度地避免不必要的麻烦。只有这样,我们才能确保项目的长期稳定运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/919502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最优的家电设备交互方式是什么?详解家电设备交互的演进之旅

家电&#xff0c;在人们的日常生活中扮演着不可或缺的角色&#xff0c;也是提升人们幸福感的重要组成部分&#xff0c;那你了解家电的发展史吗&#xff1f; 70年代 结婚流行“四大件”&#xff1a;手表、自行车、缝纫机&#xff0c;收音机&#xff0c;合成“三转一响”。 80年…

精进语言模型:探索LLM Training微调与奖励模型技术的新途径

大语言模型训练&#xff08;LLM Training&#xff09; LLMs Trainer 是一个旨在帮助人们从零开始训练大模型的仓库&#xff0c;该仓库最早参考自 Open-Llama&#xff0c;并在其基础上进行扩充。 有关 LLM 训练流程的更多细节可以参考 【LLM】从零开始训练大模型。 使用仓库之…

36k字从Attention解读Transformer及其在Vision中的应用(pytorch版)

文章目录 0.卷积操作1.注意力1.1 注意力概述(Attention)1.1.1 Encoder-Decoder1.1.2 查询、键和值1.1.3 注意力汇聚: Nadaraya-Watson 核回归1.2 注意力评分函数1.2.1 加性注意力1.2.2 缩放点积注意力1.3 自注意力(Self-Attention)1.3.1 自注意力的定义和计算1.3.2 自注意…

DataFrame.query()--Pandas

1. 函数功能 Pandas 中的一个函数&#xff0c;用于在 DataFrame 中执行查询操作。这个方法会返回一个新的 DataFrame&#xff0c;其中包含符合查询条件的数据行。请注意&#xff0c;query 方法只能用于筛选行&#xff0c;而不能用于筛选列。 2. 函数语法 DataFrame.query(ex…

【OJ比赛日历】快周末了,不来一场比赛吗? #08.26-09.01 #16场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-08-26&#xff08;周六&#xff09; #8场比赛2023-08-27…

redis在linux和windows上的安装配置(解决问题:没有可用软件包 redis)

linux系统 安装 yum install redis安装 在终端输入yum install redis安装。 报错&#xff1a;没有可用软件包 redis。 解决&#xff1a; 运行以下命令更新软件包信息&#xff1a; sudo yum clean all sudo yum update 然后继续尝试yum install redis。 如果还不成功&a…

探索最短路径问题:寻找优化路线的算法解决方案

1. 前言&#xff1a;最短路径问题的背景与重要性 在现实生活中&#xff0c;我们常常面临需要找到最短路径的情况&#xff0c;如地图导航、网络路由等。最短路径问题是一个关键的优化问题&#xff0c;涉及在图中寻找两个顶点之间的最短路径&#xff0c;以便在有限时间或资源内找…

最新AI系统ChatGPT程序源码+搭建部署教程/支持GPT4/支持ai绘画/H5端/完整知识库

一、AI系统 如何搭建部署AI创作ChatGPT系统呢&#xff1f;小编这里写一个详细图文教程吧&#xff01; SparkAi使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到AIGC系统&#xff01; 程序核心功能&#xff1a; 程序已支持ChatGPT3.5/4.0提问、AI绘画、Midjourney绘画&…

【Axure原型分享】能统计中英文字数的多行输入框

今天和大家分享能统计中英文字数的多行输入框的原型模板&#xff0c;在输入框里输入内容后&#xff0c;能够动态根据输入框的内容&#xff0c;统计出字符数量&#xff0c;包括总字数、中文字数、英文字数、数字字数、其他标点符号的字数&#xff0c;具体效果可以观看下方视频或…

微服务架构2.0--云原生时代

云原生 云原生&#xff08;Cloud Native&#xff09;是一种关注于在云环境中构建、部署和管理应用程序的方法和理念。云原生应用能够最大程度地利用云计算基础设施的优势&#xff0c;如弹性、自动化、可伸缩性和高可用性。这个概念涵盖了许多方面&#xff0c;包括架构、开发、…

DataLoader

机器学习的五个步骤&#xff1a; 数据模块——模型——损失函数——优化器——训练 在实际项目中&#xff0c;如果数据量很大&#xff0c;考虑到内存有限、I/O 速度等问题&#xff0c;在训练过程中不可能一次性的将所有数据全部加载到内存中&#xff0c;也不能只用一个进程去加…

mmdetection基于 PyTorch 的目标检测开源工具箱 入门教程

安装环境 MMDetection 支持在 Linux&#xff0c;Windows 和 macOS 上运行。它需要 Python 3.7 以上&#xff0c;CUDA 9.2 以上和 PyTorch 1.8 及其以上。 1、安装依赖 步骤 0. 从官方网站下载并安装 Miniconda。 步骤 1. 创建并激活一个 conda 环境。 conda create --name…

厦门逗客传媒:抖音本地团购怎么入驻

随着社交媒体的不断发展&#xff0c;短视频平台已经成为了商家推广和营销的热门渠道之一。在这其中&#xff0c;抖音作为全球知名的短视频平台&#xff0c;以其巨大的用户基数和精准的推荐算法吸引了大量商家的关注。而在抖音上&#xff0c;本地团购也成为了一个备受关注的领域…

控制Unity发布的PC包的窗体

大家好&#xff0c;我是阿赵。   用Unity发布PC包接入某些渠道时&#xff0c;有时候会收到一些特殊的需求&#xff0c;比如控制窗口最大化(比如某些情况强制显示窗体)、最小化(比如老板键)、强制规定窗体置顶等。虽然我一直认为这些需求都是流氓软件行为&#xff0c;但作为一…

【每日易题】七夕限定——单身狗问题以及进阶问题位运算法的深入探讨

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;在写这篇博客的前一天是七夕&#xff0c;也是中国传统的“情人节”&#xff0c;不知道各位脱单了吗&#xff1f;碰巧最近刷题时遇到了经典的单身狗问题想带大家深入探…

消息队列前世今生 字节跳动 Kafka #创作活动

消息队列前世今生 1.1 案例一&#xff1a; 系统崩溃 首先大家跟着我想象一下下面的这个的场景&#xff0c; 看到新出的游戏机&#xff0c;太贵了买不起&#xff0c;这个时候你突然想到&#xff0c;今天抖音直播搞活动&#xff0c;打开抖音搜索&#xff0c;找到直播间以后&am…

JVM——类加载与字节码技术—编译期处理+类加载阶段

3.编译期处理 编译期优化称为语法糖 3.1 默认构造器 3.2 自动拆装箱 java基本类型和包装类型之间的自动转换。 3.3泛型集合取值 在字节码中可以看见&#xff0c;泛型擦除就是字节码中的执行代码不区分是String还是Integer了&#xff0c;统一用Object. 对于取出的Object&…

【ARM】Day9 cortex-A7核I2C实验(采集温湿度)

1. 2、编写IIC协议&#xff0c;采集温湿度值 iic.h #ifndef __IIC_H__ #define __IIC_H__ #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h" #include "led.h" /* 通过程序模拟实现I2C总线的时序和协议* GPIOF ---> AHB4* I2C1_S…

IoT DC3 是一个基于 Spring Cloud 的开源的、分布式的物联网(IoT)平台本地部署步骤

dc3 windows 本地搭建步骤&#xff1a; ​​ 必要软件环境 进入原网页# 务必保证至少需要给 docker 分配&#xff1a;1 核 CPU 以及 4G 以上的运行内存&#xff01; JDK : 推荐使用 Oracle JDK 1.8 或者 OpenJDK8&#xff0c;理论来说其他版本也行&#xff1b; Maven : 推荐…

记录《现有docker中安装spark3.4.1》

基础docker环境中存储hadoop3--方便后续查看 参考&#xff1a; 实践&#xff1a; export JAVA_HOME/opt/apache/jdk1.8.0_333 export SPARK_MASTER_IP192.168.0.220 export SPARK_WORKER_MEMORY4g export SPARK_WORKER_CORES2 export SPARK_EXECUTOR_MEMORY4g export HADOOP_H…