开源中国

我们不支持 IE 10 及以下版本浏览器

It appears you’re using an unsupported browser

为了获得更好的浏览体验,我们强烈建议您使用较新版本的 Chrome、 Firefox、 Safari 等,或者升级到最新版本的IE浏览器。 如果您使用的是 IE 11 或以上版本,请关闭“兼容性视图”。
支持海量数据的 MongoDB NoSQL - 技术翻译 - 开源中国社区

支持海量数据的 MongoDB NoSQL 【已翻译100%】

oschina 推荐于 5年前 (共 20 段, 翻译完成于 01-23) 评论 9
收藏  
112
推荐标签: MongoDB NoSQL 待读

关于这个速查卡

MongoDB是一个文档型数据库,它可以方便的应用于大多数语言。这个小清单列出了MongoDB经常使用和容易忘记的一些操作,命令和技术。

配置选项

安装选项

启动MongoDB的选项可以通过命令行或者配置文件设置,两者的语法稍微有点不同,这里有一个三种选项的设置例子:

命令行 配置文件
--dbpath /path/to/db dbpath=/path/to/db
--auth auth=true
-vvv vvv=true

在mongod下运行--help可以列出所有的操作选项,但是这里我们列出了一些最常用的:

操作选项 描述
--config /path/to/config 指定其他配置选项的配置文件.
--dbpath /path/to/data 数据存储目录.
--port 27017 监听端口号.
--logpath /path/to/file.log 日志输出文件,这是个明确的文件路径,不是目录.
--logappend 重启后,以追加的方式创建日志防止把之前的日志删除了。在使用--logpath时总是开启.
--fork 把mongod配置为守护进程.
--auth 单个服务器的安全验证.
--keyFile /path/to/key.txt 副本集和分片时安全验证,需要使用一个路径共享密钥。
--nohttpinterface 关闭http访问接口
--bind_ip address 只允许指定的网络ip访问.

如果想安全的启动mongod,就要使用nohttpinterface和bind_ip操作选项,确定外网不能直接访问。尤其确保你没有其余的选项启动,MongoDB需要以下网络环境可以访问:

  • 单个服务器 - 客户端程序可以获取访问连接
  • 副本集 - 任何成员集能够访问,包括自己;客户端能够访问任何一个成员集,并且可访问的成员集都能够成为主节点(活跃节点).
  • 分片- mongos进程必须能够连接到配置的服务器和分片,分片必须能够彼此连接。客户端程序必须能够连接到mongos进程。配置服务器没必要彼此提供访问连接的支持。

所有的连接都是通过tcp建立的.

缪斯的情人
 翻译得不错哦!

查看配置

如果你6个月前启动mongod时做了一堆配置,那么现在你如何知道做了什么配置呢?这里提供了一个shell小助手:

> db.serverCmdLineOpts()
{ "argv" : [ "./mongod", "--port", "30000" ], "parsed" : { },
"ok" : 1 }

解析后的字段是从配置文件读取的一些参数列表.

使用shell

Shell帮助

当你忘记一个命令时,mongodb提供了许多功能帮助你:

> // basic help
> help
		db.help() 				help on db methods
		db.mycoll.help() 		help on collection methods
		sh.help() 				sharding helpers
		rs.help() 				replica set helpers
		help admin 				administrative help
		help connect 			connecting to a db help
		...

注意对于数据库,集合,副本集,分片,管理员等提供了单独了帮助功能。这里没有一一列出,像游标的帮助功能如下:

> // list common cursor functions
> db.foo.find().help()

你可以使用这个功能和小助手作为一个内置的备忘清单。

缪斯的情人
 翻译得不错哦!

查看方法的定义

如果你不知道一个方法是干什么用的,你可以在shell中通过去除括号的方式运行它,查看它的源码:

> // run the function
> db.serverCmdLineOpts()
{ "argv" : [ "./mongod" ], "parsed" : { }, "ok" : 1 }
> // see its source
> db.serverCmdLineOpts
function () {
	return this._adminCommand("getCmdLineOpts");
}

这可以帮助我们获悉这个方法需要什么参数和抛出什么错误,以及如何在其他语言中使用。

缪斯的情人
 翻译得不错哦!

使用编辑功能

shell命令限制多行的支持,因此在里面编写程序很费劲,shell编辑小助手让它更加简单,打开一个文本编辑器,编辑一个变量,例如:

> x = function() { /* some function we're going to fill in */ }
> edit x

在编辑器修改一个变量保存退出。这个变量就在shell里面被设定好了。

不管是编辑器的环境变量或者MongoDB shell的变量编辑环境,都必须设置使用edit模式。你可以在MongoDB shell中通过如下命令配置:

> EDITOR="/usr/bin/emacs"

编辑模式在JavaScript脚本下是无法使用的,只能在交互的shell中使用。

缪斯的情人
 翻译得不错哦!

.mongorc.js

如果你的主目录下有个.mongorc.js文件,那么当你启动shell时他就会自动运行。使用它可以初始化任何你经常使用的helper方法和你不想意外操作的删除方法.

比如,你不想使用默认的dropDatabase()方法了,你可以在.mongorc.js文件中添加下面的命令:

DB.prototype.dropDatabase = function() {
	print("No dropping DBs!");
}
db.dropDatabase = DB.prototype.dropDatabase;

上面的例子改变了dropDatabase() helper方法,使他只打印出一行信息,而没有真正的删除数据库.

注意这个技巧不是一个安全手段,固执的用户仍然可以在不使用helper前提下删除数据库。然而,移除危险的admin权限命令也可以帮助阻止“大堤的奔溃”.

几个建议在.mongorc.js中使用helper命令时移除的:

  • DB.prototype.shutdownServer
  • DBCollection.prototype.drop
  • DBCollection.prototype.ensureIndex
  • DBCollection.prototype.reIndex
  • DBCollection.prototype.dropIndexes

缪斯的情人
 翻译得不错哦!

改变提示

shell的提示可以通过一个方法设置提示变量的方式来改变:

prompt = function() {
	try {
		db.getLastError();
	}
	catch (e) {
	print(e);
	}
	return (new Date())+"$ ";
}

如果你设置了提示,每次执行时都会重新返回提示信息(上面的例子将返回最后执行的信息)。
尝试在你的提示里面调用db.getLastError()方法,这将包含默认的提示和服务器重新连接以及返回的错误信息.

同时,把任何可能出现异常的用try/catch包裹起来,那是非常恼人的,当你的提示变成了一个异常信息!

缪斯的情人
 翻译得不错哦!

操作诊断

查看和终止操作

你可以通过currentOp查看当前操作状态:

> db.currentOp()
{
	"inprog" : [
		{
			"opid" : 123,
			"active" : false,
			"locktype" : "write",
			"waitingForLock" : false,
			"secs_running" : 200,
			"op" : "query",
			"ns" : "foo.bar",
			"query" : {
			}
			...
		},
		...
	]
}

使用上面的opid字段,你可以终止这个操作:

> db.killOp(123)

不是所有的操作都能被终止或者立刻终止,通常,操作不会被终止,直到他们获取到锁.

active字段表明操作当前是否在运行,如果一个操作没有运行,通常是要么没启动,要么在等待锁,要么执行了其他操作。通过numYields你可以查看操作执行的时间.

缪斯的情人
 翻译得不错哦!

索引使用

使用explain()来查看当前查询操作使用了哪个索引.

> db.foo.find(criteria).explain()
{
		"cursor" : "BasicCursor",
		"isMultiKey" : false,
		"n" : 2,
		"nscannedObjects" : 2,
		"nscanned" : 2,
		"nscannedObjectsAllPlans" : 2,
		"nscannedAllPlans" : 2,
		"scanAndOrder" : false,
		"indexOnly" : false,
		"nYields" : 0,
		"nChunkSkips" : 0,
		"millis" : 0,
		"indexBounds" : {

		},
		"server" : "ubuntu:27017"
}

explain()输出中有几个重要的字段:

  • n: 返回记录行数.
  • nscanned: 使用索引读取的记录数量.
  • nscannedObjects: 被扫描的文档数量.
  • indexOnly: 如果查询没有使用集合本身.
  • nYields: 查询读取锁的释放时间和等待下次操作时间.
  • indexBounds: 当使用索引时,显示的索引扫描范围.

缪斯的情人
 翻译得不错哦!

游标类型
一个遍历游标(BasicCursor)意味着没有使用索引;一个B树游标(BtreeCursor)意味着使用了一个常用的索引;平行游标被用于分片;二维空间索引(geospatial indexes)使用他们自己特殊的游标。

一旦一个数组被索引,那么索引上就会设定一个“multikey”标记,这就是对上面isMultiKey字段的解释。这个标记在索引生命周期内一直保存,除非你去掉了数组的索引。

如果应用索引做查询的话,explain输出的信息里将包含索引范围字段,它描述了索引遍历到的那部分记录。比如,如果你知道你的文档里面有个age字段,并且年龄在0-120之间均匀分布,索引范围从3-5,你可以看到索引只需扫描一小部分数据就能满足你的查询需要。

 

缪斯的情人
 翻译得不错哦!

暗示(Hinting)

使用hint()能让查询强制使用一个特殊的索引:

> db.foo.find().hint({x:1})

这个暗示必须和你想使用的的索引key相匹配,你可以通过运行下面命令查看可用的索引:

> db.foo.getIndexes()

一般来说,你可以创建一个索引用于查询。如果你有一个查询和排序,建索引最合适的字段取决于你的查询。如果查询一个单一的值(如:{x:y}),索引应该这样建{queryField: 1, sortField: 1}。如果查询的是一个范围或者集合,采用这样的方式建索引可能更高效:{sortField: 1, queryField: 1}。如果你是用这个索引,MongoDB必须扫描所有的索引查找结果集,但是它可以在不使用内存排序的情况下返回有序的结果。

缪斯的情人
 翻译得不错哦!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们
评论(9)
Ctrl/CMD+Enter

@Khiyuan
你翻译监控服务这部分,我翻译上面的,ok?

引用来自“缪斯的情人”的评论

@Khiyuan
你翻译监控服务这部分,我翻译上面的,ok?

deal
Mongo的查询太牛逼了
感谢!
奔溃X 崩溃O
一直在用mongodb,不过需要谨慎使用,看起来强大,滥用了no schema在性能和维护上存在管理上的问题
不错 顶一个
55
“nYields: 查询读取锁的释放时间和等待下次操作时间.”我认为这句翻译的有问题,官方是:The number of times that the storage layer requested that the query system yield its locks.我的理解:是本次查询当中有多少次因为没拿到读取索而等待的次数
顶部