1.前言随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大。相应的,数据操作的开销也会增加;此外,无论硬件资源如何升级,单台服务器的资源(CPU、磁盘、内存、网络IO、事务数、连接数)始终是有限的,最终数据库能够处理的数据量承载和数据处理能力会遇到瓶颈。分表分库,读写分离,有效降低单个数据库的压力。而数据库中间件也流行了很久,基本上每个大厂都会自己开发一套。本文主要对比业界主流数据库中间件的实现、功能、成本,总结数据库中间件的实现方式,展望未来可能的发展。2.实现方法数据库中间件一般可以分为以下六个层次。2.1代码层在同一个项目中创建多个数据源,在代码中直接使用ifelse根据条件进行路由。Spring中有一个动态切换数据源的抽象类,详见AbstractRoutingDataSource。如果项目不是很大,用这个方法可以快速分库。但缺点也很明显。这种大规模的代码入侵是绝对不能接受的。而且在返回查询结果时,还需要对跨库、聚合等查询结果进行合并,开发工作量非常巨大。这个方法够了解的,一般不会去用。2.2框架层主要是修改或增强现有ORM框架的功能,在SQL中添加一些自定义原语或提示来实现。常见的包括实现一些拦截器(比如Mybatis的Interceptor接口),添加一些自定义的分析来控制数据的流向。虽然效果更好,但是会改变一些已有的编程经验。这种情况适用于公司统一的ORM框架,但在很多情况下并不现实。而且大多数情况下需要修改框架的源码,所以不推荐。2.3驱动层无论是从代码层还是框架层处理,都是侵入性强,维护难度大。所以,普通的数据库中间件至少要从驱动层开始,我们可以理解为智能客户端。智能客户端是什么意思?通常smart-client是在连接池或者驱动的基础上再封装一层。这个智能客户端可以在内部与不同的数据库建立连接。业务需要查询的sql交给smart-client进行分析和优化,然后发送到具体的数据库进行操作。比如在读写分离的情况下,smart-client会选择sql是从数据库走还是从主库走;在分库分表的情况下,进行sql解析、sql重写等操作,然后路由到不同的分库,将得到的结果合并返回给应用程序。我们熟悉的TDDL、Sharding-JDBC等,都是在这一层切入。优点:1)易于实现,无业务侵入。smart-client不需要实现客户端通信协议,只需要封装在数据数据库厂商提供的不同语言的数据库驱动上即可。例如mysql为java语言提供了mysql-connector-java驱动,为python提供了mysql-connector-python驱动。2)自然去中心化。smart-client由应用以SDK的形式引入,然后部署到不同的服务节点,不需要代理层proxy。因此,与代理方式相比,无需考虑高可用的问题。只要所有的应用节点都没有宕机,就可以访问数据库。(这里的高可用是相对于proxy层proxy来说,数据库本身的高可用还是需要保证的。)缺点:1)通常只支持某种语言。比如tddl、zebra、sharding-jdbc都是java语言开发的,所以使用其他语言的用户是无法使用这些中间件的。如果要用其他语言,那就要开发多语言的客户端。2)版本升级困难。因为一个应用程序使用数据源代理引入了对jar包的依赖。当多个应用程序依赖某个版本的jar包时,一旦该版本出现bug,则需要对所有应用程序进行升级。数据库代理的升级比较容易,因为服务是单独部署的,只要升级代理服务器,所有连接到代理的应用自然都会升级。3)去中心化的缺点,比如不能做全局sql限流2.4代理层在应用中,我们通过一个通用的数据源(c3p0、druid、dbcp等)与代理服务器建立连接,所有的sql操作语句被发送给代理,代理操作底层数据库,得到结果返回给应用程序。在该方案下,分库分表、读写分离的逻辑对开发者是完全透明的。像MySQLRouter、MyCat、ShardingSphere(代理模式)等,都是切入这一层。优点:1)多语言支持。也就是说,不管你用什么php、java或者其他语言,都可以支持。以mysql数据库为例,如果proxy本身实现了mysql通信协议,那么就可以把它看成一个mysql服务器,这样不同语言的开发者就可以使用mysql官方提供的相应驱动来与proxy一起搭建服务器。沟通。2)对业务发展学生保持透明。由于proxy可以看成是一个mysql服务器,理论上业务同学不需要做太多的代码修改就可以完成访问。缺点:1)实现复杂。因为代理需要实现被代理数据库服务器的通信协议,所以实现起来比较困难。2)代理本身需要保证高可用。由于应用原来直接访问数据库,现在改为访问代理,也就是说代理必须保证高可用。不然数据库没宕机,代理宕机了,导致数据库无法正常访问,尴尬。3)租户隔离。可能有多个应用访问代理的底层数据库,这必然会造成代理自身内存、网络、CPU等的资源竞争,代理需要具备隔离的能力。2.5SidecarSharding-Sidecar是ShardingSphere的第三款产品,目前还在规划中。定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的形式代理所有对数据库的访问。通过非中心化、零侵入的方案提供与数据库交互的网格化层,即DatabaseMesh,也称为数据网格。DatabaseMesh的重点是如何将分布式数据访问应用程序和数据库有机地连接起来。它更注重交互,就是有效梳理杂乱的应用程序和数据库之间的交互。使用DatabaseMesh,访问数据库的应用程序和数据库最终将形成一个巨大的网格系统。应用程序和数据库只需要在网格系统中注册。它们都是由网格化层管理的对象。优势:分布式云原生数据库中间件模型融合了jdbc和proxy各自的优势,可以满足高可用、跨语言、无感知升级等多种优势。缺点:需要整体架构支持云原生系统。在线的。2.6存储层这一层其实不应该叫数据库中间件,需要换存储。比如Aurora、polardb、tidb等分布式数据库,通过计算节点和存储节点的分离,计算节点向上扩展,存储节点向外扩展的理念,将公有云关系型数据库产品推向了一个新的高度。这样一来,传统的数据库中间件就不用了,所有的问题自然也就烟消云散了。3.功能对比从上面可以看出,目前最主流的数据库中间件主要是从驱动层smart-client和代理层proxy切入的。下面我们就来看看这两个层面的业界主流中间件产品的现状和功能对比。其他还有:Atlas、Kingshard、DBProxy、mysqlrouter、MaxScale、58Oceanus、ArkProxy、携程DAL、Tsharding、Youtubevitess、网易DDB、Heisenberg、proxysql、Mango、DDAL、Datahekr、MTAtlas,大家可以看到,基本都是主要的制造商已经经历了他们自己的中间件产品。不过目前开源的比较流行的并不多,shardingsphere是主要的。下面我们从功能维度来比较几款产品。4、展望从上面的分析可以看出,虽然目前主流的数据库中间件还是在smart-client和proxy两个层面进行处理,但是未来的方向已经可以预见。随着云原生的到来,数据库中间件也将迎来变革。一方面,作为sidecar模型,可能会有一个新的阶段,比如shardingsphere推出sidecar模型之后。另一方面,云数据库通过计算与存储分离的全新架构,打破了传统关系型数据库的性能瓶颈。传统的数据库中间件将不再需要关注,一切都将以数据库基础设施的形式提供给用户。
