MongoDB Replica Set使用几点总结

本文会涉及到MongoDB副本集的初始化,读写性能,scala driver,简单运维等内容。

副本集初始化

在各个节点上replica set进程,

nohup numactl --interleave=all ./mongod --dbpath /home/mongodb/data/  --logpath /home/mongodb/mongodb-linux-x86_64-2.4.7/run.log --port 8017 --rest --journal --replSet smartq --oplogSize 500 --profile=1 --slowms=5 --fork &

我的启动中,开启了rest接口,journal log,设置了oplog size大小500M(因为之后再修改oplog大小会比较麻烦),还开启了慢查询profile,如果有不熟悉这三块日志的,可以参考下面的简单描述:

  1. Journal日志。Journal日志通过预写式的redo日志为MongoDB增加了额外的可靠性,开启该功能时,数据的更新会先写入Journal日志,定期提交,然后在真实数据上执行这些变更,如果服务器安全关闭,日志会被清除在服务器启动时,如果存在Journal日志,则会执行提交.启动Journal功能只需要在启动mongod时指定-journal参数即可,这样,系统的Journal信息都会被放到数据库目录(默认是/data/db)的journal文件夹中
  2. oplog日志。MongoDB的高可复用策略中有一种叫做Replica Sets,Replica Sets复制过程中一个服务器充当主服务器,而一个或多个服务器充当从服务器,主服务器将更新写入一个本地的collection中,这个collection记录着发生在主服务器的更新操作,并将这些操作分发到从服务器上。这个日志是一个capped Collection,且有大小之分,所以最好在启动mongod服务时配置好大小(单位:MB). mongd -oplogsize=1024
  3. 慢查询日志。慢查询日志记录了执行时间超过所设定时间阈值的操作语句,慢查询日志对于发现性能有问题的语句很有帮助,建议开启此功能经常分析该日志的内容.要配置这个功能值需要在mongod启动时指定profile参数即可。Eg.将超过5s的操作记录都记录下来 mongod --profile=1 --slowms=5 运行一段时间后,可以通过查看db.system.profile 这个collection来获取慢日志信息

要注意的是

numactl --interleave=all

这块设置。NUMA和UMA(SMP)多核CPU架构的不同实现方式,推荐阅读下Introduction to Parallel Computing的章节内容。如果不设置这个参数,进入mongod后会有相应提示,可能带来的问题可以参考记一次MongoDB性能问题,附原理解析这篇文章。

起了各个节点后,连接到某一台mongod上,进行副本集初始化工作:

var config = {
  _id: "smartq",
  members: [
    {
      _id:0,
      host:"host0-ip:8017"
    },
    {
      _id:1,
      host:"host1-ip:8017"
    },
    {
      _id:2,
      host:"host2-ip:8017"
    }
  ]
}
rs.initiate(config)

输入rs.status()可以查看primary和secondary节点情况,刚初始化的时候节点的状态会经历一些变化,之后选举出primary。更多指令可以参考 rs.help() 。更多细节可以参考文章mongodb副本集架构搭建

读写性能

我的副本集的写性能,在java driver环境下,差不多是1W-2W+ 行每秒,吞吐量大约2M+ 每秒。写只能在primary节点上进行。

我的副本集的读性能,在不带索引的情况下,DBCursor的扫描速度是4K~7K 行 每秒。输入一个查询,执行后,返回一个DBCursor是很快的,但是游标的顺序fetch行数还是比较慢的。我尝试了DBCursor提供的一些方式(我使用的是mongo-java-driver-2.10.1的包),对比了下以下几种获取速度,

rs = coll.find().sort(new BasicDBObject("_id", 1)).toArray();
rs = coll.find().batchSize(100).limit(l).toArray();
rs = coll.find().toArray(); // toArray()开销
Iterator it = coll.find().iterator(); // little faster than toArray()
while (it.hasNext()) {
    it.next();
}

刚开始一直使用toArray()的方式把DBCursor能指向的数据全部吐到内存里来,但其实toArray()的开销稍稍大于返回一个iterator之后逐个扫描一次。而基于_id字段进行排序之后再toArray(),带来的额外开销很少,侧面说明_id字段因为有索引,做排序很快很方便,值得好好利用。batchSize这个设置,我尝试设置了100,1000,感受是对于几万到几十万的数据吞吐没有多大影响。

总结是读性能在速度上还是需要索引支撑,且在能承受最终一致性的前提下,将读分布到secondary上缓解。

Scala Driver
尝试了下Scala Driver来进行读性能的测试,速度和java driver是一致的,而scala driver本身也是对java driver的简单封装,且目前支持的api也不全。

Scala Driver项目叫Casbah,是10gen官方的Toolkit。在build.sbt下的配置如下:

name := "hi-scala"

organization := "xx.xxx.xxx"

version := "0.0.1-SNAPSHOT"

scalaVersion := "2.9.3"

libraryDependencies ++= Seq(
  "org.mongodb" %% "casbah" % "2.6.3"
)

简单使用:

import com.mongodb.casbah.Imports._

object CasbahTest extends Logging {

  def main(args: Array[String]): Unit = {

    val mongoClient = MongoClient("host-ip", 8017)

    val db = mongoClient("db")

    val coll = db("collection")

    val start = System.currentTimeMillis()

    val rs = coll.find()

    // for (doc <- rs) {
    //   doc
    // }

    logInfo("Result: " + rs.size) // no toArray()

    val end = System.currentTimeMillis()

    logInfo("Time: " + (end-start))

  }
}

更多内容参看 Casbah Tutorial

Copy Collection

在同个db下拷贝collection似乎没有快速的方法,那就写简单的js,进行insert操作,

 var i = 0;
 while(i < 10000) {
   var cname = 'copy' + i;
   db.copy1.find().forEach( function(x){
     db.getCollection(cname).insert(x);
   });
   i++
 }

然后让mongod在后台执行,效率也很慢,

nohup  ./mongo localhost:8017/hdfs ../../jscript/copy_collection.js &

执行一段时间后,secondary的status可能会显示RECOVERING,原因是oplog记录的内容过多,primary的oplog可能已经重新刷过一次了,导致secondary与primary脱节,无法再持续进行本身的同步数据的操作。解决方法是把secondary kill掉,删掉data数据,重新起mongod加入副本集。这利用的是副本集同步机制中的初始化同步,即对于新的没有数据的member,拷贝现有副本集内某个member的整份数据,整个过程流程为先clone数据,然后apply
all changes,最后建索引。启动之后,secondary会出于STARTUP状态,开始比较快速地进行数据的同步,这里比较快也就是上百M每秒的样子。

(全文完)

时间: 2024-08-30 18:27:50

MongoDB Replica Set使用几点总结的相关文章

mongodb replica set 添加删除节点的2种方法_MongoDB

一,利用rs.reconfig,来添加,删除节点 1,添加节点 repmore:PRIMARY> config = {_id:"repmore",members:[{_id:0,host:'127.0.0.1:27017',priority :2},{_id:1,host:'127.0.0.1:27018',priority:1}]}; //添加节点 repmore:PRIMARY> rs.reconfig(config); //使配置生效 repmore:PRIMARY&

mongodb replica set 配置高性能多服务器详解_MongoDB

mongodb的多服务器配置,以前写过一篇文章,是master-slave模式的,请参考:详解mongodb 主从配置.master-slave模式,不能自动实现故障转移和恢复.所以推荐大家使用mongodb的replica set,来实现多服务器的高可用.给我的感觉是replica set好像自带了heartbeat功能,挺强大的. 一,三台服务器,1主,2从 服务器1:127.0.0.1:27017 服务器2:127.0.0.1:27018 服务器3:127.0.0.1:27019 1,创建

mongodb replica set 添加/删除节点方法

  replica set多服务器主从,添加,删除节点,肯定会经常遇到的.下面详细说明一下,添加,删除节点的2种方法. 一,利用rs.reconfig,来添加,删除节点 1,添加节点  代码如下   repmore:PRIMARY> config = {_id:"repmore",members:[{_id:0,host:'127.0.0.1:27017',priority :2},{_id:1,host:'127.0.0.1:27018',priority:1}]};   //

从MongoDB Replica Set HA 看分布式系统读写一致性问题

副本集基础 Replica Set是mongodb提供的一个去中心化的备份模式(同时mongodb还提供了主从部署和分片模式),每个mongod都可以是master,且副本集内会自动选举出一个primary,其他都暂时为seconary,primary挂掉后会自动选举出新的primary.副本集内所有mongod存储的都是数据全集,secondary节点会从primary同步数据操作以保证自己的数据up-to-date.副本集有自己的选举机制,相对是一种比较简单的选举,根据心跳.权重等因素选取一

mongoDB replica set configuration

startup mongodb with --replSet command optionexample : 1. startup one node:mongod --replSet $setname[/$rmt_ip:$port]2. startup another node :mongod --replSet $setname[/$rmt_ip:$port]3. run ininiate command within one of the nodes only : db.runCommand

mongodb数据库replica set shard 分片 高可用 集群

一,mongodb分片,常用的二种架构 1,每一个客户端系统上包含一个路由器mongos, 服务器的数量从十几台增长到几百台,mongos路由和mongod分片服务器之间建立了几百.有时候甚至是几千个连接,负载非常重.这意味着每当chunk平衡(MongoDB分片集群为了保持数据均匀分布所必须使用的平衡措施)发生的时候传送存储在配置数据库中的chunk位置信息都需要花费相当长的时间.这是因为每一个mongos路由都必须清楚地知道每一个chunk都存在于集群中的哪些位置. 2,路由器独立 路由独立

MongoDB之Replica Set+Sharding架构的例子

MongoDb Replica Set解决了容错和单点故障问题,但单台机器的存储和承受能力有限,Sharding就是为了海量存储和动态扩容而产生的.这才有了Replica Set+Sharding高可用架构.Sharding Cluster主要包括如下三部分: Shards:每个shard都是replica set,具有自动备份.容错.恢复能力,当然在开发环境你可配成单个mongodConfig Server:存储metadata,包括每个shard的基本信息和chunk信息,生产环境至少有3个

Use mongodb 1.8.1&#039;s replicaSet with auth,journal,keyFile feature

MongoDB replicSet 1.8.1 产品部署推荐: 1. 文件系统加载时使用参数noatime 2. no VM PAGEs 3. 推荐使用逻辑卷,文件系统推荐ext4或xfs 4. 3个full nodes 或 2个full nodes+1个arbiter node (最好是奇数个物理服务器,否则仲裁会有问题,例如两台物理机,两个mongod进程,相互网络不通的话,任何一台都无法达到majority,因此都无法成为primary.那就是只读了.因此本例的物理服务器只有2台是不合理的

MongoDB资料汇总

与大家共勉~ 1.MongoDB是什么 MongoDB介绍PPT分享 MongoDB GridFS介绍PPT两则 初识 MongoDB GridFS MongoDB GridFS 介绍 一个NoSQL与MongoDB的介绍PPT MongoDB:下一代MySQL? 写给Python程序员的MongoDB介绍 又一篇给Python程序员的MongoDB教程 MongoDB源码研究系列文章 白话MongoDB系列文章 MongoDB Tailable Cursors 特性介绍 MongoDB 文档阅