如果对松鼠的文章感兴趣也可以关注我的公众号:松鼠技术站

分库分表与读写分离

说到分库分表,我们不得不介绍另一个解决数据访问瓶颈的技术体系:读写分离

这个技术与数据库的从属架构有关。我们知道像MySQL这样的数据库提供了完善的主从架构,能够确保主数据库与数据库之间的数据同步。基于主从架构,就可以按照操作要求对读操作和写操作进行分离,从而就可以提高访问效率。读写分离的基本原理是这样的:
我们可以看到图中的数据库集群中存在一个主库,也存在一个从库,主库和从库之间通过同步机制实现两者数据的一致性。在互联网系统中,普遍认为对数据库读操作的频率要远远高于写操作,所以瓶颈往往出现在读操作上。通过读写分离,就可以把读操作分离出来,在独立的从库上进行。现实中的主从架构,主库和从库的数量,尤其从库的数量都是可以根据数据量的大小进行扩充的。

读写分离,主要解决的就是高并发下的数据库访问,也是一种常用的解决方案。但是跟提升服务器配置一样,并不是终极解决方案。终极的解决方案还是前面介绍的分库分表,按照用户 ID 等规则来拆分库或拆分表。但是,请注意,分库分表与读写分离之间的关系并不是互斥的,而是可以相辅相成的,完全可以在分库分表的基础上引入读写分离机制:

分库分表解决方案

基于前面对分库分表的讨论,我们可以抽象其背后的一个核心概念,即分片(Sharding)。

因为无论是分库还是分表,都是把数据划分成不同的数据片,并存储在不同的目标对象中。而具体的分片方式涉及到实现分库分表的不同解决方案。

针对我们上一篇文章讨论的问题,实际上已经有很多分库分表的框架已经解决的很好了,显然这些框架并不是采用的同一种解决方案。但通过分析这些框架在实现数据分片的方案上的区别,也可以把它们分成三大类型,即客户端分片、代理服务器、分布式数据库

接下来,我们就通过了解这三种方案的原理,来看看它们是怎么解决分库分表的问题吧!

1.客户端分片

客户端分片,就是相当于在数据库的客户端就实现了分片规则。这种方式将分片处理的工作进行前置,客户端管理和维护着所有的分片逻辑,并决定每次SQL执行所对应的目标数据库和数据表。

客户端分片这一解决方案也有不同的表现形式,其中最为简单的方式就是应用层分片,也就是说在应用程序中直接维护着分片规则和分片逻辑:

在具体实现上,通常会将分片规则的处理逻辑打包成一个公共 JAR 包,其他业务开发人员只需要在代码工程中引入这个 JAR 包即可。针对这种方案,因为没有独立的服务器组件,所以也不需要专门维护某一个具体的中间件。然而,这种直接在业务代码中嵌入分片组件的方法也有明显的缺点:

  • 一方面,由于分片逻辑侵入到了业务代码中,业务开发人员在理解业务的基础上还需要掌握分片规则的处理方式,增加了开发和维护成本;
  • 另一方面,一旦出现问题,也只能依赖业务开发人员通过分析代码来找到原因,而无法把这部分工作抽离出来让专门的中间件团队进行完成。

基于以上分析,客户端分片在实现上通常会进一步抽象,把分片规则的管理工作从业务代码中剥离出来,形成单独演进的一套体系。这方面典型的设计思路是重写 JDBC 协议,也就是说在 JDBC 协议层面嵌入分片规则。这样,业务开发人员还是使用与 JDBC 规范完全兼容的一套 API 来操作数据库,但这套 API 的背后却自动完成了分片操作,从而实现了对业务代码的零侵入:

这种解决方案的优势在于,分片操作对于业务而言是完全透明的,从而一定程度上实现业务开发人员与数据库中间件团队在职责上的分离。这样,业务开发人员只需要理解 JDBC 规范就可以完成分库分表,开发难度以及代码维护成本得到降低。

2.代理服务器分片

代理服务器分片的解决方案也比较明确,就是采用了代理机制,在应用层之后,就可以把分片规则集中维护在这个代理层中,并对外提供与JDBC兼容的API给到应用层。这样,应用层的业务开发人员就不用关心具体分片规则,而只要完成业务逻辑实现,如图为代理服务器的分片结构:

代理服务器分片的优点在于解放了业务开发人员对分片规则的管理工作,而缺点就是添加了一层代理层,所以天生具有代理机制所带来的一些问题,比方说因为新增了一层网络传输对性能所产生的影响。

3.分布式数据库

相信大家像松鼠一样,听到过很多分布式相关的东西,分布式的出现,就是为了解决大数据量,高并发的数据处理。因为在技术发展和演进的过程中,关系型数据库的一大问题在于缺乏分布式特性,也就是说缺乏分布式环境下面对大数据量、高并发访问的有效数据处理机制。举例来说,我们知道事务是关系型数据库的本质特征之一,但在分布式环境下,如果想要基于 MySQL 等传统关系型数据库来实现事务将面临巨大的挑战。

幸好,以 TiDB 为代表的分布式数据库的兴起赋予了关系型数据库一定程度的分布式特性。在这些分布式数据库中,数据分片及分布式事务将是其内置的基础功能,对业务开发人员是透明的。业务开发人员只需要使用框架对外提供的 JDBC 接口,就像在使用 MySQL 等传统关系型数据库一样。使用工具往往比较容易,但理解内涵往往需要花费很多时间和精力,松鼠也在继续学习的路上。

有的伙伴可能不是很理解集群、分布式,分布式集群的概念,在松鼠的的文章里已经整理过了(《形象理解集群、分布式、分布式集群的概念》),感兴趣的伙伴,可以去看看。

一款优秀的分库分表开源框架

前面说了为何要分库分表、如何分库分表,以及分库分表需要解决的问题。那么接下来就是介绍一个开源的框架,松鼠介绍它的原因其实就摆在了标题上,优秀,又免费学习(咳咳,主要是木有钱)。

像前面提到的客户端分片结构,典型的中间件包括阿里巴巴的TDDL,但是它并没有开源,所以我们根本无法知道它究竟是如何实现的客户端分片。

那么这个分布式数据库中间件 ShardingSphere,是你学习的不二选择,松鼠觉得有很多原因吧,首先开源,然后分库分表的三种解决方案,它都是有体现的。

为了显得严谨一点,我将它的优点列出来:

技术权威性,是 Apache 基金会历史上第一个分布式数据库中间件项目,代表着这一领域的最新技术方向;

解决方案完备性,它集客户端分片、代理服务器,以及分布式数据库的核心功能于一身,提供了一套适用于互联网应用架构、云服务架构的,完整的开源分布式数据库中间件解决方案和生态圈。

开发友好性,提供了友好的集成方式,业务开发人员只需要引入一个 JAR 包就能在业务代码中嵌入数据分片、读写分离、分布式事务、数据库治理等一系列功能。

可插拔的系统扩展性:它的很多核心功能均通过插件的形式提供,供开发者排列组合来定制属于自己的独特系统。

这些优秀的特性,让 ShardingSphere 在分库分表中间件领域占据了领先地位,并被越来越多的知名企业(比如京东、当当、电信、中通快递、哔哩哔哩等)用来构建自己强大而健壮的数据平台。

说了这么多,实际上学习起来并没有那么容易,也需要由浅入深的学习。

不用担心,松鼠也才刚刚起步,后面会将自己的学习笔记和学习经历分享出来。

当然听到松鼠给大家分享的框架,也可以自己去主动学习然后和我探讨。

如果有大牛学习过了,还希望能留言宝贵的建议。

文章部分来源于:拉钩教育网