早在公元前五百年,孙子就参透了数据库分区的真谛

栏目: 数据库 · 发布时间: 6年前

内容简介:数据库分区,我觉得是一个称得上“伟大”的数据库存储结构概念。如果说,一个编程者(并非一个职业DBA)除了关注表结构本身以外,分区,可能就是所需要关注的最靠近底层的一个数据库的设计。例如像数据库的表空间这样的概念,通常一个普通开发人员,就未必会去关注。但是分区概念却不一样,因为它与应用场景结合更加紧密。比如,按时间、按地区、按类别分区,等等。

数据库分区,我觉得是一个称得上“伟大”的数据库存储结构概念。

如果说,一个编程者(并非一个职业DBA)除了关注表结构本身以外,分区,可能就是所需要关注的最靠近底层的一个数据库的设计。

例如像数据库的表空间这样的概念,通常一个普通开发人员,就未必会去关注。但是分区概念却不一样,因为它与应用场景结合更加紧密。比如,按时间、按地区、按类别分区,等等。

我猜测很多人是不赞同「数据库分区是个“伟大”的概念」这个观点的。原因是,我翻阅了各种市面上主流数据库的书籍,入门级的如《XX数据库从入门到删库跑路》,看起来高端的如《XX数据库的技术内幕》,大部分书籍在介绍分区的内容的时候,都没有给很大的篇幅。

甚至有好几本书上,就这么简单的来了一句:对于一个很大的表,如果每次搜索都对全表进行扫描,会很耗时间,如果分区了之后,只要访问某个分区就会很快。

这难道不是一种误导么?分区真的能这么简单就讲清楚吗?我觉得当然不是,所以本文的内容就是想说说我认为的,分区的重要和伟大之处。

早在公元前五百年,孙子就参透了数据库分区的真谛

一、数据库为什么要有分区?

在《孙子兵法》的第五篇 —《兵势篇》中,孙子曰:凡治众如治寡,分数是也。斗众如斗寡,形名是也。

说人话:凡是在管理很大的数据库表时就和管理小的数据库表时一样,把它分区就好了;发挥好所有分区的功能就和发挥好其中一个分区的功能一样,他们能有一个统一的表名,可以使用统一的 SQL 语句来调度就好了。

上面这段话,从分号隔开,可以分成上下两句。那么“伟大”是在于前半句还是后半句呢?显然是后半句。为啥?你把人分了容易,但是你要把茫茫多的已经分开的人,指挥得像一个人一样,这件事情就伟大了。

1、考虑隔离与瓶颈

好,先讨论上半句,分治的思想。我常常遇到这样的对话场景。

场景一:

对话者:“我们的数据太大了,我们分表吧!”

我:“为什么不用分区呢?”

对话者:“分区可以解决吗?”(请自己脑补不信任的眼神和质疑的语气)

场景二:

演讲者:“我们考虑用最先进的分库技术理念来解决这个瓶颈”。

众人投去了羡慕嫉妒而又膜拜的眼神,等待着大神讲出华丽又牛叉的方案。

我:“这里有个瓶颈,我们需要给这个表分区。”

众人轻视又不懈说,好的,那分一下吧。

其实无论是分区、分表还是分库,我们都需要围绕两个重要概念,一是隔离,一是瓶颈。

在场景一种,为什么使用者要求分表呢?常见的情况中,例如,我这两个表,虽然结构一样,但是我一个是北京的数据,一个是上海的数据。如果北京的数据坏了,或者,我在对北京的数据进行奇奇怪怪的操作的时候,我需要对上海的数据完全没有影响,这就是所谓隔离。

又比如,可能全国的数据放在一起量太大,交易量太多,出现了,磁盘、IO、网络、CPU等撑不住的情况,这就是所谓瓶颈。

分区、分表、分库满足的是不同的隔离级别,以及解决不同的瓶颈。但是,他们的思想是非常接近的。

2、Partition与Sharding

Sharding这个词(通常译为分片),可以说是自带高贵的属性。每当与人讨论数据库技术,一聊到Sharding,就有一种自然而然上档次的感觉。

而且,它有很多好朋友,说出来各个华丽无比,比如分布式、集群、大数据等等。

而Partition这个词,虽然从很多角度上来看,都很类似于Sharding,或者说它们都是从“分数是也”的理念而来。但就是感觉LOW。

为啥?按我的理解,因为Partition的实现是由DBMS来完成的,使用者没感觉。而Sharding往往需要程序,设计模式,乃至整个架构的设计围绕着它服务,十分有存在感。

那它们在实际运用的时候有区别吗?当然有!那么什么时候应该Sharding,什么时候应该Partition呢?

我个人觉得Sharding的使用有两种情况,第一种叫没钱的时候,第二种是Partition用到极致,也搞不定的时候。

那么Partition什么时候搞不定呢?又有两种,一种叫没钱的时候,第二种叫超过了当今世上的硬件极限(买最贵的设备都抗不住)的时候。

1)没钱的时候

我们细细思量可以发现,分库分表这个套路在什么数据库上用的范围最广?或者你在什么地方见得会比较多?我觉得通常会指到同一个地方,叫MySQL。

虽然它有各种各样华丽的马甲,比如腾讯的TDSQL。为什么要用MySQL?因为开源免费。什么?InnoDB也很强大?如果明天Oracle开源免费,你选型的时候还会选MySQL?

不扯远了,MySQL为啥有那么多分库分表呢?我认为真相只有这一个。因为5.1版之前,MySQL不支持分区。这就是我说的第一种情况,叫没钱的时候,Oracle、SQL Server、DB2我通通买不起。好了,下一个免费的MySQL,做分库分表。

抛开玩笑的内容,Partition确实有解决不掉瓶颈需要使用分库分表的时候。但是,一个成熟的数据库使用者不应该滥用分库分表。这就是所谓DBA界分库铁律第一条,我非常赞同,叫做:能不分,就不分。然后,说说,第二种,Partition用到了极致的场景。

2)超过当前硬件极限

简单的说,我买了个Oracle,但是我的系统TPS要1万。在X86上跑Oracle,撑不住怎么办?

那么出路两条,第一条,Exadata了解一下?IBM主机买一台?买不起,好,我们在MySQL,或者X86上用Oracle做分库分表,这就是第二类里面的没钱的时候。

还有一种就是Exadata、IBM主机撑不住,所谓超越了地球上科技产品的极限,反正我没见过。

3、分库、分表、分区的使用场景

看到这里,是不是觉得扯淡内容太多了。到底什么情况分区?什么情况分表?什么时候分库呢?还是那句话,第一看隔离级别,第二看瓶颈。前一段主要说的是瓶颈场景,那么从隔离级别上来看呢?

1)分库选择

两份结构一样的数据。但他属于两个客户,客户说,我有监管要求,我不能把数据和别人的数据放在一起,必须绝对的隔离,有严格的访问控制,别人根本不能有我的DB服务器的登陆权限。

这就要求,数据在数据库层面就完全的隔开,就可以用分库。

2)分表选择

如果说我是一个云提供商,两个客户都用我的客户,他们分别有自己的用户(Schema),他们允许和他人共用数据库服务器,但是,严禁其他人使用归属于他的数据库表。

那么这时候,可以分表。

3)分区选择

如果,两份数据要求简单的隔离,相互处理不影响就可以了,有时候,我还希望一个用户一条SQL,就能对比分析他们的差异。

那这时候,分区就是一个极佳的选择。

二、数字库分区的优势

接下来讲后半部分,斗众如斗寡,形名是也。

1、分区的同时处理掉技术关口

斗众如斗寡,这句话讲起来简单,实现起来可不是那么简单。在主流的DBMS里面,不同的分区意味着不同的对象(如Oracle中,不同的Segment,DB2分区表不同分区对应数据文件)。

不夸张的说,很多数据库中间件产品,在反复纠缠、实现的内容,其本身就是主流DBMS在分区时要处理掉的技术关口。

比如有:跨库的SQL重写,一个运行在分布式场景的SQL,需要被中间件重写成多个SQL,丢到多个库去执行。尤其是,跨库的连结、聚合(包括Max、Min、Sum、Count)。其实在多分区的时候,一样存在这样的问题。

如果说这个问题,不太容易被开发者所关注到。再举一个例子:全局/本地索引。

在DBMS中,全局索引通常是要在设计上有所回避的。一般数据表一旦分区,意味着数据量比较大。例如最常见的B树索引,全局索引意味索引层次多,查询速度慢。

但是当无论如何,我在查询时,无法送入分区KEY时,全局索引总归还是最后的选择。而在分布式场景里,没有分库KEY就会非常尴尬,要么查不了,要么就要遍历所有的库,这个代价几乎就是不可接受的。

2、分区与优化密不可分

分区和分库面临的很多问题都存在着巨大的相似之处,开发者总是会重视分库所面临问题和困难,然而普遍会轻视分区可能带来的副作用。

我常常被质问,数据多了,为什么不加分区!?并发有冲突,为什么不加分区!?程序速度慢了,为什么不加分区!?PS:这一系列的质问,同样适用于为什么不加索引系列。

这种轻视源自于,主流DBMS系统对分区功能的很好的支撑。作为DBA,比较害怕的是有人懂一点数据库,且特别自信的站在他自己立场来和我讨论。

有一些开发者传递给我一个理念,分区多比分区少要好。只要用了分区,就能更快,至少不可能更差!开发者在说起这些的时候,非常的自信。

其实,在我看来分区设计和查询优化是密切相关的。分区设计一定是与特定的查询场景匹配,才能达到好的结果。

比如之前提到的没有分区列送入的查询需要逐个遍历每个分区,再比如说Hash分区后的范围查找。

Oracle中索引的Hash分区,在大规模的高并发插入的数据库表上应用十分常见,因为这种场景非常容易产生冲突事件 ,使用Hash分区之后,可以极大的缓解。然而这也挖下了一个坑,那就是这个索引上的范围查找就变得不那么理想。

由此推论,分区上可以能遇到的大坑,其实在分库的场景同样使用。

比如说,做了分库,却发现交易的业务场景拿不到Sharding Key。采用了Hash的算法,算Sharding Key,又突然发现有个交易要范围查Sharding Key,以至于可能要去各个库兜一圈。

分区面对的坑,可以说在分库场景下,是急剧放大了。所以,不可以随意滥用分区,更加不可以随便乱分库。

3、容错率提高

反过来讲,我为何在开篇说分区十分伟大,尤其是Oracle。在你违背了种种优化原则之后,做了NPI,做了跨分区的JOIN等等。尽管有性能上的损失,无论如何,数据库都帮你把那些复杂的工作给完成了。

当你的需求不是实时响应时,这些奇奇怪怪的跨分区要解决的问题,Rdbms都还是透明的把这些工作给你做完了,这怎么能不说它是伟大的呢?这一点我想那些开发分布式数据库中间件的人,最能认同。

三、写在最后

最后写到这里,作为一个DBA,我特别希望给程序开发者传递一个理念,那就是这世界上一定没有一个完美的优化方案。

你要一个表,又能高并发插入,又能做各种各样高效的查询,一会范围,一会模糊。我只想说,这是不可能的。所有优化方案都是以牺牲某一种性能来换另一种性能。

而DBA的职责,就是搞清楚业务需要什么,不需要什么。牺牲掉不需要的功能,换取需要的功能,甚至于牺牲不常用的功能,换取优异的常用功能。这其实就是完美的方案,分区也不例外。

在本文的最后,我想留一个我一直困惑的问题。在我看了无数篇分库分表放在一起的文章和帖子之后,我开始怀疑人生了。

作者介绍 

宇文湛泉,现任金融行业核心业务系统DBA,主要涉及Oracle、DB2、Cassandra等数据库开发工作。

早在公元前五百年,孙子就参透了数据库分区的真谛


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learn Python 3 the Hard Way

Learn Python 3 the Hard Way

Zed A. Shaw / Addison / 2017-7-7 / USD 30.74

You Will Learn Python 3! Zed Shaw has perfected the world’s best system for learning Python 3. Follow it and you will succeed—just like the millions of beginners Zed has taught to date! You bring t......一起来看看 《Learn Python 3 the Hard Way》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具