是什么
Capped collection
(固定大小表)是一种大小为可设定的固定值的集合。支持高性能写入操作和高性能以插入顺序读操作。Capped collection
原理类似循环缓冲区,当达到最大限制时,会覆盖最老的数据用以写入新的数据。
有什么特性
- 大小固定可设定
- 提供高性能的写入操作,高性能的基于插入顺序的读操作
什么时候需要用
下面列举两个常见场景
日志写入
在大磁盘容量的系统中,在没有索引的前提下,以接近写日志文件的速度存储日志到Capped collection
中。而且自带先进先出的磁盘空间使用策略
缓存少量数据
缓存属于读取压力大,写入压力小的操作,如果不使用Capped collection
,你就会面临两种选择
- 牺牲写入性能,添加索引
- 让这部分数据常驻内存(占用内存空间)
注意事项
更新操作
如果固定大小表会有更新操作,请先创建索引避免一次更新操作会扫描整个表
使用MMAPv1存储引擎的时候,如果有更新操作导致数据增长超过固定大小表的限制,更新将会失败
使用MMAPv1存储引擎的副本集从节点
如果主节点将固定大小表的size改小了,从节点也会随之改小
更新操作如果会让Capped collection
超出配置的大小,primary节点会执行成功,secondary节点如果使用的是MMAPv1存储引擎,就会导致出现failing update: objects in a capped ns cannot grow
的错误信息
为了解决这个问题,可以按照这个教程去处理secondary节点。
简单来说,方法就是把primary的数据目录复制一遍作为secondary的数据目录
删除操作
Capped collection
无法删除部分文档,如果要删数据,只能drop掉表,然后新建一个新的Capped collection
分片
Capped collection
不能被分片
Aggregation $out
聚合操作的$out操作符输出数据不能输出到Capped collection
常用操作
创建
1 | db.createCollection( "log", { capped: true, size: 100000 } ) // size的单位bytes |
- 以上两个参数是必要参数
Capped collection
实际占用空间大小会略微大于配置的maxsize,因为有一些磁盘空间用于内部开销- 如果size小于4096那么,
Capped collection
将认为size是4096,如果size大于4096,Capped collection
会自动让size整除256
也可以指定最大的document数量,例如1
db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
size是必传参数,size的优先级高于max
查询
1 | db.cappedCollection.find().sort( { $natural: -1 } ) |
上例是按照文档插入顺序倒排查询
检查是否是Capped collection
db.collection.isCapped()
将一个非Capped collection
转换为Capped collection
db.runCommand({“convertToCapped”: “mycoll”, size: 100000});
警告:这个命令会创建一个全局写锁,并且会阻塞其他操作一直到命令结束
注意:分片集群不支持
convertToCapped
命令
设置自动删除数据的延迟时间
如果想设置自动删除数据的延迟时间,可以参考mongodb的TTL索引机制。遗憾的是TTL集合跟Capped collection
并不兼容(没搞懂官网提这个搞什么)
Tailable Cursor
tailable cursor有点类似Unix命令tail -f
,会跟踪文件新写入的内容,使用tailable cursor
可以跟踪新插入到Capped collection
中的数据
其他相关概念
写入顺序
Capped collection
会保存数据写入顺序,所以如果返回数据顺序就是数据插入顺序,查询的时候不需要额外的索引去控制,Capped collection
会自动以插入顺序返回。这种方式比使用索引有更好的性能
旧数据的自动清除
Capped collection
会自动删除最老的数据,为新来的数据腾出空间,不需要代码控制
_id索引
2.4以及2.4以上的变更
固定大小表默认有_id字段,而且会默认在_id字段创建索引