《设计数据密集型应用》第六章(1) 数据分区:分区方式

前言

数据分区是指将数据分成不同部分,每部分属于一个分区,不同分区的数据存储在不同的节点上。这是一种提高数据可扩展性的方式,对于查询来说,每个分区可以独立处理它自己分区的数据,实现并行处理。

本章我们会介绍数据集的不同分区方式,数据索引对分区方式的影响;然后会讨论再平衡(rebalance),集群在添加和移出节点时的处理;最后会概括介绍下如何将请求路由至正确的分区,并执行查询。

分区和副本

数据的分区和副本通常是同时存在的,每个数据分区会存在多个副本,多个副本一般会存储在不同的节点上,提高容错性。在leader-follower模型中,每个节点既可能一些分区的leader,也可能是其他分区的follower,如下图所示。

《设计数据密集型应用》第六章(1) 数据分区:分区方式_第1张图片
分区和副本同时存在

数据分区方式的选择,和数据副本模型的选择通常是独立的,因此本章在讨论数据分区时,为了使描述更清楚,默认数据是单副本的。

Key-Value数据的分区

假如我们有海量的数据,如何对它进行分区呢?我们的目标是将数据分散,并使查询负载平均分配到每个节点上。这样如果集群有10个节点,数据的读写吞吐量可以提升10倍。但实际的分配可能是不公平的,会因此出现数据倾斜的现象,负载最高的节点称为数据热点

如何避免出现数据热点,直接的想法是完全随机地将数据分配到节点上。但该方式的缺点是不知道每条数据在哪个节点上,在查询时需要并行地查询所有节点。

对于Key-Value类型的数据,有哪些分区方式可以做得更好呢?

按Key区间分区

一种方式是将一段连续的Key分配到同一个分区,每个分区有固定的Key取值范围。这样可以很容易地知道每个Key属于哪个分区,可以将请求直接发送到分区对应的节点上。

《设计数据密集型应用》第六章(1) 数据分区:分区方式_第2张图片
按Key区间分区

Key的区间在空间上并不是均等的,因为数据并不是平均分布的。比如上面论文百科的例子,卷1包含A和B开头的单词,但卷12包含T、U、V、X、Y和Z的单词。因此分区的边界需要适应数据的实际分布。

分区的边界由管理员指定,或自动选择。BigTable系列的数据库使用这种分区策略,比如HBase、RethinkDB和MongoDB 2.4以前的版本。

在每个分区内部,Key是排序的(类似SSTable和LSM-Tree)。它的优点是范围查找会很简单,将Key视作为级联索引,可以在一次查询获取许多相关数据。比如Key是时间戳,格式为year-month-day-hour-minute-second,可以很快获取到特定时间段的数据。

该分区方式的缺点是可能会产生数据热点,比如按照时间范围进行分区,当写入数据时,所有的数据都会写入今天所在分区的节点,其他分区会空闲。

如何避免该缺点,方法是在Key之前增加其他元素,比如传感器名字。这样不同的传感器就会写入不同的分区,在读取时,也需要单独查询所有传感器的分区。

按Key的Hash分区

为了避免数据倾斜和热点的产生,许多分布式的存储使用Hash函数决定某个Key的分区。一个良好的Hash函数会将倾斜的数据Key重新均匀分布,在Hash之后落在某个区间内的数据为一个分区,每个分区的边界是均等的。

《设计数据密集型应用》第六章(1) 数据分区:分区方式_第3张图片
按Key的Hash分区

在对Key进行Hash后,失去了按照Key范围进行查询的特性,原本相邻的Key在Hash后可能存储在不同的分区上。在MongoDB中,使用基于Hash的分区模型,任何返回查询都会发送到所有分区上。

Cassandra使用了两种分区策略的折中方式。Cassandra的表定义了包含多列的复合主键。对Key的第一列进行Hash并决定分区,其他列作为级联索引将数据排序在SSTable中。因此一个查询不能跨Key的第一列进行范围查询,但可以指定第一列后,对其他列进行范围查询。

这种方法对于one-to-many型的数据可以很优雅的处理。比如一个社交网站,一个人可能会发布很多状态。主键选为(user_id, update_timestamp),不同用户的数据在不同的分区上,选定用户后,可以对该用户的数据进行快速的范围查找。

缓解数据倾斜和热点

使用Hash的方式会帮助我们降低热点出现的可能,但并不能完全避免。在一些极端情况,比如大量读写相同的Key,会导致所有操作集中在同一个分区上。

比如在社交网站,一个有数百万followers的用户可能会导致数据风暴,大量的写操作在同一个Key上。对于这种情况,现在的数据库并不能直接处理,需要在应用程序中进行处理。通常的做法是,针对这种可能会出现数据倾斜的Key,在Key上增加比如100个随机数后缀,使数据分散到100个分区;在读取时,读取这个100个分区的数据并将结果合并。

小结

本节介绍了关于数据分区的基础概念,两种针对Key-Value数据的分区方式和它们的优缺点,以及关于数据倾斜和数据热点的解决方式等。

你可能感兴趣的:(《设计数据密集型应用》第六章(1) 数据分区:分区方式)