我见过很多公司都在使用MongoDB来存储应用程序日志。它的模式自由性对于应用程序日志非常灵活,在这种情况下,模式往往会不时改变。此外,它的Capped Collection功能非常有用,因为它会自动清除旧数据以保持数据适合内存。
人们通过普通的 Grouping 或 MapReduce 聚合日志,但速度不是那么快。尤其是 MongoDB 的 MapReduce 只能在单线程中工作,而且它的 JavaScript 执行开销很大。新的聚合框架可以解决这个问题。
当您使用 MongoDB 进行日志记录时,需要注意的是高写入吞吐量导致的锁争用。虽然 MongoDB 的插入默认是即发即弃的风格,但调用大量的 insert() 会导致严重的写锁争用。这可能会影响应用程序性能,并阻止阅读器聚合/过滤存储的日志。
一种解决方案可能是使用日志收集器框架,例如Fluentd、Logstash或Flume。这些守护进程应该在每个应用程序节点上启动,并从应用程序进程中获取日志。
它们缓冲日志并将数据异步写入其他系统,如 MongoDB / PostgreSQL / 等。写入是通过批处理完成的,因此比直接从应用程序写入要高效得多。此链接描述了如何将日志从 PHP 程序放入 Fluentd。
这里有一些关于 MongoDB + Fluentd 的教程。
MongoDB 的问题是当数据量超过内存大小时它开始变慢。此时,您可以切换到其他解决方案,如Apache Hadoop或Cassandra。如果你有上面提到的分布式日志层,你可以随着你的成长切换到另一个解决方案。本教程介绍如何使用 Fluentd 将日志存储到 HDFS。