第二部分-分布式数据系统

第五章 数据复制

第六章 数据分区

6.1 数据分区与数据复制

可以组合使用主从复制模型和分区,分区拓展单机性能,主从模型中从节点作为容灾备份。
每个分区节点,既包含主副本,又包含从副本,副本可以隶属于不同分区。image

6.2 键值数据的分区

如果分区不均匀,某些分区节点会承担更多的数据量或者查询负载,成为倾斜,负载严重不成比例的分区即成为系统热点。

基于关键字区间分区

  • 为每个分区分配一段连续的关键字,或者关键字区间范围
  • 关键字区间不一定非要均匀分布,因为数据本身可能就不均匀
  • 每个分区内可以按照关键字进行排序
  • 缺点是某些访问模式会导致热点,解决办法是,比如原来关键字是时间戳,对于某些大事的时间戳会发生频次较高的查询,则可以使用时间戳之外的其他内容作为关键字的第一项,可以再时间戳前加上传感器名称作为前缀,这样可以首先由传感器名称,然后再由时间戳分区

基于关键字哈希值分区

  • Cassandra和MongoDB使用MD5,Voldemort使用Fowler-Noll-Vo函数,一些编程语言的内置哈希函数,可以会受不同进程的影响,并不可靠
  • 找到合适的关键字哈希函数,为每个分区分配一个哈希范围
  • 优点:很好的将关键字均匀的分配到多个分区中
  • 缺点:丧失了良好的区间查询特性,MongoDB中,区间查询会并行在所有分区查询

一致性哈希

  • 可以平均分配负载
  • 最初用于CDN等网络缓存系统
  • 采用随机选择的分区边界来规避中央控制或者分布式共识
  • 对数据库实际效果并不好,目前很少使用

分区策略综合

Cassandra采用了这种的方式,表可以声明为由多个列组成的符合主键。只有第一部分可以使用哈希分区,其他列则用作组合索引来对SSTable中的数据进行排序。
因此,它不支持再第一列区间查询,但是固定第一列时,则可以对其他列执行高效的区间查询。

负载倾斜与热点

哈希分区的极端情况是,所有读写操作针对一个关键字,即所有请求都被路由到同一个分区。
解决办法:
在应用层来减轻倾斜程度,比如某个关键字被确认为热点,可以在关键字开头或者结尾增加随机数,这样写请求会被分配到多个分区节点上。
问题就是任何读取都需要额外的工作,必须从所有分区读取数据再合并,所以通常只会对少量的热点关键字附加随机数才有意义。

6.3 分区与二级索引

二级索引:通常不能唯一标识一条记录,一般用来加速特定值的查询
前面的分区方案无法很好地适应二级索引存在的场景,主要挑战是二级索引不能规整的映射到分区中,主要有两种方案,基于文档分区和基于词条的分区。

基于文档的分区

image

  • 每个分区完全独立,各自维护自己的二级索引,且只负责自己分区内的文档
  • 文档分区也被称为本地索引,而非全局索引
  • 查询时需要查询所有分区,即“分散/聚集”,查询代价高昂,且即使并行查询,仍然容易导致读延迟显著放大
  • 目前实践:MongoDB,Riak ,Cassandra ,Elasticsearch,SolrCloud 和VoltDB

基于词条的分区

image

  • 对所有的数据构建全局索引,而非每个分区维护自己的本地索引
  • 以待查找的关键字本身作为索引
  • 索引产生:可以直接用关键词来全局划分索引,或者取哈希值。直接分区可以高效区间查询,哈希则可以更均匀划分分区。
  • 相比于文档分区
    • 优点:读取更为高效,不需要采用“分散/聚集”来对所有的分区执行一遍查询,只要确定索引所在分区一次请求即可完成
    • 缺点:写入速度较慢且非常负责,单个文
      档更新时,可能会涉及到多个二级索引多个分区节点的更新;针对于此,对全局二级索引的更新一般都是异步更新

6.4 分区再平衡

查询压力增加、数据规模增加、单节点故障,都有可能需要我们进行分区再平衡,即将数据和请求从一个节点转移到另外一个节点。

不能直接取模

  • 如果节点N发生变化,会导致很多关键字进行迁移,涉及到多个分区的调整,大大增加了再平衡的成本

固定数量分区

image

  • 创建远超实际节点数的分区,然后为每个节点分配多个分区
  • 如果集群增删节点,从已分配的分区进行选中一部分进行迁移即可
  • 注意:需要调整分区与节点的对应关系,可以逐步完成
  • 分区数量不要太大,不要太小,很那确定最佳取舍点
  • 实践:Riak,Elasticsearch,Couchbase和Voldemort

动态分区

  • 当分区数据增长超过一个可配置的参数阈值时,拆分为两个分区,每个分区承担一半
  • 当大量数据被删除,且分区缩小到某个阈值,将其与相邻分区合并
  • 与B树的分裂操作类似
  • 优点:分区数量可以自动适配数据总量
  • 缺点:对于空数据库,刚开始直到达到第一个分裂点之前,所有写入操作由单节点处理。缓解办法是,HBase和MongoDB允许再空数据库配置一组初始分区。

按节点比例分区

  • 使分区节点和集群节点成正比例关系,即每个节点具有固定数量的分区
  • 新节点加入时,随机选择固定数量的现有分区进行分裂,可能会导致不公平的分裂(Cassandra在3.0推出改进算法)
  • 实践:Cassandra和Ketama

自动 or 手动

让管理员介入到再平衡是个更好的选择,比全自动响应慢一点,但是可以有效防止意外发生

6.5 请求路由

服务发现

典型的服务发现问题,任何通过网络访问的系统都有这样的需求,尤其是当服务目标支持高可用时。
主要有三种策略,
1.允许客户端链接任意节点,如果节点不包含数据,则转发给下一个合适的节点
2.客户端请求全部发送到路由层,路由层充当分区感知的负载均衡器,不处理请求
3.客户端感知分区和节点分配关系,直连目标节点
许多分布式数据系统依赖独立的协调服务(ZooKeeper/Etcd/Consul)跟踪集群范围内的元数据,每个节点向协调服务注册自己,协调服务维护了最终的映射关系。
其他数据系统,有的使用了Helix,也有的使用gossip协议来同步集群状态,由节点负责转发请求到真正的节点。这种方式增加了数据库节点的复杂性,但是避免了对外部协调服务的依赖。

并行查询执行

对于大规模并行处理(Massively Paallel Processing, 主要用于数据分析的关系数据库),查询复杂得多,可能会包含多个联合、过滤、分组和聚合操作,MPP查询优化器会将复杂查询分解为许多执行阶段和分区,以便在集群的不同节点并行执行。

第七章 事务

7.1 深入理解事务

7.2 弱隔离级别

7.3 串行化

第八章 分布式系统的挑战

8.1 故障与部分失效

8.2 不可靠的网络

8.3 不可靠的时钟

8.4 知识,真相与谎言

参考文献

1.ddia中文翻译

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值