首页 MongoDB实践总结

MongoDB实践总结

举报
开通vip

MongoDB实践总结Mongodb实践总结2012年3月目录NoSQL数据库介绍MongoDB简介数据文件及内存索引最佳实践备份及恢复Sharding机制监控及诊断测试及总结NoSQL数据库介绍随着互联网WEB2.0网站的兴起,传统关系型数据库力不从心数据库高并发读写的需求数据库并发负载非常高,往往每秒数万次读写请求,磁盘IO瓶颈海量数据的高效率访问的需求对数亿甚至数十亿的记录高效查询高可扩展性和高可用性的需求7*24小时高可用,Failover,易扩展NoSQL数据库介绍对于互联网海量数据来说,许多SQL特性无用武之地数据的一致性需...

MongoDB实践总结
Mongodb实践总结2012年3月目录NoSQL数据库介绍MongoDB简介数据文件及内存索引最佳实践备份及恢复Sharding机制监控及诊断测试及总结NoSQL数据库介绍随着互联网WEB2.0网站的兴起,传统关系型数据库力不从心数据库高并发读写的需求数据库并发负载非常高,往往每秒数万次读写请求,磁盘IO瓶颈海量数据的高效率访问的需求对数亿甚至数十亿的 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 高效查询高可扩展性和高可用性的需求7*24小时高可用,Failover,易扩展NoSQL数据库介绍对于互联网海量数据来说,许多SQL特性无用武之地数据的一致性需求很多场景对读一致性要求较低,事务系统成为高负载下的负担数据的读写绝对实时性需求Feed/微博系统,发送一条微博并不需要马上被粉丝读到复杂SQL查询,表关联需求多数业务只是单表查询或主键关联,SQLParser大量消耗CPU资源NoSQL数据库介绍传统SQL数据库时代对大数据的处理单表单库时代:用户不停的增长、数据量增大导致压力过大Replication及主从分离分表分库时代:按业务key分片到不同的库,通常按取模算法增加维护成本,不停的重复劳动没有完美的ShardingFramework(Hivedb,限制Order/Join)NoSQL数据库介绍需要的存储:高性能、分布式、易扩展Nosql=NotOnlySQL根据海量数据特点补充关系型数据库的不足NoSQL数据库介绍类型部分代表特点key-value存储DynamoTokyoCabinetBerkeleyDBVoldemortMemcacheDBRedisLevelDB可以通过key快速查询到其value/list。value是最灵活及易扩展的数据结构,一般来说,存储不管value的 格式 pdf格式笔记格式下载页码格式下载公文格式下载简报格式下载 ,照单全收。灵活性和复杂性是双刃剑:一方面可以任意组织文档的结构,另一方面查询需求会变得比较复杂列存储BigTableHbaseCassandraHypertable鉴自Google的BigTable,按列存储。方便存储结构化和半结构化数据,方便数据压缩,对针对某一列或者某几列的查询有非常大的IO优势文档存储MongoDBCouchDBRiak一般用类json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,而且可以实现关系数据库的某些复杂查询功能图存储Neo4jFlockDBHyperGraphDB数据并非对等的,关系型的存储或者键值对的存储,可能都不是最好的存储方式,图存储是图形关系的最佳存储NoSQL数据库介绍CAP理论介绍C:Consistency一致性,任何一个读操作总是能读取到之前完成的写操作结果A:Availability可用性,每一个操作总是能够在确定的时间内返回P:Toleranceofnetwork Partition分区容忍性,在出现网络分布的情况下,仍然能够满足一致性和可用性最多只能同时满足以上两种需求ConsistencyAvailabilityTolerancetoNetworkPartitionsNoSQL数据库介绍I/O的五分钟法则JimGray与GianfrancoPutzolu发表了“五分钟法则”,如果一条记录频繁被访问,就应该放到内存里,否则的话就应该待在硬盘上按需要再访问,这个临界点就是五分钟memoryisthenewdisk,anddiskisthenewtape.—JimGray对于随机访问,硬盘慢得不可忍受;但如果你把硬盘当成磁带来用,它吞吐连续数据的速率令人震惊;它天生适合用来给以RAM为主的应用做日志结论:把随机读写交给RAM,磁盘尽量用作顺序读写及持久化NoSQL数据库介绍ConsistentHashing传统分布式架构:Hash()modnorLinearhashing问题,增删节点或节点失效会引起所有数据重新分配一致性哈希架构:每台Server分成v个虚拟节点,把n台机器的所有虚拟节点哈希映射到一致性哈希环上,增加数据按顺时针寻找第一个vnode节点存储。节点增删只影响两个节点之间的数据重新分配NoSQL数据库介绍QuorumNRW机制N:复制的节点数量R:成功读操作的最小节点数W:成功写操作的最小节点数通过,W+R>N保证强一致性场景举例:W=1,R=N,对写操作要求高性能高可用R=1,W=N,对读操作要求高性能高可用W=Q,R=QwhereQ=N/2+1读写之间取得平衡NoSQL数据库介绍Vectorclock一个(node,counter)的列表,记录数据历史版本冲突解决:业务逻辑或时间戳NoSQL数据库介绍节点间的通信传统解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 :heart-beat,pingGossip 协议 离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载 ,类P2P病毒式传播,去中心化通过gossip,每个节点都能知道集群中包含哪些节点,以及这些节点的状态,使得集群中的任何一个节点都可以完成任意key的路由,任意一个节点不可用都不会造成灾难性的后果MongoDB简介MongoDB介绍一种可扩展的高性能的开源的面向文档的数据库,C++开发10gen公司支持与推广,名字从humongous中截取,野心不言而明文档完善,官方文档覆盖了所有问题一直维持着较快的版本更新速度对社区关注度高,积极推动社区活动红杉等著名投资机构共融资3000万美金,后续升级及服务有保障MongoDB简介MongoDB主要特性ReplicaSetAutomaticfailover轻松增删数据结点Sharding自动分片自动数据迁移mongos自动路由数据管理及监控对单个文档的原子更新对任意属性可建立索引数据监控命令工具丰富查询支持丰富的查询语法查询优化及监控机制完善MongoDB简介术语对照RDBMSMongoDBTableCollectionRow/RecordDocumentColumnnameFieldnameIndexIndexJoinEmbedding&LinkdingPartitionShardPartitionKeyShardingKeyMongoDB简介BSON及数据类型BinaryJSON是一种类JSON二进制形式的存储格式,支持内嵌的文档对象和数组对象基本JSON数据类型:string,integer,boolean,double,null,array和object包括JSON没有的数据类型:timestamp,objectid,binarydata,regularexpression和codeMongoDB简介ObjectId详解被设计为跨机器分布式环境中全局唯一的类型,长度12个字节0-3这4个字节是时间戳(timestamp)4-6这3个字节是机器码(machine)7-8两个字节是进程id(pid)9-11是程序自增id或随机码(inc/random)Note1:查询时db.collection.find({_id:”xx”})查不到结果,正确写法是db.collection.find({_id:newObjectId(“xx”)})Note2:转成字符串,需要24字节(每字节转成2字节的16进制表示)Note3:_id保证collection唯一,可以是任意简单类型,不能是array/list,插入或保存为空时则自动生成MongoDB简介MongoDB插入操作:vardata={'name':'lisn','mobile':13520663641,'email':'lsn1996@163.com'}usetestdb.user.insert(data)db.user.save(data)两种操作区别:insert操作如果主键(_id)存在则不做任何处理,save操作如果主键(_id)存在则进行记录更新MongoDB简介MongoDB更新操作:更新语法:db.collection.update(criteria,objNew,upsert,multi)criteria:update的查询条件,类似sqlupdate查询内where后面的条件objNew:update的对象和一些更新的操作符(如$inc,$set...)等,类似sqlupdate查询内set后面的条件upsert:这个参数的意思是,如果不存在update的记录,是否插入,true为插入,默认是false,不插入multi:mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新Updatemodifier:$inc$push$pushAll$pull$pullAll$addToSet$set$unset…都是原子操作,可以混搭MongoDB简介MongoDB查询操作:查询实例:db.user.find({'name':'lisn'})db.user.find({'mobile':{$gte:13500000000}}).limit(10)db.user.find({}).sort({'mobile':1})db.user.find({'name':'lisn'},{'mobile':1})db.user.find().skip(10)db.user.count()Selectmodifier:$gt$lte$all$exists$mod$ne$in$nin$or$nor$size$where$type…正则表达式:db.user.find({‘name’:/l.*n$/i}),查询以l开头以n结尾的记录Distinct:返回指定字段的value列表,db.user.distinct('name')MongoDB简介Cursor:返回结果集的都隐式创建游标,服务端会清理关闭cursorvarcursor=db.user.find();while(cursor.hasNext()){varobj=cursor.next();print(tojson(obj))}查询一致性:通过对cursor进行snapshot()操作来保证一致性读,此时再进行插入或删除符合条件的记录时,结果集将不再变化,mongodb对小于1M的结果集自动进行snapshotMongoDB简介Cappedcollection:性能出色的有着固定大小的集合,以FIFO规则和插入顺序进行age-out处理可以插入及更新,不允许删除,可用drop()删除集合中数据创建时需预先指定大小,默认不对_id创建索引db.createCollection("cappedcoll",{size:10000000,autoIndexId:false})普通集合转化:db.runCommand({"convertToCapped":“user",size:10000})TailableCursor作用于cappedcollection,操作完成后可不关闭,阻塞等待新的集合元素,常用于实现消息队列或数据推送功能数据文件及内存MongoDB每个数据库都有自己的独立文件,如果开启directoryperdb选项,则每个库的文件会单独放在一个文件夹里每个库由一个名字空间文件和多个数据文件组成,名字空间文件以.ns结尾,数据文件按照数据量大小由0开始增长,第一个数据文件为64M,翻倍增长直至2G.ns文件保存数据库所有名字空间,每一个集合、索引都将占用一个命名空间以保存元数据。默认16M最大为2G,启动时可通过nssize参数选项更改ns文件大小以增加可创建集合及索引个数使用预分配数据文件方式来保证写入性能的稳定(可用–noprealloc关闭)。预分配在后台进行,并且每个预分配的文件都用0进行填充数据库启动后会产生一个6bytes的mongd.lock数据文件,用于防止同一个实例多次运行,非正常退出后需要删除此文件才能重启成功数据文件及内存名字空间文件保存的是一个hashtable,保存了每个名字空间的信息,其内容为存储信息元数据,包括其大小,块数,第一块位置,最后一块位置,被删除的块的链表以及索引信息每个数据文件被分成多个数据块(Extent),用双向链表连接。头部包含了块的元数据:自己的位置,上一个和下一个块的位置以及块中第一条和最后一条记录的位置指针。剩下部分存储具体的数据记录,也是通过双向链接来进行连接每条记录中头部包含记录元数据,如:头部长度,块中的位置偏移,上一条和下一条记录的位置。剩余是具体数据内容,如果padding>1则实际长度大于数据内容本身长度数据文件及内存内存管理采用OS的MMAP内存映射机制,把数据文件映射到内存中,读操作可以起到缓存作用,写操作可由内存转化成顺序磁盘写入操作系统虚拟内存管理器会托管所有磁盘操作,这样MongoDB内存管理实现会很简单,缺点是人工没有办法控制占多大内存32位主机最大寻址4GB,1GB用于kernel,约0.5GB用于MongoDBStack空间,剩下约2.5G可用于映射数据文件,超出报”mmapfailedwithoutofmemory”64位主机最大可映射128TB数据数据文件及内存可通过mongo命令行来监控MongoDB的内存使用情况:db.serverStatus().mem{"resident":22346,"virtual":1938524,"mapped":962283}相关字段含义:mapped:映射到内存的数据大小virtual:占用的虚拟内存大小resident:占用物理内存大小索引最佳实践MongoDB索引简介:MongoDB的索引跟传统数据库的索引相似,一般的如果在传统数据库中需要建立索引的字段,在MongoDB中也可以建立索引。MongoDB中_id字段默认已经建立了索引,并且不可删除,CappedCollections例外单个collection最多有64个index,单个query只会选择1个indexKey大小超过800字节不能被索引,会提示警告索引数据结构采用B树,每个节点数据由8k大小的Bucket承载。Bucket中的每个key由两部分组成,一部分是排好序的KeyNodes,其中保存子节点及记录值的disklocation,另一部分是索引值本身KeyObject,两部分通过每个KeyNode中的offset字段相关联索引最佳实践B树索引示例索引最佳实践B树索引结构索引最佳实践B树索引结构索引最佳实践普通索引:db.user.ensureIndex({mobile:1})其中1表示升序,-1表示降序db.user.getIndexes()[{"v":1,"key":{"_id":1},"ns":"test.user","name":"_id_"},{"v":1,"key":{"mobile":1},"ns":"test.user","name":"mobile_1"}]索引最佳实践唯一索引:创建命令:db.users.ensureIndex({name:1},{unique:true})创建唯一索引后如果插入一条name已经存在的数据会报duplicatekeyerrorindex错误添加dropDups选项可强制将重复的项删掉:db.users.ensureIndex({name:1},{unique:true,dropDups:true})索引最佳实践复合索引:MongoDB可对多个字段建立复合索引,字段后面的1表示升序,-1表示降序,是用1还是用-1主要是跟排序的时候或指定范围内查询的时候有关的示例:db.user.ensureIndex({name:1,mobile:-1})利用复合索引的多值性,可以通过以索引字段开头的组合条件进行查询,例如:以a,b,c三个字段建立索引,则查询可利用索引的查询条件为:a或者a,b或者a,b,c索引最佳实践多值索引:可对array或文档建立索引,生成索引时会分别生成多个索引元素多值索引示例:db.data.insert({name:“lisn",address:{city:“beijing",state:“haidian"}});db.data.ensureIndex({address:1});db.data.find({address:{city:“beijing",state:“haidian"}});db.data.find({address:{$gte:{city:“beijing“}}});db.data.find({address:{state:“haidian”,city:“beijing”}});无法利用索引索引最佳实践稀疏索引(1.8+):Sparseindex解决索引文件过大的问题,普通索引会对所有记录建立索引,由于MongoDB的Schemafree的特性,每个Collection中的记录属性可能不一致,sparseindex只索引包含指定属性的记录,不会对该项值为空的记录进行索引,某些情况下会大大减少索引大小示例:db.user.ensureIndex({name:1},{sparse:true})限制:目前只能包含一个属性索引最佳实践地理位置索引:此索引是MongoDB的一大亮点,也是foursquare选择它的原因之一。原理是建立索引时根据坐标对平面进行多次geohash,近似查询时就可以利用相同前缀的geohash值,mongoDB默认进行26次geohash,hash次数可控示例:db.map.ensureIndex({point:“2d”})db.map.find({point:[50,50]})db.map.find({point:{$near:[50,50]}})db.map.find({point:{$within:{$box:[[40,40],[60,60]]}}})索引最佳实践索引管理:可通过往system.indexes中插入记录来创建索引,如varspec={ns:“test.user",key:{‘name’:1},name:‘name_index’}db.system.indexes.insert(spec,true)删除索引命令:db.user.dropIndexes()删除该集合所有索引db.user.dropIndexes({name:1})db.runCommand({dropIndexes:'user',index:{name:1}})db.runCommand({dropIndexes:'user',index:'*'})索引重建:db.user.reIndex()索引最佳实践利用查询 计划 项目进度计划表范例计划下载计划下载计划下载课程教学计划下载 进行分析:使用命令:db.collection.find(query).explain();{"cursor":"BasicCursor","indexBounds":[],    "nscanned":40,    "nscannedObjects":40,    "n":40,    "millis":0,       ….}简单说明cursor:返回游标类型(BasicCursor或BtreeCursor)nscanned:被扫描的文档数量,如果过高可能无索引利用n:返回的文档数量millis:耗时(毫秒)indexBounds:所使用的索引索引最佳实践优化及注意事项:Skip函数无法利用索引,对跳过的数据也会进行扫描,如果对页面个数无严格大小要求,可考虑记录时间戳状态进行分页查询db.user.totalIndexSize()查询索引大小,Memory>Index+hotdata是高性能的保障创建索引会添加全局写锁,如果数据比较大,会挂起读写数据库的操作。可添加background选项,db.user.ensureIndex({name:1},{background:true})不同的数据类型对索引大小影响很大,开发前对字段数据类型的设计很重要备份及恢复MongoDB可靠性日志Journal:通过journal日志保证单机的可靠性,启动时可通过选项—journal决定是否开启,会预分配日志空间。journal采用groupcommit机制进行提交,避免频繁的IO操作,默认100ms,可调整oplog:多机replication机制通过oplog来实现,primary/master向oplog写操作记录,通过集群复制oplog并replay来达到replication目的。oplog是cappedcollection,所以老的日志会被overwrite,如果secondary/slave落后主节点数据量超过oplog大小,会被认为是stalenode,将进行全部primarysync操作,所以需要根据网络状况预先设置好oplogSize备份及恢复MongoDBReplication机制两种机制:Master-SlaveorReplicaSet(RS)备份及恢复ReplicaSet:以master-slave复制模式为基础,增加了auto-failover和auto-recovery的功能理论上需要三个实例,最小集为2个mongod+1个arbiter当主节点fail后,集群自动选举新的primary客户端自动切换新的primary节点进行读写操作实现读写分离功能,只有primary可写,其余secondary可读可以设置被动节点(passivemembers),该节点永远不会成为primary可以设置延迟节点(delayednodes),保持与primary一段时间的数据延迟可以设置隐藏节点(hiddennodes),此节点不提供线上服务备份及恢复ReplicaSet配置:使用--replSet参数启动mongod服务,此时log会打印告警信息提示没有初始化集群配置,system.replsetconfigfromselforanyseed(EMPTYCONFIG)在集群中任意节点运行replSetInitiate进行初始化rs.initiate({_id:"set",members:[{_id:0,host:"172.21.1.197:27018",priority:0},{_id:0,host:"172.21.1.197:27017"},{_id:1,host:"172.21.1.198:27018"},{_id:2,host:"172.21.1.200:27018",arbiterOnly:true}]});rs.initiate(config);rs.status()查看集群当前状态,rs.config()查看集群配置信息备份及恢复ReplicaSet配置:进入primary节点才能进行集群配置修改增加新成员:rs.add(“172.21.1.198:27017”),启动后节点会自动全量同步数据并成为secondary删除成员:config=rs.config();config.members=[config.members[1],config.members[3]];rs.reconfig(config,{force:true})备份及恢复ReplicaSet启动配置项详解:命令默认描述arbiterOnlyfalse如果为true,则该节点只负责仲裁,无数据存储buildIndexestrue如果为false,secondary不会被建立索引hiddenfalse如果为true,不会对客户端暴露此节点,通常用于数据备份或数据挖掘priority1.0权重,0则永远不会成为主节点slaveDelay0延迟同步于主节点选项,以秒为单位,如果设置则priority只能为0votes1选举时的投票成员数,通常不变initialSync{}新节点加入时设置同步规则,如指定从哪台主机同步,指定何时开始同步备份及恢复ReplicaSet选举机制各节点每两秒向其他节点发送心跳,每个节点收到心跳后会更新自己的状态映射表,包括:是否有新节点加入,是否有老节点宕机如果primary节点状态映射表发生变化则会通过心跳判断自己是否能和其他大多数节点(一半以上的节点)进行通信,如果不能则自动降级为secondary如果secondary节点状态表发生变化则会检测自己是否需要成为primary,它会进行三项检测,如果任意一个是否定的则不会成为primary是否集群中有其它节点认为自己是primary自己是否已经是primary自己是否有资格成为primary其他节点收到想要成为primary节点的信息包后会进行三项检测,如果任意一个满足都会投否定票他们是否已经知识集群中有一个primary了他们自己的数据是否比发送节点更新是否有其它节点的数据比发送节点更新如果确认后则节点宣布自己为primary并向其他节点发布,其余节点进行上面的最终一致性确认如果第一阶段有赞成有反对则赞成成员30秒内不得投票,发起者不会为primary备份及恢复MongoDBoplog说明:oplog在replicaset中存在local.oplog.rs中,是一个cappedcollection可以通过--oplogSize设置大小,默认为剩余磁盘空间的5%oplog无索引,可通过db.oplog.rs.find().sort({$natural:-1})查看{"ts":{"t":1330679993000,"i":1},"h":NumberLong("-1658698961994549576"),"op":"i","ns":"db0105.info","o":{"_id":ObjectId("4f509190c568791446000000"),"mobile":13436105336,"jing":"006394888","wei":"001777359","direction":"000","speed":"0000","date":"110105155959","distance":"0044382941","systime":20110105000000,"acc":"1","gps":"0","incredis":"0000000000","increstat":"1","locstat":"2","terminal":"0100000000000000"}}oplog是侵入的,甚至当目前操作时间戳大于要replay的oplog最大时间戳也不会对数据库有任何影响备份及恢复MongoDBoplog详解:由五部分组成:{ts:{},h{},op:{},ns:{},o:{},o2:{}}ts:8字节的时间戳,由4字节unix timestamp + 4字节自增计数表示h:一个哈希值(2.0+),确保oplog的连续性op:1字节的操作类型ns:操作所在的namespace。o:操作所对应的document,即当前操作的内容o2:在执行更新操作时o只记录id而o2记录具体内容,仅限于updateop操作类型“i”:insert操作“u”:update操作“d”:delete操作“c”:db cmd操作"db":声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.')"n":  no op,即空操作,其会定期执行以确保时效性 备份及恢复MongoDB增量备份及恢复数据量较小可用mongodump和mongorestore来完成数据库的备份和恢复可采用备份机+oplogreplay方式实现增量备份。比如用备份机实时追踪生产机的oplog,例如一天一次,然后每周一统一进行一次oplogreplay操作以此保证一个星期的容错窗口也可以用delaynode+oplogreplay保持一定的容错窗口,注意delay的时间一定不能超过oplog的文件大小,不然会不起作用Wordnik公司已经把用java开发的增量备份工具开源,使用很方便可到github下载:https://github.com/wordnik/wordnik-ossSharding机制MongoDBSharding机制介绍提供auto-sharding机制,自动对数据进行均衡分片可不停机轻松增加新片结合ReplicaSet集群可进行auto-failover,保证高可用Sharding机制Sharding中的角色及架构Sharding中数据分块称为chunk,每个chunk都是Collection中一段连续的数据记录,2.0+中默认大小为64MBShardServer:mongod实例,用于存储实际的数据块ConfigServer:mongod实例,存储了整个ClusterMetadata,其中包括chunk信息RouteProcesses:mongos实例,前端路由,客户端由此接入,且让整个集群看上去像单一进程数据库Sharding机制MongoDBSharding配置ShardServer:启动时加入--shardsvr选项,注意默认shardserver使用27018端口,可利用--port选项更改端口ConfigServer:启动时加入--configsvr选项指定为configserverRoute Processes:启动时加入--configdb指定多个configserver,可指定chunk块大小,用--chunkSize 选项连接到Route进行配置:db.adminCommand({addShard:“set/172.21.1.197:27017,172.21.1.198:27017,172.21.1.200:27017”});添加要分片的集群db.runCommand({enablesharding:“db0101”});设置允许分片的数据库db.runCommand({shardcollection:“db0101.info”,key:{mobile:1}})设置分片的collection和shardingkey,ShardingKey系统会自动建立索引Sharding机制MongoDBSharding管理查看分片集合信息db.collections.find()查看所有存在的分片db.runCommand({listshards:1})查看哪些数据库被分片config=db.getSisterDB("config")config.system.namespaces.find()查看分片的详细信息db.printShardingStatus();printShardingStatus(db.getSisterDB("config"),1);Sharding机制Sharding平衡机制MongoDBSharding操作有两个关键环节--split & migrate,split是轻量级操作,迁移却需要大量的服务端数据移动两大目标,第一保持不同片间的数据平衡,第二尽量最小化不同片间交互的数据块大小后台自动运行的任务,客户端不必关心数据如何拆分与迁移当数据超过一个chunk时会根据shardingkey被split到两个新的chunk中,当两个分片的数据量达到一定差异,平衡器开始工作数据迁移的基本单元是chunk,目前版本默认值为64M,可调整大小迁移时先把要迁移的数据从磁盘读到内存,再进行迁移,所以会引起热数据被剔除,形成swap颠簸Sharding前选取良好的ShardingKey非常重要Sharding机制ShardingKey选取原则避免小基数热点片键,如{server:1},如果server压力是不均衡的,一个大数据量server所有数据会集中在同一chunk中,这样导致chunk不易拆分,当chunk满时会出现整块迁移,{server:1,time:1}是优质方案写可扩展性,如果用{time:1}作为片键,导致所有的写操作都会落在最新的一个Chunk上去,这样就形成了一个热点区域选择{server:1,time:1}来作为片键,那么每一个Server上的数据将会写在不同的地方避免随机片键,此方案chunk迁移时的数据有可能是冷数据,不在内存中,会不断进行磁盘交换,严重影响性能。此方案查询也会出现随机性,结果合并会增加mongos负担查询隔离,理想的情况是一个查询直接路由到一个实例上去,并且这个实例拥有该次查询的全部数据,如果分散到各个片查询并汇总,会增加mongos主机负载、响应时间与网络成本由于Shardingkey必须建立索引,有排序查询时以ShardingKey的最左边的字段为依据最佳选择片键时尽量能保持良好的数据局部性而又不会导致过度热点的出现,组合片键是一种比较常用的做法Sharding机制Manualsharding手动split操作,MongoDB平衡机制用同样方式对待split操作,无论手工还是自动数据存在切分:db.runCommand({split:"test.foo",find:{_id:99}})预先切分:db.runCommand({split:"test.foo",middle:{_id:99}})编程切分:for(varx=97;x<97+26;x++){for(vary=97;y<97+26;y+=6){varprefix=String.fromCharCode(x)+String.fromCharCode(y);db.runCommand({split:”test.user”,middle:{email:prefix}});}}手动movechunkdb.adminCommand({moveChunk:"test.user",find:{id:{$gt:13520663641}},to:"shard0001"})关闭平衡器:db.settings.update({_id:"balancer"},{$set:{stopped:true}},true)定义平衡器窗口:db.settings.update({_id:"balancer"},{$set:{activeWindow:{start:"21:00",stop:"9:00"}}},true)监控及诊断Database Profiler:Profiling 级别:0-不开启;1-记录慢命令(默认>100ms);2-记录所有命令设置:db.setProfilingLevel(1,200)查看:db.getProfilingStatus(){"was":1,"slowms":200}查询慢命令:db.system.profile.find() {"ts":ISODate("2012-03-06T02:43:15.992Z"),"op":"query","ns":"db0105.system.profile","query":{},"nscanned":3,"nreturned":3,"responseLength":515,"millis":0,"client":"127.0.0.1","user":"“}db.system.profile.find( { millis : { $gt : 50 } } )查看大于50ms的命令db.system.profile.find().sort({$natural:-1})查看最新的profile命令 监控及诊断Profiling部分内容介绍:ts:该命令在何时执行millis:该命令执行耗时,以毫秒记op:本命令的操作信息query:具体的查询条件nscanned:本次查询扫描的记录数nreturned:本次查询实际返回的结果集responseLength:返回结果大小,以字节记update:表明这是一个update更新操作upsert:表明update的upsert参数为truemoved:表明本次update是否进行数据迁移insert:这是一个insert插入操作getmore:通常发生结果集比较大的查询时,第一个query返回了部分结果,后续的结果是通过getmore来获取的监控及诊断Mongostat查看实例统计信息监控及诊断Mongostat信息说明:insert:每秒插入量query:每秒查询量update:每秒更新量delete:每秒删除量getmore:每秒的getmore次数command:每秒命令执行次数flushes:每秒执行fsync系统调用将数据写入硬盘的次数mapped:映射总量大小,单位是MBvisze:虚拟内存总量大小,单位是MBres:物理内存总量大小,单位是MBfaults:每秒的缺页数(linuxonly),不要超过100,否则会频繁swap写入locked:被锁的时间百分比,尽量控制在50%以下吧20以下为佳idxmiss:B树索引缺失率qt|r|w:全局锁等待队列长度(total|read|write)高并发时队列值会升高conn:当前连接打开数监控及诊断其他常用监控工具db.serverStatus()数据库实例各项详细信息db.stats()数据文件大小及索引大小等信息iostat/vmstatMMS/Munion/Nagios…测试及总结ReplicaSet插入测试172.21.1.197和172.21.1.198分别部署mongodb存储实例,172.21.1.200部署仲裁实例和测试脚本无索引时,写入速度维持平均约12000条/秒,34分钟灌完,2500万条数据,继续写入数据速度下降,当内存用满后速度降低至一万以下提前声明一个复合索引,在内存吃满的情况下继续灌数据,刚开始速度维持在8000~9000,随着数据量增大,递减到6000左右测试及总结ReplicaSet查询测试单进程,17000次/秒20个并发,27000次/秒,机器负载4左右,73完成20个100000次查询50个并发,28900次/秒,机器负载4左右,35秒完成50个20000次查询200个并发,27900次/秒,机器负载6左右,70秒完成200个10000次查询500个并发,开始出错,同样处理速度27500次/秒,机器负载6~7测试及总结Sharding测试:以mobile为Shardingkey,网络环境不稳定,两个片有Replication资源竞争,插入数据很不稳定,2500W数据用时约1.5个小时,写入速度平均3500条/秒Shard1:set1/172.21.1.197:27017,172.21.1.198:27017Shard2:set2/172.21.1.198:27018,172.21.1.197:27018以mobile为Shardingkey,网络环境不稳定,非RS环境,2500W数据用时33分钟,与单机灌入速度基本一致Shard1:172.21.1.197:27018Shard2:172.21.1.198:27018测试及总结关于连接:Linux默认打开文件数为1024个,为了保证大并发有连接可用建议修改该配置/etc/security/limits.conf中增加nofile配置*softnofile10240*hardnofile10240/etc/pam.d/login中增加配置sessionrequired/lib/security/pam_limits.soLinux默认为每个进程分配Stack空间为10M(ulimit-a|grepstack),由于每个连接都会占用一个stack空间,如果连接过多则会消耗大量内存资源,据测试MongoDB最大连接为2000左右,最新版会进行连接优化或手工设置到1M(ulimit-s1024),同时建议使用连接池使连接不超过1000测试及总结关于Sharding若非必须,可考虑多库&多RS&no-sharding方案,有以下好处不必担心Route和Config的可靠性问题冷热数据分库,部署不同的ReplicaSetReplicaSet粒度可控,扩展性可控从现有非shard环境迁移是非常痛苦的事情若考虑sharding部署一定要认真设计好shardingkey,更改很难测试及总结关于NUMA问题NUMA是多核CPU架构中的一种,简单来说就是在多核心CPU中,机器的物理内存是分配给各个核的四种访问控制策略缺省(default):总是在本地节点分配(分配在当前进程运行的节点上)绑定(bind):强制分配到指定节点上交叉(interleave):在所有节点或者指定的节点上交织分配优先(preferred):在指定节点上分配,失败则在其他节点上分配采用默认策略导致核心只能从指定内存块节点上分配内存,即使总内存还有富余,也会由于当前节点内存不足时产生大量的swap操作可在启动前加numactl--interleave=all解决问题测试及总结关于文件系统:推荐XFS或EXT4,不建议用EXT3,XFS优势可用空间比高,大文件性能佳,恢复速度快xfs_growfs动态扩展空间方便至极数据文件建议进行人工预分配,否则在大量写入时预分配文件期间造成短暂不可用,可一次性将数据文件通过脚本建立好head-c2146435072/dev/zero>db0101.10cpdb0101.10db0101.11…测试及总结关于维护:如果不预设paddingFactor,数据更新操作会导致碎片,时刻关注碎片情况,定期reindex可减少索引碎片Repair&Compact都能对碎片进行整理Compact速度快可单独处理collection,但无法释放空间,实用性有限Repair速度慢但整理彻底,paddingFactor会重置,更新速度下降需定期对Primary进行repair,P->stepDown->repair->切回测试及总结关于空间及碎片:注意数据类型设计,使用短字段做key优于长字段,节省数据及索引空间避免碎片的几种方法:创建文档时设置paddingFactor>1字段占位,虽然是反MongDB的,但建议预先设计schema变长字段放置最后,如String类型BinData可用于占位,便于扩展测试及总结关于FindAndModify及写锁MongoDB采用的全局写锁一直被诟病,FindAndModify会加写锁以保证原子性尽量保证FindAndModify小范围更新普通更新采用Read-Update模式,提高索引命中,加热索引纪录更新多个文档时循环并一个个更新优于批量更新,减少全局写锁伤害测试及总结关于javascript及MapReducemongodb使用javascript做shell, mongodb的db.eval可以提供给数据驱动与这种javascriptshell类似的js接口目前mongodb的js引擎使用SpiderMonkey,性能不是十分理想,目前没有改成V8的消息,所以目前数据库的执行逻辑(类似存储过程)暂时不推荐使用MongoDB的js环境实现由于JS引擎原因,目前对于Mapreduce模式,Mongodb使用一个单独的进程来跑的,目前开发团队正在设计解决这一问题。而且目前测试效果来看对于单台机器不是很理想,执行job周期过长。
本文档为【MongoDB实践总结】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_374881
暂无简介~
格式:ppt
大小:2MB
软件:PowerPoint
页数:0
分类:互联网
上传时间:2013-04-18
浏览量:27