在开发map-reduce作业期间,我们的MR代码可以生成有用的诊断数据结构,而不依赖于地图缩减的数据。有没有一种简单的方法可以将这些数据输出到调用mapReduce的代码或将它们保存在Mongo中?只是写入日志文件是非常次优的,因为(a)已经有很多数据和(b)我们的诊断信息是高度结构化的,事实上,我们想要运行查询它。
到目前为止,我的调查表明,MR数据结构是通过值传递的(通过序列化),因此任何内存中的数据结构都会丢失,包括那些挂钩到“全局”范围的数据结构。命名空间与主JS服务器端命名空间隔离,因此dbeval
似乎无法访问它们(或者,至少,我不知道在哪里查看)。最后但并非最不重要的是,尽管存在所有数据库对象和函数,但10gen正在生成(混淆)错误消息以阻止它们的使用,例如coll.insert
typeof coll.insert === 'function'
true
{{1}} {{1}} {{1}} {{1}} }}
很明显,我有兴趣在单个节点中进行开发,因为MongoDB中的日志/调试支持非常有限。这种副作用在生产环境中并不好。
答案 0 :(得分:2)
据推测,从Map / Reduce函数中访问另一个数据库是不可能的(如MongoDB 2.2)。除了潜在的性能影响之外,还有可能产生死锁和其他不必要的副作用。
不幸的是,将print()
留给mongo日志作为唯一的“带外”输出选项。
根据您的诊断输出,尝试的一种方法是:
添加一个唯一标记,可以在日志输出中识别输出(甚至输出运行)
使用tojson()
序列化您的输出,以便使用一些可解析的结构进行记录,并在print()
将一个脚本写入tail
mongod.log日志中,以查找与您的唯一标记匹配的行,并将这些行插入另一个集合以进行报告
将在M / R函数中运行的代码示例:
var diag = {
'run' : diagrun,
'phase': 'map',
'key' : z
}
print("MAPDIAG:" + tojson(diag));
示例输出:
$ tail -f mongo.log | grep "^MAPDIAG"
MAPDIAG:{ "run" : "20120824", "phase" : "map", "key" : "dog" }
MAPDIAG:{ "run" : "20120824", "phase" : "map", "key" : "cat" }
MAPDIAG:{ "run" : "20120824", "phase" : "map", "key" : "cat" }
MAPDIAG:{ "run" : "20120824", "phase" : "map", "key" : "mouse" }
MAPDIAG:{ "run" : "20120824", "phase" : "map", "key" : "cat" }
MAPDIAG:{ "run" : "20120824", "phase" : "map", "key" : "dog" }
MAPDIAG:{ "run" : "20120824", "phase" : "reduce", "key" : "cat", "total" : 3 }
MAPDIAG:{ "run" : "20120824", "phase" : "reduce", "key" : "dog", "total" : 2 }