背景
什么情况下需要分表?这里归纳了3点:
(1)某个表被操作的频率过于频繁的时候(可以查看某个表的访问频繁),在流量越来越大的时,可以考虑分表。
(2)某个表的数据量过于庞大的时候(我给自己设置的底限是1千万)。
(3)单行数据的某几个字段位高频访问的字段。
水平分表
按哈希切分
通过某个唯一键(如雪花算法生成的值),除以分表数量后取余。比如我分了16个表,在新来数据后,我得到某个唯一值为1。接着,1除以16取余后,得到16,将该数据插入16号表。
缺点:这种方式一般需要预设好分表的数量,如果是需要动态增加分表数量的场景,那就麻烦了,需要将数据重新哈希了。
按时间切分
采取按时间切分的策略,在需要动态增加表数量的场景是比较适合的。比如按月份分表,将当前月的数据放置于同一张表中,然后设置一个定时任务,在下一个月到来之前预先创建好表。
垂直分表
某些场景下,我们的表数据可能不多,但列数据却非常多,我就见过有100多个字段的表设计。而以MySQL为例,页是InnoDB磁盘管理的最小单位,默认大小为16KB。
虽然可以通过参数innodb_page_size来设置
但即使如此,也有可能会引起数据的跨页存储,这会造成数据库额外的性能开销,而垂直分表可以解决这个问题,这是其一。
其二,如果只某几列的数据是操作频繁的,也就是我们说的热点数据,那通过垂直分表,将冷热数据分离,也是一种提高效率的手段。
中间件
在真正的业务实践中,可能更多的人倾向于使用中间件来达到分表的效果。于是总结了一些中间件的的特性,它们大致可以两种模式划分,即CLIENT模式和PROXY模式。
PROXY模式下,相当于把中间件作为一个独立的服务了,它将接收到的SQL 语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
CLIENT模式下,中间件在Driver或者连接池的基础之上,增加了一层封装。我们使用时,以Java开发为例,需要先引入一个jar包。中间件接收持久层产生的sql,同样对sql进行分析等操作,然后才落实到具体的库上。
具体的中间件可以归纳为如下两大类:
client模式
TDDL(taobao)
淘宝根据自己的业务特点开发了TDDL(Taobao Distributed Data Layer )框架,主要解决了分库分表对应用的透明化以及异构数据库之间的数据复制。
sharding-jdbc(apache)
据官网描述,定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。
zebra(美团点评)
Zebra是一个基于JDBC API协议上开发出的高可用、高性能的数据库访问层解决方案,是美团点评内部使用的数据库访问层中间件。
zdal(支付宝)
Zdal是支付宝自主研发的数据中间件产品,也是采用标准的JDBC规范。Zdal主要提供分库分表,结果集合并,sql解析,数据库failover动态切换等功能,提供互联网金融行业的数据访问层统一解决方案,目前已经在支付宝的交易,支付,会员,金融等大部分关键应用上使用,并且在2013年双11大促中运行稳定。
proxy模式
mysql-proxy
mysql-proxy是mysql官方提供的mysql中间件服务,上游可接入若干个mysql-client,后端可连接若干个mysql-server。很多中间件都基于它进行了魔改。
cobar(Alibaba)
Cobar 是由 Alibaba 开源的 MySQL 分布式处理中间件,它可以在分布式的环境下看上去像传统数据库一样提供海量数据服务。不过最近的一次维护也是两年前的事了。
mycat
mycat是在cobar基础上研发出来的,对 cobar 的代码进行了彻底的重构,使用 NIO 重构了网络模块,并且优化了 Buffer 内核,增强了聚合,Join 等基本特性,同时兼容绝大多数数据库成为通用的数据库中间件。
drds
阿里云分布式关系型数据库服务 Distributed Relational Database Service ,前身是 TDDL。似乎现在又升级了变为PolarDB-X,具体看看他们的文档了。
sharding-sphere
Apache ShardingSphere 是一套开源的分布式数据库解决方案组成的生态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成。
atlas
Atlas 是由 360 Web平台部基础架构团队开发维护的一个基于 MySQL 协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用 Atlas 运行的 MySQL 务,每天承载的读写请求数达几十亿条。
heisenberg
百度的熊照大佬编写的一款基于MySQL协议之上的分库分表中间件服务器,支持各种灵活(velocity脚本自定义)的分库分表规则,做到应用和分库分表相隔离。
Oceanus
58同城数据库中间件,按其官方的描述,致力于打造一个功能简单、可依赖、易于上手、易于扩展、易于集成的解决方案,甚至是平台化系统。文档链接如下:
Vitess
Vitess一直为YouTube所有的数据库提供服务,据其官方描述,它是一款用于部署、扩展和管理大型MySQL实例集群的数据库解决方案。
OneProxy
OneProxy是由原支付宝首席架构师楼方鑫大佬开发,保留了 MySQL-Proxy 0.8.4官方版本上其协议处理和软件框架,然后对软件做了大量优化,极大增强了系统的并发能力。