DDD-数据分区之切分大数据集

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

本系列主要是《数据密集型应用系统设计》阅读笔记,本文记录数据分区主题的笔记心得。

每一条数据只属于某个特定的分区。每个分区都可以视为一个完整的小数据库。虽然相互之间存在一些跨分区的操作。

采用分区可以提高可扩展性。不同的分区可以放在不同的节点上,这样的大数据集可以分散在更多的磁盘上,查询负载也可以分布到更多的处理器上面。

对单个分区查询的时候,每个节点对自己的分区可以独立执行查询操作,因此添加更多的节点可以提高吞吐量。

切分大型数据集

分区和复制

分区和复制一般是结合使用,每个分区在多个节点都存在副本。如下图:

image.png

那么应该怎么分区呢?

键值数据的分区

分区的目标是将数据和查询负载均匀分布在所有节点上。如果节点平均的负担负载,那么10个节点能处理10倍单机的负载量。要避免负载不均衡,需要将记录随机分配到所有的节点上,这种方法可以比较均匀的分布数据。但是当读取特定的数据时,没有办法知道数据保存在哪个节点上。假设数据上简单的key-value模型,则总是可以通过关键字来查到记录,可以做到快速查找

关键字分区

每个分区分配一段连续的关键字或关键字范围。如果知道关键字区间的上下限,就可以轻松确定哪个分区包含这些关键字。如果还知道哪个分区分配在哪个节点,则可以直接向该节点发出请求。如下图

image.png

扫描二维码关注公众号,回复: 14228379 查看本文章

关键字的区间段不一定非要均匀,主要是因为数据本身可能就不均匀。例如,卷1只包含A-B开头的单词,卷12则包含了T、U、V、X、Y和Z开始的单词。

分区边界可以由管理员手动指定,或者数据库自动选择。采用这种分区策略的系统包括Bigtable、Bigtable的开源版本Hbase、和2.4版本之前的MongoDB。

每个分区内可以按照关键字排序保存,这样可以轻松的支持区间查询。然而,基于关键字的分区是某些模式会导致数据热点。

关键字哈希值

为了解决基于关键字的分区导致热点数据的问题,许多分布式系统采用了基于关键字哈希函数的方式来分区。

一个好的哈希函数可以处理数据倾斜。比如处理字符串的32位哈希函数,当输入某个字符串,返回一个0到2^32-1之间近似随机分布的数值。即使输入的字符串非常相似,返回的哈希值也会在上述数字范围内均匀分布。

一旦找到合适的关键字哈希函数,就可以为每个区间分配一个哈希范围,关键字根据其哈希值的范围划分到不同的分区中。

这种方法可以很好的将关键字均匀的分配到多个分区中,分区边界可以是均匀间隔,也可以是随机选择(这种一般称为是一致性哈希)。

关键字哈希值的分区丧失了良好的区间查询特性

  • 在MongoDB中,如果用了基于哈希的分片模式,则区间查询会发送到所有的分区上。
  • Couchbase等干脆就不支持关键字上的区间查询。
  • Cassandra则在两种分区策略之间做了一个折中。Cassandra的表可以声明为由多个列组成的复合key,复合key只有第一部分用于分区,则其他列可以用作组合索引来对Cassandra SSTable中的数据进行排序,因此不支持在第一列上进行区间查询,可以对其他的列执行高效的区间查询。

比如对于社交网站一个用户会发布很多的消息,则更新的关键字设置为(user_id,update_timestamp),那么可以有效的检索某用户在一段时间内所做的所有更新,同时不同的用户可以存储在不同的分区上。

负载倾斜

如果所有的读写都是同一个关键字,则最终所有请求都被路由到同一个分区。 比如社交媒体上,一些名人用户有数百万的粉丝,当发布一些热点事件时可能会引发访问风暴。此时关键字是名人的ID,哈希起不到任何作用。

可以通过应用层来减轻这种倾斜程度。例如,如果某个关键字倍确认为热点,可以在关键字的开头或结尾的地方添加一个随机数,比如100以内的随机数可以将这个关键字扩张为100个关键字,从而分配到不同的分区上。但是读取的时候则需要合并所有100个关键字的数据。

猜你喜欢

转载自juejin.im/post/7105227203591290911