mongoDB执行db.runCommand时传入的不是document打印类型,String中包含new Date

在MongoDB中实现聚合函数 讲的太好了!
在MongoDB中实现聚合函数
作者&&,译者&&发布于
八月 04, 2012&|&
相关厂商内容
MongoDB提供了一个,其中包括常用功能,比如count、distinct和group。然而更多的高级聚合函数,比如sum、average、max、min、variance(方差)和standard
deviation(标准差)等需要通过MapReduce来实现。
这篇文章描述了在MongoDB存储的文档上使用MapReduce来实现通用的聚合函数,如sum、average、max、min、variance和standard deviation;聚合的典型应用包括销售数据的业务报表,比如将各地区的数据分组后计算销售总和、财务报表等。
我们从本文示例应用所需软件的安装开始。
首先在本地机器上安装并设置MongoDB服务。
从上下载MongoDB,解压到本地目录,比如C:&Mongo
在上一个文件夹内创建数据目录。比如:C:\Mongo\Data
如果数据文件存放在其他地方,那么在用mongod.exe命令启动MongoDB时,需要在命令行加参数—-dbpath
MongoDB提供了两种方式:mongod.exe以后台进程启动;mongo.exe启动命令行界面,可做管理操作。这两个可执行文件都位于Mongo\bin目录下;
进入Mongo安装目录的bin目录下,比如:C:& cd Mongo\bin
有两种启动方式,如下:
mongod.exe –dbpath C:\Mongo\data
mongod.exe –config mongodb.config
mongodb.config是Mongo\bin目录下的配置文件,需要在此配置文件中指定数据目录(比如,dbpath= C:\Mongo\Data)的位置。
连接到MongoDB,到这一步,mongo后台服务已经启动,可以通过http://localhost:27017查看。 MongoDB启动运行后,我们接下来看它的聚合函数。
实现聚合函数
在关系数据库中,我们可以在数值型字段上执行包含预定义聚合函数的SQL语句,比如,SUM()、COUNT()、MAX()和MIN()。但是在MongoDB中,需要通过MapReduce功能来实现聚合以及批处理,它跟SQL里用来实现聚合的GROUP BY从句比较类似。下一节将描述关系数据库中SQL方式实现的聚合和相应的通过MongoDB提供的MapReduce实现的聚合。
为了讨论这个主题,我们考虑如下所示的Sales表,它以MongoDB中的反范式形式呈现。
CustomerName
ProductCategory
ProductSubCategory
ProductName
基于SQL和MapReduce的实现
我们提供了一个查询的样例集,这些查询使用聚合函数、过滤条件和分组从句,及其等效的MapReduce实现,即MongoDB实现SQL中GROUP BY的等效方式。在MongoDB存储的文档上执行聚合操作非常有用,这种方式的一个限制是聚合函数(比如,SUM、AVG、MIN、MAX)需要通过mapper和reducer函数来定制化实现。
MongoDB没有原生态的用户自定义函数(UDFs)支持。但是它允许使用db.system.js.save命令来创建并保存JavaScript函数,JavaScript函数可以在MapReduce中复用。下表是一些常用的聚合函数的实现。稍后,我们会讨论这些函数在MapReduce任务中的使用。
Javascript 函数
db.system.js.save( { _id : &Sum& ,
value : function(key,values)
&&&&var total = 0;
&&&&for(var i = 0; i & values. i++)
&&&&&&&&total += values[i];
db.system.js.save( { _id : &Avg& ,
value : function(key,values)
&&&&var total = Sum(key,values);
&&&&var mean = total/values.
db.system.js.save( { _id : &Max& ,
value : function(key,values)
&&&&var maxValue=values[0];
&&&&for(var i=1;i
db.system.js.save( { _id : &Min& ,
value : function(key,values)
&&&&var minValue=values[0];
&&&&for(var i=1;i
db.system.js.save( { _id : &Variance& ,
value : function(key,values)
&&&&var squared_Diff = 0;
&&&&var mean = Avg(key,values);
&&&&for(var i = 0; i & values. i++)
&&&&&&&&var deviation = values[i] -
&&&&&&&&squared_Diff += deviation *
&&&&var variance = squared_Diff/(values.length);
STD DEVIATION
db.system.js.save( { _id : &Standard_Deviation&
, value : function(key,values)
&&&&var variance = Variance(key,values);
&&&&return Math.sqrt(variance);
SQL和MapReduce脚本在四种不同的用例场景中实现聚合函数的代码片段如下表所示。
1.各地区的平均订单量
下面的查询是用来获取不同地区的平均订单量。
MapReduce Functions
db.sales.runCommand(
mapreduce : &sales& ,
map:function()
{ // emit function handles the group by
&&&&&&&&emit( {
&&&&&&&&// Key
&&&&&&&&city:this.City,
&&&&&&&&state:this.State,
&&&&&&&&region:this.Region},
&&&&&&&&// Values
&&&&&&&&this.Quantity);
AVG(Quantity)
reduce:function(key,values)
&&&&var result = Avg(key, values);
FROM sales
GROUP BY City, State, Region
// Group By is handled by the emit(keys, values)
line in the map() function above
out : { inline : 1 } });
2.产品的分类销售总额
下面的查询是用来获取产品的分类销售额,根据产品类别的层级分组。在下面例子中,不同的产品类别作为个体维度,它们也可以被称为更复杂的基于层次的维度。
MapReduce 函数
db.sales.runCommand(
mapreduce : &sales& ,
ProductCategory, ProductSubCategory, ProductName,
map:function()
&&&&&&&&emit(
&&&&&&&&// Key
&&&&&&&&{key0:this.ProductCategory,
&&&&&&&&key1:this.ProductSubCategory,
&&&&&&&&key2:this.ProductName},
&&&&&&&&// Values
&&&&&&&&this.SalesAmt);
&SUM(SalesAmt)
reduce:function(key,values)
&&&&var result = Sum(key, values);
&&&&return
FROM sales
GROUP BY ProductCategory, ProductSubCategory, ProductName
// Group By is handled by the emit(keys, values)
line in the map() function above
out : { inline : 1 } });
&3. 一种产品的最大利润
下面的查询是用来获取一个给定产品基于过滤条件的最大利润。
MapReduce 函数
db.sales.runCommand(
mapreduce : &sales& ,
&ProductId, ProductName,
map:function()
&&&&if(this.ProductId==1)
&&&&&&&&emit( {
&&&&&&&&&&&&key0:this.ProductId,
&&&&&&&&&&&&key1:this.ProductName},
&&&&&&&&&&&&this.Profit);
MAX(SalesAmt)
reduce:function(key,values)
&&&&var maxValue=Max(key,values);
&&&&return maxV
FROM sales
WHERE ProductId=’1’
// WHERE condition implementation is provided in
map() function
GROUP BY ProductId, ProductName
// Group By is handled by the emit(keys, values)
line in the map() function above
out : { inline : 1 } });
4. 总量、总销售额、平均利润
这个场景的需求是计算订单的总数、总销售额和平均利润,订单ID在1到10之间,发货时间在2011年的1月1日到12月31日之间。下面的查询是用来执行多个聚合,比如,在指定年份以及指定的不同区域和产品类别范围里订单的总数、总销售额和平均利润。
MapReduce 函数
db.sales.runCommand(
{ mapreduce : &sales& ,
ProductCategory,
ProductId,
map:function()
&&&&emit( {
&&&&&&&&// Keys
&&&&&&&&region:this.Region,
&&&&&&&&productCategory:this.ProductCategory,
&&&&&&&&productid:this.ProductId},
&&&&&&&&// Values
&&&&&&&&{quantSum:this.Quantity,
&&&&&&&&salesSum:this.SalesAmt,
&&&&&&&&avgProfit:this.Profit} );
&Sum(Quantity),
&Sum(Sales),
&Avg(Profit)
reduce:function(key,values)
&&&&var result=
{quantSum:0,salesSum:0,avgProfit:0};
&&&&var count = 0;
&&&&values.forEach(function(value)
&&&&&&&&// Calculation of Sum(Quantity)
&&&&&&&&result.quantSum += values[i].quantS
&&&&&&&&// Calculation of Sum(Sales)
&&&&&&&&result.salesSum += values[i].salesS
&&&&&&&&result.avgProfit += values[i].avgP
&&&&&&&&count++;
&&&&// Calculation of Avg(Profit)
&&&&result.avgProfit = result.avgProfit /
&&&&return
FROM Sales
Orderid between 1 and 10 AND
Shipdate BETWEEN ‘01/01/2011’ and
‘12/31/2011’
&&&&&&&&&OrderId& : { &$gt& : 1 },
&&&&&&&&&OrderId& : { &$lt& : 10 },
&&&&&&&&&ShipDate& : { &$gt& : &01/01/2011& },
&&&&&&&&&ShipDate& : { &$lt& : &31/12/2011& },
Region, ProductCategory, ProductId
// Group By is handled by the emit(keys, values)
line in the map() function above
limit : 3,
out : { inline : 1 } });
&既然我们已经看了在不同业务场景下的聚合函数的代码示例,接下来我们准备来测试这些函数。
测试聚合函数
MongoDB的MapReduce功能通过数据库命令来调用。Map和Reduce函数在前面章节里已经使用JavaScript实现。下面是执行MapReduce函数的语法。
db.runCommand(
&&&&{ mapreduce : &collection&,
&&&&&&&&map : &mapfunction&,
&&&&&&&&reduce : &reducefunction&
&&&&&&&&[, query : &query filter object&]
&&&&&&&&[, sort : &sorts the input objects using this key. Useful for
optimization, like sorting by the emit key for fewer reduces&]
&&&&&&&&[, limit : &number of objects to return from collection&]
&&&&&&&&[, out : &see output options below&]
&&&&&&&&[, keeptemp: &true|false&]
&&&&&&&&[, finalize : &finalizefunction&]
&&&&&&&&[, scope : &object where fields go into javascript global scope &]
&&&&&&&&[, jsMode : true]
&&&&&&&&[, verbose : true]
Where the Output Options include:
{ replace : &collectionName& }
{ merge : &collectionName&
{ reduce : &collectionName& }
{ inline : 1}&
&下面是用来保存聚合函数并在MapReduce中使用的命令。
启动Mongo命令行并设置表
确保Mongo后台进程在运行,然后执行mongo.exe启动Mongo命令行。
使用命令切换数据库:use mydb
使用命令查看Sales表的内容:db.sales.find()
find命令的输出如下:
{ &_id& : ObjectId(&4f7be0d3e37bb13e&), &_class& : &com.infosys.mongo.Sales&, &orderId& : 1, &orderDate& : &26/03/2011&,
&quantity& : 20, &salesAmt& : 200, &profit& : 150, &customerName& : &CUST1&, &productCategory& : &IT&, &productSubCategory& : &software&,
&productName& : &Grad&, &productId& : 1 }
{ &_id& : ObjectId(&4f7be0d3e37bb13f&), &_class& : &com.infosys.mongo.Sales&, &orderId& : 2, &orderDate& : &23/05/2011&,
&quantity& : 30, &salesAmt& : 200, &profit& : 40, &customerName& : &CUST2&, &productCategory& : &IT&, &productSubCategory& : &hardware&,
&productName& : &HIM&, &productId& : 1 }
{ &_id& : ObjectId(&4f7be0d3e37bb140&), &_class& : &com.infosys.mongo.Sales&, &orderId& : 3, &orderDate& : &22/09/2011&,
&quantity& : 40, &salesAmt& : 200, &profit& : 80, &customerName& : &CUST1&, &productCategory& : &BT&, &productSubCategory& : &services&,
&productName& : &VOCI&, &productId& : 2 }
{ &_id& : ObjectId(&4f7be0d3e37bb141&), &_class& : &com.infosys.mongo.Sales&, &orderId& : 4, &orderDate& : &21/10/2011&,
&quantity& : 30, &salesAmt& : 200, &profit& : 20, &customerName& : &CUST3&, &productCategory& : &BT&, &productSubCategory& : &hardware&,
&productName& : &CRUD&, &productId& : 2 }
{ &_id& : ObjectId(&4f7be0d3e37bb142&), &_class& : &com.infosys.mongo.Sales&, &orderId& : 5, &orderDate& : &21/06/2011&,
&quantity& : 50, &salesAmt& : 200, &profit& : 20, &customerName& : &CUST3&, &productCategory& : &BT&, &productSubCategory& : &hardware&,
&productName& : &CRUD&, &productId& : 1 }
创建并保存聚合函数&
通过MongoDB命令行窗口执行如下命令:
& db.system.js.save( { _id : &Sum& ,
value : function(key,values)
&&&&var total = 0;
&&&&for(var i = 0; i & values. i++)
&&&&&&&&total += values[i];
在示例表Sales表上执行MapReduce程序
& db.sales.runCommand(
mapreduce : &sales& ,
map:function()
{key0:this.ProductCategory,
key1:this.ProductSubCategory,
key2:this.ProductName},
this.SalesAmt);
reduce:function(key,values)
&&&&var result = Sum(key, values);
out : { inline : 1 } });
输出如下:
&results& : [
&&&&&&&&&&&&&&&&&_id& : {
&&&&&&&&&&&&&&&&&&&&&&&&&key0& : &BT&,
&&&&&&&&&&&&&&&&&&&&&&&&&key1& : &hardware&,
&&&&&&&&&&&&&&&&&&&&&&&&&key2& : &CRUD&
&&&&&&&&&&&&&&&&},
&&&&&&&&&&&&&&&&&value& : 400
&&&&&&&&},
&&&&&&&&&&&&&&&&&_id& : {
&&&&&&&&&&&&&&&&&&&&&&&&&key0& : &BT&,
&&&&&&&&&&&&&&&&&&&&&&&&&key1& : &services&,
&&&&&&&&&&&&&&&&&&&&&&&&&key2& : &VOCI&
&&&&&&&&&&&&&&&&},
&&&&&&&&&&&&&&&&&value& : 200
&&&&&&&&},
&&&&&&&&&&&&&&&&&_id& : {
&&&&&&&&&&&&&&&&&&&&&&&&&key0& : &IT&,
&&&&&&&&&&&&&&&&&&&&&&&&&key1& : &hardware&,
&&&&&&&&&&&&&&&&&&&&&&&&&key2& : &HIM&
&&&&&&&&&&&&&&&&},
&&&&&&&&&&&&&&&&&value& : 200
&&&&&&&&},
&&&&&&&&&&&&&&&&&_id& : {
&&&&&&&&&&&&&&&&&&&&&&&&&key0& : &IT&,
&&&&&&&&&&&&&&&&&&&&&&&&&key1& : &software&,
&&&&&&&&&&&&&&&&&&&&&&&&&key2& : &Grad&
&&&&&&&&&&&&&&&&},
&&&&&&&&&&&&&&&&&value& : 200
&timeMillis& : 1,
&timing& : {
&&&&&&&&&mapTime& : NumberLong(1),
&&&&&&&&&emitLoop& : 1,
&&&&&&&&&total& : 1
&counts& : {
&&&&&&&&&input& : 5,
&&&&&&&&&emit& : 5,
&&&&&&&&&output& : 4
MongoDB提供了面向文档的存储结构,可以很容易扩展支持TB级数据。同时也提供了Map Reduce功能,可以通过批处理方式使用类SQL函数来实现数据聚合。在这篇文章中,我们描述了安装MongoDB并使用MapReduce特性执行聚合函数的过程,也提供了简单SQL聚合的MapReduce示例实现。在MongoDB中,更复杂的聚合函数也可以通过使用MapReduce功能实现。
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?副本集成员最多12个成员,其中只有7个成员拥有投票权。这是为了减少 心跳请求的网络流量和选举话费的时间。心跳每2秒发送一次。
一、新增副本集成员
1、登录primary
2、use admin &rs.add("new_node:port") 或 rs.add({"_id":4,"host":"new_node:port","priority":1,"hidden":false})
3、use admin&rs.addArb("new_port") 或 rs.addArb({"_id":5,"host":"new_node:port"})或rs.add({'_id':5,"host":"new_node:port","arbiterOnly":true})
仲裁者唯一的作用就是参与选举,仲裁者并不保存数据,也不会为客户端提供服务。成员一旦以仲裁者的身份加入副本集中,它就永远只能是仲裁者,无法将仲裁者
重新配置为非仲裁者,反之亦然。最多只能有一个仲裁者每个副本集中。
注:如果 复制集中 priority=1 (默认),调用rs.add("new_node:port") 该命令 会产生 主从切换 即选举操作;
如果 复制集中 priority=1 (默认),直接调用rs.remove("new_node:port") 该命令 也会产生 主从切换 ;
二、删除副本集成员
1、登录要移除的目标mongodb实例;
2、利用shutdownServer()命令关闭实例;即 db.shutdownServer()
3、登录复制集的primary;
4、primary&use admin
primary&rs.remove("del_node:port");
三、修改成员的优先级及隐藏性
1、登录primary
2、use admin &conf=rs.conf()
mongo&conf.members[1].priority=[0-1000]
mongo&conf.members[1].hidden=true #priority必须为0
mongo&conf.members[9].tags={"dc":"tags_name1"}
mongo&rs.reconfig(conf);
# 强制重新配置 rs.reconfig(conf,{"force":true})
成员的属性有下列选项
[, arbiterOnly : true]
[, buildIndexes : &bool&]
[, hidden : true]
[, priority: &priority&]
[, tags: {loc1 : desc1, loc2 : desc2, ..., locN : descN}]
[, slaveDelay : &n&]#秒为单位。
[, votes : &n&]
如果该成员要设置为 隐藏(hidden:true) 或延迟(slaveDelay:30) 则其优先级priority必须设置为 0;
也就是说 隐藏成员和延迟成员及buildIndexs:false的成员 的优先级别一定必须是0 即priority=0.
优先级为0的成员不能发起选举操作。
只要优先级&0即使该成员不具有投票资格,也可以成为主节点。
如果某个节点的索引结构和其他节点上的索引结构不一致,则该节点就永远不会变为主节点。
优先级用于表示一个成员渴望成为主节点的程度。优先级的取值范围是[0-100],默认为1。优先级为0的成员永远不能成为主节点。
使用rs.status()和rs.config()能够看到隐藏成员,隐藏成员只对rs.isMaster()不可见。客户端连接到副本集时,会调用rs.isMaster()
来查看可用成员。将隐藏成员设定为非隐藏成员,只需将配置中的hidden设定为false,或删除hidden选项。
每个成员可以拥有多个标签tags {“dc":"tags_name2",qty:"tag_name3"}
votes:0 代表阻止这些成员在选举中投主动票,但是他们仍然可以投否决票。
修改副本集成员配置时的限制:
1、不能修改_id;
2、不能讲接收rs.reconfig命令的成员的优先级设置为 0;
3、不能将仲裁者成员变为非仲裁者成员,反正亦然;
4、不能讲 buildIndexes:false 改为 true;
四、查看副本集成员数据同步(延迟)情况
mongo&db.printReplicationInfo();
mongo&db.printSlaveReplicationInfo();#最好在secondary上执行
mongo&rs.printReplicationInfo()
mongo&rs.printSlaveReplicationInfo()
mongo&use local&db.slaves.find()
在主节点上跟踪延迟:
local.slaves该集合保存着所有正从当前成员进行数据同步的成员,以及每个成员的数据新旧程度。
登录主节点
&use local
&db.slaves.find()、
查看其中每个成员对应的"syncedTo":{"t":9999999,"i":32} 部分即可知道数据的同步程度。
"_id"字段的值是每个当前成员服务器标识符。可以到每个成员的local.me.find()查看本服务器标识符。
如果多台服务器拥有相同的_id标识符,则依次登录每台服务器成员,删除local.me集合(local.me.dorp()),然后重启mongodb,
重启mongod后,mongod会使用新的“_id”重新生成local.me集合。
2、如果服务器的地址改变但_id没有变,主机名变了,该情况会在本地数据库的日志中看到重复键异常(duplicate key exception)。
解决方法是:删除local.slaves集合即可,不需要重启mongod。
因为mongod不会清理local.slaves集合,故里面的数据可能不准确或过于老旧,可将整个集合删除。当有新的服务器将当前成员作为
复制源时,该集合会重新生成。如果在主节点中看到了某个特定的服务器在该集合中有多个文档,即表示备份节点之间发生了复制链,
该情况不影响数据同步,只是把每个备份节点的同步源告诉主节点。
删除local.me集合,需要重新启动mongod,mongod启动时会使用新的 _id重新生成local.me集合。
删除local.slaves集合,不用重启mongod。该集合中的数据是记录该成员被作为同步源的服务器的数据。该集合用于报告副本集状态。
删除后不久如果有新的节点成员将该服务器节点作为复制源,该集合就会重新生成。
五、主节点降为secondary
mongo&use admin
mongo&rs.stepDown(60)#单位为 秒
六、锁定指定节点在指定时间内不能成为主节点(阻止选举)
mongo&rs.freeze(120)#单位为 秒
mongo&rs.freeze(0)
七、强制节点进入维护模式(recovering)
可以通过执行replSetMaintenanceMode命令强制一个成员进入维护模式。
例如自动检测成员落后主节点指定时间,则将其转入维护模式:
function maybeMaintenanceMode(){
var local=db.getSisterDB("local");
if (!local.isMaster().secondary)
var last=local.oplog.rs.find().sort({"$natural":-1}).next();
var lasttime=last['ts']['t'];
if (lasttime&(new date()).getTime()-30)
{db.adminCommand({"replSetMaintenanceMode":true});
将成员从维护模式转入正常模式。即恢复:
db.adminCommand({"replSetMaintenanceMode":false});
八、阻止创建索引(不可再修改为可以创建索引,故慎重考虑)
通常会在备份节点的延迟节点上设置阻止创建索引。因为该节点通常只是起到备份数据作用。设置选项 buildIndexs:false即可。该选项是永久性的。如果要将不创建索引的成员修改为可以创建索引的成员,那么必须将这个成员从副本集中移除,再删除它上的所有数据,最后再将其重新添加到副本集中。并且允许其重新进行数据同步。该选项也要求成员的优先级为 0.
九、指定复制源(复制链) 查看复制图谱
使用db.adminCommand({"replSetGetStatus":1})['syncingTo'] 可以查看复制图谱(每个节点的同步源);
在备份节点上执行 rs.status()['sysncingTo'] 同样可以查看复制图谱(同步源);
mongodb是根据ping时间来选择同步源的,会选择一个离自己最近而且数据比自己新的成员作为同步源。
可以使用replSetSyncFrom 命令来指定复制源或使用辅助函数rs.sysncFrom()来修改复制源。
db.adminCommand({"replSetSyncFrom":"server_name:port"});
副本集默认情况下是允许复制链存在的,因为这样可以减少网络流量。但也有可能
花费是时间更长,因为复制链越长,将数据同步到全部服务器的时间有可能就越长(比如每个备份节点都比前一个备份节点稍微旧点,这样就得
从主节点复制数据)。
解决方法:
1、手动改变复制源
登录备份节点:use admin
db.adminCommand({"replSetSyncFrom":"新复制源"})
rs.syncFrom("新复制源")
副本集中的成员会自动选择其他成员作为复制源。这样就会产生复制链。
如果一个备份节点从另一个备份节点(而非主节点)复制数据时,就会形成复制链。
复制链是可以被禁用的,这样就可以强制要求所有备份节点都从主节点复制数据。
禁用复制链:即禁止备份节点从另一个备份节点复制数据。
var config=rs.config()
config.settings=config.settings ||{}
config.settings.chainingAllowed=false
rs.reconfig(config);
十、强制修改副本集成员
var config=rs.config()
config.member[n].host=...
config.member[n].priority=...
rs.reconfig(config,{"force":true})
十一、修改Oplog集合的大小
如果是主节点,则先将primary 降为 secondary。最后确保没有其他secondary 从该节点复制数据。rs.status()
1、关闭该mongod服务 use admin &db.adminCommand({shutdownServer:1});
2、以单机方式重启该mongod(注释掉 配置文件中的 replSet
shardsvr ,修改端口号)
3、将local.oplog.rs中的最后一条 insert 操作记录保存到临时集合中
mongo& use local
mongo&var cursor=db.oplog.rs.find({"op":"i"});
mongo&var lastinsert=cursor.sort({$natural:-1}).limit(1).next();
mongo&db.templastop.save(lastinsert);
mongo&db.templastop.findOne()#确保写入
4、将oplog.rs 删除: db.oplog.rs.drop();
5、创建一个新的oplog.rs集合: db.createCollection("oplog.rs":{"capped":true,"size":10240});
6、将临时集合中的最后一条insert操作记录写回新创建的oplog.rs:
var temp=db.templastop.findOne();
db.oplog.rs.insert(temp);
db.oplog.rs.findOne()#确保写回,否则 该节点重新加入副本集后会删除该节点上所有数据,然后重新同步所有数据。
7、最后将该节点以副本集成员的身份重新启动即可。
十二、为复制集成员设置选项
即当运行rs.initiate(replSetcfg) 或运行 rs.add(membercfg)选项时,需要提供描述复制集成员的特定配置结构:
_id:replSetName,
{_id:&number&,host:&hostname|ip[:port]&,
[priority:&priority&,]#默认值为1.0.即选项的值是浮点型
[hidden:true,]#该元素将从db.isMaster()的输出中隐藏该节点。
[arbiterOnly:true,]#默认值为 false
[votes:&n&,]#默认值为1 。改选项的值为整形
[tags:{documents},]
[slaveDelay:&seconds&,]
[buildIndexes:true,]#默认值为 false。该选项用于禁止创建索引。
settings:{
[chainingAllowed:&boolen&,]#指定该成员是否允许从其他辅助服务器复制数据。默认值为 true
[getLastErrorModes:&modes&,]#模式:用于自定义写顾虑设置
[getLastErrorDefaults:&lasterrdefaults&,]#默认值:用于自定义写顾虑设置。
以上是复制集的完整的配置结构。最高级的配置结构包括3级:
_id、members、settings。
_id是复制集的名称,与创建复制集成员时时候用的 --replSet命令选项时提供的名称一样。
members是数组,由一个描述每个成员的集合组成;这是添加单个服务器到集合中时,应该在rs.add()命令中提供的成员机构;
settings也是数组,该settings数组包含应用到整个复制集的选项。这些选项可以设置复制集成员间如何通信。
十三、Rollback
mongodb只支持小于300M的数据量回滚,如果大于300M的数据需要回滚或要回滚的操作在30分钟以上,只能是手动去回滚。会在mongodb日志中报以下错误:[replica set sync] replSet syncThread: 13410 replSet too much data to roll back
经量避免让rollback发生。方法是:使用 复制的 写顾虑(Write Concern)规则来阻止回滚的发生。
如果发生了回滚操作,则会在mongodb数据文件目录下产生一个以database.collection.timestamp.bson的文件。查看该文件的内容用 bsondump 工具来查看。
十四、读偏好设置(ReadPreferred)
读取偏好是指选择从哪个复制集成员读取数据的方式。可以为驱动指定5中模式来设置读取偏好。
readPreference=primary|primaryPreferred|secondary|secondaryPreferred|nearest
setReadPreferred()命令设置读取偏好。
primary:只从主服务器上读取数据。如果用户显式指定使用标签读取偏好,该读取偏好将被阻塞。这也是默认的读取偏好。
primaryPreferred:读取将被重定向至主服务器;如果没有可用的主服务器,那么读取将被重定向至某个辅助服务器;
secondary:读取将被重定向至辅助服务器节点。如果没有辅助服务器节点,该选项将会产生异常;
secondaryPreferred:读取将被重定向至辅助服务器;如果没有辅助服务器,那么读取将被重定向至主服务器。该选项对应旧的“slaveOK”方法;
nearest:从最近的节点读取数据,不论它是主服务器还是辅助服务器。该选项通过网络延迟决定使用哪个节点服务器。
十五、写顾虑设置(Write Concern)
写顾虑类似读取偏好,通过写顾虑选项可以指定在写操作被确认完成前,数据必须被安全提交到多少个节点。
写顾虑的模式决定了写操作时如何持久化数据。参数“w”会强制 getLastError等待,一直到给定数据的成员都执行完了最后的写入操作。w的值是包含主节点的。
写顾虑的5中模式:
w=0或不确定:单向写操作。写操作执行后,不需要确认提交状态。
w=1或确认:写操作必须等到主服务器的确认。这是默认行为。
w=n或复制集确认:主服务器必须确认该写操作。并且n-1个成员必须从主服务器复制该写入操作。该选项更强大,但是会引起延迟。
w=majority:写操作必须被主服务器确认,同时也需要集合中的大多数成员都确认该操作。而w=n可能会因为系统中断或复制延迟引起问题。
j=true日志:可以与w=写顾虑一起共同指定写入操作必须被写入到日志中,只有这样才算是确认完成。
wtimeout:避免getLastError一直等待下去,该值是命令的超时时间值,如果超过这个时间还没有返回,就会返回失败。该值的单位是毫秒。如果返回失败,值在规定的时间内没有将写入操作复制到"w"个成员。
该操作只对该连接起作用,其他连接不受该连接的"w"值限制。
db.products.insert(
{ item : "envelopes" , qty : 100 , type : "Clasp" },
{ writeConcern : { w : 2 , wtimeout : 5000 } }
wtimeout#代表5秒超时
修改默认写顾虑
cfg = rs.conf()
cfg.settings = {}
cfg.settings.getLastErrorDefaults = { w: "majority" , wtimeout: 5000 }
rs.reconfig(cfg)
设置写等待
db.runCommand({"getLastError":1,w:"majority"})
db.runCommand({"getLastError":1,"w":"majority","wtimeout":10000})
即,表示写入操作被复制到了多数个节点上(majority 或 数字),这时的 w会强制 getLastError等待,一直到给定数量的成员执行完了最后的写入操作。而wtimeout是指超过这个时间没有返回则返回失败提示(即无法在指定时间内将写入操作复制到w个成员中),getLastError并不代表写操作失败了,而是代表在指定给定wtimeout时间内没有将写入操作复制到指定的w个成员中。w是限制(控制)写入 速度,只会阻塞这个连接上的操作,其他连接上的操作不受影响。
十六、读取偏好和写顾虑中使用标签(tags)
十七、选举机制
1、自身是否能够与主节点连通;
2、希望被选件为主节点的备份节点的数据是否最新;
3、有没有其他更高优先级的成员可以被选举为主节点;
4、如果被选举为主节点的成员能够得到副本集中“大多数”成员的投票,则它会成为主节点,如果“大多数”成员中只有一个否决了本次选举,则本次选举失败即就会取消。一张否决票相当于10000张赞成票。
5、希望成为主节点的成员必须使用复制将自己的数据更新为最新;
十八、数据初始化过程
1、首先做一些记录前的准备工作:选择一个成员作为同步源,在local.me集合中为自己创建一个标识符,删除索引已存在的数据库,以一个全新的状态开始进行同步;该过程中,所有的数据都会被删除。
2、然后克隆,就是将同步源的所有记录全部复制到本地。
3、然后就进入oplog同步的第一步,克隆过程中的所有操作都会被记录到oplog中。
4、接下来就是oplog同步过程的第二步,用于将第一个oplog同步中的操作记录下来。
5、截止当前,本地的数据应该与主节点在某个时间点的数据集完全一致了,可以开始创建索引了。
6、若当前节点的数据仍然落后同步源,那么oplog同步过程的最后一步就是将创建索引期间的所有操作全部同步过出来,防止该成员成为备份节点。
7、现在当前成员已经完成了初始化数据的同步,切换到普通状态,这时该节点就可以成为备份节点了。
十九、mongodb3.0 建议开启的设置
echo never & /sys/kernel/mm/transparent_hugepage/enabled
echo never & /sys/kernel/mm/transparent_hugepage/defrag
执行上面两命令后只是当前起作用。如果重启mongod服务后 就失效。永久起效则
写入到 /etc/rc.local
二十、修改服务器hostname名
1、首先修改 secondary 服务器的然后
2、重启 secondary 以修改后的新hostname;
3、登录 primary ;
4、用rs.reconfig()命令修改 复制集的配置信息;
conf=rs.conf()
conf.members[x].host='new_address:27017'
rs.reconfig(conf);
二十一、生成 keyfile文件
openssl rand -base64 666 & /opt/mongo/conf/MongoReplSet_KeyFile
chown mongod.mongod /opt/mongo/conf/MongoReplSet_KeyFile
chmod 600 /opt/mongo/conf/MongoReplSet_KeyFile
mongodb 分片群集配置 及数据迁移
配置mongodb分片群集(sharding cluster)
Sharding cluster介绍
这是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构...
Mongodb集群搭建的三种方式
Mongodb是时下流行的NoSql数据库,它的存储方式是文档式存储,并不是Key-Value形式。关于Mongodb的特点,这里就不多介绍了,大家可以去看看官方说明:http://docs.mong...
mongoDB conf 文件配置详解
mongoDB conf 文件配置 安装配置 收藏纯洁徐 发表于 3年前 阅读 361 收藏 3 点赞 0 评论 0【腾讯云】新注册用户域名抢购1元起&&& ...
MongoDB 分片集群故障RECOVERING 处理纪实
1、问题描述,备库故障RECOVERING运营同事说查询mongodb备库数据,没有最新的记录,估计是复制延时了,或者是故障了,赶紧上去查看状态rs.status(),看到备库处于RECOVERING...
-- purge disk space
1 首先使用rs.remove(“ip:port”)移除一个从库,使其下线。
http://docs.mongodb.org/manual/tutorial...
1、创建数据文件、日志路径目录及复制集key文件
mkdir -p /app/mongo/mongodb/data/sets/r0
mongodb副本集删除方法
起因:由于要搭建一个mongodb的测试环境,所以从原来的一台服务器上克隆了一个过来,上面有三个mongodb实例,组成了一个副本集。
副本集的设置也一起copy过来了,...
replica set多服务器主从,添加,删除节点,肯定会经常遇到的。下面详细说明一下,添加,删除节点的2种方法。
一,利用rs.reconfig,来添加,删除节点
1,添加节点
查看复制打印
...
正在一个总裁节点,在活跃节点上执行rs.add(&127.0.0.1:33333&,true)删除一个从节点,在活跃节点上执行rs.remove(&127.0.0.1:3...
没有更多推荐了,

我要回帖

更多关于 document打印 的文章

 

随机推荐