分布式数据库:如何正确选择分片键?

分布式数据库:如何正确选择分片键?

我们知道分布式数据库是将数据打散到不同节点上存储,从而提升性能与可靠性。那么今天我们来看看在分布式数据库中,一个非常重要的设计:正确地把数据分片,充分发挥分布式数据库架构的优势。

选出分片键

在对表中的数据进行分片时,首先要选出一个分片键(Shard Key),即用户可以通过这个字段进行数据的水平拆分。

对于我们之前使用的电商业务的订单表orders,其表结构如下所示:

CREATE TABLE `orders` ( `O_ORDERKEY` int NOT NULL, `O_CUSTKEY` int NOT NULL, `O_ORDERSTATUS` char(1) NOT NULL, `O_TOTALPRICE` decimal(15,2) NOT NULL, `O_ORDERDATE` date NOT NULL, `O_ORDERPRIORITY` char(15) NOT NULL, `O_CLERK` char(15) NOT NULL, `O_SHIPPRIORITY` int NOT NULL, `O_COMMENT` varchar(79) NOT NULL, PRIMARY KEY (`O_ORDERKEY`), KEY `idx_custkey_orderdate` (`O_CUSTKEY`,`O_ORDERDATE`), KEY `ORDERS_FK1` (`O_CUSTKEY`), KEY `idx_custkey_orderdate_totalprice` (`O_CUSTKEY`,`O_ORDERDATE`,`O_TOTALPRICE`), KEY `idx_orderdate` (`O_ORDERDATE`), KEY `idx_orderstatus` (`O_ORDERSTATUS`), CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`O_CUSTKEY`) REFERENCES `customer` (`C_CUSTKEY`)) ENGINE=InnoDB

对于类似淘宝、京东、拼多多这样业务体量的应用来说,单实例 MySQL 数据库在性能和存储容量上肯定无法满足“双 11、618 ”大促的要求,所以要改造成分布式数据库架构。

而第一步就是要对表选出一个分片键,然后进行分布式架构的设计。

对于上面的表orders,可以选择的分片键有:o_orderkey、o_orderdate、也可以是o_custkey。在选出分片键后,就要选择分片的算法,比较常见的有 RANGE 和 HASH 算法。

JAVA日知录写代码的架构师,做架构的程序员! 实战、源码、数据库、架构…只要你来,你想了解的这里都有!203篇原创内容

公众号

比如,表 orders,选择分片键 o_orderdate,根据函数 YEAR 求出订单年份,然后根据RANGE 算法进行分片,这样就能设计出基于 RANGE 分片算法的分布式数据库架构:

从图中我们可以看到,采用 RANGE 算法进行分片后,表 orders 中,1992 年的订单数据存放在分片 1 中、1993 年的订单数据存放在分片 2 中、1994 年的订单数据存放在分片 3中,依次类推,如果要存放新年份的订单数据,追加新的分片即可。

不过,RANGE 分片算法在分布式数据库架构中,是一种非常糟糕的算法,因为对于分布式架构,通常希望能解决传统单实例数据库两个痛点:

  • 性能可扩展,通过增加分片节点,性能可以线性提升;
  • 存储容量可扩展,通过增加分片节点,解决单点存储容量的数据瓶颈。

那么对于订单表 orders 的 RANGE 分片算法来说,你会发现以上两点都无法实现,因为当年的数据依然存储在一个分片上(即热点还是存在于一个数据节点上)。

如果继续拆细呢?比如根据每天进行 RANGE 分片?这样的确会好一些,但是对“双 11、618”这样的大促来说,依然是单分片在工作,热点依然异常集中。

所以在分布式架构中,RANGE 分区算法是一种比较糟糕的算法。但它也有好处:可以方便数据在不同机器间进行迁移(migrate),比如要把分片 2 中 1992 年的数据迁移到分片 1,直接将表进行迁移就行。

而对海量并发的 OLTP 业务来说,一般推荐用 HASH 的分区算法。这样分片的每个节点都可以有实时的访问,每个节点负载都能相对平衡,从而实现性能和存储层的线性可扩展。

我们来看表 orders 根据 o_orderkey 进行 HASH 分片,分片算法如下:

在上述分片算法中,分片键是 o_orderkey,总的分片数量是 4(即把原来 1 份数据打散到 4 张表中),具体来讲,分片算法是将 o_orderkey 除以 4 进行取模操作。

最终,将表orders 根据 HASH 算法进行分布式设计后的结果如下图所示:

可以看到,对于订单号除以 4,余数为 0 的数据存放在分片 1 中,余数为 1 的数据存放在分片 2 中,余数为 2 的数据存放在分片 3 中,以此类推。

这种基于 HASH 算法的分片设计才能较好地应用于大型互联网业务,真正做到分布式数据库架构弹性可扩展的设计要求。

但是,表 orders 分区键选择 o_orderkey 是最好地选择吗?并不是。

我们看一下库中的其他表,如表 customer、lineitem,这三张表应该是经常一起使用的,比如查询用户最近的订单明细。

如果用 o_orderkey 作分区键,那么 lineitem 可以用 l_orderkey 作为分区键,但这时会发现表customer 并没有订单的相关信息,即无法使用订单作为分片键。

如果表 customer 选择另一个字段作为分片键,那么业务数据无法做到单元化,也就是对于表customer、orders、lineitem,分片数据在同一数据库实例上。

所以,如果要实现分片数据的单元化,最好的选择是把用户字段作为分区键,在表 customer 中就是将 c_custkey 作为分片键,表orders 中将 o_custkey 作为分片键,表 lineitem 中将 l_custkey 作为分片键:

这样做的好处是:根据用户维度进行查询时,可以在单个分片上完成所有的操作,不用涉及跨分片的访问,如下面的 SQL:

SELECT * FROM ordersINNER JOIN lineitem ON o_orderkey = l_orderkeyINNER JOIN customer ON o_custkey = c_custkeyWHERE o_custkey = 1ORDER BY o_orderdate DESC LIMIT 10

所以,分布式数据库架构设计的原则是:选择一个适合的分片键和分片算法,把数据打散,并且业务的绝大部分查询都是根据分片键进行访问。

那为什么互联网业务这么适合进行分布式架构的设计呢?因为互联网业务大部分是 To C 业务,分片键就是用户的 ID,业务的大部分访问都是根据用户 ID 进行查询,比如:

  • 查看某个用户下的微博/短视频;
  • 查看某个用户的商品信息/购买记录;
  • 查看某个用户自己的余额信息。

学完分片键的选择后,接着就是规划分片,也就我们经常提到的分库分表。

分库分表

说了这么久分片,分片到底是什么呢?其实,分片本质是一张张表,而不是数据库实例,只是每个分片是在 MySQL 数据库实例中,严格来说:

分片 = 实例 + 库 + 表 = ip@port:db_name:table_name

对于前面的表orders,假设根据 HASH 算法进行分片,那么可以进行如下的分库分表设计:

  • 每个分片的表名库名都一样,如库 tpch,表名 orders;
  • 每个分片的库名不一样,表名一样,如库名 tpch01、tpch02、tpch03、tpch04,表名orders;
  • 每个分片的表名不一样,库名一样,如库名 tpch,表名分别为 orders01、orders02、orders03、orders04;
  • 每个分片的库名不一样,表名也不一样,如分片 1 的表在库名 tpch01下,表名为oders01;分片 2 的表名在库名 tpch02,表名为 orders02;分片 3 的表名在库名tpch03,表名为 orders03;分片 3 的表名在库名 tpch04,表名为 orders04。
  • 在这 4 种分库分表规则中,最推荐的是第 4 种,也是我们通常意义说的分库分表,这样做的好处有以下几点:

    • 不同分片的数据可以在同一 MySQL 数据库实例上,便于做容量的规划和后期的扩展;
    • 同一分片键的表都在同一库下,方便做整体数据的迁移和扩容。

    如果根据第 4 种标准的分库分表规范,那么分布式 MySQL 数据库的架构可以是这样:

    有没有发现,按上面这样的分布式设计,数据分片完成后,所有的库表依然是在同一个 MySQL实例上!!!

    牢记,分布式数据库并不一定要求有很多个实例,最基本的要求是将数据进行打散分片。接着,用户可以根据自己的需要,进行扩缩容,以此实现数据库性能和容量的伸缩性。这才是分布式数据库真正的魅力所在。

    对于上述的分布式数据库架构,一开始我们将 4 个分片数据存储在一个 MySQL 实例上,但是如果遇到一些大促活动,可以对其进行扩容,比如把 4 个分片扩容到 4 个MySQL实例上:

    如果完成了大促活动,又可以对资源进行回收,将分片又都放到一台 MySQL 实例上,这就是对资源进行缩容。

    总的来说,对分布式数据库进行扩缩容在互联网公司是一件常见的操作,比如对阿里来说,每年下半年 7 月开始,他们就要进行双 11 活动的容量评估,然后根据评估结果规划数据库的扩容。

    一般来说,电商的双 11 活动后,还有双 12、新年、春节,所以一般会持续到过完年再对数据库进行缩容。接下来,我们来看看如何进行扩缩容。

    扩缩容

    在 HASH 分片的例子中,我们把数据分片到了 4 个节点,然而在生产环境中,为了方便之后的扩缩容操作,推荐一开始就把分片的数量设置为不少于 1000 个。

    不用担心分片数量太多,因为分片 1 个还是 1000 个,管理方式都是一样的,但是 1000 个,意味着可以扩容到 1000 个实例上,对于一般业务来说,1000 个实例足够满足业务的需求了(BTW,网传阿里某核心业务的分布式数据库分片数量为 10000个)。

    如果到了 1000 个分片依然无法满足业务的需求,这时能不能拆成 2000 个分片呢?从理论上来说是可以的,但是这意味着需要对一张表中的数据进行逻辑拆分,这个工作非常复杂,通常不推荐。

    所以,一开始一定要设计足够多的分片。在实际工作中,我遇到很多次业务将分片数量从 32、64 拆成 256、512。每次这样的工作,都是扒一层皮,太不值得。所以,做好分布式数据库设计的工作有多重要!

    那么扩容在 MySQL 数据库中如何操作呢?其实,本质是搭建一个复制架构,然后通过设置过滤复制,仅回放分片所在的数据库就行,这个数据库配置在从服务器上大致进行如下配置:

    # 分片1从服务器配置replicate_do_db =”tpch01″

    所以在进行扩容时,首先根据下图的方式对扩容的分片进行过滤复制的配置:

    然后再找一个业务低峰期,将业务的请求转向新的分片,完成最终的扩容操作:

    至于缩容操作,本质就是扩容操作的逆操作,这里就不再多说了。

    总结

    今天这一讲,我们学习了分布式数据库架构设计中的分片设计,也就是我们经常听说的分库分表设计。希望通过本讲,你能牢牢掌握以下内容:

    • 分布式数据库数据分片要先选择一个或多个字段作为分片键;
    • 分片键的要求是业务经常访问的字段,且业务之间的表大多能根据这个分片键进行单元化;
    • 如果选不出分片键,业务就无法进行分布式数据库的改造;
    • 选择完分片键后,就要选择分片算法,通常是 RANGE 或 HASH 算法;
    • 海量 OLTP 业务推荐使用 HASH 算法,强烈不推荐使用 RANGE 算法;
    • 分片键和分片算法选择完后,就要进行分库分表设计,推荐不同库名表名的设计,这样能方便后续对分片数据进行扩缩容;
    • 实际进行扩容时,可以使用过滤复制,仅复制需要的分片数据。
    郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
    用户投稿
    上一篇 2022年6月20日 13:01
    下一篇 2022年6月20日 13:01

    相关推荐

    • 淘宝工厂店的东西是正品吗?淘宝工厂店为什么便宜

      淘工厂直营店其实就是链接淘宝卖家与工厂的平台,直接对接工厂型的商家,店铺里的东西大部分价格都会很低。那么,淘工厂直营店靠谱吗? 淘工厂直营店是靠谱的,但售后问题可能得不到很好的保障…

      2022年11月27日
    • 数字看亮点!前十月我国造船三大指标继续全球领先

      央视网消息:工业和信息化部最新数据显示,今年1—10月,我国造船三大指标继续保持全球领先。随着生产节奏加快,船企产业集中度进一步提升。 2022年1—10月,全国造船完工量、新接订…

      2022年11月25日
    • 前十个月我国造船业三大指标稳居世界第一

      今年1—10月,我国造船业在国际市场的份额继续稳居世界第一。一批高技术高附加值船舶实现了批量接单、批量生产。 近日,中国船舶上海船舶研究设计院又新接了韩国船东三艘汽车运输船的设计追…

      2022年11月25日
    • 客服的岗位职责怎么写(客服工作内容及职责)

      各位小伙伴们大家周一好,又到了每周一给大家分享干货内容的时候啦~ 本期来跟大家分享一下客服工作管理流程以及客服岗位里面的每项职能岗位的核心细则,也是干货满满推荐收藏~ 一.补偿流程…

      2022年11月25日
    • 商家收到货才会退款吗(淘宝代付款退款钱到哪里了)

      在淘宝上有一些人下单购买商品的时候是通过代付的形式来支付的,一般情况下是家长帮助家里的小孩或者长辈进行代付,而代付订单和普通的订单没有太大的区别,不过如果发生退款的话,钱是退到哪里…

      2022年11月25日
    • 什么是推广cpa一篇文章带你看懂CPA推广渠道

      CPA渠道 CPA指的是按照指定的行为结算,可以是搜索,可以是注册,可以是激活,可以是搜索下载激活,可以是绑卡,实名认证,可以是付费,可以是浏览等等。甲乙双方可以根据自己的情况来定…

      2022年11月25日
    • 百度关键词快速排名的4大原理解析(百度怎么刷关键词)

      近期百度公告惊雷算法2.0,升级之快还是第一次吧,看来百度对于刷点击行为是零容忍了。之前尹华峰SEO技术博客介绍过一篇如何使用刷点击工具,其实市面上有很多这类SEO快速排名的软件,…

      2022年11月25日
    • 抖音直播带货有哪些方法技巧(抖音直播带货有哪些痛点)

      如今抖音这个短视频的变现能力越来越突显了,尤其是在平台上开通直播,更具有超强的带货属性,已经有越来越多的普通人加入到其中了。不过直播带货虽然很火,但是也不是每个人都能做好的,那么在…

      2022年11月24日
    • 英皇文化产业:结束全部7间英皇UA电影城经营

      11月21日,英皇文化产业发布公告,英皇娱艺影院(广东)有限公司(“中国附属公司”)为英皇UA的全资附属营运公司。 董事会谨此知会公司股东,于2022年11月21日,英皇UA(作为…

      2022年11月24日
    • 淘宝直播开通后带货链接怎么做(淘宝直播需要开通淘宝店铺吗)

      直播带货无论是对于商家来说还是主播收益都是非常可观的,所以不少平台都有直播带货功能,一些小伙伴也想加入淘宝直播,那么淘宝直播开通后带货链接怎么做?下面小编为大家带来淘宝直播开通后带…

      2022年11月24日

    联系我们

    联系邮箱:admin#wlmqw.com
    工作时间:周一至周五,10:30-18:30,节假日休息