一、业务场景

        1、当一张表进行水平分库分表之后,可能会影响已有产品功能,同时想要进行多张分表的搜索结果数据聚合在一起,在sql上会比较麻烦(只能不断 join),而且如果不知道分表的表名,业务sql书写上无法做到。

        2、数据库搭建好了完善的集群后,由于复杂度的上升,主从主备、读写分离、故障切换、心跳检测都是很繁杂的,能不能有种解决方案,能简单解决上述的各类繁杂问题。

        等等.....

二、解决方案

        引进数据库中间件,例如:Cobar、MyCat、Atlas、TDDL。

        (一)、定义

        数据库中间件:处于底层数据库和用户应用系统之间,主要用于屏蔽异构数据库的底层细节的中间件。是客户端与后台的数据库之间进行通信的桥梁。

        (二)、设计模式

        典型的数据库中间件设计模式有2种:服务端代理、客户端代理

        下图演示了这两种方案的架构:        

        1、服务端代理模式(server-proxy)

        我们独立部署一个代理服务,这个代理服务背后管理多个数据库实例。而在应用中,通过一个普通的数据源(c3p0、druid、dbcp等)与代理服务器建立连接,所有的sql操作语句都是发送给这个代理,由这个代理去操作底层数据库,得到结果并返回给应用。在这种方案下,分库分表和读写分离的逻辑对开发人员是完全透明的。

        这种模式下典型的中间件有:

  • 阿里开源的cobar(目前已经不再维护)

  • 在cobar基础上开发的mycat(持续更新中....)

  • mysql官方提供的mysql-proxy(目前已经不再维护)

  • 奇虎360在mysql-proxy基础开发的Atlas(只支持分表,不支持分库)

  • 当当网开源的sharing-sphere(持续更新中....)

        优点:

        1、多语言支持。不论你用的php、java或是其他语言,都可以支持。以mysql数据库为例,如果proxy本身实现了mysql的通信协议,那么你可以就将其看成一个mysql 服务器。mysql官方团队为不同语言提供了不同的客户端却动,如java语言的mysql-connector-java,python语言的mysql-connector-python等等。因此不同语言的开发者都可以使用mysql官方提供的对应的驱动来与这个代理服务器建通信。

        2、对业务开发透明。由于可以把proxy当成mysql服务器,理论上业务开发不需要进行太多代码改造,既可以完成接入。

        缺点:

        1、proxy本身需要保证高可用。由于应用本来是直接访问数据库,现在改成了访问proxy,意味着proxy必须保证高可用。否则,数据库没有宕机,proxy挂了,导致数据库无法正常访问,就尴尬了。 

        2、租户隔离。可能有多个应用访问proxy代理的底层数据库,必然会对proxy自身的内存、网络、cpu等产生资源竞争,proxy需要需要具备隔离的能力。

        2、客户端代理模式(client-proxy)

        业务代码需要进行一些改造,引入支持读写分离或者分库分表的功能的sdk。通常client-proxy是在连接池或者driver的基础上进行了一层封装,内部与不同的库建立连接。应用程序产生的sql交给代理层进行处理,其内部对sql进行必要的操作,例如在读写分离情况下,选择走从库还是主库;在分库分表的情况下,进行sql解析、sql改写等操作,然后路由到不同的分库,将得到的结果进行合并,返回给应用。

        这种模式下典型的中间件有:

  • 阿里开源的TDDL(目前已经不再维护)

  • 大众点评开源的zebra(目前已经不再维护)。

  • 当当网开源的sharding-jdbc,目前算是做的比较好的,文档资料比较全。

        优点:

        1、实现简单。proxy需要实现数据库的服务端协议,但是代理层不需要实现客户端通信协议。原因在于,大多数据数据库厂商已经针对不同的语言提供了相应的数据库驱动driver,例如mysql针对java语言提供了mysql-connector-java驱动。客户端的通信协议已经在driver层面做过了。因此通常只需要在此基础上进行封装即可。

        2、天然去中心化。smart-client的方式,由于本身以sdk的方式,被应用直接引入,随着应用部署到不同的节点上,且直连数据库,中间不需要有代理层。因此相较于proxy而言,除了网络资源之外,基本上不存在任何其他资源的竞争,也不需要考虑高可用的问题。只要应用的节点没有全部宕机,就可以访问数据库。(这里的高可用是相比proxy而言,数据库本身的高可用还是需要保证的)

        缺点:

        1、通常仅支持某一种语言。例如tddl、zebra、sharding-jdbc都是使用java语言开发,因此对于使用其他语言的用户,就无法使用这些中间件,除非开发多语言客户端。

        2、版本升级困难。因为应用使用数据源代理就是引入一个jar包的依赖,在有多个应用都对某个版本的jar包产生依赖时,一旦这个版本有bug,所有的应用都需要升级。而数据库代理升级则相对容易,因为服务是单独部署的,只要升级这个代理服务器,所有连接到这个代理的应用自然也就相当于都升级了。

三、部分中间件技术讲解

(一)Cobar

       Cobar 是由 Alibaba 开源的 MySQL 分布式处理中间件,Cobar是关系型数据的分布式处理系统,它可以在分布式的环境下像传统数据库一样为您提供海量数据服务。

        github地址:https://github.com/topics/cobar

        特点:

  • 解决了大数据量下的透明水平分表
  • 必须使用封装过的 MySQL 驱动包 Cobar Driver,无框架要求
  • 后端对 MySQL 是直接面向二进制协议的
  • 基于 LL(2) 手写的 SQL 解析器
  • 支持弱一致性事务(多库并行执行/提交)
  • 不支持跨库 join、分页、排序、子查询、读写分离
  • 在 MySQL 实例上没有 agent
  • MySQL 主从数据同步使用 MySQL 解决方案
  • 主异常时切换到从后主恢复,没有 failback,只能手动切换回主
  • 后端对 MySQL 有连接池
  • 支持跨地域

(二)MyCat

        官网:Mycat1.6        

        前身 Cobar,开源,较为活跃。

        特点:

  • 遵守Mysql原生协议,跨语言,跨数据库的通用中间件代理。
  • 基于心跳的自动故障切换,支持读写分离,支持 MySQL 一双主多从,以及一主多从
  • 有效管理数据源连接,基于数据分库,而不是分表的模式。
  • 基于 NIO 实现,有效管理线程,高并发问题。
  • 支持数据的多片自动路由与聚合,支持 sum , count , max 等常用的聚合函数。
  • 支持2表 join,甚至基于 caltlet 的多表 join。
  • 支持通过全局表,ER 关系的分片策略,实现了高效的多表 join 查询。
  • 支持多租户方案。
  • 支持分布式事务(弱xa)
  • 支持全局序列号,解决分布式下的主键生成问题。
  • 分片规则丰富,插件化开发,易于扩展。
  • 强大的 web,命令行监控。
  • 支持前端作为 MySQL 通用代理,后端 JDBC 方式支持 Oracle、DB2、SQL Server 、 mongodb 、巨杉。
  • 集群基于 ZooKeeper 管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。

        对比:开源的分布式数据库中间件系统Mycat和阿里巴巴Cobar的对比_许恒的博客-CSDN博客_cobar

(三)Atlas

        较为活跃,Atlas 是由 360 Web平台部基础架构团队开发维护的一个基于 MySQL 协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用 Atlas 运行的 MySQL 务,每天承载的读写请求数达几十亿条。

        官网:Apache Atlas – Data Governance and Metadata framework for Hadoop

        主要功能:
        1. 读写分离
        2. 从库负载均衡
        3. IP过滤
        4. SQL语句黑白名单
        5. 自动分表

(四)sharing-sphere

        Apache ShardingSphere 由 JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成。 它们均提供标准化的基于数据库作为存储节点的增量功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。

        官网:ShardingSphere

        手册:概览 :: ShardingSphere

四、结论

        每项数据库中间件都有自己的优势和特点,在做技术选型的时候,先结合实际业务场景需要确定采用哪种模式的中间件,再去选择哪个中间件技术更符合实际需求。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐