第二部分-分布式数据系统
作者:互联网
第五章 数据复制
第六章 数据分区
6.1 数据分区与数据复制
可以组合使用主从复制模型和分区,分区拓展单机性能,主从模型中从节点作为容灾备份。
每个分区节点,既包含主副本,又包含从副本,副本可以隶属于不同分区。
6.2 键值数据的分区
如果分区不均匀,某些分区节点会承担更多的数据量或者查询负载,成为倾斜,负载严重不成比例的分区即成为系统热点。
基于关键字区间分区
- 为每个分区分配一段连续的关键字,或者关键字区间范围
- 关键字区间不一定非要均匀分布,因为数据本身可能就不均匀
- 每个分区内可以按照关键字进行排序
- 缺点是某些访问模式会导致热点,解决办法是,比如原来关键字是时间戳,对于某些大事的时间戳会发生频次较高的查询,则可以使用时间戳之外的其他内容作为关键字的第一项,可以再时间戳前加上传感器名称作为前缀,这样可以首先由传感器名称,然后再由时间戳分区
基于关键字哈希值分区
- Cassandra和MongoDB使用MD5,Voldemort使用Fowler-Noll-Vo函数,一些编程语言的内置哈希函数,可以会受不同进程的影响,并不可靠
- 找到合适的关键字哈希函数,为每个分区分配一个哈希范围
- 优点:很好的将关键字均匀的分配到多个分区中
- 缺点:丧失了良好的区间查询特性,MongoDB中,区间查询会并行在所有分区查询
一致性哈希
- 可以平均分配负载
- 最初用于CDN等网络缓存系统
- 采用随机选择的分区边界来规避中央控制或者分布式共识
- 对数据库实际效果并不好,目前很少使用
分区策略综合
Cassandra采用了这种的方式,表可以声明为由多个列组成的符合主键。只有第一部分可以使用哈希分区,其他列则用作组合索引来对SSTable中的数据进行排序。
因此,它不支持再第一列区间查询,但是固定第一列时,则可以对其他列执行高效的区间查询。
负载倾斜与热点
哈希分区的极端情况是,所有读写操作针对一个关键字,即所有请求都被路由到同一个分区。
解决办法:
在应用层来减轻倾斜程度,比如某个关键字被确认为热点,可以在关键字开头或者结尾增加随机数,这样写请求会被分配到多个分区节点上。
问题就是任何读取都需要额外的工作,必须从所有分区读取数据再合并,所以通常只会对少量的热点关键字附加随机数才有意义。
6.3 分区与二级索引
二级索引:通常不能唯一标识一条记录,一般用来加速特定值的查询
前面的分区方案无法很好地适应二级索引存在的场景,主要挑战是二级索引不能规整的映射到分区中,主要有两种方案,基于文档分区和基于词条的分区。
基于文档的分区
- 每个分区完全独立,各自维护自己的二级索引,且只负责自己分区内的文档
- 文档分区也被称为本地索引,而非全局索引
- 查询时需要查询所有分区,即“分散/聚集”,查询代价高昂,且即使并行查询,仍然容易导致读延迟显著放大
- 目前实践:MongoDB,Riak ,Cassandra ,Elasticsearch,SolrCloud 和VoltDB
基于词条的分区
- 对所有的数据构建全局索引,而非每个分区维护自己的本地索引
- 以待查找的关键字本身作为索引
- 索引产生:可以直接用关键词来全局划分索引,或者取哈希值。直接分区可以高效区间查询,哈希则可以更均匀划分分区。
- 相比于文档分区
- 优点:读取更为高效,不需要采用“分散/聚集”来对所有的分区执行一遍查询,只要确定索引所在分区一次请求即可完成
- 缺点:写入速度较慢且非常负责,单个文
档更新时,可能会涉及到多个二级索引多个分区节点的更新;针对于此,对全局二级索引的更新一般都是异步更新
6.4 分区再平衡
查询压力增加、数据规模增加、单节点故障,都有可能需要我们进行分区再平衡,即将数据和请求从一个节点转移到另外一个节点。
不能直接取模
- 如果节点N发生变化,会导致很多关键字进行迁移,涉及到多个分区的调整,大大增加了再平衡的成本
固定数量分区
- 创建远超实际节点数的分区,然后为每个节点分配多个分区
- 如果集群增删节点,从已分配的分区进行选中一部分进行迁移即可
- 注意:需要调整分区与节点的对应关系,可以逐步完成
- 分区数量不要太大,不要太小,很那确定最佳取舍点
- 实践: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中文翻译
标签:索引,第二,查询,关键字,哈希,数据系统,分布式,节点,分区 来源: https://www.cnblogs.com/boqianliu/p/15408490.html