xiaohack's Blog - etcd
type: channel
link: https://blog.xiaohack.org/tag/etcd/
items: vivo GPU容器与 AI 训练平台探索与实践
items: ETCD的内存问题
items: 基于 Patroni,Etcd,Haproxy,Keepalived 搭建 PG16 高可用集群

vivo GPU容器与 AI 训练平台探索与实践
type: item
date: 2026-01-29T11:57:39+08:00
description: 作者：互联网容器团队-Chen Han、AI 研发团队 - Liu Dong Yang在大规模GPU容器集群与模型训练场景，面临稳定性和资源利用率等多重挑战。本文展示vivo GPU平台的总体架构，介绍容器平台在大规模GPU容器集群稳定性建设措施，以及探索多种GPU容器降本提效的解决方案。分享AI工程训练平台大规模训练稳定性建设，及GPU利用率提升实践经验。本文为2025年 vivo 开发者大会互联网技术专场分享内容之一，在微信公众号"vivo互联网技术"对话框回复【2025VDC】获取 2025VDC 互联网技术会场议题相关资料。1分钟看图掌握核心观点👇图1 VS 图2，您更倾向于哪张图来辅助理解全文呢？欢迎在评论区留言一、GPU平台架构vivo的GPU平台由物理层、容器平台层与AI工程层三方面构成。由多种GPU服务器和分布式存储以及高性能网络等基础设施，构成了可靠的物理层。容器平台层的GPU容器能力，主要包含了资源管理、编排调度、GPU虚拟化与多容器网络这四个方面。其中资源管理，表现为多种架构资源池的部署与管理能力。编排调度能力，由GPU弹性伸缩、训推潮汐部署以及多种卡调度策略组成。自研的GPU虚拟化囊括了业界主流的MIG虚拟化、内核层虚拟化以及CUDA层虚拟化三种技术。由传统的Underlay网络以及SRIOV的RDMA直通网络，组成了丰富的容器网络架构。容器平台提供了开放的API接口，为AI工程层的训练和推理平台，提供了坚实的算力底座。通过训练和推理平台，支撑公司内的智能计算业务。二、GPU容器能力实践GPU容器能力实践分为两个模块，首先是大规模容器集群稳定性建设，其次是GPU容器提效降本方案。先了解下容器平台在大规模容器集群场景，如何进行稳定性建设的。2.1 大规模容器集群稳定性集群稳定性是一切的基石。当集群规模大时，任务多，调度频繁，导致核心组件负载激增，极易发生集群崩溃。随着节点规模扩大，运维复杂度呈指数级增长，日常运维工作繁重，发现问题不及时。同时故障处理也面临严峻挑战，故障中涉及的复杂场景多，故障处理的难度大。稳定性建设需要解决上述问题。为了解决高频调度导致的核心组件高负载问题，我们针对Apiserver、etcd、CoreDNS，这3个核心组件进行了架构和性能优化，具体的方案如图所示。通过这些优化手段提升了组件性能，并且降低了组件负载，有利于大规模集群的平稳运行。为了减轻集群运维负担，我们重点建设了自动化节点管理方案。把重复性的运维事项自动化。同时我们还完善了监控告警体系，开发了自动化巡检功能，使运维人员能够及时发现集群问题，快速介入，处理潜在风险，保障集群能够长久稳定运行。故障处理是集群稳定的兜底措施，我们针对多个核心组件都做了，各类故障处理预案。结合可能存在的故障特点，构造故障场景，进行故障恢复演练，确保故障发生时，能够第一时间找到合理的解决方案，准确的处理问题。通过上述的措施，在集群稳定性方面取得了不错的效果，首先日常的集群可用性稳定保持在99.99%水平，其次平台的年度故障复盘数相较于上一年下降60%。核心组件方面的优化也达到了不错效果，其中Apiserver的CPU负载下降70%，etcd提交延迟，从秒级缩短到毫秒级，CoreDNS的毛刺现象消失了，并且负载量下降了90%左右。2.2 GPU容器提效降本实践容器平台的核心竞争力之一就是助力业务提效降本，我们从不同业务维度，对GPU容器提效降本方案进行了探索。首先在单卡维度，通过自研GPU虚拟化方案，使多个容器，互不干扰的共享一张卡资源。其次是在单服务维度，使业务能够自动应对，负载变化的GPU弹性扩缩容方案。在多服务维度，能够让推理服务和训练服务，分时复用整机资源的，训推潮汐部署方案。最后是在多机多卡的分布式场景中，让GPU容器搭配RDMA网络，来解决跨节点通信的瓶颈问题。2.2.1 单卡共享-GPU虚拟化如何让一张卡同时运行多个容器又不互相干扰，就涉及到GPU虚拟化技术。GPU虚拟化一直是AI云原生领域的热门话题之一，各大云厂商都有成熟的解决方案售卖。vivo容器平台的自研GPU虚拟化方案，主要为了解决业务的三大痛点，首先是部分推理业务负载偏低，无法有效用满整卡资源，需要通过共享部署方式，减少资源总量，降低业务成本，提升利用率。其次是不同业务共享同一张卡时，对于安全性以及隔离性的要求各不相同，就需要使用不同的GPU虚拟化技术来满足不同业务诉求。最后在Dev开发机场景，用户使用频率偏低，需要通过显存超售，来提升资源复用率，但显存超售后又需要避免某个用户将显存耗尽，导致OOM错误影响同卡的其他用户。自研GPU虚拟化方案包含MIG虚拟化、内核层虚拟化、CUDA层虚拟化这三种技术。结合业务场景，提供了丰富的卡调度策略，例如尽量聚集的Binpack策略、尽量…

ETCD的内存问题
type: item
date: 2026-01-24T18:24:06+08:00
description: 今天跟大家分享一个etcd的内存大量占用的问题，这是前段时间在我们开源软件Easegress中遇到的问题，问题是比较简单的，但是我还想把前因后果说一下，包括，为什么要用etcd，使用etcd的用户场景，包括etcd的一些导致内存占用比较大的设计，以及最后一些建议。希望这篇文章不仅仅只是让你看到了一个简单的内存问题，还能让你有更多的收获。当然，也欢迎您关注我们的开源软件，给我们一些鼓励。为什么要用ETCD先说一下为什么要用etcd。先从一个我们自己做的一个API网关 – Easegress（源码）说起。Easegress 是我们开发并开源的一个API应用网关产品，这个API应用网关不仅仅只是像nginx那样用来做一个反向代理，这个网关可以做的事很多，比如：API编排、服务发现、弹力设计（熔断、限流、重试等）、认证鉴权（JWT，OAuth2，HMAC等）、同样支持各种Cloud Native的架构如：微服务架构，Service Mesh，Serverless/FaaS的集成，并可以用于扛高并发、灰度发布、全链路压力测试、物联网……等更为高级的企业级的解决方案。所以，为了达到这些目标，在2017年的时候，我们觉得在现有的网关如Nginx上是无法演进出来这样的软件的，必需重新写一个（后来其他人也应该跟我们的想法一样，所以，Lyft写了一个Envoy。只不过，Envoy是用C++写的，而我用了技术门槛更低的Go语言）另外，Easegress最核心的设计主要有三个： 一是无第三方依赖的自己选主组集群的能力 二是像Linux管道命令行那样pipeline式的插件流式处理（支持Go/WebAssembly） 三是内置一个Data Store用于集群控制和数据共享。 对于任何一个分布式系统，都需要有一个强一制性的基于Paxos/Raft的可以自动选主机制，并且需要在整个集群间同步一些关键的控制/配置和相关的共享数据，以保证整个集群的行为是统一一致的。如果没有这么一个东西的话，就没有办法玩分布式系统的。这就是为什么会有像Zookeeper/etcd这样的组件出现并流行的原因。注意，Zookeeper他们主要不是给你存数据的，而是给你组集群的。Zookeeper是一个很流行的开源软件，也被用于各大公司的生产线，包括一些开源软件，比如：Kafka。但是，这会让其它软件有一个依赖，并且在运维上带来很大的复杂度。所以，Kafka在最新的版本也通过内置了选主的算法，而抛弃了外挂zookeeper的设计。Etcd是Go语言社区这边的主力，也是kubernetes组建集群的关键组件。Easegress在一开始（5年前）使用了gossip协议同步状态（当时想的过于超前，想做广域网的集群），但是后发现这个协议太过于复杂，而且很难调试，而广域网的API Gateway也没遇到相应的场景。所以，在3年前的时候，为了稳定性的考量，我们把其换成了内嵌版本的etcd，这个设计一直沿用到今天。Easegress会把所有的配置信息都放到etcd里，还包括一些统计监控数据，以及一些用户的自定义数据（这样用户自己的plugin不但可以在一条pipeline内，还可以在整个集群内共享数据），这对于用户进行扩展来说是非常方便的。软件代码的扩展性一直是我们追求的首要目标，尤其是开源软件更要想方设法降低技术门槛让技术易扩展，这就是为什么Google的很多开源软件都会选使用Go语言的原因，也是为什么Go正在取代C/C++的做PaaS基础组件的原因。背景问题好了，在介绍完为什么要用etcd以后，我开始分享一个实际的问题了。我们有个用户在使用 Easegress 的时候，在Easegress内配置了上千条pipeline，导致 Easegress的内存飙升的非常厉害- 10+GB 以上，而且长时间还下不来。用户报告的问题是——在Easegress 1.4.1 上创建一个HTTP对象，1000个Pipeline，在Easegres初始化启动完成时的内存占用大概为400M，运行80分钟后2GB，运行200分钟后达到了4GB，这期间什么也没有干，对Easegress没有进行过一次请求。一般来说，就算是API再多也不应该配置这么多的处理管道pipeline的，通常我们会使用HTTP API的前缀把一组属于一个类别的API配置在一个管道内是比较合理的，就像nginx下的location的配置，一般来说不会太多的。但是，在用户的这个场景下配置了上千个pipeline，我们也是头一次见，应该是用户想做更细粒度的控制。经过调查后，我们发现内存使用基本全部来自etcd，我们实在没有想到，因为我们往etcd里放的数据也没有多少个key，感觉不会超过10M，但不知道为什么会占用了10GB的内存。这种时候，一般会怀疑e…

ETCD的内存问题
type: item
date: 2026-01-19T18:06:45+08:00
description: 今天跟大家分享一个etcd的内存大量占用的问题，这是前段时间在我们开源软件Easegress中遇到的问题，问题是比较简单的，但是我还想把前因后果说一下，包括，为什么要用etcd，使用etcd的用户场景，包括etcd的一些导致内存占用比较大的设计，以及最后一些建议。希望这篇文章不仅仅只是让你看到了一个简单的内存问题，还能让你有更多的收获。当然，也欢迎您关注我们的开源软件，给我们一些鼓励。为什么要用ETCD先说一下为什么要用etcd。先从一个我们自己做的一个API网关 – Easegress（源码）说起。Easegress 是我们开发并开源的一个API应用网关产品，这个API应用网关不仅仅只是像nginx那样用来做一个反向代理，这个网关可以做的事很多，比如：API编排、服务发现、弹力设计（熔断、限流、重试等）、认证鉴权（JWT，OAuth2，HMAC等）、同样支持各种Cloud Native的架构如：微服务架构，Service Mesh，Serverless/FaaS的集成，并可以用于扛高并发、灰度发布、全链路压力测试、物联网……等更为高级的企业级的解决方案。所以，为了达到这些目标，在2017年的时候，我们觉得在现有的网关如Nginx上是无法演进出来这样的软件的，必需重新写一个（后来其他人也应该跟我们的想法一样，所以，Lyft写了一个Envoy。只不过，Envoy是用C++写的，而我用了技术门槛更低的Go语言）另外，Easegress最核心的设计主要有三个： 一是无第三方依赖的自己选主组集群的能力 二是像Linux管道命令行那样pipeline式的插件流式处理（支持Go/WebAssembly） 三是内置一个Data Store用于集群控制和数据共享。 对于任何一个分布式系统，都需要有一个强一制性的基于Paxos/Raft的可以自动选主机制，并且需要在整个集群间同步一些关键的控制/配置和相关的共享数据，以保证整个集群的行为是统一一致的。如果没有这么一个东西的话，就没有办法玩分布式系统的。这就是为什么会有像Zookeeper/etcd这样的组件出现并流行的原因。注意，Zookeeper他们主要不是给你存数据的，而是给你组集群的。Zookeeper是一个很流行的开源软件，也被用于各大公司的生产线，包括一些开源软件，比如：Kafka。但是，这会让其它软件有一个依赖，并且在运维上带来很大的复杂度。所以，Kafka在最新的版本也通过内置了选主的算法，而抛弃了外挂zookeeper的设计。Etcd是Go语言社区这边的主力，也是kubernetes组建集群的关键组件。Easegress在一开始（5年前）使用了gossip协议同步状态（当时想的过于超前，想做广域网的集群），但是后发现这个协议太过于复杂，而且很难调试，而广域网的API Gateway也没遇到相应的场景。所以，在3年前的时候，为了稳定性的考量，我们把其换成了内嵌版本的etcd，这个设计一直沿用到今天。Easegress会把所有的配置信息都放到etcd里，还包括一些统计监控数据，以及一些用户的自定义数据（这样用户自己的plugin不但可以在一条pipeline内，还可以在整个集群内共享数据），这对于用户进行扩展来说是非常方便的。软件代码的扩展性一直是我们追求的首要目标，尤其是开源软件更要想方设法降低技术门槛让技术易扩展，这就是为什么Google的很多开源软件都会选使用Go语言的原因，也是为什么Go正在取代C/C++的做PaaS基础组件的原因。背景问题好了，在介绍完为什么要用etcd以后，我开始分享一个实际的问题了。我们有个用户在使用 Easegress 的时候，在Easegress内配置了上千条pipeline，导致 Easegress的内存飙升的非常厉害- 10+GB 以上，而且长时间还下不来。用户报告的问题是——在Easegress 1.4.1 上创建一个HTTP对象，1000个Pipeline，在Easegres初始化启动完成时的内存占用大概为400M，运行80分钟后2GB，运行200分钟后达到了4GB，这期间什么也没有干，对Easegress没有进行过一次请求。一般来说，就算是API再多也不应该配置这么多的处理管道pipeline的，通常我们会使用HTTP API的前缀把一组属于一个类别的API配置在一个管道内是比较合理的，就像nginx下的location的配置，一般来说不会太多的。但是，在用户的这个场景下配置了上千个pipeline，我们也是头一次见，应该是用户想做更细粒度的控制。经过调查后，我们发现内存使用基本全部来自etcd，我们实在没有想到，因为我们往etcd里放的数据也没有多少个key，感觉不会超过10M，但不知道为什么会占用了10GB的内存。这种时候，一般会怀疑e…

基于 Patroni,Etcd,Haproxy,Keepalived 搭建 PG16 高可用集群
type: item
date: 2026-01-19T17:52:09+08:00
description: 概述使用 postgresql + etcd + patroni + haproxy + keepalived 可以实现 PG 的高可用集群，其中，以 postgresql 做数据库，Patroni 监控本地的 PostgreSQL 状态，并将本地 PostgreSQL 信息 / 状态写入 etcd 来存储集群状态，所以，patroni 与 etcd 结合可以实现数据库集群故障切换（自动或手动切换），而 haproxy 可以实现数据库读写分离 + 读负载均衡（通过不同端口实现），keepalived 实现 VIP 跳转，对 haproxy 提供了高可用，防止 haproxy 宕机。Patroni 介绍Patroni 是一个基于 Python 的用于实现 PostgreSQL HA 解决方案的框架。为了最大程度的兼容性，它支持多种分布式配置存储，包括 ZooKeeper、etcd、Consul 或 Kubernetes。旨在帮助数据库工程师、DBA、DevOps 工程师和 SRE 快速部署数据中心（或任何地方）的 HA PostgreSQL 环境。当前支持的 PostgreSQL 版本从 9.3 到 16。支持自动化故障转移、物理复制和逻辑复制、提供 RESTful API 接口，允许外部应用或运维工具直接操作 PostgreSQL 集群，进行如启停、迁移等操作，与 Linux watchdog 集成，以避免脑裂现象。项目地址： GitHub - patroni/patroni: A template for PostgreSQL High Availability with Etcd, Consul, ZooKeeper, or KubernetesETCD 介绍etcd 是一个分布式键值存储数据库，支持跨平台，拥有强大的社区。etcd 的 Raft 算法，提供了可靠的方式存储分布式集群涉及的数据。etcd 广泛应用在微服务架构和 Kubernates 集群中，不仅可以作为服务注册与发现，还可以作为键值对存储的中间件。从业务系统 Web 到 Kubernetes 集群，都可以很方便地从 etcd 中读取、写入数据。etcd 完整的 cluster（集群）至少有三台，这样才能选举出一个 master 节点，两个 slave 节点。如果小于 3 台则无法进行选举，造成集群不可用。Etcd 使用 2379 和 2380 端口。2379 端口：提供 HTTP API 服务，和 etcdctl 交互2380 端口：集群中节点间通讯项目地址：GitHub - etcd-io/etcd: Distributed reliable key-value store for the most critical data of a distributed system环境说明服务器信息 服务器名ip 地址os数据库读写端口只读端口组件组件端口 k8s-mater01192.168.28.11ubuntu 24.101543325433PostgreSQL，Patroni、Etcd，haproxy、keepalived8008k8s-mater02192.168.28.12ubuntu 24.101543325433PostgreSQL，Patroni、Etcd，haproxy、keepalived8008k8s-mater01192.168.28.13ubuntu 24.101543325433PostgreSQL，Patroni、Etcd，haproxy、keepalived8008vip192.168.28.10PostgreSQL，Patroni、Etcd，haproxy、keepalived8008 软件信息 软件名版本 Patroni4.0.6Etcd3.5.16Keepalived2.3.1Haproxy2.9.10-1ubuntu1.2PostgreSQL16.9watchdog5.16python3.12.7 架构图这个架构中，PostgreSQL 提供数据服务，Patroni 负责主从切换，etcd 提供一致性存储，HAProxy 提供访问路由，Keepalived 提供网络 VIP 高可用，Watchdog 提供节点存活及脑裂防护机制。 六者协同组成一个企业级高可用数据库集群预先准备网络设置防火墙设置关闭防火墙 (相对简单，但是不安全)放行对应的端口（安全）安装 PostgreSQL通过 apt 安装 PostgreSQL (所有节点)sudo apt install curl ca-certificates sudo install -d /usr/share/postgresql-common/pgdg sudo c…

ETCD的内存问题
type: item
date: 2026-01-18T12:11:46+08:00
description: 今天跟大家分享一个etcd的内存大量占用的问题，这是前段时间在我们开源软件Easegress中遇到的问题，问题是比较简单的，但是我还想把前因后果说一下，包括，为什么要用etcd，使用etcd的用户场景，包括etcd的一些导致内存占用比较大的设计，以及最后一些建议。希望这篇文章不仅仅只是让你看到了一个简单的内存问题，还能让你有更多的收获。当然，也欢迎您关注我们的开源软件，给我们一些鼓励。为什么要用ETCD先说一下为什么要用etcd。先从一个我们自己做的一个API网关 – Easegress（源码）说起。Easegress 是我们开发并开源的一个API应用网关产品，这个API应用网关不仅仅只是像nginx那样用来做一个反向代理，这个网关可以做的事很多，比如：API编排、服务发现、弹力设计（熔断、限流、重试等）、认证鉴权（JWT，OAuth2，HMAC等）、同样支持各种Cloud Native的架构如：微服务架构，Service Mesh，Serverless/FaaS的集成，并可以用于扛高并发、灰度发布、全链路压力测试、物联网……等更为高级的企业级的解决方案。所以，为了达到这些目标，在2017年的时候，我们觉得在现有的网关如Nginx上是无法演进出来这样的软件的，必需重新写一个（后来其他人也应该跟我们的想法一样，所以，Lyft写了一个Envoy。只不过，Envoy是用C++写的，而我用了技术门槛更低的Go语言）另外，Easegress最核心的设计主要有三个： 一是无第三方依赖的自己选主组集群的能力 二是像Linux管道命令行那样pipeline式的插件流式处理（支持Go/WebAssembly） 三是内置一个Data Store用于集群控制和数据共享。 对于任何一个分布式系统，都需要有一个强一制性的基于Paxos/Raft的可以自动选主机制，并且需要在整个集群间同步一些关键的控制/配置和相关的共享数据，以保证整个集群的行为是统一一致的。如果没有这么一个东西的话，就没有办法玩分布式系统的。这就是为什么会有像Zookeeper/etcd这样的组件出现并流行的原因。注意，Zookeeper他们主要不是给你存数据的，而是给你组集群的。Zookeeper是一个很流行的开源软件，也被用于各大公司的生产线，包括一些开源软件，比如：Kafka。但是，这会让其它软件有一个依赖，并且在运维上带来很大的复杂度。所以，Kafka在最新的版本也通过内置了选主的算法，而抛弃了外挂zookeeper的设计。Etcd是Go语言社区这边的主力，也是kubernetes组建集群的关键组件。Easegress在一开始（5年前）使用了gossip协议同步状态（当时想的过于超前，想做广域网的集群），但是后发现这个协议太过于复杂，而且很难调试，而广域网的API Gateway也没遇到相应的场景。所以，在3年前的时候，为了稳定性的考量，我们把其换成了内嵌版本的etcd，这个设计一直沿用到今天。Easegress会把所有的配置信息都放到etcd里，还包括一些统计监控数据，以及一些用户的自定义数据（这样用户自己的plugin不但可以在一条pipeline内，还可以在整个集群内共享数据），这对于用户进行扩展来说是非常方便的。软件代码的扩展性一直是我们追求的首要目标，尤其是开源软件更要想方设法降低技术门槛让技术易扩展，这就是为什么Google的很多开源软件都会选使用Go语言的原因，也是为什么Go正在取代C/C++的做PaaS基础组件的原因。背景问题好了，在介绍完为什么要用etcd以后，我开始分享一个实际的问题了。我们有个用户在使用 Easegress 的时候，在Easegress内配置了上千条pipeline，导致 Easegress的内存飙升的非常厉害- 10+GB 以上，而且长时间还下不来。用户报告的问题是——在Easegress 1.4.1 上创建一个HTTP对象，1000个Pipeline，在Easegres初始化启动完成时的内存占用大概为400M，运行80分钟后2GB，运行200分钟后达到了4GB，这期间什么也没有干，对Easegress没有进行过一次请求。一般来说，就算是API再多也不应该配置这么多的处理管道pipeline的，通常我们会使用HTTP API的前缀把一组属于一个类别的API配置在一个管道内是比较合理的，就像nginx下的location的配置，一般来说不会太多的。但是，在用户的这个场景下配置了上千个pipeline，我们也是头一次见，应该是用户想做更细粒度的控制。经过调查后，我们发现内存使用基本全部来自etcd，我们实在没有想到，因为我们往etcd里放的数据也没有多少个key，感觉不会超过10M，但不知道为什么会占用了10GB的内存。这种时候，一般会怀疑e…