你可以的,加油

logstash导入mysql上亿级别数据的效率问题

Logstash | 作者 446978780@qq.com | 发布于2017年11月23日 | 阅读数:20719

请教各位:
  当mysql表中数据存在上亿条时,使用logstash同步表中数据到ES,而且使用jdbc_paging_enabled分页时,其是直接将原sql语句作为子查询,拼接offset和limit来实现。当查询出的结果集较大时存在深度分页瓶颈。
 日志如下:
TIM图片20171123144411.png

可以看到一次查询花费几千秒。
 
当查询出的结果集较小时,比如几百万时,则只要花费几十秒。
333.png

 
请问各位,有什么好办法提高logstash在数据量较大情况下的查询效率吗,现在测试表中生成了一亿条左右数据,但是当logstash从mysql中查询数据实在是太慢了,几千秒才能查出一次数据,请问有什么好的方式增加速度吗?或者有没有大神做过类似场景的测试,请大神指教。
已邀请:
我也遇到你同样问题,可以这么解决:
1.给updated_ts时间字段加上索引。
2.分批处理原则
(1)你的SQL:每批处理100000个
SELECT a.party_id AS id ,a.* FROM PARTY_ALL_1 a WHERE a.updated_ts > '2011-11-17 13:23:58' order by a.updated_ts asc LIMIT 100000;
 
(2)logstash分页的时候每次处理50000个
SELECT * FROM (SELECT a.party_id AS id ,a.* FROM PARTY_ALL_1 a WHERE a.updated_ts > '2011-11-17 13:23:58' order by a.updated_ts asc LIMIT 100000) AS `t1` LIMIT 50000 OFFSET 0;
 
SELECT * FROM (SELECT a.party_id AS id ,a.* FROM PARTY_ALL_1 a WHERE a.updated_ts > '2011-11-17 13:23:58' order by a.updated_ts asc LIMIT 100000) AS `t1` LIMIT 50000 OFFSET 50000;
 
(3)处理两次就写一个最后一条记录的updated_ts时间到指定文件。下一个定时任务启动的时候进行循环处理就行,因为每批处理updated_ts都会改变
 

xiaoke - http://blog.51cto.com/kexiaoke

赞同来自: 446978780@qq.com

这个感觉和Logstash就无关了,上亿条数据,如果索引没有优化好,哪怕直接在mysql cli里面查询也是慢的。

lunatictwo

赞同来自: xiaoke

logstash jdbc 比较坑的一点就是这个,对sql 的分页执行优化的很差,它的分页的逻辑就是先有个最大的子查询,然后再在这个字查询中分页拿数据,而不是直接在sql尾部追加limit offset。建议是在原生的sql上分页,而不是用jdbc_paging_enabled分页,缺点就是得增量同步,不过几亿条数据多做几次增量也同步的过来。

Jea - 一只猿

赞同来自: cccthought

停止使用offset来导数据, 改为:使用自增主键(或有大小顺序的)如果有的话, 否则就慢慢来吧, 没办法
有主键的话:
假设步长10000
var id =0;
while(true){
data = select * from 你的表 where 自增主键> id limit 10000 order by id asc;
id = data中的最大的id
if(data.len == 0){
break;
}
}

zhangyufu - 学习使我快乐

赞同来自:

最简单的解决方式就是写一个脚本  一次查一点上传到Redis,  logstash从redis读取数据上传到ES,这样可以通过脚本想怎么上传就怎么上传,把效率控制在自己的脚本中

laoyang360 - 《一本书讲透Elasticsearch》作者,Elastic认证工程师 [死磕Elasitcsearch]知识星球地址:http://t.cn/RmwM3N9;微信公众号:铭毅天下; 博客:https://elastic.blog.csdn.net

赞同来自:

读的时候,限定条数。我的理解:慢的原因是每次读的时候加载到内存,所以慢。

wajika

赞同来自:

有个比较坑的问题,jdbc出错就会重新开始读取。
 
 

要回复问题请先登录注册