数据分片
分片
对数据进行分片的策略,主要有三种:水平分片、垂直分片和混合分片,具体如下图所示。水平分片和垂直分片是通过数据切分的操作方向来区分的,而混合分片 是它们的组合体。

水平分片
水平分片有点类似于负载均衡,从流量角度来看,是负载均衡,从数据存储角度来看,是水平分片。
水平分片算法有两个最关键的因素,一是,如何对数据进行划分,即数据划分,二是,分片是 否支持动态分裂与合并,即数据平衡。
数据划分
数据划分主要有两种方案,一种是基于模运算,一种是基于范围划分。基于模运算比较简单,不再阐述。而基于范围划分,又分为基于关键词划分和基于关键词的 Hash 值划分两种方式。


这两种分片都是给每一个分片分配一个固定的范围,两者的不同区别在于一个是直接拿关键词进行划分,另一个是利用了关键词的Hash值进行划分。看似区别不大,但是会影响数据的分布。
基于关键词划分
基于关键词划分的好处是,分片后数据的分布依然保留了关键词的顺序,我们可以方便地进行区间查询,因为某个关键词区间的数据都是连续存储的。
但是基于关键词划分也会带来问题,即数据分布不均匀和访问的热度不均匀。比如说按照地区进行划分,那么某些省份人数多,这个分片的数据就会多,人数少,分片数据就少。而且数据分布不均时,数据多的分片被访问到的概率也会变大。
如果基于自增 ID 或者时间等关键词对数据进行分片的时候,即使数据是均匀分布的,对于一般的业务场景来说,往往新产生数据的访问热度,也是远远大于历史数据的,这也会导致访问的热度不均匀。
很明显,数据的分布与关键词的分布是一致的。
基于关键词的hash值
基于关键词的 Hash 值划分就可以上述问题,它通过对关键词进行 Hash 运算,然后基于计算后的 Hash 值范围对数据进行划分,一个好的 Hash 算法可以处理数据倾斜并让它均匀分布。这样可以解决数据分布和访问热度不均的问题。
但导致的问题就是无法高效的进行范围查询。
数据平衡
根据数据分片是否支持动态的分裂与合并,我们可以将水平分片的数据平衡方式分为静态分片和动态分片。
静态分片是指在系统设计之初,数据分片的数目和区间就预估好了,数据划分后不能再变化。
动态分片则可以在运行时,根据分片的负载和容量做调整。
因为动态分片在运行时分区时可以进行分裂与合并的,不需要担心数据分布的问题,所以动态分片与基于关键词的划分,往往是一个 比较好的组合方式,它避免了基于关键词划分的问题,还保留了数据基于关键词有序的优点。
但是,在基于关键词的划分中,基于自增 ID 或者时间戳等原因,导致的访问冷热不均匀的问题,即使是在动态分片中也不能很好地解决,因为数据的热点往往集中在最新的一个分片区间上。而基于关键词的 Hash 值划分的方式,则可以很方便地将最新的热点数据分布到多个分片 上,很好地解决这个问题。
动态分片存在冷启动的问题。当一个基于动态分片的存储系统启动时,通常是从一个分片开始,当数据量不断增长后,再动态进行分裂。在第一次进行分裂前,所有的读写请求都由 第一个分片来进行处理,而其他的节点则都属于空闲状态。关于这个问题,一个比较好的解决 方式是,动态分片在冷启动时,预分裂为多个分片来缓解。

垂直分片
水平分片策 略将整个数据集的条数作为划分的对象,每一个分片负责处理一定的数据条数。而垂直分片策略则是将数据 Schema 的字段集个数作为划分的对象,每一个分片负责处理一个或几个字段 的全部数据,具体如下图所示。

如果垂直分片策略的处理方式为一个字段一个分片,那么垂直分片策略就等价于列式存储了,所以列式存储是垂直分片策略的一种特殊情况,也是最常见的情况。
列式存储往往用于大数据分析当中,这类数据的特点是一次写入,多次查询(从不修改),而且是按列读取,每次只关心一列或者几列,每张表都很宽,比如上百列。而且查询无规律,不能索引覆盖。
列式存储
如果是行式存储,当我们只需要读取一列时,有两种方案,第一个是挨个读取每一行的数据,但是只取出自己要的那一列,这会导致读取数据的量放大很多。如果我们只读取那一列,这会导致我们读取时不是按顺序读取,会对读取造成性能影响。
读多写少的场景,会减少列式存储对写性能的影响。一般来说,数据写入存储系统是以 行的形式写入的,而列式存储会导致一行数据的写入操作,按字段拆分为多个写入操作,使写入放大。
大数据场景,采用列式存储非常适合压缩存储,比如下图:

好处是使用压缩会大大减小存储成本,提高了存储效率,但是在存储和读取数据时,需要多一步,即找到数据的编码,需要消耗额外的CPU资源。
混合分片策略
根据水平分片和垂直分片的策略,混合分片可以分为垂直水平分片策略和水平垂直分片策略。前者先 进行垂直分片,再进行水平分片,而后者先进行水平分片,然后再进行垂直分片。具体如下图:

垂直水平分片看着不怎么滴,不过多介绍。
水平垂直分片更像是两者的结合提。先水平划分,划分完后在每一个分片内部再采用列式存储,这样可以保留水平分片和垂直分片的优点。
行列存储比较

参考
《深入浅出分布式技术原理》