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


    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;

    扩容

    分布式事务

  • 相关阅读:
    二、项目和框架矩阵
    一、PowerDesigner概述(系统分析与建模)
    Visual Studio Code 常用插件整理
    IntelliJ IDEA 显示行号
    IntelliJ IDEA 常用快捷键
    MyEclipse中常用的快捷键
    使用Oracle数据库,对某个表频繁更新
    更改MyEclipse中的src目录的浏览方式
    nginx最大并发连接数的思考:worker_processes、worker_connections、worker_rlimit_nofile
    Nginx性能优化
  • 原文地址:https://www.cnblogs.com/xiaogangfan/p/11173388.html
Copyright © 2020-2023  润新知