美文网首页
logstash input-jdbc 分页性能优化

logstash input-jdbc 分页性能优化

作者: Boole_74bf | 来源:发表于2018-10-30 22:12 被阅读0次

    场景:

        DB 数据全量同步 Elasticsearch 时,数据量过大时需要使用分页查询。在conf中配置jdbc_paging_enabled、jdbc_page_size这两个参数,input-jdbc插件会自动对SQL进行分页查询,分批同步数据。

    问题:

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

        项目的ES升级至5.6后,全量数据同步由java定时任务改为logstash。线上数据量比较大,优化索引后单个分页查询执行依旧很慢,需要几十秒。

        原因在于input-jdbc插件的分页是使用临时表分页,每条分页SQL都是将全集查询出来当作临时表,再在临时表上分页查询。这样导致每次分页查询都要对主表进行一次全表扫描。

        举个例子:

        商品表(goods)有1000万条数据,每次同步1万条。input-jdbc插件执行的分页查询sql类似下面这样的。

        select * from (select * from goods left join ...) as T limit 0,10000

    解决方案

        通过修改input-jdbc插件源码,支持子查询分页。修改后执行的查询sql类似下面这样的,这样每次分页只需要扫描主表中需要的数量。

    select * from (select * from goods limit 0,10000 ) as T left join ...

    效果

        项目中单个分页查询都在2S内完成。并且优化后的插件由运维推广到了所有项目,一次有价值的优化。

    优化内容:

    源码

    1、logstash-input-jdbc\lib\logstash\plugin_mixins\jdbc.rb中添加subquery_paging_enabled、sum_statement变量;(具体参见我修改的源码 Line100)

    2、perform_query方法中优先判断是否进行子查询优化。(具体参见我修改的源码 Line255)

    jdbc.rb源码

    配置文件

    1、添加两个配置项:

    subquery_paging_enabled => "true"

    sum_statement => "select count(*) as sum from goods"

    2、优化statement SQL

    主表改为分页子查询,添加:data_offset、:jdbc_page_size分页参数。例如:

    statement => " select * from (select * from goods limit :data_offset , :jdbc_page_size ) as T left join ... "

    开发参考

    https://github.com/logstash-plugins/logstash-input-jdbc

    https://github.com/jeremyevans/sequel

    插件构建和安装

    1、项目安装依赖(先去github下载源码)

    bundle install

    2、构建插件gem (在项目主目录下产生logstash-input-jdbc-4.3.5.gem文件)

    gem build logstash-input-jdbc.gemspec

    3、logstash卸载logstash-input-jdbc插件

    /bin/logstash-plugin uninstall logstash-input-jdbc

    4、logstash安装本地插件 (先将构建成功的gem文件拷贝至logstash主目录的trade_gem文件夹中)

    /bin/logstash-plugin install --no-verify --local ../logstash-input-jdbc-4.3.5.gem

    相关文章

      网友评论

          本文标题:logstash input-jdbc 分页性能优化

          本文链接:https://www.haomeiwen.com/subject/bemntqtx.html