TiKV 集群版本的安全迁移

Easter79
• 阅读 297

问题描述

在 TiDB 的产品迭代中,不免会碰到一些兼容性问题出现。通常协议上的兼容性 protobuf 已经能帮我们处理的很好,在进行功能开发,性能优化时,通常会保证版本是向后兼容的,但并不保证向前兼容性,因此,当集群中同时有新旧版本节点存在时,旧版本不能兼容新版本的特性,就有可能造成该节点崩溃,影响集群可用性,甚至丢失数据。目前在有不兼容的版本升级时,会要求进行离线升级,但这会影响到服务,我们需要一个适合的机制来进行不停服务的升级。因此我们需要在进行滚动升级时,让这些不能保证整个集群的向后兼容性的功能不被启用。只有在保证集群中所有节点都已经升级完成后,我们才安全的启用这些功能。

常见的当我们对引入新的 RaftCommand 的时候,旧版本的 TiKV 并不能识别新的添加的 RaftCommand,对于不能认知的 RaftCommand TiKV 有不同的处理,可能会报错退出或忽略。比如为了支持 Raft Learner, 在 raftpb 里对添加新的 ConfChange 类型。 当 PD 在进行 Region 调度时,会先发送 AddLearner 到 TiKV 上,接受到这个命令的肯定是这个 Region 的 Leader,在进行一系列检查后,会将该命令 Proposal, 而 Follwer 如果是旧版本的话,在 Apply 这条 Command 就会出错。而在滚动升级时,很有可能存在 Leader 是新版本,Follwer 是老版本的情况。

引入版本检查机制

TiDB 的版本定义是遵循 Semver 的版本规则的。版本格式一般由主版本号(Major),次版本号(Minor),修订号(Patch),版本号递增规则如下:

  1. 主版本号:当进行了不兼容的 API 修改。
  2. 次版本号:当做了向下兼容的功能性新增。
  3. 修订号:当做了向下兼容的问题修正。

先行版本号(PreRelase)及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。比如 TiDB 目前的版本是 2.1.0-beta,先行版号为 beta 版。

在此之前,集群并没有版本的概念,虽然每个组件都有各自的版本信息,但各个节点的各自组件的版本都可以任意的。没有一个管理机制可以管理或查看所有组件的版本信息。为了解决滚动升级过程中存在多个版本的兼容性问题,这里引入集群版本的概念,并由 TiDB 集群的中心节点 PD 来进行管理和检查。

具体实现

1.升级集群

在 PD 中,会设置一个 cluster_version 的键值对,对应当前运行集群中 TiKV 节点中最旧的版本。也就是必须要兼容这个版本, 因此不能打开集群中其他新版本的节点的一些不兼容的特性。

在集群启动的时候,每个 TiKV 都需要向 PD 注册,注册时会带上版本信息。当当前 TiKV 的版本低于集群版本的时候,该 TiKV 会注册失败。因为此时集群的版本已经是更高的版本了,而加入旧版本的节点需要对旧版本进行兼容,为了防止已有的特性降级,直接拒绝不兼容的版本加入,目前默认主版本号和此版本号一样则为兼容的版本。

如果 TiKV 的版本高于或等于当前的 cluster_version 时, TiKV 能够注册成功并成功启动。每次注册都会触发 PD 的一次检查,会检测当前集群中正常运行的 TiKV 的最低版本,并与当前的 cluster_version 进行比对,如果最低版本比 cluster_version 更加新,则将 cluster_version 更新。因此每次滚动升级的时候,能够自动更新集群的版本。

2. 版本特性的开启

TiKV 很多功能是需要 PD 的参与,目前这些新功能的开启也是通过 PD 进行控制的。在 PD 中,会将每个版本新特性记录下来,在 TiKV 2.0 中,对应有 Raft Leaner, Region Merge。 TiKV 2.1 中有 Batch Split,Joint Consensus 等。这些特性都需要 PD 的参与与控制。比如说 Add Leaner,Region Merge,Joint Consensus 需要 PD 下发调度给 TiKV,Batch Split 则是 TiKV 主动发起并请求 PD 分配新的 Region ID。因此这些功能都是能通过 PD 进行控制的。PD 会通过比对当前的集群版本,选择开启当前集群版本所支持的新特性。从而保证版本的兼容性。

3. 集群回滚

当升级完成后,如果遇到问题需要进行集群进行回滚时, 需要手动修改集群版本后。PD 提供了 pdctl 可以通过命令手动修改集群的 cluster_version,这时旧版本的 TiKV 就能注册并启动,从而进行回滚。

PD 对 cluster_version 是通过 etcd 进行了持久化,在每次 PD 启动的时候,leader 都会从 etcd kv 中加载出 clustrer_version,然后提供服务。从而保证在 PD leader 切换后 cluster_version 的一致性。另外 PD 本身的版本可能会小于当前 cluster_version。因此在滚动升级的时候,需要先升级 PD,如果只升级了 TiKV,虽然 cluster_version 已经更新到新的版本的,但 PD 并不能开启新的功能,因为对它来说是不支持的。如果出现这种情况,PD 的日志中会有报警。在升级的时候,最好按 PD,TiKV,TiDB 的顺序逐一对各个组件。

后续计划

上面提到的新功能特性一般都是需要 PD 参与的。而有些特性不需要PD的参与,因此需要保证这种特性在 TiKV 之间是可以兼容的,实现的时候可以采用类是 http2 <-> http 的方式,对请求进行降级装发,保留两套接口等。另为 TiDB 目前是自身保证可以无缝兼容,但与 TiKV 可能存在兼容性问题,往后同样考虑让TiDB 也在 PD上进行注册。

作者:陈书宁

TiKV 集群版本的安全迁移

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
APP测试点总结
APP测试点总结1.功能性测试:  ——根据产品需求文档编写测试用例。  ——软件设计文档编写用例。  注意:就是根据产品需求文档编写测试用例而进行测试。2.兼容性测试:  ——android版本的兼容性  ——手机分辨率兼容性  ——网络的兼容性:2G\\3G\\4G\\WIFI,弱网下、断网时  ——app跨版本的兼容性  1.适配
Stella981 Stella981
2年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
新支点小玉 新支点小玉
3个月前
软件兼容性测试要考虑什么?
兼容性测试兼容性测试报告软件兼容性测试要考虑什么?1、向前兼容和向后兼容。向前兼容是指可以使用软件的未来版本,向后兼容是指可以使用软件的以前版本。并非所有的软件都要求向前兼容和向后兼容,这是软件设计者需要决定的产品特性。2、不同版本之间的兼容。不同版本之间
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k