分布式数据库的多主场景解析
vikingapple  2024-06-29 10:38  发布于中国

我们知道,当前的分布式数据库改造中,最大的问题之一是数据库不能支持多读多写模式,所以数据除了做副本之外还必须切片,这导致了业务改造难度加大,同时可靠性降低。另一方面当前很多分布式数据库,包括社区开源代的MySQL,都宣称可以支持多主工作模式,可以多读多写。

那么这些数据库所讲的多主工作模式各自有哪些特点,又有哪些区别呢。通过本文的探讨,希望能获得一些答案。

分布式数据库为什么要做多主

讲具体实施方案之前,我们要先讨论场景。

所谓多主,顾名思义,是相对于主备模式而言的。由于当前开源数据库里,MySQL仍然使用广泛,所以我们以MySQL为例讨论。MySQL的主备部署模式下,只有主机可以接受读写请求。备机通过获取主机产生的binlog,回放出页面。所以,备机和主机的数据不是完全实时同步的。实际部署中,大部分业务都部署为直接访问主机。备机只是作为故障时的接管用,不跑业务。

062901.png

这会造成资源的浪费,大部分资源要给备机预留,服务器规模急剧变大。另外主从之间的RPO和RTO很难保障,很多基于MySQL实现的数据库厂商,都在尝试修改主从同步这部分的实现,通过不断打补丁的方式,加固可靠性获得更好的RPO/RTO。

有些业务会把多套上述MySQL主从组串在一起,组成一个分布式解决方案。比如使用分布式中间件,这个选型就比较多了,很多互联网大厂也都发布过自己的中间件。这些中间件的本质都是通过分库分表的方式,实现水平扩展。我们抽象一下,大概就是像下面这样。

在这种模式下,不同的MySQL主从组,对应的是完全不同的内容,所以虽然集群总体规模可以很大,但每个主从组其实都是一个孤岛。业务层或中间件层要知道某个数据位于哪个孤岛,以便能够正确访问。而具体到每一个MySQL主从组内,所遇到的问题和上面说的单个主从部署模式其实是完全一样的。此外这种模式下对于弹性不太友好,因为要增加性能,增加节点,必须调整数据在MySQL各个主从组之间的分布。这是需要业务参与和感知甚至停机的。

所以,实现数据库多主其实要解决几个问题,首先是备机要能参与工作,提升资源利用率,而不是闲置在那里浪费资源;还应打破多个主从组之间的孤岛,不需要业务或中间件去感知和记录;进一步地,能够让业务无感知的透明扩缩容,不需要为补从或者数据搬迁苦恼;最后还要解决大规模集群便于维护管理的问题。

带着上面这几个问题,我们看一下业界都是怎么构建多主的。

从写一本书开始谈起

为了便于直观理解,我们先暂时不说数据库的事,先讲一个写书的故事。

假设我要写一本书。为了写书,我聘请了一个叫张三的人,他在自己的电脑上建了一个Word文档开始写作。为了在他万一请假时写书不中断,我又请了两个人张A和张B作为张三的后备。不过张三正常出勤的时候,他俩只能在旁边看着。为不让他俩闲着,我让张A和张B每人也拿一台电脑,在张三码字同时,他俩在旁边各开一个Word照着张三写的内容完整地抄。每天这仨人“噼啪”敲键盘热火朝天。

062903.png

不过我这书的内容有点多,张三一个人写得太慢了。我又聘了一个叫李四的人来帮张三。可张三和李四俩人要各用一台电脑,没办法打开同一个Word文档一起写,怎么办呢?我就切分了一下章节,把一部分章节单独拆出另一个Word文件,让李四拿到自己电脑上去写。为预防李四请假,我本想让张A和张B在李四请假的时候帮他写,结果这俩人说他们每天抄张三码的字都忙不过来,没空帮李四。我只好另外请了两个后备李A和李B,每天抄李四的**。

可是出版社那边还是觉得我的书写的太慢了,不停催我。我只好又聘用了王五,又再拆分几个章节让王五去写,并请了王A和王B每天照着王五的抄。

就这样,团队的人越来越多,有必要请个项目经理了。于是赵六来了。赵六负责整本书章节怎么分,谁来写。一个10人小团队运作起来了。

062904.png

读者可能已经看出,这张图和分布式MySQL的基本架构是完全一样的。

我犯了什么错误,让写书这么困难

有一天,我跟赵六说,我需要加一段情节进去,这段情节要张三和李四分别配合修改。结果2天过去毫无进展。找赵六问,他说早就把任务传达下去了;而张三却说他不知道这事;李四则说稿子早写完了,也没人再找过他。我只好把几个人叫到一起,开会讨论半天才解决问题。我叮嘱赵六,他要协调好这几个人的工作,别总出是岔子让我擦屁股。

但出岔子总是常态。张三请了一天假回来,就和张A吵起来了。张三坚持说他休假前写过的一段内容被张A篡改了,而且他的电脑本地盘不知怎么坏了,数据全没了。张A现在写的东西和他之前的完全不同。张A却说从没见过张三写的这段,这段是自己全新写的。两个人吵得我脑袋嗡嗡响。我只好把赵六叫来问怎么回事,赵六却两手一摊说这事情他管不了,这是张三和张A之间的事。一声叹息……我只好把张三张A张B叫一起又开一下午会。

心累啊,都聘请十个人了,还有专职项目经理。帮我写一本书而已,为什么却这么难?

因为我犯了错误。我误以为一份文档几个人没办法同时编辑。其实多人在线共享编辑一个文档的技术早就有了,只是我不知道。当然张三李四王五赵六也没跟我提起过。

为了提高工作效率,我的写书小组变成了多主架构

我决定不再让他们每个人在自己电脑上各写各的文档了。我把张三李四王五的文档合重新整成一份(原本就是一本书啊,我当时为啥要拆开的呢?),还让他们继续负责自己的章节,通过共享文档进行编辑。

同时为了避免再出现电脑本地盘坏的事情,我去买了一套共享存储,把文档存在上面了。

听说了这事,张A、张B、李A、李B、王A、王B都跑来找我。因为他们的工作就是每天照抄文档,现在文档全合一起了,他们该抄谁的文档呢。我说,你们不用再抄文档了,都先回家吧。但一转念,张三李四王五这仨人还是有可能请假的。就又说,王A你留下吧。如果他们仨谁请假了,你就继续替写**吧。

其余5个人一听要被解聘都不干了,嚷嚷说万一张三和王A同时病了怎么办,没人顶替。我一想也对,就跟大家说,你们明天开始不用来办公室了,我也不发钱。万一人手不够的时候,你们再随时来,按天结算。就这样我的团队常驻人员一下少了5个。

赵六看走了这么多人有点慌,悄悄问我他自己怎么办。我拍拍赵六说,项目经理还是需要的,只不过文档共享了,以后再有要增加故事情节的事,我会直接交给其中一个人去负责,不再会扯皮打架了。赵六你的主要任务,是关注大家工作压力和状态,别把一个人累垮了。

这样,我的项目组人员一下少了一半,也不吵了。一切变得顺利多了。

062905.png

上面其实就是数据库一致性多主多写的模型。这是基于Share Everything的多写,所有数据库实例共享所有数据进行协同工作,每个实例都可以对接业务,按需操作访问所有的库和表。这种方式下可以节省很多数据库实例,也就能减少很多计算用服务器。

同时由于大家是共享数据,所以协同的难度要远远小于分拆成几个分片,而且需要弹的时候可以直接加实例,应用几乎无感知,维护管理要简单很多。

分片多主是怎么一回事

业界还有一种分片方式的多主。他是怎么运作的呢。我们先回到我的写书工作室。

为了多人一起写书,大家还是每人拷贝一份文档各写各的,不做合并。但赵六帮我发布了一个分工表,每个人都需要知道三个人是如何对文档分工的。一旦我需要增写一个新情节的时候,我直接把工作丢给一个人去写就行(比如张三),然后此人把不属于自己负责的部分,转交给另一个人去写(比如王五),写完后(张三)交给我。这样一来张三,李四,王五每个人都可以直接接收写作任务,私下再根据分工进行交换。我的工作似乎也简单了,只管下发任务给他们仨就行。

062906.png

但没几天,我检查书稿发现有一段内容写错了。一查,这部分是交给张三负责的,就把张三叫来臭骂了一顿。张三却觉得不是他的错,说是李四改错了。我很恼火,质问道,任务交给你了,你只管自己吗,就不懂得端到端拉通吗。

张三一摊手,李四那边内容我不负责啊,我就传个话而已,我又不是李四的领导。我瞪了一眼李四。李四马上弹起来说,我每天从领导你这领一堆活,张三王五还要给我转一堆活,交代的也不清不楚,我忙不过来。张三王五最近又没啥事,为什么非都丢给我做。

李四这种借口正要令我发作,我转头却看见张A、张B、李A、李B,几个人居然在旁边看报喝茶。火就更大了,你们几个怎么不去干活?!4个人嬉皮笑脸地说,领导我们要抄张三和李四的书,可他们都在和你开会啊……

改进的分片多主,能拯救我吗

我忍无可忍了,让这几个喝茶的走人!张三,李四,王五,以后你们给我互相抄对方的书,我不养这几个不干活的了。李四一听直接瘫在了地上,领导你是认真的吗?写书的活都干不过来了,还要抄书,抄书你当不用花时间的吗?

顾不上管昏迷不醒的李四,我喊来赵六,让他把大家工作拆分细一些,任务均衡一点。赵六却说,工作再怎么拆,总量也还在那里,这几个人要互相抄书恐怕真的忙不过来。

我一咬牙,那就再把写书的章节重新划分一下,让更多的人一起写书、抄书。赵六一听要加人,嘴上没说话,心里很复杂。加人?拆好的文档得重新再拆,分工任务表得重整一遍,我自己得折腾半天不说,大家手上的写书任务起码也得停半天啊。关键是加人就不吵了吗?

062907.png

这种分片多主,通过分片级的交叉主备,可以解决一部分资源闲置的问题,但备机(也即抄书人)的额外开销其实还在。同时分片之间逻辑上还是一个个孤岛,虽然可以做一些协同,但拉通不彻底。在扩缩容的时候,对业务也不能完全透明。所以对管理和运维而言,简化程度远远不够。

MGR是一种多主解决思路吗?

MySQL自己其实也提供了一种多主方式叫MGR。这种方式的多主又是怎么工作的呢。我们再请来张三李四王五出场,当当当……

首先,张三李四王五几个人把文档合成了一本书,但他们之间不是共享协同编辑,每人都各自拷了一份完整文档,放在自己电脑本地盘编辑。为了保证大家**别写乱,我定了个规矩,张三每次改的内容写完保存前(聪明的读者,可以想想为什么是写完保存前而不是张三开始动手写之前),都必须通知李四和王五,让他俩一起修改保存。李四也是一样,每次修改保存前都得通知给张三和王五一起修改保存。我想这样做,应该和共享文档修改没啥区别,我就不用单独买个共享存储了。不就是每天他们费点嘴皮子沟通而已嘛。

但很快,张三就发飙了,他质问李四王五为啥不同步保存他的修改。王五很不解,说明明李四先告诉他要改某一段,张三通知晚了呀。张三火冒三丈,问李四为什么要改这一段,自己写了一下午都白写了,本可以下班现在却要加班。李四也很不爽,大家约定好的保存前才通知,你自己写的慢怪我咯,我当然可以改啊。赵六跑来找我报告情况,顺便还说了一句,老大这事可不归我管。好吧,一切罪恶我来承担,我只能出面协调安抚每个小伙伴。

062908.png

这所谓的多主的模式,孤岛倒是打破了,每个人都有一份完整数据了,可资源利用率变得更糟了,存储多副本没解决不说,每个人还都处在不停的和别人协商的状态。一旦冲突了活就算白干,还得业务介入来解决,这种管理维护也是非常考验人的耐心的。所以这种方式用的并不多,用了MGR的人,自有一把辛酸泪。

分布式数据库,共享数据多主时代,已经来到

写书的故事到此讲完了。为了提高多人一起写书的效率,我们尝试了一致性多主,分片多主和类MGR多主三种不同的方式。

看到这里大家可能会说,这个故事开头设定就不太合理,文档多人共享编辑这个技术早就有了呀,有这种技术,一开始就可以更合理的分工,不需要这么复杂的过程呀。

是的,可现在分布式数据库改造过程里,不少业务的实际工作方式,其实就和本文的写书一样,在摸索中前进。也在尝试分片多主或者类MGR多主等方式视图解决问题,但这两种方式并不能把资源利用发挥到极致,同时管理的开销也很大。

有小伙伴问,多人写书能高效合理地分工合作的前提,是借助多人共享编辑技术,数据库现在有这种“多人共享编辑”方法吗?这个现在真的已经有了。如下图:

062909.png

所有的数据库实例全部共享同一份数据,消除多余的副本。基于全局的缓存和全局的资源管理系统,实现对业务完全透明的多读多写。目前部分厂商已经完全无侵入地支持MySQL生态,直接以插件方式就能接入现有数据库集群无需改造。基于GaussDB生态的预计未来也会发布。

全部回复(
回复
回复