DDIA - 第五次作业

第6章, 分区.

概览

当我们的数据量很大时, 不适合放在一个数据库的时候, 就需要做分区了, 也就是常说的分库分表.

分区的理想状态是:

  • 数据均衡分布, 数据不是集中在某部分节点
  • 容易查询, 例如根据键值可以很容易知道数据在哪个分区, 避免一次查询多个分区
  • 易扩展, 当要新增或者减少分区时, 减少数据的搬移

键值数据的分区方法

  • 根据键的范围分区, 如字符串以A和B开头为一个分区, B和C开头为一个分区. 缺点是容易分配不均衡, 可能某个字母开头的数据特别多, 造成数据热点.
  • 根据键的散列分区, 选择一个好的散列函数, 可以将数据均匀分布. 缺点是失去了高效范围查询的能力, 键值本来是相邻的, 数据库查询相邻数据有优势, 现在打散了.

次级索引查询

根据键值很容易查询, 但是次级索引就麻烦了, 有两种方式.

  • 本地索引. 每个分区内创建属于自己的次级索引, 只包含本分区的内容. 当你要根据一个索引查询时, 要把请求发送给所有分区, 再将结果合并.
  • 全局索引. 创建全局的次级索引, 然后再将索引根据关键字分到各个分区, 如根据颜色分区, 红色分到分区1, 蓝色分到分区2, 这样如果只查红色, 则可以只查分区1的结果就可以, 缺点是全局写入较慢且复杂.

再平衡策略

取余/hash mod N

最简单的一种hash算法, 就是取余. 如将键值hash后对10取余, 返回0~9的数字, 共对应10个分区. 每个分区对应1个节点.

但是一旦分区增加或者减少, 就会造成大量的数据迁移. 比如现在增加1个分区, 现在需要键值hash后对11取余, 返回0~10的数字, 那么90%的数据的分区都要改变, 这个再平衡的代价太大了.

分区不变, 节点改变

一次性分配很多分区, 如1000个分区, 刚开始流量不大, 只分配10个节点, 每个节点分配100个分区, 当新增节点时, 从现有分区分配一定数量的分区过来.

这样数据对应的分区不需要改变, 只是访问的节点需要调整. 难点在于如何分配分区数量.

动态分区

对于使用键范围分区的数据库,具有固定边界的固定数量的分区将非常不便:如果出现边界错误,则可能会导致一个分区中的所有数据或者其他分区中的所有数据为空。手动重新配置分区边界将非常繁琐.

按键的范围进行分区的数据库(如HBase和RethinkDB)会动态创建分区。当分区增长到超过配置的大小时(在HBase上,默认值是10GB),会被分成两个分区,每个分区约占一半的数据, 当大量数据删除时, 分区缩小到某个阈值, 则可以与相邻分区合并, 类似B树的分裂和合并行为.

一致性哈希, 环状哈希

经常在网上可以看到一种环状的哈希实现, 叫一致性哈希, 如https://www.cnblogs.com/williamjie/p/9477852.html
可以看wiki, https://en.wikipedia.org/wiki/Consistent_hashing

posted @ 2020-11-21 10:04  Panda110  阅读(167)  评论(0编辑  收藏  举报