首页 > 代码库 > Mongodb 分片

Mongodb 分片

分片(Sharding)

   

在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。

分片是将数据拆分后分发到各个节点上,所以它的各个节点上的数据是不一样的,这是跟副本集最大的差别。

分片好处之一是将数据拆分到不同节点,这样可以减少写的压力。

当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。

下图展示了在MongoDB中使用分片集群结构分布:

技术分享

上图中主要有如下所述三个主要组件:

  • Shard:

用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障

  • Config Server:

mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。

  • Query Routers:

前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

   

sharding是MongoDB进行横向扩容的方法,sharding把一个集合的不同部分存储到不同的机器上,当一个数据库集合变得很大时,你只需要加入新的机器即可。sharding自动把集合的数据分布到新的服务器上,sharding自动实现数据和读写负载均衡。

为了使集群具有sharding功能,首先需要建立一个sharding集群。然后就可以在集群内指定某个数据库是否启用sharding,在启用sharding的数据库内,可以选择哪个集合(collection)可以sharding,每个sharding的集合要有一个shard key。shard key用于决定该集合内的所有文档如何在集群内的机器上分布。shard key是一个字段,存在于每一个文档中。一个给定的分片保存了所有key值在其范围内的文档。shard key如同indexes一样,可以使单字段或多字段的。

在一个shard内,mongodb还把文档分为chunks,每个chunk代表本shard内的一个小的范围。当一个chunk的大小超过chunk size时,mongodb把chunk切分为更小的chunk,但依然属于这个shard。

shard key的选择

shard key的好坏直接影响到集群的性能,容量和能力。选择shard key要考虑数据的模式和你的应用程序读写数据库的方式。

理想的shard key具有以下特点:

    1. 易于切分,最好是无限的。

    2. 具有高度的随机性。

    3. 应该是你的请求的主要字段。

mongodb使用balancing进行分布式数据均衡。当一个shard与其它shard相比具有太多的chunk时,mongodb自动在shard间均衡数据,但应用层对此无感知。

sharding会给集群带来一些负载,在以下情况发生时,可以考虑使用sharding:

1. 数据接近或超过单个节点的存储容量。

2.系统中活动working set的大小很快将要超过系统RAM的最大容量。

3.系统有大量的写请求,单个mongodb实例不足以支持。

设计系统时,如果预见到最终需要扩容时,考虑哪个集合需要sharding,并为其设计shard key。

所有分片的集合在片键上都必须建索引,这是MongoDB自动执行的,所以如果选择某个字段作为片键但是基本不在这个字段做查询那么等于浪费了一个索引,而增加一个索引总是会使得插入操作变慢。

唯一索引问题 如果集群在_id上进行了分片,则无法再在其他字段上建立唯一索引:之所以出现这个错误是因为MongoDB无法保证集群中除了片键以外其他字段的唯一性(验证了CAP理论),能保证片键的唯一性是因为文档根据片键进行切分,一个特定的文档只属于一个分片,MongoDB只要保证它在那个分片上唯一就在整个集群中唯一。

Mongodb 分片