前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mongodb分片模式分片键的选择

mongodb分片模式分片键的选择

作者头像
山行AI
发布2019-06-28 11:15:16
6.2K0
发布2019-06-28 11:15:16
举报
文章被收录于专栏:山行AI

1. 分片介绍

官方说明:

代码语言:javascript
复制
Sharding is a method for distributing data across multiple machines. MongoDB uses sharding to support deployments with very large data sets and high throughput operations.

分片就是一种把数据分布在多台机器上的方法。mongodb使用分片来支持大数据量、高吞吐量的布署。

一个分片集群的结构见图:

shard server:用于存储实际的数据块,每个分片存储部分分片数据,每个分片都可以布署成其他分片的副本集(replica set)。实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障。 config server:顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。 mongos server:协调中心。数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。

2. 部署流程

关注之后文章或参考官网:https://docs.mongodb.com/manual/sharding/

3. 一些概念

1. collection

mongodb是通过一个个collection来做数据存储的,可以类比关系型数据库的表。

2. 分片键

mongodb是通过分片键来对collection进行分区的,也就是通过分片键来决定一个document如何分布式存入collection中。分片键是每个存放在collection中的document都持续拥有的不可缺少的一个字段或多个字段的组合。 分片键有下面几个要求:

  • 每个document都必须拥有,不可缺少。
  • 已经分片的数据,分片键不可更改。
  • 分片键必须加上索引。
  • 分片键的选择对分片的性能、效率和可扩展性都有着重要影响。分片键和索引也会影响集群的分片策略。

3. 声明分片键

代码语言:javascript
复制
sh.shardCollection( namespace, key )
  • namespace是一个 .类型的字符串;
  • key是一个document的组成部分,而且它的索引是横向索引。 参考:https://docs.mongodb.com/manual/core/sharding-shard-key/#sharding-shard-key-creation

4. 分片键索引

分片键必须有索引,索引可以是分片键上的索引,当分片键是索引前缀时,也可以是复合索引。 注意:分片键索引必须是横向(正向),比如用id做索引时定义为key{id:1} 参考:https://docs.mongodb.com/manual/core/sharding-shard-key/#sharding-shard-key-indexes

5. 分片键的基数(散列度)

分片键的基数(散列度)决定了balancer创建的块(chunks)的最大数量。如果一个分片键只有一个值,那么它最多只会存放在一个区块(chunks)中。如果一个分片键有四个取值,那么分片集群中至多有四个区块(chunks),每个区块保存唯一的的个分片键对应的值。 对于一个以字段X做为分片键的集群,如果X的散列度比较低,那么数据分布大至如下图:

一个分片键的散列程度很高时,并不能保证在集群中是均匀分布的,但是一个高散列度的分片键更易于水平扩展。如果你的分片键有较低的散列度,最好考虑使用组合索引,用这个字段与另一个有相对比较高散列度的字段一起组合。

6. 分片键数据值的频率

分片键的频率是指,一个数据值重复出现的频率。如果主要的document中重复的数据大量出现,那么保存这些数据的区块(chunks)会变成集群中的瓶颈。之后,当这些区块越来越大时,它们会变成不可分割开的区块,这将很大程度上影响集群的可拓展性。

如果X为分片键,当某些数据出现频率比较高时,数据分布大致如下图:

还有一点就是当分片键出现频率低时是不能保证集群数据的均匀分布的。如果你的数据模型要求数据分片键要建立在一个高频率出现的数据上,考虑使用组合索引,与唯一的或者低频率的值进行组合。

参考:https://docs.mongodb.com/manual/core/sharding-shard-key/#sharding-shard-key-creation

7. 单调变化的分片键

分片键的数据值单调递增或单调递减时就比较像是把数据插入集群的一个单一分片里面了。这是因为集群中的区块有一个最大值(maxKey)和一个最小值(minKey)的临界点,也就是说有一个区块的上界是maxKey,也会有一个区块的下界是minKey。 如果数据是单调递增的,会导致所有新插入的数据都进入以maxKey为上界的区块中去。如果单调递减,会导致新插入数据进入以minKey为下界的区块中去。 比较形象的见下图(以X为分片键时):

如果分片键X上的数据是单调递减的,所有的数据都会进入Chunk A。

如果你的数据模型要求分片键上的值单调变化,考虑使用Hashed Sharding分片策略,见下面介绍。

8. 分片策略

mongodb有两种分片策略,分片策略是根据分片键的选择来定的:

1. Hashed Sharding: 使用hashed index来对数据进行分区。它计算单一字段上的hash值作为索引值和分片键。

如果要使用hash分片键,首先分片键数据散列度必须要高,拥有很多不同的值。hash散列键对单调变化的数据比如ObjectId和时间戳是比较好的方案。一个好的例子就是_id。 使用hash分片键:

代码语言:javascript
复制
sh.shardCollection("<database>.<collection>", { <shard key> : "hashed" } )

参考:https://docs.mongodb.com/manual/tutorial/deploy-sharded-cluster-hashed-sharding/

2. Ranged Sharding

通过分片键的值来将数据分成不同的范围。它可以提供比较快的范围查询,但是当分片键选择不好的时候,也会降低读写性能 。 如果没有配置Hashed Sharding或者zones(https://docs.mongodb.com/manual/core/zone-sharding/#zone-sharding)它是默认的分片键方法。

代码语言:javascript
复制
sh.shardCollection( "database.collection", { <shard key> } )

大致分布见下图:

3. zones sharding

The following image illustrates a sharded cluster with three shards and two zones. The A zone represents a range with a lower boundary of 1 and an upper bound of 10. The B zone represents a range with a lower boundary of 10 and an upper boundary of 20. Shards Alpha and Beta have the A zone. Shard Beta also has the B zone. Shard Charlie has no zones associated with it. The cluster is in a steady state and no chunks violate any of the zones.

For example, given a shard key { a : 1, b : 2, c : 3 }, creating or updating a zone to cover values of b requires including a as the prefix. Creating or updating a zone to covers values of c requires including a and b as the prefix. 创建shard tag:

代码语言:javascript
复制
sh.addShardTag("shard0000", "NYC")sh.addShardTag("shard0001", "NYC")sh.addShardTag("shard0002", "SFO")sh.addShardTag("shard0002", "NRT")

创建zone rang:

代码语言:javascript
复制
sh.addTagRange("records.users", { zipcode: "10001" }, { zipcode: "10281" }, "NYC")sh.addTagRange("records.users", { zipcode: "11201" }, { zipcode: "11240" }, "NYC")sh.addTagRange("records.users", { zipcode: "94102" }, { zipcode: "94135" }, "SFO")

参考:https://docs.mongodb.com/manual/tutorial/manage-shard-zone/

与hashed shard key一起使用时,zone的范围一般要覆盖minKey和maxKey才可以。 参考:https://docs.mongodb.com/manual/core/zone-sharding/#zone-sharding

4. hashed sharding与ranged sharding区别

主要在单调数据的场景,不使用hash时:

数据会集中放入一个chunks中。 使用hash时:

5. 问题

  • MongoDB在分片后的集合上进行db.collection.count()操作时,出现结果不准确的现象,需要采用聚合的方法获取集合的count结果。要用aggregate代替:
代码语言:javascript
复制
db.collection.aggregate( [   { $count: "myCount" }])

代码语言:javascript
复制
db.collection.aggregate( [   { $group: { _id: null, count: { $sum: 1 } } }   { $project: { _id: 0 } }] )

参考:https://docs.mongodb.com/manual/reference/method/db.collection.count/

  • mongodb中string类型可以使用Numberlong转换。
  • mongodb中的update incr方法支持原子操作。
  • java中存储时,可以自己定义DefaultMongoTypeMapper去掉。
  • mongodb 的maxinum bason document size是16M。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发架构二三事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 分片介绍
  • 2. 部署流程
  • 3. 一些概念
    • 1. collection
      • 2. 分片键
        • 3. 声明分片键
          • 4. 分片键索引
            • 5. 分片键的基数(散列度)
              • 6. 分片键数据值的频率
                • 7. 单调变化的分片键
                  • 8. 分片策略
                    • 1. Hashed Sharding: 使用hashed index来对数据进行分区。它计算单一字段上的hash值作为索引值和分片键。
                    • 2. Ranged Sharding
                    • 3. zones sharding
                    • 4. hashed sharding与ranged sharding区别
                  • 5. 问题
                  相关产品与服务
                  云数据库 MongoDB
                  腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档