DB分库分表(三):使用框架还是自研以及分片实现层面的考虑分片方案的实现,目前在分片方面有很多开源框架和产品可以参考。同时,很多团队也会选择独立开发实现,无论是选择框架还是独立开发,都会面临一层分片逻辑的实现,本文将对这一系列问题进行分析和思考逐个。1.分片逻辑的实现层次从一个系统的程序架构来看,分片逻辑可以在DAO层、JDBCAPI层、DAO和JDBC之间的Spring数据访问封装层(各种spring模板)和中介层四个方面实现应用服务器和数据库之间的分片代理服务器级别。图1.Sharding实现级别和相关框架/产品在DAO层实现。当团队决定自己实现分片时,DAO层可能是最好的嵌入分片逻辑的地方,因为在这个层次上,每个DAO的方法都有明确的定义,知道需要访问的数据表和查询参数,并利用这些信息直接定位到目标分片,而不是像框架那样解析SQL,然后根据配置的规则进行路由。另一个优点是不受ORM框架的约束。由于现在大部分应用在数据访问层都依赖某种ORM框架,所以大多数shrading框架往往不能支持或者只能支持一种ORM框架,这极大地制约了框架的选择和应用。但是自己实现分片是没有问题的,甚至使用不同ORM框架的不同分片也可以相互协调协同工作。比如现在的Java应用大多使用hibernate,但是没有非常满意的基于hibernate的sharding框架(关于hibernatehards下面会介绍),所以很多团队会选择自己实现sharding。简单总结一下,在DAO层实现分片的优点是:不受ORM框架的限制,实现起来比较简单,容易根据系统特性灵活定制,不需要SQL解析和路由规则匹配,性能略好;缺点是:有一定的技术门槛,工作量比依靠框架实现要大(反之,框架会有学习成本),不通用,只能在特定系统下工作。当然,在DAO层,也可以通过XML配置或者注解,将分片逻辑“外”抽出来,形成一个通用的框架。但是,目前还没有出现这样的框架。在ORM框架层实现分片有两个方向。一种是在同时实现O-RMapping的前提下提供分片支持,定位为分布式数据访问框架。这类框架的代表是guzz的另一个方向是通过修改和增强现有的ORM框架来添加分片机制。该类型的代表产品是hibernateshard。应该说,随着hibernate的主流地位,业界迫切需要一个面向hibernate的sharding框架,但是从目前的hibernateshards来看,表现并不亮眼。满意,主要是它对hibernate的使用限制太多,比如它对HQL的支持非常有限。mybatis方面,目前还没有成熟的相关框架。有人提出利用mybatis的插件机制来实现分片,可惜mybatis的插件机制无法控制多数据源的连接层次。在mybatis框架上,目前还没有框架可以参考,团队可能要在DAO层或者Spring模板类上下功夫。在JDBCAPI层实现JDBCAPI层是很多人想到的最好的实现分片的地方。如果我们能够提供一个实现分片逻辑的JDBCAPI实现,那么分片将对整个应用程序是完全透明的。并且这样的实现可以直接用作通用的分片产品。但是这个方案的技术门槛和工作量显然是普通团队无法企及的,所以基本上没有团队会在这个层面上实现分片,更没有这样的开源产品。笔者知道目前只有一款商业产品dbShards采用了这种方案。在springd流行DAO和JDBC之间的Spring数据访问封装层的今天,java平台上构建的应用几乎没有不使用spring的。在DAO和JDBC之间,spring提供了各种模板来管理资源。事务的创建和发布以及与事务的同步,大部分基于spring的应用都会使用模板类作为数据访问的入口,这给了我们另外一个嵌入分片逻辑的机会,通过提供一个嵌入分片逻辑的模板类来完成分片工作。该方案的效果与基于JDBCAPI的方案基本一致。对上层代码也是透明的,在sharding改造时可以平滑过渡,但实现起来比基于JDBCAPI的方式简单,因此成为了很多框架的选择。阿里集团研究院开源的CobarClient就是这类方案的一个实现。通过代理在应用服务器和数据库之间添加代理。应用程序对数据发送的数据请求,首先会经过代理,代理根据配置??的路由规则解析SQL,路由到目标。Shard,因为这种方案对应用程序完全透明,通用性好,所以成为了很多分片产品的选择。这方面比较知名的产品有mysql官方的代理工具:MysqlProxy和一个国人开发的产品:amoeba。Mysql代理本身不实现任何分片逻辑。它只是mysql数据库的代理,为开发者提供了一个嵌入分片逻辑的地方。它使用lua作为编程语言,这是很多团队需要考虑的一个问题。amoeba是专门实现读写分离和分片的代理产品。使用非常简单,不使用任何编程语言,只需要通过xml进行配置即可。但是amoeba不支持事务(当应用程序发出的包含事务信息的请求到达amoeba时,事务信息会被抹掉,所以即使是单点数据访问也不会有事务)一直是硬伤。当然,这取决于产品的定位和设计理念。只能说阿米巴不适合对事务要求非常高的系统。2.使用框架还是自研?前面的讨论中已经列出了许多开源框架和产品。这里梳理一下:MySQLProxy和Amoeba是基于代理方式,HibernateShards是基于Hibernate框架。通过重写spring的ibatis模板类为CobarClient。这些框架中的每一个都有自己的优点和缺点。架构师可以根据项目的实际情况深入研究后进行选择,但总的来说,我对框架的选择持谨慎态度。一方面,大部分框架缺乏成功案例的验证,其成熟度和稳定性存疑。另一方面,一些成功商业产品的开源框架(比如阿里、淘宝的一些开源项目)是否适合你的项目,需要架构师深入研究分析。当然,最终的选择还要综合考虑项目特点、团队状态、技术门槛、学习成本等因素。
