MongoDB

MongoDB: db-collection-document

MongoDB更类似Mysql,支持字段索引、游标操作,其优势在于查询功能比较强大,擅长查询JSON数据,能存储海量数据,但是不支持事务。


内存管理机制:MongoDB数据存在磁盘上,数据库启动后将数据以文件映射(由linux mmap()实现)的方式加载中到内存中,当内存不够时,只将热点数据放入内存,其他数据存在磁盘。

http://huoding.com/2011/08/19/107

Linux系统,内存分物理内存和虚拟内存,虚拟内存是物理内存的抽象,程序访问虚拟内存地址,然后操作系统通过Page Table机制翻译到物理内存地址。Swap交换空间不是虚拟内存,而是虚拟内存引申出的一种技术。当物理内存不足时,为腾出内存空间存放新内容,将当前物理内存中的内容放到Swap交换空间中,需要时再取回物理内存中。Swap的使用可能带来性能问题,因为需要频繁交换物理内存和Swap的内容,可增加物理内存解决。

MongoDB使用内存映射存储引擎,将数据文件映射到内存中。对于读操作,内存中的数据起到缓存作用,对于写操作,内存可以把随机的写操作变成顺序的写操作,提高性能。MongoDB的内存使用是由操作系统的虚拟内存管理器控制的(LRU算法淘汰冷数据)。



MongoDB优点:

1、弱一致性(最终一致),访问速度快

2、文档结构存储,不用定义复杂表结构,查询方便

4、性能优越,大数据量下优于关系型数据库

4、存储对象为BSON,不可被解析,安全,防范SQL注入攻击

5、扩展性好

×、自带分布式文件系统GridFS,自带对map-reduce的支持、


MongoDB缺点:

1、不支持事务操作

        跟优点1对应

2、占用空间过大

        1、空间预分配:mongodb每次空间不足都会申请一大片空间,申请空间大小指数级递增

        2、字段名占空间:为保证每一条记录都包含结构数据,每一个字段都以key-value的形式保存

        3、删除记录不释放空间:防止数据删除后其他数据的大规模挪动;原记录空间不删除,只标记为已删除;只有db.repairDatabase()后才释放,但修复时间很长


MongoDB VS MySQL

主键:_id   PRIMARY KEY

索引:优化查询性能,尽量选择小的、简单的(整型优于字符型)、非NULL的数据类型创建索引

查询速度:MongoDB充分利用内存资源,查询效率远高于通过磁盘I/O的MySQL

插入:MongoDB插入效率略高(不指定_id插入,此时_id自动生成,对相关字段做索引查询),指定_id插入效率极低



MongoDB操作:

索引

默认为_id建立索引,不可删除。索引分升序(:1)降序(:-1)。只有参数顺序相同的查询会用到对应的索引。

数据量大后建立索引很慢,可以后台执行,只需要加上参数 {backgroud:true}。

> db.test.ensureIndex({t:1},{backgroud:true})		// 建立索引
> db.test.ensureIndex({tt:1},{unique:true})		// 唯一索引,不允许插入重复键值
> db.test.ensureIndex({t:1,tt:1})			// 组合索引
> db.test.getIndexes()					// 查看集合test下所有索引
[
	{
		"v" : 1,
		"key" : {
			"_id" : 1
		},
		"ns" : "smartstock.test",
		"name" : "_id_"
	},
	{
		"v" : 1,
		"key" : {
			"tt" : 1
		},
		"unique" : true,
		"ns" : "smartstock.test",
		"name" : "tt_1"
	},
	{
		"v" : 1,
		"key" : {
			"t" : 1,
			"tt" : 1
		},
		"ns" : "smartstock.test",
		"name" : "t_1_tt_1"
	}
]
> db.test.find({"t":{$lt:30}}).hint({t:1, tt:1})	// hint强制使用索引
> db.test.find().sort({t:1,tt:1});			// 查询并排序,升降序同索引
> db.test.dropIndexes(tt_1)				// 删除单个索引
> db.test.dropIndexes()					// 删除所有索引

查询

插入

修改

删除


性能分析Explain

> db.test.find()
{ "_id" : ObjectId("5618e0ed808f3d701fb0467c"), "t" : "1" }
{ "_id" : ObjectId("561b47c0808f3d194bf0d2fd"), "t" : "1", "tt" : "2" }
> db.test.ensureIndex({"t":1})
> db.test.find({"t":1}).explain()
{
	"cursor" : "BtreeCursor t_1",
	"isMultiKey" : false,
	"n" : 0,
	"nscannedObjects" : 0,
	"nscanned" : 0,
	"nscannedObjectsAllPlans" : 0,
	"nscannedAllPlans" : 0,
	"scanAndOrder" : false,
	"indexOnly" : false,
	"nYields" : 0,
	"nChunkSkips" : 0,
	"millis" : 9,
	"indexBounds" : {
		"t" : [
			[
				1,
				2
			]
		]
	},
	"server" : "TZ-IT-Yanym:27017"
}

cursor: 返回游标类型,BasicCursor(遍历游标) 或 BtreeCursor(B树游标)
nscanned: 被扫描的文档数量
n: 返回的文档数量
millis: 总耗时(毫秒)
indexBounds: 所使用的索引


性能监控工具

1、mongosniff   此工具可以从底层监控到底有哪些命令发送给了MongoDB 去执行,从中就可以进行分析:

以root 身份执行:$./mongosniff --source NET lo
然后其会监控位到本地以localhost 监听默认27017 端口的MongoDB 的所有包请求。

2、mongostat   实时查看MongoDB实例的运行状态信息,每秒刷新一次

insert: 每秒插入量
query: 每秒查询量
update: 每秒更新量
delete: 每秒删除量
locked: 锁定量
qr | qw: 客户端查询排队长度(读|写)
ar | aw: 活跃客户端量(读|写)
conn: 连接数
time: 当前时间

3、db.serverStatus()   查看数据库实例运行状态

db.serverStatus().connections   查询连接数,连接数过多会拖累性能

db.serverStatus().mem    查询内存使用情况,还可以使用mongostat命令查看,mapped:映射到虚拟内存的大小,virtual:占用的虚拟内存大小,resident:占用的物理内存大小,faults:每秒访问失败数,faults高时性能下降

4、db.stats()   查询数据库状态信息:数据大小,索引大小



COMMANDS:

db.listCommands()

db.repairDatabase() / db.runCommand({repairAllDatabase:1}) MongoDB碎片整理(产生锁,对磁盘空间需求大)

db.runCommand({closeAllDatabases:1}) (先use admin) 释放MongoDB占用的内存



常用性能优化方案
    创建索引
    限定返回结果数
    只查询使用到的字段
    采用capped collection
    采用Server Side Code Execution
    使用Hint,强制使用索引
    采用Profiling


优化器Profiling(对应MySQL的慢查询日志)

MongoDB Database Profiler

1、开启profiling

两种开启方式,一是启动参数加上 -profile=[级别],二是调用db.setProfilingLevel(级别)。

共有三个级别:0-不开启;1、记录慢命令(默认为>100ms);2、记录所有命令。

两种方式设置慢命令时限,一是启动参数加上 -slowms,而是db.setProfilingLevel加上第二个参数db.setProfilingLevel(level, slowms)。

2、查询profiling记录

Profiler的日志记录在数据库里,位于system.profile,

> db.system.profile.find( { millis : { $gt : 5 } } )// 列出执行时间长于某一限度(5ms)的Profile记录:
> show profile // 列出最近5 条执行时间超过1ms 的 Profile 记录


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值