使用Fluentd和MongoDB时出现“超出最大插入大小 xxxx”的问题
请问有什么问题吗?
当尝试将Fluentd插入MongoDB时,出现以下错误。
Exceded maximum insert size of 8388608
导致这个问题的原因是,当fluentd将数据块一次性写入MongoDB时,文档集合的大小超过了阈值。
在这里让我觉得奇怪的是,MongoDB有一个写入查询的大小限制为16MByte,但不知为何错误消息中却写着8MByte的限制。
这个差异是什么?
阅读源代码后,发现以下部分存在问题。
/usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/mongo-1.8.6/lib/mongo/collection.rb
1072 def insert_documents
(中略)
1102 if message.size > @connection.max_message_size
1103 raise InvalidOperation, "Exceded maximum insert size of #{@connection.max_message_size} bytes" ★
1104 end
换句话说,这并不是MongoDB本身的限制,而是由于Ruby的MongoDB驱动程序计算出的@connection.max_message_size值导致的。(这个值似乎依赖于BSON库之类的东西)
针对措施
当我们进行调查时,发现Ruby的MongoDB驱动程序在1.9.0版本中修复了这部分逻辑,并且能够将超过阈值的文档集合分割成批量插入。
-
- JIRA: https://jira.mongodb.org/browse/RUBY-533
修正コミット: https://github.com/mongodb/mongo-ruby-driver/commit/f54f10f7e24bd8dfe975b1df832531a0446a22e5
因此,我們需要採取對策。
将Ruby的MongoDB驱动程序升级至1.9.0或更高版本。
可以用「可以了」进行翻译。
确认效果
当对比以下代码在Ruby的MongoDB驱动程序1.9.0版本以下和1.9.0版本以上进行实验时会发现,前者会出错,而后者能够顺利执行。
require 'mongo'
str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
10.times { str += str }
ary = []
1000.times { ary << {"a" => str} }
con = Mongo::Connection.new
con["test"]["mycol"].insert(ary)
最终
在这些博客等资源中,提到了”调整buffer_chunk_limit”作为一种解决方案,但我觉得这并不必要。
* http://blog.stanaka.org/entry/2013/02/22/171053
* http://d.hatena.ne.jp/ckreal/20111116/1321455441