我试图将一个大型(~30M行)MySQL数据库导入ElasticSearch。很酷,有一个logstash
工具看起来像是为这类东西而建的;它的JDBC插件可以让我连接到数据库并快速实现行。
然而!当我尝试它时,它会与java.lang.OutOfMemoryError
一起轰炸。好的。它可能试图批量过多行或其他东西。所以我将jdbc_fetch_size => 1000
添加到我的配置中。没有骰子,仍然没有记忆。好吧,也许这个选项不起作用,或者做不到我的想法?
所以我尝试将jdbc_paging_enabled => true
和jdbc_page_size => 10000
添加到我的配置中。成功!它开始以10k的批量向我的索引添加行。
但它放慢了速度。起初我跑100k行/分钟;然而,当我在2M行时,我可能只有十分之一。并不奇怪;我很确定这是使用LIMIT和OFFSET,并且在查询中使用大量OFFSET非常慢,所以我在这里处理O(n ^ 2)类的事情。
我真的很想只运行整个大查询并让光标迭代结果集,但看起来因为某些原因它不起作用。如果我对查询有更多的控制权,我可以更改LIM {/ 1}类似物的LIMIT / OFFSET,但是我无法看到我可以在哪里进行操作。
关于我如何不能崩溃但仍以合理的速度运行的任何建议?
答案 0 :(得分:5)
好!搜索了" Memory"的logstash-input-jdbc github页面的问题之后我找到了chrome 59.0.3071.115:
似乎需要在mysql 5.x的连接字符串中添加一个额外的参数
?useCursorFetch=true
。
事实证明,由于某些原因,MySQL JDBC客户端默认不使用游标来获取行,并且logstash客户端不会警告您它无法使用游标即使您因为其他原因设置了jdbc_fetch_size
,也会迭代结果集。
当然,了解这一点的显而易见的方法是仔细阅读this revelation,确实提到游标默认是关闭的,但不是原因。
无论如何,我将useCursorFetch=true
添加到连接字符串,将jdbc_query_paging
踢到路边,并在2.5小时内将16M行导入我的索引,在老化的Macbook Pro上使用8G内存。
感谢github用户the MySQL Connector/J documentation提供了有用的评论!