数据库-数据库设计-分库分表

why分库分表

分库分表其实是解决海量数据存储、高并发查询和写的问题。解决这个问题还有其他的方案,但是使用场景不同,比如:

  • NosSql:比如Hbase,MongoDB,这些适合非结构化、不关心事务的场景,这时可以可以选择Nosql阵营的产品。
  • 关系型数据库:
    • 读写分离:读多写少模式,采用主从架构,根据qps的峰值和单台机器查询的性能确定数量。
    • 表分区:在表存储阶段进行存储,应用无感知,因为是在一个库内完成的操作,无法线性扩展,所以只能适应数据量不是特别大的case。

本章主要讨论关系型数据库的分库分表

  • 分表:单表瓶颈:单表数据过千万时,查询RT会升高,整体的QPS会下降,难以支撑高并发场景。
  • 分库:单库瓶颈:应用数变多,io,磁盘达到瓶颈,整体的QPS会下降,难以支撑高并发场景。

how分库分表

  • 水平切分与垂直切分

    • 垂直切分:垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。表的记录并不多,但是字段却很长,表占用空间很大,检索表的时候需要执行大量的IO,严重降低了性能。这时需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系。
      • 切分原则
        • 1,把不常用的字段单独放在一张表;,
        • 2,把text,blob等大字段拆分出来放在附表中;
        • 3,经常组合查询的列放在一张表中;
      • 优点
        • 数据库的拆分简单明了,拆分规则明确;
        • 应用程序模块清晰明确,整合容易;
        • 数据维护方便易行,容易定位;
      • 缺点
        • 部分表关联无法在数据库级别完成,需要在程序中完成;
        • 对于访问极其频繁且数据量超大的表仍然存在性能平静,不一定能满足要求;
        • 事务处理相对更为复杂;
        • 切分达到一定程度之后,扩展性会遇到限制;
        • 过读切分可能会带来系统过渡复杂而难以维护。
      • 备注:一定要在设计阶段就解决这个问题,时候的拆分成本代价较高
    • 水平切分:将一个表的记录水平分到多张表里面,下面会细说
  • 如何选择分库分表字段:

    • 充分的业务场景分析,找出使用频度最高的字段。
    • 常见的有卖家id、买家id、订单id、商户id、业务id、时间
  • 分库分表水平切分的策略:确定分表字段后,要确定如何按照字段去分,常见算法分区、取模、数据路由表

    • 按照时间分区
      • 原理:将一定区间内的数据放到一张表,多个表在一个库里面
      • 案例:具体用哪一种,需要根据数据量进行评估
        • 按照日分
          每日1张表,当单库超过100张表的时候,分到下一个库。
          算法:库ID=(当前日期-上线日期)/100 表ID=业务表_yyyyMMdd
        • 按照月分
          业务表_yyyyMM
        • 按照年分
          业务表_yyyy
    • 先hash,后取模
    • 直接取模
    • 范围分表
      • 比如四张表,每个表只存1000w,第一个表存1-1000w,第四张表存储3001-4000w

带来的问题&解决的办法

事物都具有两面性,分库分表固然解决了高并发存储的问题,但是也带来了一些后遗症

  • 全局主键问题
  • 多种查询维度的问题:比如订单表,既要通过买家id来查,又要通过卖家id来查,这时sharding column就矛盾了。怎么解决呢?
    • 数据冗余:上面的例子,可以冗余两张表,分别是买家和卖家表。牺牲存储来换查询复杂度
    • 表替代索引:数据冗余适合查询维度较少的场景,如果多了,数据冗余量太大,就不再是合理的方案了,表替代索引法
    • 全局存储搜索法:通过搜索引擎的方式存储和查询,比如数据同步到ES上。
      • 分库分表+es的方案,随着数据量越来越来,虽然分库分表可以继续成倍扩容,但是这时候压力又落到了es这里,这个架构也会慢慢暴露出问题!
        一般订单表,积分明细表等需要分库分表的核心表都会有好几十列,甚至上百列(假设有50列),但是整个表真正需要参与条件索引的可能就不到10个条件(假设有10列)。这时候把50个列所有字段的数据全量索引到es中,对es集群有很大的压力,后面的es分片故障恢复也会需要很长的时间。
        这个时候我们可以考虑减少es的压力,让es集群有限的资源尽可能保存条件检索时最需要的最有价值的数据,即只把可能参与条件检索的字段索引到es中,这样整个es集群压力减少到原来的1/5(核心表50个字段,只有10个字段参与条件),而50个字段的全量数据保存到HBase中,这就是经典的es+HBase组合方案,即索引与数据存储隔离的方案。
        Hadoop体系下的HBase存储能力我们都知道是海量的,而且根据它的rowkey查询性能那叫一个快如闪电。而es的多条件检索能力非常强大。这个方案把es和HBase的优点发挥的淋漓尽致,同时又规避了它们的缺点,可以说是一个扬长避免的最佳实践。
        它们之间的交互大概是这样的:先根据用户输入的条件去es查询获取符合过滤条件的rowkey值,然后用rowkey值去HBase查询,后面这一查询步骤的时间几乎可以忽略,因为这是HBase最擅长的场景

业界知名中间件产品和优劣对比

  • 阿里的TDDL,DRDS和cobar,
  • 开源社区的sharding-jdbc(3.x已经更名为sharding-sphere);
  • 民间组织的MyCAT;
  • 360的Atlas;
  • 美团的zebra;

扩容

分布式事务

原文地址:https://www.cnblogs.com/xiaogangfan/p/11173388.html