数据库中间件---详解
一、业务场景1、当一张表进行水平分库分表之后,可能会影响已有产品功能,同时想要进行多张分表的搜索结果数据聚合在一起,在sql上会比较麻烦(只能不断 join),而且如果不知道分表的表名,业务sql书写上无法做到。2、数据库搭建好了完善的集群后,由于复杂度的上升,主从主备、读写分离、故障切换、心跳检测都是很繁杂的,能不能有种解决方案,能简单解决上述的各类繁杂问题。等等.....二、解决方案引进数据库
一、业务场景
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 同构、异构语言、云原生等各种多样化的应用场景。
四、结论
每项数据库中间件都有自己的优势和特点,在做技术选型的时候,先结合实际业务场景需要确定采用哪种模式的中间件,再去选择哪个中间件技术更符合实际需求。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)