分布式基础——分区

137 阅读4分钟

本章主要介绍了「垂直分区」和「水平分区」的适用场景及优缺点,并重点阐述了「水平分区」的三种分区算法:「范围分区」、「哈希分区」和「一致性哈希分区」。 注:本文偏向于总结,适用于有一定基础的读者。

定义

分区是指将一个数据集拆分成较小的数据集,同时将存储和处理这些较小数据集的责任分配给分布式系统中的不同节点。

垂直分区

对表的列进行拆分,将某些列的整列数据拆分到不同的分区中。

适用场景

  • 总列数过多
  • 某些列过大
  • 各个列的访问频次不均
  • 敏感数据隔离

优点

  • 减少扫描的列,降低IO和内存的开销。
  • 不同的分区可以使用不同的存储引擎,更加灵活。(「myisam」可以创建只读的压缩表,减少磁盘占用;因为不支持事务,在查询时不会有复杂的检查,并且没有聚簇索引,没有回表的开销,所以查询效率更高;)
  • 不同的分区可以使用不同的安全策略,提高数据安全性。

缺点

  • 当需要查询一个逻辑实体的完整记录时,需要用到联合查询,增加复杂度。
  • 当事务涉及到多分区的时候,需要使用分布式事务,较为复杂。
  • 需要额外的机制,来保证一致性。

水平分区

对表的行进行拆分,将不同的行放入不同的分区中。

适用场景

  • 单张表数据过大
  • 单库的流量压力过大
  • 归档或历史数据管理

优点

  • 使单张表数据量减小,提神访问效率。
  • 使单库的流量减小,减小数据库压力。
  • 通过拓展节点,可以提高吞吐量。
  • 某些分表可以独立管理,如归档旧数据或清理特定表。

缺点

  • 当查询的记录跨分区的时候,需要查询多个分区,增加复杂性。
  • 当事务涉及到多分区的时候,需要使用分布式事务,较为复杂。
  • 开发和维护成本增加。

水平分区算法

1. 范围分区

根据指定的关键字,将数据集拆分成若干连续的范围,每个范围存储到一个单独的节点上。(例如以年份为「分区键」对数据进行分区。)

优点

  • 实现起来较为简单。
  • 能够进行范围查询。
  • 容易通过修改范围边界,来对分区进行调整。

缺点

  • 进行范围查询的时候,只能使用「分区键」,具有局限性。
  • 当范围查询跨越多节点的时候,性能较差。
  • 容易造成数据不均和访问流量不均。(例如,以年龄为「分区键」,那么25~54岁的人会比较多;若以年份为「分区键」,则最近年份的访问流量会比较大。)

2. 哈希分区

将制定的关键字经过一个哈希函数计算后,根据得到的值来决定数据集的分区。

优点

  • 数据分布较为均匀,能在一定程度上避免热点问题。

缺点

  • 在不额外存储数据的情况下,无法进行范围查询。
  • 在增减节点的时候,需要修改哈希函数,这将导致现有的许多数据都要重新映射,引起大规模的数据移动,并且在此期间,系统可能无法正常工作。

3. 一致性哈希

一致性哈希是一种特殊的哈希算法,用来缓解普通「哈希分区」中的增删节点时引起的大规模数据迁移的问题。一致性哈希将所有的hash值组成一个抽象的圆环,然后将所有的节点映射到圆环上,那么每个节点负责的「hash片」就是逆时针方向上相邻节点之间的所有「hash值」。

优点

  • 在增减节点的时候,只需要迁移相邻节点的数据,成本较小。

缺点

  • 在不额外存储数据的情况下,无法进行范围查询。
  • 当一个节点发生下线时,该节点的数据将会转移到相邻的节点上,进而导致数据分布不均。(解决方案:引入「虚拟节点」,例如物理节点A,有虚拟节点A1,那么A1就可以负责一部分分片,但实际的数据处理还是由物理节点负责。)