分区
解决问题:解决可扩展性
分区与复制
通常分区与复制是结合在一起的(多副本)
键值的分区
根据键的范围分区
- 每个分区可用SSTable以顺序方式保存键
- 缺点:某些特定访问模式会产生访问热点
- 解决方法:尝试用多个字段组合来创建键
根据键的HASH分区
-
保证平衡性但失去高效范围查询的能力
-
Cassandra折中策略
- 复合主键的第一列作为分区键,而后续键作为SSTable排序数据连接索引,虽不能在第一列做高效范围查询,但后续列可进行范围扫描
负载倾斜与消除热点
- 基于应用层,由用户控制编写程序将热点数据打散至各分片,只对热点数据作处理
分片与次级索引
键值的分区是针对于主键
按文档的二级索引(本地索引)
-
每个分区有独立的二级索引,该索引只对本分区的文档建立
- MongoDB,Riak 【15】,Cassandra 【16】,Elasticsearch 【17】,SolrCloud 【18】和VoltDB 【19】
根据关键词的(全局索引)
-
按关键词分区,对关键词范围分区或对关键词的HASH值进行分区
- 范围分区利于范围扫描
- HASH分区利于负载均衡
-
特点
-
优点
- 读取查询索引时只需要查询一个分区
-
缺点
- 写入时可能会修改多个分区
-
写入的文档与关键词索引构成分布式事务
-
通常全局索引的写入是异步的
-
分区再平衡
反面教材:HASH MOD N,扩容(如MOD9 改为 MOD10)会造成大量数据迁移
固定数量分区,从原节点中迁移部分分区使负载能够平衡
-
由于数据集大小很难预估,具体固定多少数量的分区难以确定
- Riak 【15】,Elasticsearch 【24】,Couchbase
【10】和Voldemort 【25】
- Riak 【15】,Elasticsearch 【24】,Couchbase
动态分区
-
在分区大小超过一定值后,分离分区;小于一定值后,合并分区
- 如HBase和RethinkDB
-
初始时数据集很小,只会有一个分区,随着分区的增大才会分离出多个分区。对于多节点的集群负载不均衡。
- HBase和MongoDB采用预分区
- MongoDB 2.4以后同时支持范围和哈希分区,并且都是进行动态分割分区
按节点比例分区
-
每个节点负责固定数量的分区,当集群添加节点时,随机选择固定数量的分区,从选中的分区中分一半数据移至新节点
- 实例:Cassandra和Ketama
请求路由
路由转发
- 客户端连接其中一个节点,如果访问的数据不在该节点,则将请求转发至对应节点,接收回复并传回客户端
- 添加路由层
- 由客户端直接连接有数据的节点,需要客户端管理路由
节点分区分配状况改变了如何感知?
-
依赖于配置服务
-
集中式
-
ZK
- Espresso HBase,SolrCloud和Kafka
-
自建
- MongoDB
-
-
分布式
-
基于GOSSIP传播协议,每个节点均保存分区节点的配置状况
- Cassandra和Riak
-
-