当前位置:网站首页>Etcd 存储,Watch 以及过期机制
Etcd 存储,Watch 以及过期机制
2022-07-04 12:33:00 【富士康质检员张全蛋】
etcd v3存储,Watch 以及过期机制
etcd在存储数据的时候主要分为了两个部分,第一部分叫做kvstore,这个kvstore是存储在内存当中的,这个是in memory的kvstore,任何数据库都需要做索引,所以etcd就是通过这种方式在内存当中构建了索引,这个索引的目标是来做快速的查找。
另外后端会有真正落盘的数据库,etcd默认使用blotdb去实现的,blotdb是Google开源的key value数据库,当你任何数据要去存储到etcd store的时候,它同时会去存索引和落盘,通过blotdb去落盘。(最终的数据持久化是基于blotdb)
watchablestore是干嘛的呢?因为etcd本身是支持监听的,你可以去监听某个对象的事件,这些对象就会组织在watchablestore里面。
存储机制
etcd v3 store分为两部分∶一部分是内存中的索引,kvindex,是基于Google开源的一个Golang的Btree实现的,另外一部分是后端存储。按照它的设计,backend可以对接多种存储,当前使用的是boltdb。
boltdb是一个单机的支持事务的KV存储,etcd的事务是基于boltdb的事务实现的。etcd在boltdb中存储的key是reversion, value是etcd自己的key-value组合, 也就是说 etcd 会在 boltdb 中把每个版本都保存下,从而实现了多版本机制。
reversion主要由两部分组成,第一部分main rev,每次事务进行加一,第二部分 sub rev,同一个事务中的每次操作加一。
对于任何的数据都有reversion的概念,它相当于是一个版本的信息,reversion主要由两部分组成,一部分是main rev,一部分是sub rev。
下面去get一个key,-wjson是将其细节打印出来,这里面可以看到有create mode reversion,这里就有一个版本的概念,对于任何etcd里面存的对象,它都有版本的概念,有个当前的reversion 3。
reversion是当前集群类似于自增长的这么一个值,当我们去对整个集群做任何数据修改的时候,它的reversion就会增加,reversion分为了sub和main两个部分,如果你开了一个事务,那么这个事务里面所有写操作可以公用mian reversion,然后里面子命令对应sub reversion。
对于k8s来说,我们大部分时候使用main reversion,sub reversion没有用。
回过头看k8s对象的时候,有个resource version,可以将它理解为乐观锁,其实这个resource reversion就和etcd里面的对象mod reversion是一一对应的,当对etcd做数据变更的时候,这个etcd mod revesion也会跟着变化。k8s在读取对象的时候就会以mod reversion作为它的resource version。
- etcd提供了命令和设置选项来控制 compact,同时支持 put操作的参数来精确控制某个key 的历史版本数。
- 内存 kvindex 保存的就是key 和 reversion 之前的映射关系,用来加速查询。
etcd数据存储流程
客户端要发起一个写的请求,假设这个请求发给了follower,最终这个请求会转给一致性模块,一致性模块会去判断自己是不是leader,如果是leader就直接处理,如果不是就转给leader。
请求到了leader要做一些预检查,第一个配额,就是etcd有数据大小的配置,你这次写请求还能不能放进去,第二要限速,作为一个服务器要频繁的调取我的写操作会把我压垮的,第三就是去认证鉴权, 第四会去做数据包检查,如果数据包超过1.5M,它就不让写了。
如果数据包太大了,它反复确认,包括后面做索引,做查询,它的开销就非常的大,会导致etcd的性能直线下降。因为它需要多次确认,需要数据同步,它就会导致数据同步的效率非常低,所以它做了一些限制,让你不要无休止的去增加,把数据变的非常大,在k8s里面,很难将yaml写成1.5M以上的,yaml不是无限增长的,而是有一定限制的。
这些预检查做完之后,请求会被发送到主模块叫做kvserver,kvserver接收到请求发现是一次写请求,比如是y=9,它会把请求发到一致性模块,一致性模块实现两件事,它其实就是raft协议的实现者,第一,它会实现选主,第二就是日志复制,它会在etcd的内存里面构建raft log,这个raft log其实是一个数据结构,这个raft log其实是一个数据结构,它会先将自己的信息写到unstable里面,记录了我有一条数据要写入,接下来这个请求会被同时写入到本地的wal log,就是写y=9,将y=9的这条日志写到本地,这个写入最后是要落盘的,不能每次写入都落盘这样效率太低了,wal log落盘其实是由fsyn,就相当于前端写在buffer里面,最后通过fsync周期性的将这些事件正真的落在磁盘上面。
写wal log的同时它有另外的goroutine去把同样的message,就是通过一个append message发到其他follower那里,follower那边收到请求之后,它要做同样的事情,就相当于要将写操作写入wal log。
并且写完以后回复response,回到leader这边,leader发现有半数确认了这条日志的写入,那么它就认为这条数据已经commit了,所以它会更新自己的数据结构,更新match index,每条写入都有自增长的index。
同时它这个请求会以apply的方式请求状态机来记录这次数据。状态机基于mvcc模块,就是多版本并发控制的这么一个模块,经过半数确认之后要往mvcc里面去写,首先在tree index
这里,就是memory index里面
Etcd 数据的一致性
有个matchindex,在leader这一端,它会保存一个信息,第一个term大家都写了a和b,然后后面就变为第二个term,在第二个term里面又发生了很多的变更,wal log里面存了a b c d e f g,这里有8次变更,每次变更都会在etcd里面去维护一个自身的index,leader这边都会维护一个matchindex,代表leader和哪个index保持一致了,这里有leader a,follower b c,以提交的日志是代表超过半数确认的日志,这三个人组成的集群超过半数确认的是到第7个index,也就是当前的match index是7,第8还没有被多数确认,它并不是一个正真确认过的index,如果重新选举的话,c的log本身比leader的commit index是要小的,如果c去作为新的leader就有可能丢数据了。
之所以记录index,就是用来确保说拥有最新数据的这些人,才可以去做新的leader,c是做不了新的leader的,所以通过index从leader这边记录一下,最新的commit log的index已经到哪里了,来确保新的leader永远包含所有已经确认的数据,通过这样的方式保证数据的一致性。
Watch机制
etcd除了上面的提供基本的读写功能,还提供了watch的机制。
watch类型
watch又分为两类,一类是watch某一类的key,这种叫做key watcher,一类是提高--prefix,通过模糊匹配来查询以斜杠开头的所有key的变更,这种叫做range watcher。
etcd V3的 Watch机制支持Watch某个固定的 key,也支持Watch一个范围(可以用于模拟目录的结构的Watch),所以 watchGroup 包含两种 watcher,一种是key watchers,数据结构是每个key 对应一组 watcher,另外一种是 range watchers,数据结构是一个IntervalTree,方便通过区间查找到对应的watcher。
如何满足watch请求
etcd如何满足watch请求,就是之前说的watchablestore,它会开辟了一片内存空间,来满足watch的需求,watchablestore里面分了两个组,一个叫sync group,一个叫unsync group。
当你要去获取最新数据的时候,没有增加reversion,那么这个时候就可以直接将内存当中的数据给你,这种watch叫做sync group。
如果是带着历史的reversion,那么在整个内存当中是没有这个信息的,它要去db里面加载,所以你去拿unsync group当中数据的时候这个请求会被发到unsync group,发到unsync group之后,etcd会有backend的也就是背后会去启动goroutine去同步数据,当将数据同步到内存之后,然后会把watch发到sync group,然后将数据同步给你。
同时,每个WatchableStore 包含两种 watcherGroup,一种是 synced,一种是 unsynced,前者表示该 group 的watcher数据都已经同步完毕,在等待新的变更,后者表示该group 的watcher 数据同步落后于当前最新变更,还在追赶。
当 etcd收到客户端的 watch请求,如果请求携带了revision参数,则比较请求的revision和
store 当前的revision,如果大于当前revision,则放入 synced组中,否则放入 unsynced 组。
同时,etcd 会启动一个后台的 goroutine 持续同步 unsynced 的watcher,然后将其迁移到Synced 组。
在这种机制下,etcd V3支持从任意版本开始 watch,没有V2的1000条历史 event表限制的问题(当然这是指没有compact的情况下)。
这里有两个窗口,一个更新一个watch,左边的窗口可以看到有put的操作,不断的变更,左边的窗口就不断收到通知,一个个的put事件,
-wjson将当前数据的详细信息展示出来
可以看到key values本身是加密过的了,记录了创建的reversion是多少,可以看到创建对象的时候的它的一个状态。这个信息还是存放在etcd里面,虽然这个值已经改掉了,但是还是存储在db里面。
可以看到依次记录了这几次reversion的变化,如果其他线程改变了值,那么reversion还是会跳的。
左边的watch窗口关闭重开,不加任何的reversion,也就是从当前的版本给我通知新的事件,如果有新的变更,这个时候这些对象没有发生变化,所以它就没有任何的通知。
也可以指定从4的版本开始watch,可以看到将所有的变更都发给我了
上面就是etcd多版本的变更。
etcd常用操作
边栏推荐
- Complementary knowledge of auto encoder
- Fly tutorial 02 advanced functions of elevatedbutton (tutorial includes source code) (tutorial includes source code)
- MPLS experiment
- LVS load balancing cluster deployment - Dr direct routing mode
- 01. Basics - MySQL overview
- IPv6 experiment
- Mongodb vs mysql, which is more efficient
- IIS error, unable to start debugging on the webserver
- A few words explain redis cache penetration, breakdown, avalanche, and redis sentinel
- MySQL advanced (Advanced) SQL statement
猜你喜欢
分布式事务相关概念与理论
Practice of retro SOAP Protocol
It's hard to hear C language? Why don't you take a look at this (V) pointer
How to use "bottom logic" to see the cards in the world?
Hongke case study on storm impact in coastal areas of North Carolina using lidar
C language array
昨天的事情想说一下
What if the chat record is gone? How to restore wechat chat records on Apple Mobile
《天天数学》连载57:二月二十六日
Method of setting default items in C # ComboBox control code
随机推荐
Googgle guava ImmutableCollections
Complementary knowledge of auto encoder
C language array
0x15 string
Iframe to only show a certain part of the page
Azure solution: how can third-party tools call azure blob storage to store data?
C語言:求100-999是7的倍數的回文數
IPv6 experiment
Unity performance optimization reading notes - explore performance issues -profiler (2.1)
C语言数组
Source code analysis of the implementation mechanism of multisets in guava class library
Play Sanzi chess easily
MySQL performance optimization index
【Android Kotlin】lambda的返回语句和匿名函数
[Android kotlin] lambda return statement and anonymous function
13、 C window form technology and basic controls (3)
How to use "bottom logic" to see the cards in the world?
C语言:求100-999是7的倍数的回文数
Star leap plan | new projects are continuously being recruited! MSR Asia MSR Redmond joint research program invites you to apply!
How to use the mongodb ID array to get multiple documents- How to get multiple document using array of MongoDb id?