本文使用的是node.js版本的mongodb连接库
写这篇的时候才发现我根本没写过tag
是 #mongodb 的博客,足以见得知识浅薄,甚至这篇也没有什么技术含量
有个有趣的工作是遍历某mongo库的索引,对其上符合要求的文档做某些操作,数据量大到可能要跑十天半个月,中途可能还要避开业务高峰期,而每次都用find({_id:{$gt:lastid}}).sort().skip().limit()
感觉又不够好玩
于是计划用一个游标从头遍历到尾,这样的好处是不会重复发出多次op,在网络请求层面上还是要好一点的(游标有一个batchSize
控制每次读取的数据量,可以视情况调整),而我又可以使用游标的流特性,来做一些下游打包、管道之类的好玩操作(见《Stream研究笔记II》)
延长查询超时时间
MongoClient
建立实例时传递的socketTimeoutMS
选项默认是6分钟,当查询耗时非常长时(比如没命中索引的count()
),客户端将不再等待服务端返回并抛错,此选项只是以防万一,如果没有耗时很长的单次查询,这个可以保持默认
设置游标不超时
在find()
的参数内传递noCursorTimeout
,避免闲置的游标被服务端主动释放
设置session活跃
然而只靠上面的选项还不够,官方文档-cursor.noCursorTimeout 又说了,服务端还是会清理闲置30分钟以上的session
(每个op
都包含在session
中,不主动指定的话会生成一个隐式的),除非你主动地定期刷新session
的活跃状态,连代码都附出来了
1 | var session = db.getMongo().startSession() |
需要自己显示声明一个session
,在它之上发起游标查询,然后定期刷新session
,这样游标就不会被服务器给释放掉了