• [MongoDB] mongodb profile日志(慢日志)
    本帖最后由 Mongo_奇 于 2018-3-25 23:04 编辑关于profile日志: 官方文档的说明为:The database profiler collects detailed information about Database Commands executed against a running mongod instance. 即database profiler收集正在运行的mongod实例上执行的数据库命令的详细信息。注意:只能是mongod,不包含mongos profile日志的作用: profile日志其实就是把之前进行的数据库操作的详细信息记录到system.profile集合中。随着业务数据的不断增多,数据库的查询也会越来越慢,如果这时需要定位具体是哪些操作导致的数据库变慢,第一个想到可以定位问题的方法就是开启profile日志功能了。因为profile日志几乎可以记录已经执行数据库操作的所有详细信息,而且还支持按查询时间排序等操作,可以帮助用户很快的定位到究竟哪些操作才是效率低下的元凶。 profile日志的级别: profile日志可以设置的级别为(0,1,2) 0:默认的日志级别就是0,指的是不打印数据库具体的访问日志。 1:表示只记录时间大于slowms的数据库操作(记录慢日志)。 2:表示记录所有数据库操作。(数据访问量大时会影响iops,慎用) 一般想要查询profile日志需要经过以下几步: 1. 切到想要查询的数据库use testProfile: 2. 可以通过db.getProfilingStatus()来查询当前profile的设置状态: 3. 设置profile日志级别可以使用db.setProfilingLevel(1,100) (记录执行时间超过100ms的操作) 4. 查询慢日志db.system.profile.find() profile日志样例分析: 样例 { "op" : "insert", "ns" : "testslowlog.person", "query" : { "insert" : "person", "documents" : [ { "_id" : ObjectId("5a9d31e1e9ab426b4767e186"), "Uid" : 1000, "Name" : "testProfile", "Age" : 13, "Date" : ISODate("2018-03-05T12:02:41.496Z") } ], "ordered" : true }, "ninserted" : 1, "keyUpdates" : 0, "writeConflicts" : 0, "numYield" : 0, "locks" : { "Global" : { "acquireCount" : { "r" : NumberLong(4), "w" : NumberLong(4) } }, "Database" : { "acquireCount" : { "w" : NumberLong(3), "W" : NumberLong(1) } }, "Collection" : { "acquireCount" : { "W" : NumberLong(1) } }, "Metadata" : { "acquireCount" : { "w" : NumberLong(2) } }, "oplog" : { "acquireCount" : { "w" : NumberLong(2) } } }, "responseLength" : 85, "protocol" : "op_command", "millis" : 132, "execStats" : { }, "ts" : ISODate("2018-03-05T12:02:41.629Z"), "client" : "192.168.**.***", "allUsers" : [ { "user" : "rwuser", "db" : "admin" } ], "user" : "rwuser@admin" } 常用字段及其含义: 1. system.profile.op 定义:操作类型 取值范围:insert,query,update, remove,getmore, command 2. system.profile.ns 定义:进行操作的命名空间(数据库,集合名称) 3. system.profile.ts 定义:语句执行的时间戳。 4. system.profile.millis 定义:操作消耗的时间。 5. system.profile.query 定义:查询文档或**操作**的文档。如果文档超过50千字节,则该值是该对象的字符串摘要。 6. system.profile.command 定义:命令操作。如果命令文档超过50千字节,则该值为该对象的字符串摘要。 7. system.profile.updateobj 定义:更新操作期间传入的文档。如果文档超过50千字节,则该值是该对象的字符串摘要。 8. system.profile.cursorid 定义:query和getmore的游标ID 9. system.profile.key**amined 定义:MongoDB为了执行操作而扫描的索引键的数量。 10. system.profile.doc**amined 定义:MongoDB为了执行操作而扫描的集合中的文档数量。 11. system.profile.ndeleted 定义:操作删除的文档数。 12. system.profile.ninserted 定义:**操作的文档数 13. system.profile.nMatched 定义:符合查询条件的更新操作文档数 14. system.profile.nModified 定义:更新操作改变的文档数 15. system.profile.writeConflicts 定义:写入操作期间遇到的冲突次数;例如更新操作会尝试修改与另一个更新操作相同的文档。 16. system.profile.numYield 定义:该查询为其他查询让出锁的次数为允许其它操作完成而产生操作的次数 17. system.profile.locks 定义:信息,R:全局读锁;W:全局写锁;r:特定数据库的读锁;w:特定数据库的写锁 18.system.profile.nreturned 定义:返回文档的数量。 华为云DDS服务已经提供了慢日志功能(默认记录超过100ms的慢操作),客户可以通过界面一键点击轻松查询。在展示数据库慢日志的同时还会对用户的数据进行加密处理,保证用户的放心使用。
  • MongoDB 副本集初始化背后的过程
    本帖最后由 danglf 于 2018-3-23 15:18 编辑副本集方式是MongoDB最常用的部署方式,副本集使用之前必须先初始化, 副本集初始化是通过执行replSetInitiate完成的,本文主要分析副本集收到该命令后背后的逻辑(本文基于MongoDB3.2.18分析)。1.1 入口 当用户执行replSetInitiate 命令后, 最终会调用到CmdReplSetInitiate类的 run 方法,CmdReplSetInitiate 在Replset_commands.cpp里面定义。对于Mongod 启动后, 用户执行各种命令和查询操作, 是如何运行起来的,及command内部原理和体系结构 ,后续会写一篇专门的文章去分析。代码如下: 13173 13174 总体流程如下1 校验mongod的配置文件是不是配置配置副本集参数。2 对于副本集配置参数进行补齐3 核心语句, 调用getGlobalReplicationCoordinator()->processReplSetInitiat, 进入复制集初始化流程。1.2 主体流程: 1 ) 判断当前状态是不是可以进行初始化,必须是副本集之前没有初始化过才可以,否则报错 2) 构建内部初始化需要的配置数据, 并判断初始化副本集中的副本集名称和配置文件中的是不是一致,初次以外还有其他的逻辑校验 3 ) 判断当前实例状态, 发起选举,选出主 备节点 4)启动所有后台线程: a)后台拉取主节点oplog线程 b) 向主节点同步自己复制状态的线程 c) 定时快照线程。 相关流程对应代码如下 1)状态判断 replication_coordinator_impl.cpp –>processReplSetInitiate 13175 2) 部分参数校验 13176 3) 发起选举 processReplSetInitiate->_finishReplSetInitiate->_performPostMemberStateUpdateAction->_startElectSelfV1 4) 启动后台线程: 13177 以上就是replSetInitiate 命令后,mongod 内部的大致流程, 分析比较粗, 实际上每一个流程,如选举的内部机制, 初始化同步过程, 增量同步过程, 备节点如何应用oplog,每一个都可以作为专项来分析,后面会持续进行, 文中如有不正确的地方,也欢迎指出并讨论。
  • [技术干货] Mongodb引擎RocksDB系列----初识RocksDB
    Mongodb引擎RocksDB系列----初识RocksDBRocksDB简介RocksDB由facebook开创和维护(项目git址:https://github.com/facebook/rocksdb), 该项目旨在开发一个与快速存储器(尤其是闪存)存储数据性能相当的数据库软件,以应对高负载服务。RocksDB官网(https://rocksdb.org)首页头条注明了其项目的宗旨:RocksDB是一个可嵌入的,持久型的key-value存储,为了更快速的存储环境而生。RocksDB起源Leavel DB,在LevelDB的基础上优化而成,其在写性能上有了很大的提升。Mongodb和RocksDB的关系mongodb从3.2版本开始支持多数据存储引擎(WiredTiger,MMAPv1, In-Memory),其中WiredTiger为MongDB默认的存储引擎。所谓的多数据储存引擎形象的说就是拔插式引擎,你想使用哪个引擎就**这个引擎并拔掉前面的引擎就可以使用了,简单方便快捷。Mongodb提供整个数据库集群的管理工作,而真正将数据持久化的则是数据存储引擎。 12651 Mongodb和存储引擎之间的关系Mongodb 集成RocksDB要将RocksDB集成到Mongodb中,首先需要RocksDB实现Mongodb 的Engine API,这样mongodb通过操作Engine API 来存储数据而不用关注真正的数据存储引擎是什么。RocksDB由于是一款独立的数据存储引擎,facebook并没有实现mongodb Engine API, 因此需要使用第三方提供的开源软件Mongo-rocks(git:https://github.com/mongodb-partners/mongo-rocks).12652 安装和编译RocksDB:RocksDB依赖一些开源第三方软件,需要先安装这些软件:gflags: unzipgflags-2.0.zipcd gflags./configure&& make && sudo make install Snappy: tar -xzvfsnappy-1.1.4.tar.gzcdsnappy-1.1.4./configure&& make && sudo make install zlib, zlib-devel, bzip2, bzip2-devel: sudo yum installzlibsudo yuminstall zlib-develsudo yuminstall bzip2sudo yuminstall bzip2-devel zstd: tar zxvfzstd-1.1.3.tar.gzcdzstd-1.1.3make&& sudo make install 编译 rocksdb:注意:rocksdb版本向后兼容的,因此最新的版本都是可以集成的,本文档以5.4.10版本为例。其中rocksdb-rocksdb-5.4.10为编译的rockdb源码目录. cd rocksdb-rocksdb-5.4.10;USE_RTTI=1 CFLAGS=-fPIC make shared_lib;sudo INSTALL_PATH=/usr make install 编译mongo-rock ,mongod: 注意:其中mongo-r3.2.18为mongodb源码目录,mongo-rocks-r3.2.18为mongo-rocks的源码目录.mkdir -p/data/mongodb/shm/mongo-r3.2.18/src/mongo/db/modules/;ln -sf/data/mongodb/shm/mongo-rocks-r3.2.18 /data/mongodb/shm/mongo-r3.2.18/src/mongo/db/modules/rock;cd/data/mongodb/shm/mongo-r3.2.18; scons MONGO_VERSION=3.2.18 all --ssl -j 16 --opt=off; 启动mongod: 执行完上述的编译步骤后,编译出来的mongod的存储引擎就是RocksDB了,启mongod的时候带参数--storageEngine=rocksdb即可(详尽的参数可以参考文章https://www.percona.com/doc/percona-server-for-mongodb/3.4/mongorocks.html).
  • 手动创建MongoDB副本集
    本帖最后由 Nosql_newbee 于 2018-3-19 09:01 编辑MongoDB作为分布式数据库,其支持复制功能,复制功能保证将数据的副本保存到多台服务器上。 在创建一个副本集之后就可以使用复制功能了。副本集是一组服务器,其中有一个主服务器(primary),用于处理客户端请求,还有多个备份服务器(secondary),用于保存主服务器的数据副本。如果主服务器崩溃了,备份服务器会自动将其中一个成员升级为新的主服务器。 本文介绍快速搭建三成员的副本集。 在mongodb官方网站上下载mongodb Windows版本,并安装。一般在产品级应用中,每个副本集成员单独在一个机器上。这里为了快速搭建,在同一台机器上起三个mongod进程,使用默认绑定的ip地址(127.0.0.1)。 本例子将mongodb安装在D:\MongoDB 目录下 1、首先创建三个目录存储数据,例如 D:\MongoDB\data\db, D:\MongoDB\data1\db, D:\MongoDB\data2\db 2、开启三个cmd窗口,分别启动三个服务器: mongod.exe --port 27017 --dbpath "D:\MongoDB\data\db" --logpath "D:\MongoDB\data\MongoDB.log" --replSet rs0 --logappend 按照此方法启动另外两个服务器: mongod.exe --port 27018 --dbpath "D:\MongoDB\data1\db" --logpath "D:\MongoDB\data1\MongoDB.log" --replSet rs0 --logappend mongod.exe --port 27019 --dbpath "D:\MongoDB\data2\db" --logpath "D:\MongoDB\data2\MongoDB.log" --replSet rs0 --logappend 其中,--port 指定端口 --replSet 指定副本集的名称,三个服务的进程的副本集名称要一致 3、链接其中一个服务器并初始化副本集 三个服务启动后,cmd窗口不要关闭,另开一个cmd窗口,链接到27017端口的服务器(连接其他的端口也可以): use test 定义副本集的配置 rs.initiate({"_id":"rs0","members":[{"_id":0,host:"127.0.0.1:27017"},{"_id":1,host:"127.0.0.1:27018"},{"_id":2,host:"127.0.0.1:27019"}]}) _id 的值是副本集名称,成员分别是三个服务器 执行完成后通过 rs.status() 查看副本集状态,其中可以看出副本集的primary节点和连个secondary节点 到此,最简单的副本集就搭建完成了,接下来链接primary 节点就可以**数据进行验证了 链接primary节点,并**验证数据: 在primary节点**数据成功后,可以在任意的secondary节点查看数据。由于主备节点数据复制存在时间差,MongoDB为了防止用户在secondary节点读入脏数据,默认情况下禁止从secondary节点读入数据,可以通过执行 setSlaveOk 命令来允许在secondary节点读入数据: 副本集的复制功能也验证完了。 接下来介绍如何添加或去掉副本集节点成员,通过配置文件启动服务,配置文件中常用项的介绍。
  • [技术干货] mongodb副本及发生回滚(rollback)情景与规避措施
    本帖最后由 lipo 于 2018-3-18 21:58 编辑[*]关于回滚: 官方文档的说明为:A rollback reverts write operations on a former primary when the member rejoins its replica set after a failover. 即rollback发生在主备故障切换后,会回滚掉前一个主节点的部分写入数据。这明显属于丢数据,对于某些应用场景,简直不可忍受。那么我们就需要了解这个过程怎么发生的,才能做出针对性的对应措施。 [*]mongodb发生回滚的过程分析 1. 下图为一个正常工作的副本集,绿色的为主节点,蓝色为备节点,数字代表我们依次写入的数据。 那么此时下图中,A为主节点,BC为备节点,我们成功写入数据至13,此时A已写入,BC正在同步数据,一切看起来很正常,很祥和。 在这里,我们还要着重简单说明一下主备同步的机制,简单的说,就是备节点会去主节点的Oplog(operation log)内去寻找自己最新的Oplog,找到后,就知道自己落后主节点多少operation,此时备节点会把自己落后的主节点的新的oplog拿过来,在自己这边重新执行一遍(别担心,每一条Oplog都具有幂等性),这样主节点的数据和状态就会更新过来了。 12646 2. 此时,如下图,意外发生了,由于一些不可知的原因,A与BC断开了网络链接,而BC之间通信正常,BC很快发现了这一点,于是我们mongodb强大的failover机制起作用了,A被踢出了主权限,BC将会商量选出新的主节点,我们假设将选出的主节点为B。 12647 3. 经过短暂的两三秒后,新的主节点B诞生了。整个过程我们客户端没有任何感知,继续高兴的执行我们写入计划,好的,继续写入数据14。14成功的被写入了,接下来是15,16,17...当然,这些新数据都会写到我们的新主节点B内。 12648 4. 非常幸运的,我们修复好了A节点的网络故障!A又回来了!此时A会发现,自己的最后的Oplog时间,也就是写入数据13的时间,落后与当前主节点B的Oplog最后时间,也就是数据17的写入时间。A决定要尽快新的主节点保持同步,赶上B节点的最新数据。于是,A用自己本地最新的数据去与新的主节点做比对,首先是数据13,它发现B内竟然没有数据13,哦,数据13肯定是脏数据,等会扔掉。然后是12,哎哟,12也是脏数据,接着是11...最后,它发现,它与主节点最近的相同数据就是数据10。谢天谢地,总算和老大找到共同点了。 12649 5. 在于老大(主节点B)找到共同点后,为了保持和主节点一直,节点A非常没有节操的扔掉了它认为的脏数据。扔完脏数据后,节点ABC达到如下的节点状态: 12650 6. 那么,A节点丢脏数据这个过程,也就是官方文档所说的rollback。 [*]RollBack规避措施: 了解了这个过程,我们就容易发现,想数据不发生回滚,那我们只要保证主备节点的数据随时一致就行了!这句话说起来简单,实现起来却无比头大。 不过万幸的是!mongodb提供了一个非常强大选项:Write Concern,当设置Write Concern为majority时,会在主节点写入后,保证备节点也同步了该数据,才返回写入成功,这样就再也不怕failover时发生数据回滚了! 至于Write Concern到底是个什么东西,还有既然有Write Concern,是不是还有Read Concern?这个就有待下回分解啦!
  • [技术干货] 如何下载mongodb源代码
    本帖最后由 eharry 于 2018-3-18 14:58 编辑mongodb作为业界最火的开源nosql数据库, 在nosql领域有着广泛的应用. mongodb以敏捷,可扩展,对企业友好和内置的分布式系统设计为企业所青睐.如华为,思科,博世等大公司都在使用,研究,并改进mongodb在生产环境中的表现. 1. 获取mongodb文档 如果使用的是osx系统, 那么只需要在dash软件上下载mongodb的文档即可 12632 如果是linux或者windows系统, 强烈推荐官网的在线文档, https://docs.mongodb.com 需要注意的是, 官网的文档,默认显示的是最新的稳定版本文档, 如果要查找老版本的文档,记得选择文档切换, 如下图所示 12633 官方文档一般都是冗余且复杂,如果你只想入个门,熟悉一下mongodb操作, 或者是英文不是看原版文档有些困难,可以参考w3school里面的文档 https://www.w3cschool.cn/mongodb/ 这些教程通俗易懂,基于新手和初学者的视角讲解mongodb操作, 是很好的入门材料. 2. 获取mongodb内部文档 像很多数据库一样, 如果你需要对数据库进行二次开发,那么仅仅用户文档是满足不了需求的, 这个时候我们就需要mongodb的一些内部技术文档,用来加深对数据库的理解. 熟悉和深入代码框架,实现流程等设计方案,才能更好地进行二次开发. 可惜的是,mongodb并没有提供很多技术细节的文档出来, 大部分的细节需要开发者通过代码阅读 或者追踪mongodb开发大牛的技术博客才能获得. 这里说一下可能包含技术文档的网站: a) https://github.com/mongodb/mongo/wiki mongodb的github的wiki, 这个wiki里面包含了几篇讲述服务内部技术实现的文章, 内容深度略深于用户手册. 可以做入门研究. b) http://www.mongoing.com mongodb中文社区, 里面文章有些会描述mongodb内部实现细节,因为是中文版, 文章作者或者译者也是中国人,可以很方便的领会文章的内容并和作者交流. c) https://www.mongodb.org/community mongodb的全球通用交流频道, 邮件列表和irc. 不过英语不好的同学,可能用起来比较痛苦. 不过很多紧急的问题,都可以在上面提问, 有很多热心人会帮助你解决问题. d) https://groups.google.com/forum/#!forum/mongodb-user , https://groups.google.com/forum/#!forum/mongodb-dev, https://university.mongodb.com/ 这几个资源需要访问google,或者是YouTube, 有条件的同学可以在里面学习.都是很有帮助的文档. 如果碰到的问题,上述文档都没有解决,那么最后一条路,只有下载代码, 自己研究,然后解决问题后,将解决办法分享汇总出来,造福社会大众. 3. 如何下载mongodb代码 官方网站就可以下载mongodb代码, 链接如下: https://www.mongodb.com/download-center?jmp=nav#community 12634 不过从正规官网下载,只能下载到最新的几个文档版本的源代码, 如果你想下载其他版本的源代码, 基本上没有链接可以点进去. 12636 比如上面只让你下载 3.4.13, 3.2.19, 3.0.16这三个版本的源代码, 如果你生生产环境跑的是3.4.10, 所以你需要调查3.4.10问题的时候, 你就得想办法得到3.4.10的代码. 方法如下: * 鼠标放到3.4.13的下载连接上,选择右键复制下载链接. https://fastdl.mongodb.org/src/m ... 19540906.1515159031 * 手动删除后面那一串数字, 只保留到?前面, 并替换3.4.13位3.4.10, 链接如下: https://fastdl.mongodb.org/src/mongodb-src-r3.4.10.tar.gz * 将这个链接copy到浏览器中下载就可以了. 方法二: 如果不喜欢访问mongodb的官网,或者觉得拼接的方式得到的下载链接不是官方方式, 那么可以从github下载mongodb源代码. 官方的github仓库地址如下: https://github.com/mongodb/mongo 个人可以根据爱好fork自己的仓库,或者直接从主库上下载, 下载特定版本方式跟其他项目一样, 仍以3.4.10代码举例: 登录到mongodb仓库, 选中tas, 选则3.4.10版本, 然后点击右边的 "clone or download" 然后继续点选Download Zip 12638
  • [技术干货] MongoDB数据模型浅析-01
    本帖最后由 danglf 于 2018-3-16 17:24 编辑1MongoDB 数据模型介绍MongoDB的数据模型比较灵活,不像关系型数据库,在写数据之前,需要预先定义好数据表的结构, 数据表每个列的类型。 MongoDB的集合类似于关系型数据库中的表, 集合不需要预先定义具体的结构,所以对于MongoDB来说,该特性非常方便单条文档和一个数据实体进行映射, 应用可以随意的变更文档的数据结构,不受限于表结构定义的影响。这也就是我们通常说的MonogDB的一个优点,灵活的数据模式。 对于一个使用MongoDB存储数据的的系统来说, 需要良好的设计MongoDB的文档的数据结构, 以及数据之间联系。2MongoDB数据模型设计应用使用MongoDB,需要根据具体的应用来设计一个高效的数据模型,数据模型设计的优劣直接影响应用程序的性能。目前MongoDB对于数据之前的关系设计,通常有两种方式:嵌入,引用。2.1内嵌数据模型:在MongoDB里面,你可以把相关的数据包括在一个单个的结构或者文档下面。这样的数据模式也叫做“非规范化”模式,它充分利用了MongoDB的灵活文档格式的功能。以下图为例: 12535 内嵌数据可以让应用程序把相关的数据保存在同一条数据库记录里面。这样一来,应用程序就可以发送较少的请求给MongoDB数据库来完成常用的查询及更新请求。一般来说,下述情况建议使用内嵌数据:· 数据对象之间有“contains” (包含) 关系。如一对一关系建模:内嵌文档模型。· 数据对象之间有一对多的关系。这些情况下“多个”或者子文档会经常和父文档一起被显示和查看。通常情况下,内嵌数据会对读操作有比较好的性能提高,也可以使应用程序在一个单个操作就可以完成对数据的读取。 同时,内嵌数据也对更新相关数据提供了一个原子性写操作。.2.1.1一对一关系例子 让我们来看一个针对于顾客和地址关系建模的一个例子。通过这个例子中我们可以明白在需要同时看到两个数据的场景下,使用内嵌会比使用引用更有优越性。在这个顾客和地址的一对一的关系中,address是属于顾客的。在一个规范化的数据模型中, address 文档包含一个对父文档顾客的引用。{ _id: "joe", name: "JoeBookreader"} { patron_id: "joe", street: "123Fake Street", city: "Faketon", state: "MA", zip: "12345" }假如 address 信息会经常和 name 字段一起被查询出来并显示, 那么应用程序必须发出额外的请求去解析并读取父文档。在这里更好的选择是把 address 数据直接内嵌到 patron 文档里面,如下所示:{ id: "joe", name: "Joe Bookreader", address: { street:"123 Fake Street", city:"Faketon", state:"MA", zip:"12345" } } 2.1.2一对多关系例子让我们来看一个针对于顾客和其多个地址关系建模的一个例子。通过这个例子中我们可以明白在需要同时看到多个数据记录的场景下,使用内嵌会比使用引用更有优越性。在这个顾客和地址的一对多的关系中,一个顾客 有多个 address 记录。在一个规范化的数据模型中, address 文档包含一个对父文档patron 的引用。{ _id: "joe", name:"Joe Bookreader"} { patron_id: "joe", street: "123 Fake Street", city:"Faketon", state: "MA", zip:"12345"} { patron_id: "joe", street: "1 Some Other Street", city:"Boston", state: "MA", zip:"12345"}假如 address 信息会经常和 name 字段一起被查询出来并显示, 那么应用程序必须发出额外的请求去解析并读取父文档。在这里更好的选择是把 address 数据直接内嵌到 patron 文档里面,如下所示:{ _id: "joe", name:"Joe Bookreader", addresses: [ { street: "123 Fake Street", city: "Faketon", state: "MA", zip: "12345" }, { street: "1 Some Other Street", city: "Boston", state: "MA", zip: "12345" } ] }通过嵌入模型,应用可以通过一次查询得到全量数据。(基本是对官网相关内容的翻译,未完待续,后面分析引用型数据模型)
  • [技术干货] [MongoDB] MongoDB 3.2连接问题总结
    本帖最后由 Mongo_奇 于 2018-3-12 20:30 编辑客户购买华为云dds(MongoDB)实例时往往最先遇到的问题就是数据库的连接问题,数据库的连接问题大体上可以分为几类,所以在这里总结三种连接MongoDB的方式(mongo shell,java mongo客户端,python mongo客户端),希望对大家有所帮助。 一. mongo shell连接:1.连接的前提条件:(1)连接数据库的弹性云主机必须和MongoDB实例网络畅通,可以用curl命令连接MongoDB实例服务端的ip和port测试: curl ip:port,如果返回为:"It looks like you are trying to access MongoDB over HTTP on the native driver port." 说明网络畅通(2)在Mongodb官网下载二进制(https://www.mongodb.com/download-center#community),解压取其中的mongo并上传到弹性云主机。(3)如果是开启ssl的集群,需要在dds服务的界面上下载证书并上传到弹性云主机。 2.mongo shell连接命令:(1)ssl方式:./mongo ip:port --authenticationDatabase admin -u username -p password --ssl --sslCAFile ${path to certificate authority file}(2)非ssl方式:./mongo ip:port --authenticationDatabase admin -u username -p password 3.mongo shell连接常见问题:(1)如果集群开启ssl,则连接必须要带--ssl和--sslCAFile选项,CA证书从官网上可以直接下载。(2)华为云DDS现在用的mongod为3.2.7版本,所以连接的mongo客户端版本最好也选用3.2.7,否则可能出现版本间不兼容的问题。(3)认证数据库--authenticationDatabase必须为admin,因为现在还不支持用户创建数据库用户(在经过华为云对MongoDB内核的安全加固后该功能将会开放),所以rwuser用户必须要在admin上认证。 二. python客户端连接:1.连接的前提条件:(1)连接数据库的弹性云主机必须和MongoDB实例网络畅通。(验证方式见一、1.(1))。(2)如果是开启ssl的集群,需要在dds服务的界面上下载证书并上传到弹性云主机。(3)在弹性云主机上安装python以及三方包pymongo(pymongo下载地址:https://pypi.python.org/pypi/pymongo/2.7#downloads)。 2.样例代码:(1)ssl方式:import sslfrom pymongo import MongoClientconn_urls="mongodb://rwuser:rwuserpassword@ip:port/{mydb}?authSource=admin"connection = MongoClient(conn_urls,connectTimeoutMS=5000,ssl=True, ssl_cert_reqs=ssl.CERT_REQUIRED,ssl_ca_certs=${path to certificate authority file})dbs = connection.database_names()print "connect database success! database names is %s" % dbs (2)非ssl方式import sslfrom pymongo import MongoClientconn_urls="mongodb://rwuser:rwuserpassword@ip:port/{mydb}?authSource=admin"connection = MongoClient(conn_urls,connectTimeoutMS=5000)dbs = connection.database_names()print "connect database success! database names is %s" % dbs 3.python客户端连接常见问题:(1)推荐pymongo2.8版本。(2)url中的认证数据库必须为authSource=admin 三. java客户端连接:1.连接的前提条件:(1)连接数据库的弹性云主机必须和MongoDB实例网络畅通。(验证方式见一、1.(1))。(2)下载mongo jar包:http://central.maven.org/maven2/org/mongodb/mongo-java-driver/(3)弹性云主机安装jdk 2.样例代码:(1)ssl方式:用keytool工具手动生成trustStore:keytool -import -file /var/chroot/mongodb/CA/ca.crt -keystore /home/Mike/jdk1.8.0_112/jre/lib/security/mongostore -storetype pkcs12 -storepass test123"/var/chroot/mongodb/CA/ca.crt"为根证书路径,可从console上直接下载。可以自己替换其它路径"/home/Mike/jdk1.8.0_112/jre/lib/security/mongostore"为生成的trustStore的地址。可以自己替换其它路径"test123"为trustStore的密码。可以自己替换其它值生成的mongostore位于jre的security目录中 连接代码: import java.util.ArrayList;import java.util.List;import org.bson.Document;import com.mongodb.MongoClient;import com.mongodb.Mong**dential;import com.mongodb.ServerAddress;import com.mongodb.client.MongoDatabase;import com.mongodb.client.MongoCollection;import com.mongodb.MongoClientURI;import com.mongodb.MongoClientOptions;public class MongoDBJDBC {public static void main(String[] args){ try { System.setProperty("javax.net.ssl.trustStore", "/home/Mike/jdk1.8.0_112/jre/lib/security/mongostore"); System.setProperty("javax.net.ssl.trustStorePassword", "test123"); ServerAddress serverAddress = new ServerAddress("ip", port); List addrs = new ArrayList(); addrs.add(serverAddress); Mong**dential credential = Mong**dential.createScramSha1Credential("rwuser", "admin", "!rwuserPassword".toCharArray()); List credentials = new ArrayList(); credentials.add(credential); MongoClientOptions opts= MongoClientOptions.builder() .sslEnabled(true) .sslInvalidHostNameAllowed(true) .build(); MongoClient mongoClient = new MongoClient(addrs,credentials,opts); MongoDatabase mongoDatabase = mongoClient.getDatabase("testdb"); MongoCollection collection = mongoDatabase.getCollection("testCollection"); Document document = new Document("title", "MongoDB"). append("description", "database"). append("likes", 100). append("by", "Fly"); List documents = new ArrayList(); documents.add(document); collection.insertMany(documents); System.out.println("Connect to database successfully"); } catch (Exception e) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } }} 运行样例代码:javac -cp .:mongo-java-driver-3.2.0.jar MongoDBJDBC.javajava -cp .:mongo-java-driver-3.2.0.jar MongoDBJDBC (2)非ssl方式:import java.util.ArrayList;import java.util.List;import org.bson.Document;import com.mongodb.MongoClient;import com.mongodb.Mong**dential;import com.mongodb.ServerAddress;import com.mongodb.client.MongoDatabase;import com.mongodb.client.MongoCollection;import com.mongodb.MongoClientURI;import com.mongodb.MongoClientOptions;public class MongoDBJDBC {public static void main(String[] args){ try { ServerAddress serverAddress = new ServerAddress("ip", port); List addrs = new ArrayList(); addrs.add(serverAddress); Mong**dential credential = Mong**dential.createScramSha1Credential("rwuser", "admin", "!rwuserPassword".toCharArray()); List credentials = new ArrayList(); credentials.add(credential); MongoClient mongoClient = new MongoClient(addrs,credentials); MongoDatabase mongoDatabase = mongoClient.getDatabase("testdb"); MongoCollection collection = mongoDatabase.getCollection("testCollection"); Document document = new Document("title", "MongoDB"). append("description", "database"). append("likes", 100). append("by", "Fly"); List documents = new ArrayList(); documents.add(document); collection.insertMany(documents); System.out.println("Connect to database successfully"); } catch (Exception e) { System.err.println( e.getClass().getName() + ": " + e.getMessage() ); } }} 3.java客户端连接常见问题:(1)ssl连接需要手动生成trustStore文件,见样例。(2)认证数据库必须选择admin,然后再转到业务数据库
  • [技术干货] Mongodb 3.2 云上数据迁移之纯手工版
    好些用户购买华为云dds(mongodb)时都会告知我们他在某某友商云上有mongdb数据库,想把友商上的数据库迁移过来,但在官网上没有发现mongodb数据迁移的工具,问怎么办?此时我们尴尬的说,目前数据迁移工具正在规划中,很快就能在官网上线mongodb数据迁移工具,到时手指动一动就能迁移数据了。但目前呢?目前怎么办?考虑到用户有这个云服务商之间迁移数据的需求,虽然华为云还没出mongodb自动迁移工具,但为解客户燃眉之急,我写些自己平时关于mongodb数据迁移的方法:那就是目前还是有办法的!当然只能利用开源工具进行纯手工操作了,虽然麻烦但也是一种手段,也能将友商数据迁移过来。好,下面我就详细和大家聊聊纯手工迁移mongodb的方案.(目前华为云dd只支持mongodb 3.2.7,因此我们讨论的方案都是围绕3.2.7版本进行的。)任何方案都是有业务场景的,不同的业务场景对应的方案的操作和复杂度是不一样的,我们按照业务场景的复杂度讲解。1. 业务数据不重要,允许业务长时间中断。(1). 停掉友商的mongodb服务,中断业务,不允许任何数据的变更。(2). 使用mongoexport导出数据mongoexport --host --port --ssl --sslAllowInvalidCertificates --type json--authenticationDatabase --username --password --db --collection --out (3).使用mongoimport将数据导入到华为云dds mongoimport--host --port --ssl--sslAllowInvalidCertificates --type json --authenticationDatabase --username --password --db --collection --file 注意:如果购买的华为云数据库有公网ip,可以在任何一台能连上公网ip的服务器上导入导出数据。如果没有购买公网ip,则先购买一台华为云的ecs,这台ecs和数据库在同一个网段和安全组,然后在这台ECS上导入数据。 (4). 将业务数据库ip切换至华为云mongodb,启动业务,数据迁移成功。2. 业务数据不重要,允许丢失数据但不能中断业务 这种业务场景一般是客户数据为临时,但业务不能中断必须保证在迁移的时间段业务是可用的。第二个业务场景和第一个很相似,因此迁移数据的方案也很相似,在数据迁移阶段不停掉友商数据库,数据迁移完成直接切换数据库ip到华为云dds,当然迁移这段时间的数据库就会丢失,因为没有从友商同步数据到华为云dds。3. 业务数据重要不允许丢失,业务不允许中断.这种业务场景中我们选取最具代表性也是最复杂的场景进行分析:我们选取用户存量数据大(上T的数据),ops高,一个小时就新增上百G的数据。因为存量数据大,数据迁移至少都在数小时以上,而ops高,那么在迁移的时间段会积累上百G的数据没有迁移到华为dds。Mongodb社区版没有提供增量导出,增量备份数据的方案,这些都是企业版mongodb才提供的。那么我们能用纯手工的方式(使用mongodb开源社区提供的生态工具)做到增量迁移数据吗?答案是利用开源工具是无法完美做到纯手工增量迁移的。原因如下:1. mongoexport/mongoimport : 首先说下mongoexport的工作原理,看上图是一边mongoexport导出数据一边往数据库里面**数据,显然最后导出的数据大于开始执行mongexport时数据库的数据。看了下mongoexport的源码,工作流程大概如下:首先获取开始执行mongoexport导出数据库的记录数量。得出这个记录数量后,mongoexport 开启一个cursor,利用这个cursor迭代读取数据,cursor每次读取的时候都是批量读取,最后一次迭代读取的数据量是在此时数据库总量和每次批量读取数据量中取最大值,如果此时数据库一直在变更数据那么很难确定最后总共读取的数量。因此客户在导出数据过程中一直在变更数据那么使用mongoexport导出的总数据量是无法确定的。那么迁移过程中新增数据怎么增量迁移呢?mongoexport本身并没有提供增量迁移的功能,但可以通过回放oplog的方法将迁移过程中增量的数据的oplog在目标机器上进行重做。不过Oplog记录的是所有的数据当然也包括不是这次迁移需要的数据的oplog,需要对oplog进行过滤重放,这块手工处理比较麻烦也容易出错,需要写程序进行自动处理。2. mongodump/mongorestore: mongodump可以备份所有数据然后利mongrestore进行恢复。对于备份过程中的增量数据,可以使用开源工具mongooplog处理增量oplog以达到增量备份数据的目的。但由于不同云服务商对shard的命名各不相同,因此恢复完成后必须登录数据库手动修改数据库里面shard的名字,这一步手动处理比较麻烦也容易出错。上述两种方法都需要注意oplog的大小,防止在备份过程中新增数据量过大,oplog数据被轮转覆盖,一旦覆盖就无法增量备份数据了。总结:目前纯手工操作的迁移数据的方式只能适应一些比较简单的业务场景,对于复杂场景,手工迁移存在操作复杂容易出错的缺点,程序化自动化的mongodb迁移工具不久就会出现在华为云官网上,那才是用户最贴心的解决方案。
  • [技术干货] Mongodb 3.2 云上数据迁移之纯手工版
    好些用户购买华为云dds(mongodb)时都会告知我们他在某某友商云上有mongdb数据库,想把友商上的数据库迁移过来,但在官网上没有发现mongodb数据迁移的工具,问怎么办?此时我们尴尬的说,目前数据迁移工具正在规划中,很快就能在官网上线mongodb数据迁移工具,到时手指动一动就能迁移数据了。但目前呢?目前怎么办?考虑到用户有这个云服务商之间迁移数据的需求,虽然华为云还没出mongodb自动迁移工具,但为解客户燃眉之急,我写些自己平时关于mongodb数据迁移的方法:那就是目前还是有办法的!当然只能利用开源工具进行纯手工操作了,虽然麻烦但也是一种手段,也能将友商数据迁移过来。好,下面我就详细和大家聊聊纯手工迁移mongodb的方案.(目前华为云dd只支持mongodb 3.2.7,因此我们讨论的方案都是围绕3.2.7版本进行的。)任何方案都是有业务场景的,不同的业务场景对应的方案的操作和复杂度是不一样的,我们按照业务场景的复杂度讲解。1. 业务数据不重要,允许业务长时间中断。(1). 停掉友商的mongodb服务,中断业务,不允许任何数据的变更。(2). 使用mongoexport导出数据mongoexport --host --port --ssl --sslAllowInvalidCertificates --type json--authenticationDatabase --username --password --db --collection --out (3).使用mongoimport将数据导入到华为云dds mongoimport--host --port --ssl--sslAllowInvalidCertificates --type json --authenticationDatabase --username --password --db --collection --file 注意:如果购买的华为云数据库有公网ip,可以在任何一台能连上公网ip的服务器上导入导出数据。如果没有购买公网ip,则先购买一台华为云的ecs,这台ecs和数据库在同一个网段和安全组,然后在这台ECS上导入数据。 (4). 将业务数据库ip切换至华为云mongodb,启动业务,数据迁移成功。2. 业务数据不重要,允许丢失数据但不能中断业务 这种业务场景一般是客户数据为临时,但业务不能中断必须保证在迁移的时间段业务是可用的。第二个业务场景和第一个很相似,因此迁移数据的方案也很相似,在数据迁移阶段不停掉友商数据库,数据迁移完成直接切换数据库ip到华为云dds,当然迁移这段时间的数据库就会丢失,因为没有从友商同步数据到华为云dds。3. 业务数据重要不允许丢失,业务不允许中断.这种业务场景中我们选取最具代表性也是最复杂的场景进行分析:我们选取用户存量数据大(上T的数据),ops高,一个小时就新增上百G的数据。因为存量数据大,数据迁移至少都在数小时以上,而ops高,那么在迁移的时间段会积累上百G的数据没有迁移到华为dds。Mongodb社区版没有提供增量导出,增量备份数据的方案,这些都是企业版mongodb才提供的。那么我们能用纯手工的方式(使用mongodb开源社区提供的生态工具)做到增量迁移数据吗?答案是利用开源工具是无法完美做到纯手工增量迁移的。原因如下:1. mongoexport/mongoimport : 首先说下mongoexport的工作原理,看上图是一边mongoexport导出数据一边往数据库里面**数据,显然最后导出的数据大于开始执行mongexport时数据库的数据。看了下mongoexport的源码,工作流程大概如下:首先获取开始执行mongoexport导出数据库的记录数量。得出这个记录数量后,mongoexport 开启一个cursor,利用这个cursor迭代读取数据,cursor每次读取的时候都是批量读取,最后一次迭代读取的数据量是在此时数据库总量和每次批量读取数据量中取最大值,如果此时数据库一直在变更数据那么很难确定最后总共读取的数量。因此客户在导出数据过程中一直在变更数据那么使用mongoexport导出的总数据量是无法确定的。那么迁移过程中新增数据怎么增量迁移呢?mongoexport本身并没有提供增量迁移的功能,但可以通过回放oplog的方法将迁移过程中增量的数据的oplog在目标机器上进行重做。不过Oplog记录的是所有的数据当然也包括不是这次迁移需要的数据的oplog,需要对oplog进行过滤重放,这块手工处理比较麻烦也容易出错,需要写程序进行自动处理。2. mongodump/mongorestore: mongodump可以备份所有数据然后利mongrestore进行恢复。对于备份过程中的增量数据,可以使用开源工具mongooplog处理增量oplog以达到增量备份数据的目的。但由于不同云服务商对shard的命名各不相同,因此恢复完成后必须登录数据库手动修改数据库里面shard的名字,这一步手动处理比较麻烦也容易出错。上述两种方法都需要注意oplog的大小,防止在备份过程中新增数据量过大,oplog数据被轮转覆盖,一旦覆盖就无法增量备份数据了。总结:目前纯手工操作的迁移数据的方式只能适应一些比较简单的业务场景,对于复杂场景,手工迁移存在操作复杂容易出错的缺点,程序化自动化的mongodb迁移工具不久就会出现在华为云官网上,那才是用户最贴心的解决方案。
  • [技术干货] 选择MongoDB的几个参考点
    本帖最后由 云里的计算 于 2017-11-14 14:43 编辑众所周知,MongoDB已经成为NoSQL Document Store的代表: 4709 那么什么样的系统适合使用MongoDB呢? 这里有几个问题,可以在您系统设计和数据库选型时是否选择MongoDB提供参考和思路: n应用场景不需要事务及复杂关联查询 ? n对事务ACID要求不高? n需求会变,数据模型无法确定,想快速迭代开发, 后期有可能在大表上频繁的修改表结构? n应用需要2000-3000以上的读写QPS(更高也可以)? n应用需要TB甚至 PB 级别数据存储?应用发展迅速,需要能快速水平扩展? n应用要求存储的数据不丢失? n应用需要99.999%高可用? n应用需要大量的地理位置查询、文本查询? 如果以上问题的答案是Yes,Yes越多,那么是时候重点考虑您的系统构架在MongoDB上啦 {:3_52:}
总条数:165 到第
上滑加载中