基于裸数据的异地数据库性能诊断与优化

在猪爸爸的努力下,泥坑银行终于能高效正常的运作了,但猪爸爸一直比较担心海盗岛那边的网点,因为他总是担心跨海的通讯会因为极端情况出现问题。果不其然,一个雷雨交加的晚上,海盗岛的发电站被击中,整个岛处于停电状态,海盗岛的网点没法正常工作了。虽然狗爷爷尽了很多努力,让海盗岛重新供电也花了一天时间。

第二天,猪爸爸去见了兔小姐:

Problem

这里, 其实就是一个集群成员变更常见的问题,当我们添加或者删除节点的时候,如何让其他的节点知道成员变更了。最通常的做法,可能就是通过一个全局的协调器,譬如 zookeeper 或者 etcd 这种的,做一个 Two Phase(2 PC) 的变更,但这样其实是有问题的,先不说 2 PC 一些 corner case 需要处理,整个过程还可能会导致暂时的服务不可用,虽然这个时间在多数情况下面可能比较短,所以 Raft 这边采用了另外一种做法,我们继续说明。

Add/Remove one Node

在 Raft 的博士论文里面,当 Leader 收到 Configuration Change 的消息之后,它就将新的配置(后面叫 C-new,旧的叫 C-old) 作为一个特殊的 Raft Entry 发送到其他的 Follower 上面,任何节点只要收到了这个 Entry,就开始直接使用 C-new。当 C-new 这个 Log 被 committed,那么这次 Configuration Change 就结束了。当在 TiKV 以及 etcd 里面,我们并没有使用这种方式,只有当 C-new 这个 Log 被 committed 以及被 applied 之后,节点才知道最新的 Configuration 的情况。这样做的方式是比较简单,但需要注意几点:

  1. 当 Log 里面有一个 Configuration Change 还没有被 committed,不允许接受新的 Configuration Change 请求,主要是为了防止出现多 Leader 情况。
  2. 如果只有两个节点,需要移除一个节点,如果 Leader 在发起命令之后,另一个节点挂了,这时候系统没法恢复了。

Snapshot

好了,我们继续回到小镇银行这边,兔小姐跟猪爸爸选好了新的场地 - 森林小径,然后就准备开始海盗岛的网点替换工作了。但这时候,兔小姐突然想到一个严重的问题:

Snapshot 虽然简单,但需要注意,假设 3 个节点,然后新加入了一个节点,如果 Leader 在给新的 Follower 发送 Snapshot 的时候,另一个 Follower 当掉了,这时候整个系统是没法工作了,只有等 Follower 完全收完 Snapshot 之后才能恢复。为了解决这个问题,我们可以引入 Learner 的状态,也就是新加入的 Learner 节点是不能算 Quorum 的,它不能投票。只有 Leader 确认这个 Learner 接受完了 Snapshot,能正常同步 Raft Log 了,才会考虑将其变成正常的可以 Vote 的节点。

Joint Consensus

虽然上面一次进行一个成员变更的方式已经能在生产环境中满足大部分情况,但还有一种 corner case 我们是没有办法解决的。假设现在我们有 3 个 IDC,用 A,B,C 来表示,每个 IDC 里面有两台机器,就是 A1,A2,B1,B2,C1,C2。现在有一个 Raft 副本在 A1,B1,C1 上面,这时候,如果我们发现 A1 压力比较大,要将副本转移到 A2 上面,那么有两种办法:

  1. 移除 A1,增加 A2
  2. 增加 A2,移除 A1

但无论是上面哪一种方法,都会有风险,譬如第一种,当 A1 移除之后,如果 B1 或者 C1 当掉,那么整个集群是不可用的。而对于第二种,A2 增加之后,如果这时候整个 IDC A 当掉,那么整个 Raft 集群也是不可用的了。也就是说,我们虽然将数据放在了 3 个 IDC 上面,但在一些情况下面,如果一个 IDC 整个当掉,都可能引起 Raft 集群不可用。

我们可以通过 Learner 的方式缓解这个问题,也就是先增加 A2,但 A2 是 Learner,只有 A2 完全追上了,我们才将 A2 给变成 Voter,然后在移掉 A1。但这个方式只是能减少不可用的概率,并不能完全防止,所以最好的做法就是支持 Joint Consensus 算法。

这个算法其实比较简单,相对于上面的一次成员变更的算法,它只引入了一个过渡状态,叫做 joint consensus。当一个 Leader 收到成员变更的请求的时候,他首先会将 C-old 和 C-new 都放在 joint consensus 里面(我们叫做 C-old-new),作为一个 Raft Log 发送给其他的 Followers。当节点收到 Log,不需要等待 Log 被 committed,就可以使用最新的 C-new 配置了,但这时候,仍然只有 C-old 里面的集群能进行 Vote。如果这时候 Leader 当掉了,新选出来的节点 要不在 C-old 里面,要不在 C-old-new 里面,因为我们前面没约定 C-old-new 这个 Log 必须 committed。但无论是哪一种 Leader,C-new 这边的集群都不可能单边决策的。

当 C-old-new 被 committed 之后,就进行了 joint consensus 状态,在这个状态里面:

  1. Log 会被复制到所有在两个 configurations 里面的节点上面;
  2. 在两个 configuration 里面的节点都可能被选为 Leader;
  3. 但只有 C-old 里面 majority 和 C-new 里面 majority 都同意,才能选出 Leader 和进行 Log 提交。

当进入 joint consensus 之后,Leader 就可以再次提交一个新的 C-new Raft Log,仍然是只要其他节点收到了这个 Log,就可以使用新的 Configuration 了,当 C-new 这个 Log 被 committed 了,那么 C-old 就没用了,不在 C-new 的节点就可以直接关闭。这套流程就能保证在任意时候,C-old 和 C-new 不会出现单边投票的情况。

虽然 joint consensus 很强大,但现在用的最多的仍然是一次成员变更的方法,毕竟很简单,而 joint consensus 我只在 LogCabin 中看到过,所以这里并没有很详细的介绍。一些 corner case 的处理大家可以直接去看论文了。

那没有 joint consensus,一些极端的 corner case 怎么办呢?可能就先忍忍呗,或者使用 5 副本,甚至用 7 副本。

小结

成员变更我认为算是 Raft 里面最难的概念,尤其是在 Raft 的 Paper 里面,重点就提到的是 joint consensus 算法,其实比较让人难以理解。这里其实就体现了一个工程上面的取舍,虽然我知道理论上面 100% 的事情怎么做,但为了更加简单,我可以稍微放低一点要求。

TiKV 和 etcd 现在都是没有用 joint consensus 的,但我们现在在开始添加 Learner,后面如果真的遇到了其他的 corner case,会不会考虑一下,没准也不是不可能的事情。

本次嘉年华上,我们很荣幸邀请到了作者唐刘来到现场为大家分享,本次分享将介绍 TiDB 如何使用 Raft 算法构建分布式可扩展的后端存储系统,以及 TiDB 在可靠性、可用性、性能等方面对 Raft 做的工程优化。


原文发布时间为:2017-11-16

本文作者:唐刘

时间: 2024-08-16 11:30:26

基于裸数据的异地数据库性能诊断与优化的相关文章

15年老司机的DPM数据库性能分析产品研发之路

本文根据DBAplus社群第87期线上分享整理而成.   讲师介绍  邹德裕 轻维软件首席专家   DBAplus社群联合发起人,OraZ产品作者.Oracle OCM. 15年运维管理经验,在数据库诊断.故障排除.优化.架构设计等方面具有丰富的经验.   主题简介: 1.运维中常见的场景及对应解决案例 2.解密DPM数据库性能分析平台   本次我给大家带来的主题分享为<15年老司机的DPM数据库性能分析产品研发之路>.   我将通过Oracle在实际生产中常见的运维场景及问题处理案例,解析如

《Oracle数据库性能优化方法论和最佳实践》——第2章 Oracle性能优化方法论的发展 2.1 基于局部命中率分析的优化方法论

第2章 Oracle性能优化方法论的发展 Oracle数据库在开发和使用过程中对数据库的性能优化极为重视,几乎在每个版本的更新中都会对可优化的数据库做出改善.不仅如此,Oracle数据库还会使用优化方法来指导性能优化,会不断推出新的性能优化方法论,并依据优化方法论持续完善其可观察的性能优化体系.从Oracle 6到现在的Oracle 12c,经历了Oracle 7.Oracle 8.Oracle 8i.Oracle 9i & R2.Oracle 10gR1 & R2.Oracle 11gR

用裸设备与Oracle数据库的性能

        要知道这样一个事实:磁盘I/O是影响Oracle数据库性能的一个重要原因.就本质来说,任何Oracle数据库负责存储数据,从磁盘中查询数据是非常昂贵和费时的操作.        由于许多Oracle系统需要大量的I/O操作,很多Oracle专职人员在碰到大块(DB_BLOCK_SIZE)数据操作时就考虑使用"裸设备"(raw device).裸设备指得是绕过UNIX 的Journal文件系统(Journal File System ,JFS)直接进行访问的磁盘,这样就省

100个GB的数据,放在ORACLE数据库中,然后基于大数据平台处理

问题描述 100个GB的数据,放在ORACLE数据库中,然后基于大数据平台处理,求助 解决方案 解决方案二:你确定你的是大数据?解决方案三:引用1楼War_Craft_World的回复: 你确定你的是大数据? 100G数据第一相比普通数据够大第二是数据简称大数据解决方案四:直接上阿里云就是了,有数据处理,要不就是自己搭建环境,

mfc求助-求教 2010mfc基于对话框如何连接access数据库及如何运用数据编程及后期的美化??

问题描述 求教 2010mfc基于对话框如何连接access数据库及如何运用数据编程及后期的美化?? 即将毕业的学生这方面太差,希望能给与帮助,谢谢!!! 1.熟悉输油站的结构及常见的输油.混油工艺: 2. 了解泵站所用输油泵的类型,对泵的运行方式及运行特征进行重点学习,并予以总结和综述: 3. 了解已有泵优化运行的方法,根据输油泵的特征,有针对性的选择1~2种优化运行的数学模型和求解方法: 4. 至少掌握一种面向对象的编程语言(c++或Delphi),并用其实现对所确定的输油泵优化的数学模型求

数据库Oracle数据的异地的自动备份_oracle

正在看的ORACLE教程是:数据库Oracle数据的异地的自动备份.在大型商业应用中,数据的异地容灾备份十分重要,也必不可少.笔者根据自己的实践经验,设计了一套简洁地实现异地数据自动备份的方法,可供数据库管理人员参考.文中所有的程序都经过测试,运行良好.这里模拟的异地运行环境为一主一备两套Sun Solaris系统,所采用的备份方法为Oracle数据库提供的标准备份:export. 相关命令 文中主要用到三个命令,这里先单独介绍一下: export: 将数据库中数据备份成一个二进制系统文件,它有

云创存储数据立方与国际某知名分布式数据库性能测试报告

在相同条件下,进行国际某知名分布式数据库与云创存储的数据立方(DataCube)产品性能对比测试. 测试报告请下载:temp_13020600188886.pdf

MySQL Innodb数据库性能实践——热点数据性能

对于大部分的应用来说,都存在热点数据的访问,即:某些数据在一定时间内的访问频率要远远高于其它数据. 常见的热点数据有"最新的新闻"."最热门的新闻"."下载量最大"的电影等. 为了了解MySQL Innodb对热点数据的支持情况,我进行了基准测试,测试环境如下: [硬件配置] 硬件 配置 CPU Intel(R) Xeon(R) CPU E5620 主频2.40GHz, 物理CPU 2个,逻辑CPU 16个 内存 24G(6块 * 4G  DDR

阿里云数据库CloudDBA智慧解决数据库性能优化和问题诊断难题

背景 我要申请CloudDBA免费体验     阿里云数据库为何推出CloudDBA?问题诊断(trouble shooting) 和 性能优化(performance tunning) 一直都是数据库领域的专业问题,需要资深DBA的专业技能才能胜任解决,但这样的人才是稀缺的,无法及时满足大部分的企业紧急需求.如果有一款产品能够在大多数情况下,客户借助它非常迅速的找出数据库性能隐患点.排查出问题症结所在,这将无疑协助客户解决燃眉之急,可以大大降低风险和提高效率.        先来分析下为什么数