当前位置: 首页 > news >正文

怎么建网站手机版松门建设规划局网站

怎么建网站手机版,松门建设规划局网站,百度网站排名软件,作文网下载作者 | 奇伢来源 | 奇伢云存储你以为删掉就没事了#xff1f;有些童鞋以前还真是做过些傻事#xff0c;以为删掉一些东西#xff0c;覆盖一些东西就能掩盖某一些不可告人的秘密。来看看 etcd 的例子#xff1a;./etcdctl put 张三 是个憨憨哎呀#xff0c;这可… 作者 | 奇伢来源 | 奇伢云存储你以为删掉就没事了有些童鞋以前还真是做过些傻事以为删掉一些东西覆盖一些东西就能掩盖某一些不可告人的秘密。来看看 etcd 的例子./etcdctl put 张三 是个憨憨哎呀这可不大对怎么能说这么羞耻的话呢黑历史赶紧删掉。./etcdctl del 张三再来写过一个正常的./etcdctl put 张三 是个大聪明这就对了嘛数据我已经删了也更新了新的数据。这个黑历史已经永远被埋藏了万万没想到直到某一天还是有人把这些黑历史全部捞了出来./etcdctl watch 张三 --rev1PUT 张三 是个憨憨DELETE 张三PUT 张三 是个大聪明愣主半天我的老天啊。。。。。。这是啥呀太羞耻了吧。旁白这就是 MVCC数据多版本机制。存储系统核心功能存储系统核心功能其实非常简单聚焦三个操作读写删。用户把数据写进来好好保存读的时候安全返回删的时候释放空间以便重复利用。etcd 虽然有很多丰富的功能也有它特殊的定位但本质上也是一个存储系统。不过 etcd 有两个特色的功能watch 机制和 MVCC 机制 数据多版本 。提前思考两个小问题在用户删除 key 的时候却没有释放空间为什么呢此时不释放还待何时watch 机制监听一个 key 的所有变化怎么才能做到可靠MVCC 是啥东西这就先聊聊数据多版本的了。什么是数据多版本大白话就是同一份数据有多个版本。更准确的来讲是同一个 key 的多个版本的数据。举个例子你反复的三次写入一个 key的 value 值第一次写入 world-1 第二次写入 world-2 第三次写入 world-3 常规存储来讲是最新的值不断覆盖以前的。但在数据多版本的系统中每一次写入都写了新的位置旧的不会动每一次写入都对应一个版本。所以这三次的数据用户其实都能读到。key  v1 v2 v3数据多版本本质上就是把同一个 key 的历史变化都留下来了。数据多版本这个其实就是 watch 机制可靠的根源因为来时的路都在呀。什么是 MVCC 讲了数据多版本再来看看 MVCC 是个啥MVCC 是 Multiversion Concurrency Control 的英文缩写也叫多版本并发控制。如果仔细观察过各种数据库的话你会发现 MVCC 的概念经常在其中出没。数据库领域事务的并发控制是非常核心的一个话题。那一般大家怎么做事务的并发控制呢最简单的思路加锁呗。遇事不决就上大锁。但通常这一把大锁就基本上让你跟高性能无缘了。举个例子锁机制解决覆盖写的场景程序猿 A我要写 0 这个位置 我没搞好之前不要放人进来哦 程序猿 B我要写 0 这个位置旁白不好意思有人 A 正在更新你先等等程序猿 C我要读 0 这个位置旁白不好意思有人 A 正在更新还没搞完呢再等等还有更好的策略吗有的MVCC 机制也可以解决并发问题。MVCC 解决并发问题原理其实很容易理解没有覆盖写了嘛每次更新都对应一个数据版本。虽然是并发但是各写各的那就没啥需要控制的并发问题自然就没了。并发出现问题的根源就在于大家同一时间搞一个东西嘛。每次写入都是新的版本不会更新旧的位置。新的数据写入跟我旧的数据又有啥关系呢。大家各搞各的互不干扰天下太平。所以小结一下常见的并发控制有两大类第一种就是锁机制锁呢一般还分为悲观锁或者乐观锁 第二种就是 MVCC 机制核心就是不覆盖更新每次的写都在新的位置数据存在多个版本下面笔者就不再单独区分数据多版本还有 MVCC 机制了下面就用 MVCC 指代多版本的机制。etcd 的 MVCC 带来了什么可靠的 watch 机制简单的事务并发控制这两点其实非常容易理解一个 key 的历史版本全部被记录而不是覆盖更新那这个对于 watch 就太友好了。毕竟历史都在这嘛数据又安全读出来又方便。MVCC 每次写都产生一个版本的数据并发读写数据各搞各的并发问题自然就好解决了。 1   聊聊 revision 是个啥这里既然说到多版本那总有个版本号吧。etcd 里的版本号叫做 revision 。revision 有两个字段type revision struct {main int64      // 主版本号sub int64       // 次版本号 }每个不同的写事务都有唯一一个编号这个编号就是主版本号它是单调递增的。次版本号呢其实是为了区分同一个事务里的多次写操作因为写事务串行化为了提高吞吐所以尽量是批量操作把大批量的写操作聚合到一个事务中这样次版本号就有用途啦。通过 主版本号次版本号 组成的 revision 就能唯一确定 etcd 中的一次更新操作哦。这里提前提一下用户通过 etcdctl 能摸到的一个参数就是 rev 这个 rev 其实是主版本号哦。直观体验一下来 put 一个数据:./etcdctl put hello world-v1 -wjson{header:{cluster_id:14841639068965178418,member_id:10276657743932975437,revision:2,raft_term:2}}我们看到这次的版本号 revision 是 2 。再 put 一个数据./etcdctl put hello world-v2 -wjson{header:{cluster_id:14841639068965178418,member_id:10276657743932975437,revision:3,raft_term:2}}看到这次的版本号 revision 是 3 。好了我们来 get 一下这两个数据# 默认 get 是最新的 revision: 3 ./etcdctl get hello       hello world-v2# 指定获取 revision3 的数据  ./etcdctl get hello --rev3 hello world-v2# 指定获取 revision2 的数据 ./etcdctl get hello --rev2 hello world-v1来把它删了再看看。./etcdctl del hello1再来读读数据看看# 默认 get 是最新的 revision: 4 ./etcdctl get hello       # 空# 看下最新的版本号 ./etcdctl get hello  -wjson         {header:{cluster_id:14841639068965178418,member_id:10276657743932975437,revision:4,raft_term:2}}# 再来指定获取 revision3 的数据  ./etcdctl get hello --rev3 hello world-v2# 再来指定获取 revision2 的数据 ./etcdctl get hello --rev2 hello world-v1神奇不神奇你删了的 key 还能获取到历史版本的数据呢神奇 1   什么时候真正释放呢上面提到数据是多版本的哪怕删除其实也是一个特殊数据的插入。但现实是空间不是无限的所以无论怎么花里胡哨的系统删除的数据空间 100% 是一定要释放出来的。现在的问题是什么时候释放在数据多版本的设计中空间的由一个叫做 compact 的操作来实现。MVCC 的设计中可以认为用户的删除都是标记删除 让你有足够的信息识别到删除 compact 回收则完全由内部或者外部触发。常规的删除就现场释放了空间而 MVCC 显式的把空间回收的动作拆成了两个步骤用户删除标记删除系统回收compact 空间回收原理剖析好讲了那么多这里来浅析一下 etcd 的原理来看看 etcd 的具体实现。 1   用户写了个 key 变了个身很早我们就知道etcd 底层用的是 boltdb 做持久化的存储引擎boltdb 是一个纯粹的 kv 存储。那现在问题来了etcd 是怎么来存储用户的 key/value 呢是否是直接把用户的 key 做 key用户的 value 做 value存入 boltdb 呢不用问肯定不是的。etcd 内部生成了一个唯一 id 用作 boltdb 的 key用户的 key/value 打包在一起作为 boltdb 的 value 存入 boltdb 的。而这个所谓的 “内部唯一 id” 其实就是 revision 结构一个主版本号单调递增一个次版本号。所以实际写入 boltdb 的 key/value 格式如下keyrevision value 用户 key, 用户 value 举个例子上面举例的用户存储两对键值 hello world-v1 hello world-v2 这样的 key/value 。上面两次的 put 操作其实 boltdb 内部是存储成注意版本号我随意写的boltdb key: revision{11,} value: hello, world-v1 key: revision{12,} value: hello, world-v2划重点boltdb 存储的 key 是内部的 revision 结构value 则是一整个打包 用户 key用户 value 。 整个映射关系搞成一维平坦的样子。 2   可这叫我怎么索引呢既然存储到 boltdb 的 kv 已经和用户理解的 kv 大变样了。但用户对存储系统内部的原理是不关心的他们只关系自己的 key/value 所以必须有个手段能通过用户的 key 找到 boltdb 的 key 从而捞出用户的 value 。怎么实现呢这其实是一个查找需求查找需求的话最简单的就是链表但显然不够高级查找复杂度太高随着节点个数的增多时间线型递增所以 etcd 用的是 B 树一个来自开源的库 github.com/google/btree 。这颗 B 树存储管理的就是用户 key 到 revision 的索引。etcd 把所有的 boltdb 的 key revision 都解析过一遍在内存中构建了一颗完整的 B 树B 树的查找复杂度 O(logN)并且是纯内存操作查找过程不涉及到磁盘操作所以速度稳定而高效。找到 revision 之后就可以去 boltdb 中捞数据了捞到数据返回给用户即可。划重点这是一颗纯内存的 B 树里面有所有的用户 key 还有对应的 revision 记录。有两个问题大家要想一下这颗 B 树的 key 是啥这颗 B 树的 value 又是个啥第一个问题很简单这棵树是用来查找用户 key 到 revision 的映射的。那么自然 B 树的 key 就是用户的 key 。第二个问题稍微要想下我们大体知道是 revision但这个 revision 也是组织了一下的。etcd 用了一个叫做 keyIndex 的结构体来装这个用户所有的 revision 。来看一下 keyIndex 这个结构体这个结构体还挺有意思的记录着 key 的“生死轮回”type keyIndex struct {key         []byte       // 用户 keymodified    revision     // 最新的版本号generations []generation // 一个key有可能是有多次创建删除的每一次的轮回都是一个 generation }每个 generation 代表 key 一次轮回这里是个数组那就是说可以记录多次轮回呗。举个用户增删的例子写入用户 kv 键值对key 是 hellovalue 是 world-v1 产生的 revision {11.0}写入用户 kv 键值对key 是 hellovalue 是 world-v2 产生的 revision {12.0}写入用户 kv 键值对key 是 hellovalue 是 world-v3 产生的 revision {13.0}删除用户 kv key 是 hello 产生的 revision {14.0}写入用户 kv 键值对key 是 hellovalue 是 world-v4 产生的 revision {15.0}写入用户 kv 键值对key 是 hellovalue 是 world-v5 产生的 revision {16.0}删除用户 kv key 是 hello 产生的 revision {17.0}写入用户 kv 键值对key 是 hellovalue 是 world-v6 产生的 revision {18.0}上面对 keyhello 进行了反复的摩擦不断的写入删除经过来上面的操作在内存中形成的 keyIndex 如下世代轮回:  第一代    { 11.0 , 12.0 , 13.0 , 14.0(t) } 第二代    { 15.0 , 16.0 , 17.0(t) } 最新代    { 18.0 } 3   用户删除了个 key做了啥既然在多版本的系统中写入的数据上做了一层转化每一次的更新操作都对应了一条数据并且记录了下来。很多人其实都忘了所谓的“删除”其实本质也是更新。划重点删除也是写入一条特殊的数据。 用户删除一个 key 的时候etcd 其实在 boltdb 里面又写入了一条数据这个数据格式是这样的keyrevision value 用户 key 想必眼尖的小伙伴应该看出来了这个 value 它只有用户的 key 没有用户 value 而这条数据则恰恰是用来用户 key 被删除的标记。举个例子还是以上面 hello world 为例用户删除 key: hello 的话在 boltdb 里面的数据如下boltdb key: revision{11,} value: hello, world-v1 key: revision{12,} value: hello, world-v2 key: revision{13,} value: hello当然了上面说的是持久化的数据内存里面肯定也是要改的比如用来索引的那颗 B 树。 4   哎空间总归还是要释放的现在思考另一个核心的问题空间总归是要释放的虽迟但到。只增不减的话空间一定是会满的。用户既然要删除那还是说明了这之前的数据用户不要了的。为了防止空间不够用必须定期释放一些用户已经声明删除的数据。这个动作就叫做 compact compact 需要一个版本号。这个版本号就是写事务递增的那个版本号。划重点这个用的是主版本号。比如 compact 7 就是说把版本 7 以前的标记删除了的数据释放掉。注意到一个细节这里其实并不能非常精细的控制每一个 key 的回收。因为它用的是一个全局的版本号。那比这个版本号小的 key/value 都会被回收吗当然不是。用户没删除的数据肯定不能回收即使版本号比 compact 传入的小。举个例子// k1 有 3 个版本的数据 { revision: 1 key: k1valuev1 } { revision: 4 key: k1valuev2 } { revision: 7 key: k1valuev3 }// k2 有两个版本的数据 { revision: 10 key: k2valuev1 } { revision: 12 key: k2valuev2 }现在做 compact 9 // k1 留下一个在用版本的数据 { revision: 7 key: k1valuev3 }// k2 有两个版本的数据 { revision: 10 key: k2valuev1 } { revision: 12 key: k2valuev2 }你看这不就释放了 revision 1revision 4 这两条数据嘛。总结数据多版本不覆盖更新并发的时候各搞各的MVCC 嘛。在具有 MVCC 的系统中要小心哦所有的黑历史都记着呢版本用 revision 表示其内有两个主版本号和次版本号主版本在每次写事务单调递增次版本号在事务内多次更新时候递增在 MVCC 的设计中删除被显式搞成两个步骤用户的删其实是写入一个删除标记真正的空间释放是异步的compact 使用的参数是主版本号释放这个版本以前所有的被标记删除的数据etcd 用的 B 树是全内存的解析了所有的用户 key 用来管理用户 key 到 revision 的映射关系boltdb 是一个纯粹的 kv 存储引擎内部无覆盖写B 树索引 kv 的映射适合读多写少的场景写事务串行读事务并发etcd 在 boltdb 的基础上又给每一个 key 实现了多版本数据能够很方便的实现事务并发的控制etcd 的 MVCC 其实并没有给性能带来多大提升很容易理解因为底层用的是 boltdb 天然就是读并发、写串行的引擎上层无论怎么做都逃不掉这一点但在 etcd 中 MVCC 机制对于 watch 机制却很关键后记etcd 里的 MVCC 是占比非常大的模块MVCC 也是很多数据库系统的核心理解它非常有用。往期推荐云计算到底是谁发明的从Docker的信号机制看容器的优雅停止低代码发展专访系列之三低代码平台会成为企业数字化基础设施么内容整理志愿者招募了点分享点收藏点点赞点在看
http://www.pierceye.com/news/737214/

相关文章:

  • wordpress网站破解整容医院网络建设公司
  • app如何推广深圳网络排名优化
  • 网站seo规范南昌it制作电商网站的公司
  • 深圳网站设计 工作室深圳品牌设计工作室
  • 手机网站静态动态wordpress注意
  • 什么网站没人做v5shop微分销系统
  • 做鞋子的网站品牌vi设计包括哪些
  • 做产品类的工作上什么网站好asp.net做的网站模板下载
  • 金融公司网站规划方案我司网站改版上线网站建设
  • 城乡与住房建设部网站首页深圳响应式设计企业网站
  • 做网站 带宽 多少钱做电影网站的服务器需要多大
  • 西安网站建设全包用手机制作游戏的软件
  • 哪个网站生鲜配送做的好drupal wordpress网站
  • 网站后台需要多少建设部举报网站
  • 重庆建筑证书查询网站wordpress博客怎么访问不了
  • 网站案例鉴赏wordpress html5视频
  • 免费申请网站 主机 空间网站不稳定
  • 建立个人网站视频教程中国空间站和国际空间站对比
  • 佛山网站seo推广推荐一个专门做海鲜的网站
  • 长春网站建设与健网站外链如何做
  • 网站开发国内现状网站建设与维护教学计划
  • 如何解决网站图片打开慢网站如何做跳转
  • 网站开发作用大学生网络营销策划书
  • 有域名了如何建网站用自己的身份做网站备案
  • 免费的黄冈网站有哪些平台游戏软件上海网站建设自学
  • 网站建设摊销几年wordpress怎样建立二级菜单
  • 营销方案案例北京搜索引擎优化seo专员
  • 网站建设是什么科目wordpress 火车头
  • 做网站需要什么专业方向的员工wordpress yeti
  • 网站建设项目登记表长沙建网站培训机构