欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

【MongoDB】在windows平台下mongodb的分片集群(五)

程序员文章站 2022-06-01 20:05:02
...

本篇接着上面的四篇继续讲述在window平台下mongodb的分片集群搭建。在分片集群中也照样可以创建索引,创建索引的方式与在单独数据库中创建索引的方式一样。因此这不再多说。本篇主要聚焦在分片键的选取问题上。 分片键通俗来说就是分割海量数据的标记符。 如

本篇接着上面的四篇继续讲述在window平台下mongodb的分片集群搭建。在分片集群中也照样可以创建索引,创建索引的方式与在单独数据库中创建索引的方式一样。因此这不再多说。本篇主要聚焦在分片键的选取问题上。

分片键通俗来说就是分割海量数据的标记符。 如果更高效的划分海量数据往往依赖于分片键的选择。 分片键选得不好,应用程序就无法利用分片集群所提供的诸多优势。在这种情况下,查询和插入得系能都回显著下降。

一、低效的分片键

1.1 分布差

BSON对象ID是每个mongodb文档的默认主键。所有的对象ID最重要的组成部分是时间戳,也就是说对象ID是升序的,遗憾的是升序对于分片键来说是很糟糕的。由于分片是基于范围的。使用升序的分片键后,所有最近插入的文档会落在某个很小的连续范围内。如果想让插入负载分不到多个分片上,就不能使用升序分片键,应需某些随机性更强发的的东西。

1.2 缺乏局部性

升序分片键由明确的方向,完全随机的分片键根部没有方向。前者无法分散插入,而后者则可能将插入分散太慢。假设分片集合中每个文档都包含一个MD5,而MD5字段就是分片键。因为MD5随着文档的不同而进行变化。所有该分片键能确保插入的文档均匀分布在集群的分片上。但是有个问题,对于每个分片的MD5字段索引进行的插入过程中,索引中每个虚拟内存分页都有可能被访问到。这就意外着有可能所有的索引和数据都装在内存中。从而超出了物理内存。

3. 无法拆分的块

随机分片键和升序分片键都不好用,那么就尝试一下粗粒度分片键。举个例子,例如用户Id上传了100张照片,那么分片键就是用户ID,第一原因对于每张照片来说具有随机性,同时可以通过局部性引用来提升效率。但有个问题就是当用户ID上传的照片太大时候,以至于不得不分块。而系统又不能把一个用户的照片拆分成多个快。

二、理想的分片键

通过上面分析,理想的分片键应该满足:
1. 将插入数据均匀分布到各个分片上 2.保证crud操作能够利用局部性 3. 有足够的粒度进行块划分
举个例子:创建一个网站分析系统,一个不错的数据模型就是每个网页每月保存一个文档,随后在那个文档中保持该月每天的数据,每次访问某个页面增加一些计数器字段。下面是于分片键有关的实例分析文档:
{ _id: objectId("34535353245eraf32223sdarwe") domin:"org.mongod" url:"download" perid:"2011-12" }
最简单的分片就是包含每个网页的域名,随后是url{domain:1, url:1}所有来自指定域的页面通常都落在一个分片上,但是一些特殊的域拥有大量页面,在必要时候仍会被拆分到分片上。

备注:本篇内容大多引自《MongoDB in action》 Kyle Banker著