热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Etcd高可用集群与性能优化

谈到生产系统etcd高可用集群一般有几类,第一类为kubeadm搭建的K8s集群,这种的etcd我们通常通过kubelet扫描本地目录,这个本地目录我们可以将etcd的pod放进去

高可用etcd解决方案


谈到生产系统etcd高可用集群一般有几类,第一类为kubeadm搭建的K8s集群,这种的etcd我们通常通过kubelet扫描本地目录,这个本地目录我们可以将etcd的pod放进去,kubelet扫描到etcd的pod清单,然后它就会去启动etcd的pod,这个就是K8s控制平面怎么拉起自己的etcd。

有些时候我们可能使用另外的方式去搭建etcd集群,etcd-operator是基于k8s crd完成etcd的集群配置。

etcd operator


 operator本身其实就是crd和controller的组合,所以etcd operator引入了几个核心对象,扩展对象。

第一个对象就是etcd cluster,用户可以定义一个第三方对象,扩展对象叫etcd cluster,在这个cluster里面可以定义什么呢?第一我的etcd版本是什么,第二我需要多少副本数。当你定义好这些对象之后,etcd-operator会运行一个控制器,这个控制器就会去解析etcd-cluster,然后创建k8s pod,这些pod就会运行etcd image,并且按照用户的输入来组成etcd集群。

etcd-operator作用就是按照用户的input定义用户的etcd的版本和副本数,我就将etcd的集群拉起来,它还支持其他两类对象,一类是banckup对象,一类是restore对象。

backup对象是用来保证数据的安全性的,那么它就可以定义一些备份的策略,备份的策略可以说要往哪备份,往GCS上备份还是往s3上面备份,这些公有云的存储都需要密码,在backup对象里面你可以去提供认证的credentials,那么它会按照你backup里面定义的频度和要保存备份的数量,那么它会按照你定义的时间周期一直去做snapshot,并且将这个snapshot存放在远端的存储里面去。

如果要去恢复就去定义etcd restore这样一个对象,他会关联volume,并且从volume拉下你的备份,并且通过etcd的operator来恢复整个etcd集群。

operator模式是什么?它其实就是crd + controller,crd是你的模型抽象,要把你做的事情,声明式的形式定义出来,controller行为是之前我自动化怎么做的,可能是自动化脚本,或者手敲的命令,希望可以通过控制器的模式以go语言的方式将它加载出来。

基于Bitnami安装etcd高可用集群


 上面介绍了两种工具快速的去构建集群。

Kubernetes如何使用etcd的


api server对于etcd来说是一个客户端,它就要指定客户端的ca 文件 crt kety文件,同时要指定etcd server的地址。

Kubernets 对象在 etcd 中的存储路径


 

 

可以将整个namespace对象dump出来。所以api server去通过/api/v1/namespace/default去get一个namespace对象的时候,它就等价于在etcd里面get /registry/namspace/default,除了前缀不一样,拼装的逻辑还是一样的,它将整个路径组装为key,然后存储在etcd里面。

etcd在集群当中的位置


堆叠etcd集群:一个集群里面有3个master,每个master里面都有etcd这个pod,这个pod通常通过kubelet自管理。

kubelet会去读取一个config,这个config定义了static pod path,kubelet它本身的作用是维护pod的生命周期,他有几种方式来加载pod的清单,一种方式是监听api server,还有一种方式是它会去扫描本地的static pod path,扫描这个目录,它要去看这个目录里面有没有pod清单,如果有的话就直接加载。

这种模式就是etcd会在每个master上面部署,它是以静态的方式去部署。

堆叠式好处:apiserver和etcd之间是紧绑定的,所有apiserver的请求以loopback方式发送到etcd,读操作可以直接读走,读操作不需要经过master,读操作不需要经过网络调用的,本地就走了,其次这些组件放在一起好管理维护,不需要网络调用就可以读取数据。还有etcd是一个重落盘的,它对disk io是有要求的,其他的应用没有那么高的要求,那么放在一起也是ok的。

外部构建etcd高可用集群,那么apiserver指定路径的时候,就指定一个外部路径,而不是一个loopback地址,不是localhost。 

 实践 etcd集群高可用


 etcd集群高可用是1 3 5节点?如果是偶数个节点会出现投票数均等的情况,投票数均等的情况会导致重新投票,会导致leader无主状态的时间变长,所以选择奇数个。

如果你选了1个节点作为master,那么它的性能最高,写任何数据确认就结束了,所以它性能是最高的,但是它的数据安全性是无法保证的,数据丢了就丢了,除非备份备份也不具有时效性,会丢数据。

3个就好处是有了最基本的冗余,3个里面有一个坏掉了,那么系统还是好的,运维人员要立刻上线修复,如果再崩掉一个,那么系统就出问题了。

5个性能首先是最差的,如果1个坏掉了还有4个,2个坏掉还有三个,如果1个出现问题不需要立刻修复,这样对运维的压力会小,多两个etcd又得多两台机器,这都是钱,得权衡。

强调一下,读操作都可以从follower去读的,写操作都要经过leader去写。

很多时候一个应用性能不够了,我们要去做横向扩展,对于etcd这样的应用来说其实是相反的,你peer越多,它写入数据的时候需要确认的人就越多,所以它做横向扩展会使得它的性能降低。

apiserver是etcd的唯一客户端,apiserver和etcd通信是grpc协议,grpc协议的一个特性就是连接复用,也就说不管多少个请求从同一个客户端来,它都会去复用一个连接到server,同一个group所有对象是共用一个tcp连接的,也就是pod node 这些等这些核心对象通过共用一个grpc连接到etcd端,

实践 etcd存储规划

 挂网盘的好处是数据永远保存,它严重依赖于外部的网络存储设备,网络会经常出问题,当网络抖动etcd就会出现问题,最后就导致整个集群的稳定性非常的差,所以不要使用网络存储,使用本地存储。

能不能使用大部分的member都用local来保证其时效性,一个member挂网盘?让它跟着听就好了,实际上一样不行,在数据io高的时候,本地数据更新走的快,网络那个memb而永远跟不上,久而久之就掉队了,这样就会导致集群的状态不对,所以全部存储到本地是最好的选择。

最佳实践就是local ssd,一定要让etcd落盘快,使用local ssd,并且给它独立的盘,不让别人来干扰它,这样可以提高整个etcd的性能。

上面可以看到db size是不一致的,它和我们的compcat defrag是相关的。

在k8s里面有大部分对象是用来做声明的,比如pod期望它长的什么样,service是定义我希望怎么样去发布服务,但是有些对象纯属是用来做审计的,比如说event,希望了解一下这个对象发生过什么事情,每个控制器都会建立大量的event,所以量非常大,第二他们不那么重要,即使这些数据丢失也不会对集群造成破坏的影响,所以k8s允许你在api server里面去定义etcd-servers-overrrides ,这样可以再启动一个etcd的instance,然后将一部分对象转到新的etcd里面,这样好处是etcd数据量大了扛不住的时候,可以将一部分数据分出去,其次对于频繁变更的东西可以放到其他地方去,这样可以保证主的etcd写和etcd event落在不同的盘,那么整个的写性能会好一些。

 etcd是个集群,网络效率对整个集群效率息息相关的,包发出去再回来看看需要多长时间。

etcd本身有election timeout,heartbeat timeout,它会有各种超时的时间限制,如果部署在不同的地域,那么heartbeat就要花很长时间。

虽然etc将客户端通信和peer通信分为不同的端口了,当客户端连接到leader连接数过多,那么leader和follower之间通信可能发生错误,发到follower就出错了,直接drop掉了,因为发送队列的缓冲区满了,所以发不出去,这个时候可以去节点上面做一些网络调优,通过tc的命令去调节peer通信的优先级,优先保证etcd的peer之间的通信。

减少磁盘io延时

 这个影响是最高的,etcd要落盘,它的盘和其他的盘共享,那么就可能导致我的etcd的写入非常的慢,那么就进一步的降低了我的etcd的性能,在生产系统里要去做etcd落盘的时候,请给它划分单独的盘,而且尽可能的给ssd这种高性能的数据盘,如果要和其他业务共享落盘,那么你可以通过Ionice来提高etcd对磁盘写入的优先级,避免被其他影响,因为etcd是整个集群性能的根本,如果它的性能没法保证,那么集群的性能就会变差。

保持合理日志的文件的大小

etcd里面有wal log,wal会随着数据的修改而线性增长,修改数据它的reversion就会改变,虽然我key只有一个,只要我不停的去动它,那么数据就会很大。

etcd本身支持快照体系,当日志修改到一定次数的时候,参数通过sanpshot-count去指定,比如日志积累到1w次变更,它会自动生成snapshot,snapshot就是基于当前状态做个快照,然后将之前的wal log全部压缩掉。

如果etcd的内存和磁盘使用过高,那就要去分析是不是数据写入的频度太高了,大部分这种时候这种性能调优都要去找到bad user,日常运维集群的时候,最容易出问题的是apiserver和etcd,出问题往往就是bad user导致的,找到bad user并且修正他们的行为。

当然在etcd里面可以通过调节快照触发阈值,降低对磁盘内存的使用。

设置合理的存储配额

一般来说对于生产集群就配置8G,并且把auto-compact,dfrag这些参数设置好,来确保这8个G的空间不会被占满。

同时我们要做好监控,如果到了6 7G的时候,那么就要收到告警集群快要占满了,不能让它出现alarm,出现了alarm之后所有的写操作都不能成功,之前演示过,那么集群就变为一个只读集群了,就会导致某些控制器的行为异常。

自动压缩历史版本

 如何保证磁盘的量小呢?有一个auto-compac这样一个参数,来允许自动的去压缩历史版本。

定期消除碎片化

其实就是dfrag,也就是配合dfrag和compact两个命令,我们可以有效的压缩历史版本,清除磁盘碎片,使得etcd更加高效的去利用磁盘。

优化运行参数

 

心跳默认100ms,选举超时时间1000ms也就是1s,这两个参数分别控制了,第一个leader以什么样的频次来发起心跳,第二就是follower多久接收不到leader过来的心跳,它要重新去选举。

这两个参数要配合使用,一般会把选举超时时间设置为心跳通知的这个周期的10倍,这是一个经验数据,也是etcd的一个推荐。

针对不同的网络环境我们就需要去做一些调优了,跨大陆的可能一个round-trip就要400ms,那么我心跳的interval就要改成很长,可能要改到800ms,所以针对于不同的网络环境,我需要去调节这些参数来适应网络延时。

心跳怎么设置呢,一般设置为RTT的0.5-1.5倍,选举超时时间设置为RTT的10倍。这是一些经验和建议。

etcd备份存储

它主要通过snapshot去备份的,snapshot是不能很频繁去做的,因为做snapshot的时候要去锁住磁盘空间,然后做一个快照,这个时候做的任何修改都要开辟新的空间来写,也就是snapshot频繁的时候,它就快速的让你磁盘占用的空间变的非常的大。

有了wal log,那么wal log存放的是增量数据的写入日志,它们两个结合到一起就是全局,

备份方案实践


 

上面是社区方案里面做了增强, 比如说在每个etcd member里面,会有一个备份的客户端,是一个sidecar形式,这个sidecar会去watch etcd leader,它每30分钟去做一次snapshot,这样snapshot的频度没有那么大,30分钟的数据备份一定是不足够的,因为极端的情况下可能是29.5秒的数据全部没有了,那么怎么减少snapshot频度又可以保证数据的时效性。

在这基础之上先做snapshot,然后去监听从快照结束reversion开始监听etcd事件,也就是通过etcd的客户端去做watch,watch所有对象,所有对象修改的信息,我们都可以通过每10s一次把这些watch到的event写入到磁盘,也就是通过snapshot的方式加上event这种方式去做增强备份。

30分钟snapshot+10s一次的event,这个event是实时去监听的,每10s写入一次,这个就是增强备份方案。


推荐阅读
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • wpf+mvvm代码组织结构及实现方式
    本文介绍了wpf+mvvm代码组织结构的由来和实现方式。作者回顾了自己大学时期接触wpf开发和mvvm模式的经历,认为mvvm模式使得开发更加专注于业务且高效。与此同时,作者指出mvvm模式相较于mvc模式的优势。文章还提到了当没有mvvm时处理数据和UI交互的例子,以及前后端分离和组件化的概念。作者希望能够只关注原始数据结构,将数据交给UI自行改变,从而解放劳动力,避免加班。 ... [详细]
  • Android源码中的Builder模式及其作用
    本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。 ... [详细]
  • [转载]从零开始学习OpenGL ES之四 – 光效
    继续我们的iPhoneOpenGLES之旅,我们将讨论光效。目前,我们没有加入任何光效。幸运的是,OpenGL在没有设置光效的情况下仍然可 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
author-avatar
纠结大王烨要人陪往_763
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有