MongoDB中的Capped Collection

发布时间 2023-04-03 09:51:36作者: abce

capped collection是固定大小的结合,支持基于插入顺序的插入和检索文档的高吞吐量操作。Capped collections的工作方式类似循环buffer:一旦一个集合填满了它分配的空间,它就会通过覆盖集合中最老的文档来为新文档腾出空间。

作为capped collection的替代方案,可以考虑MongoDB的TTL(Time to Live)索引。正如在通过设置TTL使集合中的数据过期中所述,这些索引允许根据日期类型字段的值和索引的TTL值过期并从普通集合中删除数据。不过TTL索引与capped collection不兼容。

capped collection会维护文档的插入顺序,因此,不需要额外的索引来检索文档。这就使得capped collection可以维护一个高吞吐量的插入。capped collection的文档包含_id列,这是默认的索引。文档的删除操作也是基于最老的_id。mongodb会自动将capped collection扩展成256的整数倍。用户应该避免更新capped collection中的文档,如果你想更新,也是可以更新的。除非更新后不会增加文档的大小,而且也是兼做轻量级的更新,因为要扫描整个capped collection。可以创建一个索引,避免集合扫描。

创建capped collection

> db.createCollection( "logs", { capped: true, size: 500000 } );  // size is in bytes.

也可以指定capped collection中存放的文档的最大值。

> db.createCollection( "logs", { capped: true, size: 500000, max: 500 } );  // Size parameter is always needed even if we define the max document number.
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1676896611, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1676896611, 1)
}
>

 

将常规结合转换成capped collection

> db.runCommand({ "convertToCapped" : "log_old", size: 500000, max : 50 })
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1676896802, 3),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1676896802, 3)
} 

 

查询集合是否是capped collection

> db.log_old.isCapped()
true
> 

 

查询capped collection

mongodb可以保证按照文档的插入顺序检索capped collection。

> db.log_old.find().sort( { $natural: -1 } )

逆序返回结果:

> db.log_old.find().sort( { $natural: -1 } )

 

修改capped collection的大小

从MongoDB v6.0开始,可以修改capped collection的大小。然而在重新设置大小之前,要保证featureCompatibilityVersion至少被设置为6.0

db.runCommand( { collMod: "log", cappedSize: 100000 } ) //cappedSize should be in between 0 and 1PB.

否则会遇到以下错误:"unknown option to collMod: cappedSize"

> db.version()
4.4.16-16
rs1:PRIMARY> db.runCommand( { collMod: "logs", cappedSize: 100000 } )
{
"operationTime" : Timestamp(1678096200, 1),
"ok" : 0,
"errmsg" : "unknown option to collMod: cappedSize",
"code" : 72,
"codeName" : "InvalidOptions",
"$clusterTime" : {
"clusterTime" : Timestamp(1678096200, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
>

 

capped collection的优点

1.支持高插入吞吐量

2.存储日志信息很有用,按顺序保存

 

capped collection的缺点

1.不支持分片

2.没有TTL索引

 

总结

capped collection对于存储日志文件信息非常有用,因为它接近于将日志信息直接写入文件系统的速度,而且没有索引开销。

由于其稳定的性能,MongoDB本身使用capped collection来复制oplog.rs集合。

oplog.rs集合是一个特殊的capped collection,不能在其中创建索引、插入文档或删除集合。

capped collection有优点也有缺点,因此在使用之前,请确保了解应用程序的需求并做出相应的决定。