冗余关系表:只有一个sharding column的分库分表的数据是全量的,其他分库分表只是与这个sharding column的关系表。实际使用中可能会冗余更多常用字段,如用户名称、商户名称等。
冗余全量表 VS 冗余关系表
速度对比:冗余全量表速度更快,冗余关系表需要二次查询,即使有引入缓存,还是多一次网络开销;
存储成本:冗余全量表需要几倍于冗余关系表的存储成本;
维护代价:冗余全量表维护代价更大,涉及到数据变更时,多张表都要进行修改。
总结:选择冗余全量表还是索引关系表,这是一种架构上的trade off(权衡),两者的优缺点明显,阿里的订单表是冗余全量表。
(3)单个sharding column分库分表示例(账户表)
一般账户相关API使用account_no为sharding column
(4)多个sharding column分库分表示例(用户表)
用户可以通过mobile_no,email和username进行登录,一些用户相关API又常使用user_id,所以sharding column选这4个字段。
(5)sharding column分库分表 + ES检索(模糊查询)
上面提到的都是条件中有sharding column的SQL执行。但是,总有一些查询条件是不包含sharding column的,同时,我们也不可能为了这些请求量并不高的查询,无限制的冗余分库分表。那么这些查询条件中没有sharding column的SQL怎么处理?以sharding-jdbc为例,有多少个分库分表,就要并发路由到多少个分库分表中执行,然后对结果进行合并。这种条件查询相对于有sharding column的条件查询性能很明显会下降很多。
更有甚者,尤其是有些运营系统中的模糊条件查询,或者上十个条件筛选。例如淘宝我的所有订单页面,筛选条件有多个,且商品标题可以模糊匹配,这即使是单表都解决不了的问题,更不用谈分库分表了。
sharding column + es的模式,将分库分表所有数据全量冗余到es中,将那些复杂的查询交给es处理。(ElasticSearch,搜索引擎)以订单表为例:
PS:多sharding column不到万不得已的情况下***不要使用,建议采用单sharding column + es的模式简化架构。
5.全文索引思路(HBase)
Solr+HBase
ES+HBase
可能参与条件检索的字段索引到ES中,所有字段的全量数据保存到HBase中,这就是经典的ES+HBase组合方案,即索引与数据存储隔离的方案。Hadoop体系下的HBase存储能力我们都知道是海量的,而且根据它的rowkey查询性能那叫一个快如闪电。而es的多条件检索能力非常强大。这个方案把es和HBase的优点发挥的淋漓尽致,同时又规避了它们的缺点,可以说是一个扬长避免的***实践。
它们之间的交互大概是这样的:先根据用户输入的条件去es查询获取符合过滤条件的rowkey值,然后用rowkey值去HBase查询,后面这一查询步骤的时间几乎可以忽略,因为这是HBase最擅长的场景,交互图如下所示:
6.总结
最后,对几种方案总结如下(sharding column简称为sc):
对于海量数据,且有一定的并发量的分库分表,绝不是引入某一个分库分表中间件就能解决问题,而是一项系统的工程。需要分析整个表相关的业务,让合适的中间件做它最擅长的事情。例如有sharding column的查询走分库分表,一些模糊查询,或者多个不固定条件筛选则走es,海量存储则交给HBase。
做了这么多事情后,后面还会有很多的工作要做,比如数据同步的一致性问题,还有运行一段时间后,某些表的数据量慢慢达到单表瓶颈,这时候还需要做冷数据迁移。
MySQL单表可以存储10亿级数据,只是这时候性能比较差,业界公认MySQL单表容量在1KW以下是***状态,因为这时它的BTREE索引树高在3~5之间。
参考文档:
分库分表技术演进&***实践-修订篇