mongo 固定集合,大文件存储,简单优化 + 三招解决MongoDB的磁盘IO问题
1.固定集合
> db.createCollection('c1',{capped:true, size:, max:});//固定集合 必须 显式创建。 设置capped为true, 集合总大小xxx字节, [集合中json个数max]
{ "ok" : }
> db.c1.stats()
{
"ns" : "test.c1",
"count" : ,
"size" : ,
"storageSize" : ,
"numExtents" : ,
"nindexes" : ,
"lastExtentSize" : ,
"paddingFactor" : ,
"flags" : ,
"totalIndexSize" : ,
"indexSizes" : {
},
"capped" : ,
"max" : ,
"ok" :
}
> db.c1.insert({name:''});
> db.c1.insert({name:''});
> db.c1.insert({name:''});
> db.c1.find()
{ "_id" : ObjectId("51e28837cf05e15d315aa74a"), "name" : "" }
{ "_id" : ObjectId("51e28839cf05e15d315aa74b"), "name" : "" }
{ "_id" : ObjectId("51e2883dcf05e15d315aa74c"), "name" : "" }
> db.c1.insert({name:''});
> db.c1.find()
{ "_id" : ObjectId("51e28839cf05e15d315aa74b"), "name" : "" }
{ "_id" : ObjectId("51e2883dcf05e15d315aa74c"), "name" : "" }
{ "_id" : ObjectId("51e28845cf05e15d315aa74d"), "name" : "" }
普通集合转化为 固定集合
> db.runCommand({convertToCapped:'c1', size:});
{ "ok" : }
2.GridFS 存储大文件。 视频,大图片...
GrdiFS使用两个表来存储数据:
files 包含元数据对象
chunks 包含其他一些相关信息的二进制块.
3.性能优化
> db.c1.find().explain()//查看执行效率
{
"cursor" : "ForwardCappedCursor",
"nscanned" : , //扫描集合中文档次数
"nscannedObjects" : ,
"n" : ,
"millis" : ,
"nYields" : ,
"nChunkSkips" : ,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : { }
}
3.1建立索引
> db.c1.ensureIndex({name:}, {background:true});//后台建立索引
> db.c1.getIndexKeys();//简单的查看索引 元素
[ { "name" : } ]
> db.c1.getIndexes();//查看索引 详细信息
[
{
"v" : ,
"key" : {
"name" :
},
"ns" : "test.c1",
"name" : "name_1",
"background" : true
}
]
> db.c1.find({name:''}).explain()
{
"cursor" : "BtreeCursor name_1",
"nscanned" : ,//只查询一次
"nscannedObjects" : ,
"n" : ,
"millis" : ,
"nYields" : ,
"nChunkSkips" : ,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"name" : [
[
"",
""
]
]
}
}
建立唯一索引:
> db.c2.ensureIndex({age:}, {unique:}, {background:});//唯一索引, 索引值不得重复。
删除索引:
> db.c2.dropIndex({age:});
{ "nIndexesWas" : , "ok" : }
db.c2.dropIndexes(); //删除所有索引,除_id索引外
3.2限定返回行数, 设定返回字段数, 将集合转为固定集合
性能监控:
mongosniff --source
随着时间增长存取速度慢下来,明显感觉到。遂进行一下优化:
三招解决MongoDB的磁盘IO问题 转载
有点标题党的意思,不过下面三招确实比较实用,内容来自Conversocial公司的VP Colin Howe在London MongoDB用户组的一个分享。
申请:下面几点并非放四海皆准的法则,具体是否能够使用,还需要根据自己的应用场景和数据特点来决定。
1.使用组合式的大文档
我们知道MongoDB是一个文档数据库,其每一条记录都是一个JSON格式的文档。比如像下面的例子,每一天会生成一条这样的统计数据:
{ metric: "content_count", client: 5, value: 51, date: ISODate("2012-04-01 13:00") }
{ metric: "content_count", client: 5, value: 49, date: ISODate("2012-04-02 13:00") }
而如果采用组合式大文档的话,就可以这样将一个月的数据全部存到一条记录里:
{ metric: "content_count", client: 5, month: "2012-04", 1: 51, 2: 49, ... }
通过上面两种方式存储,预先一共存储大约7GB的数据(机器只有1.7GB的内存),测试读取一年信息,这二者的读性能差别很明显:
第一种: 1.6秒
第二种: 0.3秒
那么问题在哪里呢?
实际上原因是组合式的存储在读取数据的时候,可以读取更少的文档数量。而读取文档如果不能完全在内存中的话,其代价主要是被花在磁盘seek上,第一种存储方式在获取一年数据时,需要读取的文档数更多,所以磁盘seek的数量也越多。所以更慢。
实际上MongoDB的知名使用者foursquare就大量采用这种方式来提升读性能。见此
2.采用特殊的索引结构
我们知道,MongoDB和传统数据库一样,都是采用B树作为索引的数据结构。对于树形的索引来说,保存热数据使用到的索引在存储上越集中,索引浪费掉的内存也越小。所以我们对比下面两种索引结构:
db.metrics.ensureIndex({ metric: 1, client: 1, date: 1})
与
db.metrics.ensureIndex({ date: 1, metric: 1, client: 1 })
采用这两种不同的结构,在插入性能上的差别也很明显。
当采用第一种结构时,数据量在2千万以下时,能够基本保持10k/s 的插入速度,而当数据量再增大,其插入速度就会慢慢降低到2.5k/s,当数据量再增大时,其性能可能会更低。
而采用第二种结构时,插入速度能够基本稳定在10k/s。
其原因是第二种结构将date字段放在了索引的第一位,这样在构建索引时,新数据更新索引时,不是在中间去更新的,只是在索引的尾巴处进行修改。那些插入时间过早的索引在后续的插入操作中几乎不需要进行修改。而第一种情况下,由于date字段不在最前面,所以其索引更新经常是发生在树结构的中间,导致索引结构会经常进行大规模的变化。
3.预留空间
与第1点相同,这一点同样是考虑到传统机械硬盘的主要操作时间是花在磁盘seek操作上。
比如还是拿第1点中的例子来说,我们在插入数据的时候,预先将这一年的数据需要的空间都一次性插入。这能保证我们这一年12个月的数据是在一条记录中,是顺序存储在磁盘上的,那么在读取的时候,我们可能只需要一次对磁盘的顺序读操作就能够读到一年的数据,相比前面的12次读取来说,磁盘seek也只有一次。
db.metrics.insert([
{ metric: 'content_count', client: 3, date: '2012-01', 0: 0, 1: 0, 2: 0, ... }
{ .................................., date: '2012-02', ... })
{ .................................., date: '2012-03', ... })
{ .................................., date: '2012-04', ... })
{ .................................., date: '2012-05', ... })
{ .................................., date: '2012-06', ... })
{ .................................., date: '2012-07', ... })
{ .................................., date: '2012-08', ... })
{ .................................., date: '2012-09', ... })
{ .................................., date: '2012-10', ... })
{ .................................., date: '2012-11', ... })
{ .................................., date: '2012-12', ... })
])
结果:
如果不采用预留空间的方式,读取一年的记录需要62ms
如果采用预留空间的方式,读取一年的记录只需要6.6ms
mongo 固定集合,大文件存储,简单优化 + 三招解决MongoDB的磁盘IO问题的更多相关文章
- GitLab 之 Git LFS 大文件存储的配置
转载自:https://cloud.tencent.com/developer/article/1010589 1.Git LFS 介绍 Git 大文件存储(Large File Storage,简称 ...
- mongoDB 大文件存储方案, JS 支持展示
文件存储 方式分类 传统方式 存储路径 仅存储文件路径, 本质为 字符串 优点: 节省空间 缺点: 不真实存储在数据库, 文件或者数据库发送变动需要修改数据库 存储文件本身 将文件转换成 二进制 存储 ...
- mongo固定集合
固定集合:事先创建,大小固定 类型于环形队列,空间不足队列头文件被替换 不能手动删除文档,只能自动替换 db.ceateCollection("COLLECTION_NAME",{ ...
- ios大文件存储
I am using Erica Sadun's method of Asynchronous Downloads (link here for the project file: download) ...
- java 大文件上传 断点续传 完整版实例 (Socket、IO流)
ava两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路: 1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接操 ...
- 【好书摘要】性能优化中CPU、内存、磁盘IO、网络性能的依赖
系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上 ...
- 性能优化中CPU、内存、磁盘IO、网络性能的依赖(转)
关于系统性能优化,推荐一篇不错的博客! 系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试 ...
- 性能优化中CPU、内存、磁盘IO、网络性能的依赖
系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上 ...
- 转-性能优化中CPU、内存、磁盘IO、网络性能的依赖
转自:https://www.cnblogs.com/Javame/p/3665565.html 系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估. ...
随机推荐
- ASIHTTPRequest-Cookie的使用[转]
ASIHTTPRequest允许你使用全局存储来和所有使用CFNetwork或者NSURLRequest接口的程序共享cookie. 如果设置useCookiePersistence为YES(默认值) ...
- Layout布局源码浅析之——FrameLayout
一直想研究下安卓各种布局控件,FrameLayout是安卓最简单的界面布局,所以就从FrameLayout讲起. 1.属性.frameLayout继承ViewGroup,除了拥有ViewGroup的属 ...
- Concurrent Request:Inactive phase,No Manager status
Symptom 随便submit一个request,发现几乎所有的Concurrent Manager都为No Manager状态,Phase为Inactive. Solution 一个Concurr ...
- [Erlang28]使用匿名函数灵活组合不同的case
cowboy_http.erl里面的date1/2 启示: 以前一般写case里都是这样子: date1(Date) -> case month1(Date) of {error,badarg} ...
- Solr相似度算法四:IBSimilarity
Information based:它与Diveragence from randomness模型非常相似.与DFR相似度模型类似,据说该模型也适用于自然语言类的文本.
- C++ 模板和 C# 泛型之间的区别(C# 编程指南)
C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能. 然而,这两者之间存在许多差异. 在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C++ 模板的复杂性. 此外,C# 并不 ...
- 企业IT架构转型之道 读书笔记-1.阿里巴巴集团中台战略引发的思考
前言 1.为什么选择看这本书 2.Supercell公司的开发模式 3.“烟囱式”系统建设模式弊端,及产生这种现象的原因 4.IT人员在企业信息中心的组织职能 一.为什么选择看这本书 多日没有更新博客 ...
- JAVA—编码问题
一.编码.(引用 百度百科) 编码是信息从一种形式或格式转换为另一种形式的过程也称为计算机编程语言的代码简称编码.用预先规定的方法将文字.数字或其它对象编成数码,或将信息.数据转换成规定的电脉冲信号 ...
- 【总结】 NOIp2018考时经历记
可能我因为比较菜的原因,还是要写一下这个东西! 发布时间迟与更新时间,毕竟浙江选手为先例 那么希望NOIp8102RP++!!! 突然发现博客园支持更新创作时间了,那么就不咕了! 本次NOIp感受很深 ...
- WPF ControlTemplate 动画板 结束事件不触发
解决此问题很简单 将Storyboard单独提取出来及可 给定Key名称,然后在触发器中的BeginStoryboard的storyboard绑定即可 <!--单独提取并设置Xkey--> ...