分区:在Mongo/ES和Solr被称为分片(shard),在HBase中称为区域(Region),Bigtable中是表块(tablet),Cassandra和Riak中是虚节点(vnode),Counchbase中叫做虚桶(vBucket).
分区主要是为了可扩展性,不同的分区可以放在非共享集群的不同节点上,每个节点可以独立执行对自己的查询.
分区通常与复制结合,使得每个分区副本存储在多个节点上.即每条记录虽然只属于一个分区,但是可以存储在不同的节点上(复制)获得容错能力.
偏斜(skew):分区不平衡,导致一些分区比其他分区有更多数据或者查询.偏斜会使数据分区效率下降,高负载分区称为热点(hot spot).
Bigtable和HBase使用了这种策略.Cassandra和Mongo的散列分区模式使用这种策略.user_id, update_timestamp)建立索引,不同用户在不同分区上,同一个用户更新时间存储在单个分区上.这样可以有效检索特定用户在某个时间段内的按时间戳排序的所有更新(使用键的一部分来标识分区,而使用另一部分作为排序顺序).根据主键可以确定分区,并且将请求路由到该分区.而次级索引在分区中的问题是不能整齐地映射到分区.
Mongo/Riak/Cassandra/ES/SolrCloud和VoltDB都使用这种方式.最好采用能在单个分区上提供二级索引查询的分区方案.Riak的搜索功能和Oracle采用此种方式.当现有的节点不能满足实际情况时,诸如查询吞吐量增加,数据集变大,机器故障,需要将数据和请求从一个节点移动到另一个节点.
当使用hash mod N,其中N是节点数,节点发生变化,大量数据都要重新移动,并不是一种好的方案.如何只移动必需数据?
Riak/ES/Couchbase/Voldemort使用这种方案.HBase和Mongo 2.4都使用这种方法.Cassandra和Ketama采用与节点数量相关的分区方式: 每个节点具有固定数量的分区.每个分区大小与数据集大小成比例增长,节点数量保持不变.当节点增加时,分区将再次变小(当一个新节点加入集群时,它随机选择固定数量的现有分区进行拆分,然后占有这些拆分分区中每个分区的一半,同时将每个分区的另一半留在原地).发起请求时如何决定应该将请求发送至哪个节点呢?
ZooKeeper来跟踪集群元数据.Espresso/HBase/Solr和Kafka都使用ZK跟踪分区分配.Mongo依赖于自己的配置服务器,Cassandra和Riak在节点之间采用Gossip协议传播集群状态变化.原文:https://www.cnblogs.com/yuyinzi/p/15183700.html