1背景与挑战

随着腾讯自研上云及私有云用户的迅速增长,一方面,腾讯云容器服务TKE服务数量和核数大幅增长, 另一方面咱们提供的容器服务类型(TKE托管及独立集群、EKS弹性集群、edge边缘计算集群、mesh服务网格、serverless knative)也越来越丰盛。各类容器服务类型背地的外围都是K8s,K8s外围的存储etcd又对立由咱们基于K8s构建的etcd平台进行治理。基于它咱们目前治理了千级etcd集群,背地撑持了万级K8s集群。

在万级K8s集群规模下的咱们如何高效保障etcd集群的稳定性?

etcd集群的稳定性危险又来自哪里?

咱们通过基于业务场景、历史遗留问题、现网经营教训等进行稳定性危险模型剖析,危险次要来自旧TKE etcd架构设计不合理、etcd稳定性、etcd性能局部场景无奈满足业务、测试用例笼罩有余、变更治理不谨严、监控是否全面笼罩、隐患点是否能主动巡检发现、极其劫难故障数据安全是否能保障。

后面所形容的etcd平台曾经从架构设计上、变更治理上、监控及巡检、数据迁徙、备份几个方面水平解决了咱们治理的各类容器服务的etcd可扩展性、可运维性、可观测性以及数据安全性,因而本文将重点形容咱们在万级K8s场景下面临的etcd内核稳定性及性能挑战,比方:

•数据不统一

•内存泄露

•死锁

•过程Crash

•大包申请导致etcd OOM及丢包

•较大数据量场景下启动慢

•鉴权及查问key数量、查问指定数量记录接口性能较差

本文将繁难形容咱们是如何发现、剖析、复现、解决以上问题及挑战,以及从以上过程中咱们取得了哪些教训及教训,并将之利用到咱们的各类容器服务存储稳定性保障中。

同时,咱们将解决方案全副奉献、回馈给etcd开源社区, 截止目前咱们奉献的30+ pr已全副合并到社区。腾讯云TKE etcd团队是etcd社区2020年上半年最沉闷的奉献团队之一, 为etcd的倒退奉献咱们的一点力量, 在这过程中特别感谢社区AWS、Google、Ali等maintainer的反对与帮忙。

2稳定性优化案例分析

从GitLab误删主库失落局部数据到GitHub数据不统一导致中断24小时,再到号称"不沉航母"的AWS S3故障数小时等,无一例外都是存储服务。稳定性对于一个存储服务、乃至一个公司的口碑而言至关重要,它决定着一个产品生与死。稳定性优化案例咱们将从数据不统一的严重性、两个etcd数据不统一的bug、lease内存泄露、mvcc 死锁、wal crash方面论述,咱们是如何发现、剖析、复现、解决以上case,并分享咱们从每个case中的取得的播种和反思,从中吸取教训,防患于未然。

数据不统一(Data Inconsistency)

谈到数据不统一导致的大故障,就不得不具体提下GitHub在18年一次因网络设备的例行保护工作导致的美国东海岸网络核心与东海岸次要数据中心之间的连贯断开。尽管网络的连通性在43秒内得以复原,然而短暂的中断引发了一系列事件,最终导致GitHub 24小时11分钟的服务降级,局部性能不可用。

GitHub应用了大量的MySQL集群存储GitHub的meta data,如issue、pr、page等等,同时做了货色海岸跨城级别的容灾。故障外围起因是网络异样时GitHub的MySQL仲裁服务Orchestrator进行了故障转移,将写入数据定向到美国西海岸的MySQL集群(故障前primary在东海岸),然而美国东海岸的MySQL蕴含一小段写入,尚未复制到美国西海岸集群,同时故障转移后因为两个数据中心的集群当初都蕴含另一个数据中心中不存在的写入,因而又无奈平安地将主数据库故障转移回美国东海岸。

最终, 为了保障保障用户数据不失落,GitHub不得不以24小时的服务降级为代价来修复数据一致性。

数据不统一的故障严重性显而易见,然而etcd是基于raft协定实现的分布式高牢靠存储系统,咱们也并未做跨城容灾,按理数据不统一这种看起来高大上bug咱们是很难遇到的。然而幻想是美妙的,事实是残暴的,咱们不仅遇到了不堪设想的数据不统一bug, 还一踩就是两个,一个是重启etcd有较低的概率触发,一个是降级etcd版本时如果开启了鉴权,在K8s场景下较大概率触发。在具体探讨这两个bug前,咱们先看看在K8s场景下etcd数据不统一会导致哪些问题呢?

•数据不统一最恐怖之处在于client写入是胜利的,但可能在局部节点读取到空或者是旧数据,client无奈感知到写入在局部节点是失败的和可能读到旧数据

•读到空可能会导致业务Node隐没、Pod隐没、Node上Service路由规定隐没,个别场景下,只会影响用户变更的服务

•读到老数据会导致业务变更不失效,如服务扩缩容、Service rs替换、变更镜像异样期待,个别场景下,只会影响用户变更的服务

•在etcd平台迁徙场景下,client无奈感知到写入失败,若校验数据一致性也无异样时(校验时连贯到了失常节点),会导致迁徙后整个集群全面故障(apiserver连贯到了异样节点),用户的Node、部署的服务、lb等会被全副删除,重大影响用户业务

首先第一个不统一bug是重启etcd过程中遇到的,人工尝试复现屡次皆失败,剖析、定位、复现、解决这个bug之路几经挫折,过程很乏味并充斥挑战,最终通过我对关键点减少debug日志,编写chaos monkey模仿各种异样场景、边界条件,实现复现胜利。最初的真凶居然是一个受权接口在重启后重放导致鉴权版本号不统一,而后放大导致多版本数据库不统一, 局部节点无奈写入新数据, 影响所有v3版本的3年之久bug。

随后咱们提交若干个相干pr到社区, 并全副合并了, 最新的etcd v3.4.9[1],v3.3.22[2]已修复此问题, 同时google的jingyih也曾经提K8s issue和pr[3]将K8s 1.19的etcd client及server版本升级到最新的v3.4.9。


第二个不统一bug是在降级etcd过程中遇到的,因etcd短少要害的谬误日志,故障现场无效信息不多,定位较艰难,只能通过剖析代码和复现解决。然而人工尝试复现屡次皆失败,于是咱们通过chaos monkey模仿client行为场景,将测试环境所有K8s集群的etcd调配申请调度到咱们复现集群,以及比照3.2与3.3版本差别,在可疑点如lease和txn模块减少大量的要害日志,并对etcd apply request失败场景打印谬误日志。

通过以上措施,咱们比拟快就复现胜利了, 最终通过代码和日志发现是3.2版本与3.3版本在revoke lease权限上呈现了差别,3.2无权限,3.3须要写权限。当lease过期的时候,如果leader是3.2,那么申请在3.3节点就会因无权限导致失败,进而导致key数量不统一,mvcc版本号不统一,导致txn事务局部场景执行失败等。最新的3.2分支也已合并咱们提交的修复计划,同时咱们减少了etcd外围过程失败的谬误日志以进步数据不统一问题定位效率,欠缺了降级文档,具体阐明了lease会在此场景下引起数据不一致性,防止大家再次采坑。

从这两个数据不统一bug中咱们取得了以下播种和最佳实际:

•算法实践数据一致性,不代表整体服务实现能保证数据一致性,目前业界对于这种基于日志复制状态机实现的分布式存储系统,没有一个外围的机制能保障raft、wal、mvcc、snapshot等模块合作不出问题,raft只能保障日志状态机的一致性,不能保障应用层去执行这些日志对应的command都会胜利

•etcd版本升级存在肯定的危险,须要认真review代码评估是否存在不兼容的个性,如若存在是否影响鉴权版本号及mvcc版本号,若影响则降级过程中可能会导致数据不一致性,同时肯定要灰度变更现网集群

•对所有etcd集群减少了一致性巡检告警,如revision差别监控、key数量差别监控等

•定时对etcd集群数据进行备份,再小概率的故障,依据墨菲定律都可能会产生,即使etcd自身虽具备齐备的自动化测试(单元测试、集成测试、e2e测试、故障注入测试等),但测试用例仍有不少场景无奈笼罩,咱们须要为最坏的场景做筹备(如3个节点wal、snap、db文件同时损坏),升高极其状况下的损失, 做到可用备份数据疾速复原

•etcd v3.4.4后的集群灰度开启data corruption检测性能,当集群呈现不统一时,回绝集群写入、读取,及时止损,管制不统一的数据范畴

•持续欠缺咱们的chaos monkey和应用etcd自身的故障注入测试框架functional,以帮助咱们验证、压测新版本稳定性(长时间继续跑),复现暗藏极深的bug, 升高线上采坑的概率

内存泄露(OOM)

家喻户晓etcd是golang写的,而golang自带垃圾回收机制也会内存泄露吗?首先咱们得搞清楚golang垃圾回收的原理,它是通过后盾运行一个守护线程,监控各个对象的状态,辨认并且抛弃不再应用的对象来开释和重用资源,若你迟迟未开释对象,golang垃圾回收不是万能的,不泄露才怪。比方以下场景会导致内存泄露:

•goroutine泄露

•deferring function calls(如for循环外面未应用匿名函数及时调用defer开释资源,而是整个for循环完结才调用)

•获取string/slice中的一段导致长string/slice未开释(会共享雷同的底层内存块)

•利用内存数据结构治理不周导致内存泄露(如为及时清理过期、有效的数据)

接下来看看咱们遇到的这个etcd内存泄露属于哪种状况呢?事件起源于3月末的一个周末起床后收到现网3.4集群大量内存超过平安阈值告警,立即排查了下发现以下景象:

•QPS及流量监控显示都较低,因而排除高负载及慢查问因素

•一个集群3个节点只有两个follower节点出现异常,leader 4g,follower节点高达23G

•goroutine、fd等资源未呈现透露

•go runtime memstats指标显示各个节点申请的内存是统一的,然而follower节点go_memstats_heap_release_bytes远低于leader节点,阐明某数据结构可能长期未开释

•生产集群默认敞开了pprof,开启pprof,期待复现, 并在社区上搜寻开释有相似案例, 后果发现有多个用户1月份就报了,没引起社区器重,应用场景和景象跟咱们一样

•通过社区的heap堆栈疾速定位到了是因为etcd通过一个heap堆来治理lease的状态,当lease过期时须要从堆中删除,然而follower节点却无此操作,因而导致follower内存泄露, 影响所有3.4版本。

•问题剖析分明后,我提交的修复计划是follower节点不须要保护lease heap,当leader产生选举时确保新的follower节点能重建lease heap,老的leader节点则清空lease heap.

此内存泄露bug属于内存数据结构治理不周导致的,问题修复后,etcd社区立刻公布了新的版本(v3.4.6+)以及K8s都立刻进行了etcd版本更新。


从这个内存泄露bug中咱们取得了以下播种和最佳实际:

•继续关注社区issue和pr, 他人明天的问题很可能咱们今天就会遇到

•etcd自身测试无奈笼罩此类须要肯定工夫运行的能力触发的资源泄露bug,咱们外部须要增强此类场景的测试与压测

•继续欠缺、丰盛etcd平台的各类监控告警,机器留足足够的内存buffer以扛各种意外的因素。

存储层死锁(Mvcc Deadlock)

死锁是指两个或两个以上的goroutine的执行过程中,因为竞争资源互相期待(个别是锁)或因为彼此通信(chan引起)而造成的一种程序卡死景象,无奈对外提供服务。deadlock问题因为往往是在并发状态下资源竞争导致的, 个别比拟难定位和复现, 死锁的性质决定着咱们必须保留好剖析现场,否则剖析、复现及其艰难。

那么咱们是如何发现解决这个deadlock bug呢?问题起源于外部团队在压测etcd集群时,发现一个节点忽然故障了,而且始终无奈复原,无奈失常获取key数等信息。收到反馈后,我通过剖析卡住的etcd过程和查看监控,失去以下论断:

•不通过raft及mvcc模块的rpc申请如member list能够失常返回后果,而通过的rpc申请全副context timeout

•etcd health衰弱监测返回503,503的报错逻辑也是通过了raft及mvcc

•通过tcpdump和netstat排除raft网络模块异样,可疑指标放大到mvcc

•剖析日志发现卡住的时候因数据落后leader较多,接管了一个数据快照,而后执行更新快照的时候卡住了,没有输入快照加载结束的日志,同时确认日志未失落

•排查快照加载的代码,锁定几个可疑的锁和相干goroutine,筹备获取卡住的goroutine堆栈

•通过kill或pprof获取goroutine堆栈,依据goroutine卡住的工夫和相干可疑点的代码逻辑,胜利找到两个相互竞争资源的goroutine,其中一个正是执行快照加载,重建db的主goroutine,它获取了一把mvcc锁期待所有异步工作完结,而另外一个goroutine则是执行历史key压缩工作,当它收到stop的信号后,立即退出,调用一个compactBarrier逻辑,而这个逻辑又恰好须要获取mvcc锁,因而呈现死锁,堆栈如下。


这个bug也暗藏了很久,影响所有etcd3版本,在集群中写入量较大,某落后的较多的节点执行了快照重建,同时此时又恰好在做历史版本压缩,那就会触发。我提交的修复PR目前也曾经合并到3.3和3.4分支中,新的版本曾经公布(v3.3.21+/v3.4.8+)。

从这个死锁bug中咱们取得了以下播种和最佳实际:

•多并发场景的组合的etcd自动化测试用例笼罩不到,也较难构建,因而也容易出bug, 是否还有其余相似场景存在同样的问题?须要参加社区一起持续进步etcd测试覆盖率(etcd之前官网博客介绍一大半代码曾经是测试代码),能力防止此类问题。

•监控尽管能及时发现异常节点宕机,然而死锁这种场景之前咱们不会主动重启etcd,因而须要欠缺咱们的衰弱探测机制(比方curl /health来判断服务是否失常),呈现死锁时可能保留堆栈、主动重启复原服务。

•对于读申请较高的场景,需评估3节点集群在一节点宕机后,残余两节点提供的QPS容量是否可能反对业务,若不够则思考5节点集群。

Wal crash(Panic)

panic是指呈现重大运行时和业务逻辑谬误,导致整个过程退出。panic对于咱们而言并不生疏,咱们在现网遇到过几次,最早遭逢的不稳定性因素就是集群运行过程中panic了。

虽说咱们3节点的etcd集群是能够容忍一个节点故障,然而crash霎时对用户仍然有影响,甚至呈现集群拨测连贯失败。

咱们遇到的第一个crash bug,是发现集群链接数较多的时候有肯定的概率呈现crash, 而后依据堆栈查看社区已有人报grpc crash(issue)[4], 起因是etcd依赖的组件grpc-go呈现了grpc crash(pr)[5],而最近咱们遇到的crash bug[6]是v3.4.8/v3.3.21新版本公布引起的,这个版本跟咱们有很大关系,咱们奉献了3个PR到这个版本,占了一大半以上, 那么这个crash bug是如何产生以及复现呢?会不会是咱们本人的锅呢?

•首先crash报错是walpb: crc mismatch, 而咱们并未提交代码批改wal相干逻辑,排除本人的锅。

•其次通过review新版本pr, 指标锁定到google一位大佬在修复一个wal在写入胜利后,而snapshot写入失败导致的crash bug的时候引入的.

•然而具体是怎么引入的?pr中蕴含多个测试用例验证新加逻辑,本地创立空集群和应用存量集群(数据比拟小)也无奈复现.

•谬误日志信息太少,导致无奈确定是哪个函数报的错,因而首先还是加日志,对各个可疑点减少谬误日志后,在咱们测试集群轻易找了个老节点替换版本,而后很容易就复现了,并确定是新加的验证快照文件合法性的锅,那么它为什么会呈现crc mismatch呢? 首先咱们来简略理解下wal文件。

•etcd任何通过raft的模块的申请在写入etcd mvcc db前都会通过wal文件长久化,若过程在apply command过程中呈现被杀等异样,重启时可通过wal文件重放将数据补齐,防止数据失落。wal文件蕴含各种申请命令如成员变动信息、波及key的各个操作等,为了保障数据完整性、未损坏,wal每条记录都会计算其的crc32,写入wal文件。重启后解析wal文件过程中,会校验记录的完整性,如果数据呈现损坏或crc32计算算法呈现变动则会呈现crc32 mismatch.

•硬盘及文件系统并未出现异常,排除了数据损坏,通过深刻排查crc32算法的计算,发现是新增逻辑未解决crc32类型的数据记录,它会影响crc32算法的值,导致呈现差别,而且只有在当etcd集群创立产生后的第一个wal文件被回收才会触发,因而对存量运行一段时间的集群,100%复现。

•解决方案就是通过减少crc32算法的解决逻辑以及减少单元测试笼罩wal文件被回收的场景,社区已合并并公布了新的3.4和3.3版本(v3.4.9/v3.3.22).

尽管这个bug是社区用户反馈的,但从这个crash bug中咱们取得了以下播种和最佳实际:

•单元测试用例十分有价值,然而编写齐备的单元测试用例并不容易,须要思考各类场景。

•etcd社区对存量集群降级、各版本之间兼容性测试用例简直是0,须要大家一起来为其舔砖加瓦,让测试用例笼罩更多场景。

•新版本上线外部流程标准化、自动化, 如测试环境压测、混沌测试、不同版本性能比照、优先在非核心场景应用(如event)、灰度上线等流程必不可少。

配额及限速(Quota&QoS)

etcd面对一些大数据量的查问(expensive read)和写入操作时(expensive write),如全key遍历(full keyspace fetch)、大量event查问, list all Pod, configmap写入等会耗费大量的cpu、内存、带宽资源,极其容易导致过载,乃至雪崩。

然而,etcd目前只有一个极其简略的限速爱护,当etcd的commited index大于applied index的阈值大于5000时,会回绝所有申请,返回Too Many Request,其缺点很显著,无奈准确的对expensive read/write进行限速,无奈无效避免集群过载不可用。

为了解决以上挑战,防止集群过载目前咱们通过以下计划来保障集群稳定性:

•基于K8s apiserver下层限速能力,如apiserver默认写100/s,读200/s

•基于K8s resource quota管制不合理的Pod/configmap/crd数

•基于K8s controller-manager的-terminated-Pod-gc-threshold参数管制有效Pod数量(此参数默认值高达12500,有很大优化空间)

•基于K8s的apiserver各类资源可独立的存储的个性, 将event/configmap以及其余外围数据别离应用不同的etcd集群,在进步存储性能的同时,缩小外围主etcd故障因素

•基于event admission webhook对读写event的apiserver申请进行速率管制

•基于不同业务状况,灵便调整event-ttl工夫,尽量减少event数

•基于etcd开发QoS个性,目前也曾经向社区提交了初步设计计划,反对基于多种对象类型设置QoS规定(如按grpcMethod、grpcMethod+申请key前缀门路、traffic、cpu-intensive、latency)

•通过多维度的集群告警(etcd集群lb及节点自身出入流量告警、内存告警、精细化到每个K8s集群的资源容量异样增长告警、集群资源读写QPS异样增长告警)来提前防备、躲避可能呈现的集群稳定性问题

多维度的集群告警在咱们的etcd稳定性保障中施展了重要作用,屡次帮忙咱们发现用户和咱们本身集群组件问题。用户问题如外部某K8s平台之前呈现bug, 写入大量的集群CRD资源和client读写CRD QPS显著偏高。咱们本身组件问题如某旧日志组件,当集群规模增大后,因日志组件不合理的频繁调用list Pod,导致etcd集群流量高达3Gbps, 同时apiserver自身也呈现5XX谬误。

尽管通过以上措施,咱们能极大的缩小因expensive read导致的稳定性问题,然而从线上实际成果看,目前咱们依然比拟依赖集群告警帮忙咱们定位一些异样client调用行为,无奈自动化的对异样client的进行精准智能限速,。etcd层因无奈辨别是哪个client调用,如果在etcd侧限速会误杀失常client的申请, 因而依赖apiserver精细化的限速性能实现。社区目前已在1.18中引入了一个API Priority and Fairness[7],目前是alpha版本,期待此个性早日稳固。

3性能优化案例分析

etcd读写性能决定着咱们能撑持多大规模的集群、多少client并发调用,启动耗时决定着咱们当重启一个节点或因落后leader太多,收到leader的快照重建时,它从新提供服务须要多久?性能优化案例分析咱们将从启动耗时缩小一半、明码鉴权性能晋升12倍、查问key数量性能晋升3倍等来简略介绍下如何对etcd进行性能优化。

启动耗时及查问key数量、查问指定记录数性能优化

当db size达到4g时,key数量百万级别时,发现重启一个集群耗时居然高达5分钟, key数量查问也是超时,调整超时工夫后,发现高达21秒,内存暴涨6G。同时查问只返回无限的记录数的场景(如业务应用etcd grpc-proxy来缩小watch数,etcd grpc proxy在默认创立watch的时候,会发动对watch门路的一次limit读查问),仍然耗时很高且有微小的内存开销。于是周末闲暇的时候我对这几个问题进行了深入调查剖析,启动耗时到底花在了哪里?是否有优化空间?查问key数量为何如何耗时,内存开销如此之大?

带着这些问题对源码进行了深入分析和定位,首先来看查问key数和查问只返回指定记录数的耗时和内存开销极大的问题,剖析论断如下:

•查问key数量时etcd之前实现是遍历整个内存btree,把key对应的revision寄存在slice数组外面

•问题就在于key数量较多时,slice扩容波及到数据拷贝,以及slice也须要大量的内存开销

•因而优化计划是新增一个CountRevision来统计key的数量即可,不须要应用slice,此计划优化后性能从21s升高到了7s,同时无任何内存开销

•对于查问指定记录数据耗时和内存开销十分大的问题,通过剖析发现是limit记录数并未下推到索引层,通过将查问limit参数下推到索引层,大数据场景下limit查问性能晋升百倍,同时无额定的内存开销。


再看启动耗时问题过高的问题,通过对启动耗时各阶段减少日志,失去以下论断:

•启动的时候机器上的cpu资源etcd过程未能充分利用

•9%耗时在关上后端db时,如将整个db文件mmap到内存

•91%耗时在重建内存索引btree上。当etcd收到一个申请Get Key时,申请被层层传递到了mvcc层后,它首先须要从内存索引btree中查找key对应的版本号,随后从boltdb外面依据版本号查出对应的value, 而后返回给client. 重建内存索引btree数的时候,恰好是相同的流程,遍历boltdb,从版本号0到最大版本号一直遍历,从value外面解析出对应的key、revision等信息,重建btree,因为这个是个串行操作,所以操作及其耗时

•尝试将串行构建btree优化成高并发构建,尽量把所有核计算力利用起来,编译新版本测试后发现成果甚微,于是编译新版本打印重建内存索引各阶段的具体耗时剖析,后果发现瓶颈在内存btree的插入上,而这个插入领有一个全局锁,因而简直无优化空间

•持续剖析91%耗时发现重建内存索引居然被调用了两次,第一处是为了获取一个mvcc的要害的consistent index变量,它是用来保障etcd命令不会被反复执行的要害数据结构,而咱们后面提到的一个数据不统一bug恰好也是跟consistent index有密切关系。

•consistent index实现不合理,封装在mvcc层,因而我后面提了一个pr将此个性重构,做为了一个独立的包,提供各类办法给etcdserver、mvcc、auth、lease等模块调用。

•个性重构后的consistent index在启动的时候就不再须要通过重建内存索引数等逻辑来获取了,优化成调用cindex包的办法疾速获取到consistent index,就将整个耗时从5min从缩短到2分30秒左右。因而优化同时依赖的consistent index个性重构,改变较大暂未backport到3.4/3.3分支,在将来3.5版本中、数据量较大时能够享受到启动耗时的显著晋升。


明码鉴权性能晋升12倍

某外部业务服务始终跑的好好的,某天client稍微增多后,忽然现网etcd集群呈现大量超时,各种折腾,切换云盘类型、切换部署环境、调整参数都不发挥作用,收到求助后,索要metrics和日志后,通过一番排查后,失去以下论断:

•景象确实很诡异,db延时相干指标显示没任何异样,日志无任何无效信息

•业务反馈大量读申请超时,甚至能够通过etcdctl客户端工具简略复现,可是metric对应的读申请相干指标数居然是0

•疏导用户开启trace日志和metrics开启extensive模式,开启后发现无任何trace日志,然而开启extensive后,我发现耗时居然全副花在了Authenticate接口,业务反馈是通过明码鉴权,而不是基于证书的鉴权

•尝试让业务同学短暂敞开鉴权测试业务是否复原,业务同学找了一个节点敞开鉴权后,此节点立即复原了失常,于是抉择长期通过敞开鉴权来复原现网业务

•那鉴权为什么耗时这么慢?咱们对可疑之处减少了日志,打印了鉴权各个步骤的耗时,后果发现是在期待锁的过程中呈现了超时,而这个锁为什么耗时这么久呢?排查发现是因为加锁过程中会调用bcrpt加密函数计算明码hash值,每次消耗60ms左右,数百并发下期待此锁的最高耗时高达5s+。

•于是咱们编写新版本将锁的范畴缩小,升高持锁阻塞工夫,用户应用新版本后,开启鉴权后,业务不再超时,恢复正常。

•随后咱们将修复计划提交给了社区,并编写了压测工具,测试晋升后的性能高达近12倍(8核32G机器,从18/s晋升到202/s),然而仍然是比较慢,次要是鉴权过程中波及明码校验计算, 社区上也有用户反馈明码鉴权慢问题, 目前最新的v3.4.9版本曾经蕴含此优化, 同时能够通过调整bcrpt-cost参数来进一步晋升性能。

4总结

本文简略形容了咱们在治理万级K8s集群和其余业务过程中遇到的etcd稳定性和性能挑战,以及咱们是如何定位、剖析、复现、解决这些挑战,并将解决方案奉献给社区。

同时,详细描述了咱们从这些挑战中播种了哪些贵重的教训和教训,并将之利用到后续的etcd稳定性保障中,以反对更大规模的单集群和总集群数。

最初咱们面对万级K8s集群数, 千级的etcd集群数, 10几个版本散布,其中不少低版本蕴含重要的潜在可能触发的重大bug, 咱们还须要投入大量工作一直优化咱们的etcd平台,使其更智能、变更更加高效、平安、可控(如反对自动化、可控的集群降级等), 同时数据安全也至关重要,目前腾讯云TKE托管集群咱们曾经全面备份,独立集群的用户后续将疏导通过利用市场的etcd备份插件开启定时备份到腾讯云对象存储COS上。

将来咱们将持续严密融入etcd的社区,为etcd社区的倒退奉献咱们的力量,与社区一块晋升etcd的各个性能。