每天进步一点点(20201029) - 分库分表


带着问题去学习,让记忆更深的。今天学习工作中可能会遇到的分库分表,通过如下问题来学习记忆相关知识点。

1.什么是分库分表?

分库分表是为了解决由于库、表数据量过大,而导致数据库性能持续下降的问题。按照一定的规则,将原本数据量大的数据库拆分成多个单独的数据库,将原本数据量大的表拆分成若干个数据表,使得单一的库、表性能达到最优的效果(响应速度快),以此提升整体数据库性能。
分库 和 分表 是两个概念,但分库一定伴随着分表。

2.在什么情况下分库分表?

根据阿里推出的java开发手册中,推荐单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。
说明: 如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

3.分库分表有哪些框架,如何选择?

分库分表的技术方案总体上来讲分为两大类:应用层依赖类中间件中间层代理类中间件

应用层依赖类中间件

这类分库分表中间件的特点就是和应用强耦合,需要应用显示依赖相应的jar包(以Java为例),比如知名的TDDL、当当开源的sharding-jdbc、蘑菇街的TSharding、携程开源的Ctrip-DAL等。

此类中间件的基本思路

就是重新实现JDBC的API,通过重新实现DataSource、PrepareStatement等操作数据库的接口,让应用层在基本(注意:这里用了基本)不改变业务代码的情况下透明地实现分库分表的能力。

中间件给上层应用提供熟悉的JDBC API,内部通过sql解析、sql重写、sql路由等一系列的准备工作获取真正可执行的sql,然后底层再按照传统的方法(比如数据库连接池)获取物理连接来执行sql,最后把数据结果合并处理成ResultSet返回给应用层。

优点

就是无需额外部署,只要和应用绑定一起发布即可

缺点

就是不能跨语言,比如Java写的sharding-jdbc显然不能用在C#项目中,所以携程的dal也要重新写一套C#的客户端

中间层代理类中间件

核心原理是在应用和数据库的连接之间搭起一个代理层,上层应用以标准的MySQL协议来连接代理层,然后代理层负责转发请求到底层的MySQL物理实例,这种方式对应用只有一个要求,就是只要用MySQL协议来通信即可,所以用MySQL Workbench这种纯的客户端都可以直接连接你的分布式数据库,自然也天然支持所有的编程语言。比较有代表性的产品有开创性质的Amoeba、阿里开源的Cobar、社区发展比较好的Mycat 等。

sharding-jdbc

sharding-jdbc 是一款轻量级 Java 框架,以 jar 包形式提供服务,是属于客户端产品不需要额外部署,相当于是增强版的 JDBC 驱动;相比之下像 Mycat 这类需要单独的部署服务的服务端产品,就稍显复杂了。

  • sharding-jdbc的兼容性也非常强大,适用于任何基于 JDBCORM 框架,如:JPAHibernateMybatisSpring JDBC Template 或直接使用的 JDBC
  • 完美兼容任何第三方的数据库连接池,如:DBCPC3P0BoneCPDruidHikariCP 等,几乎对所有关系型数据库都支持。

相比较之下sharding-jdbc是比较强大的一款工具,而且它对项目的侵入性很小,几乎不用做任何代码层的修改,也无需修改 SQL 语句,只需配置待分库分表的数据表即可。可以让开发者更多精力放在实现业务,不想做额外的运维工作。

4.如何分库分表,有哪些注意项?

分库分表的核心理念就是对数据进行切分(Sharding),以及切分后如何对数据的快速定位与查询结果整合。而分库与分表都可以从:垂直(纵向)和 水平(横向)两种纬度进行切分。

在这里插入图片描述

5.分库分表难点

分布式事务、分页、排序、联查、分布式主键、读写分离