1、logstash-input-jdbc 的同步原理是什么? (1)、对于全量同步依据 配置文件jdbc.sql的sql语句的进行同步。 (2)、对于增量实时同步依据 1)设定的定时策略。 如最小更新间隔每分钟更新一次设定:schedule => “* * * * *”,目前最小更新间隔为1分钟,验证发现,不支持60s以内的秒级更新。 2)设定的sql语句。 如jdbc.sql, 决定同步哪些内容及同步更新的条件。

2、logstash-input-jdbc 只支持基于时间同步吗? 验证表名:同步更新除了支持根据时间同步外,还支持根据某自增列(如:自增ID)字段的变化进行同步。 上次举例只是举了同步时间变化的例子,设定条件:

[root@5b9dbaaa148a logstash_jdbc_test]# cat jdbc.sql_bak

select
        *
from
        cc
where   cc.modified_at > :sql_last_value

实际进一步研究发现,在配置文件中有use_column_value字段决定,是否需要记录某个column 的值,如果 record_last_run 为真,可以自定义我们需要 track 的 column 名称,此时该参数就要为 true. 否则默认 track 的是 timestamp 的值.

举例:以下即是设定以id的变化作为同步条件的。

[root@5b9dbaaa148a logstash_jdbc_test]# cat jdbc_xm.sql
select
        *
from
        cc
where   cc.id >= :sql_last_value

我们可以指定文件,来记录上次执行到的 tracking_column 字段的值 比如上次数据库有 12 条记录,查询完后该文件中就会有数字 12 这样的记录,下次执行 SQL 查询可以从 13 条处开始.

我们只需要在 SQL 语句中 WHERE MY_ID > :last_sql_value 即可. 其中 :last_sql_value 取得就是该文件中的值(12).

last_run_metadata_path => “/etc/logstash/run_metadata.d/my_info”

[root@5b9 run_metadata.d]# cat /etc/logstash/run_metadata.d/my_info

--- 12

3、如何实现实时同步?

两个文件:  jdbc.conf   jdbc.sql 名字随便起啦。 一个 mysql 的java 驱动包  : mysql-connector-java-5.1.36-bin.jar

jdbc.conf 内容: 注意 statement_filepath => "jdbc.sql" 这个名字要跟下面的sql文件的名字对应上。

input {
  stdin {
  }
  jdbc {
  # mysql jdbc connection string to our backup databse  后面的test对应mysql中的test数据库
  jdbc_connection_string => "jdbc:mysql://192.168.1.1:3306/test"
  # the user we wish to excute our statement as
  jdbc_user => "root"
  jdbc_password => "******"
  # the path to our downloaded jdbc driver
  jdbc_driver_library => "/elasticsearch-jdbc-2.3.2.0/lib/mysql-connector-java-5.1.38.jar"
  # the name of the driver class for mysql
  jdbc_driver_class => "com.mysql.jdbc.Driver"
  jdbc_paging_enabled => "true"
  jdbc_page_size => "50000"
#以下对应着要执行的sql的绝对路径。
  statement_filepath => "/usr/local/logstash/bin/logstash_jdbc_test/jdbc.sql"
#定时字段 各字段含义(由左至右)分、时、天、月、年,全部为*默认含义为每分钟都更新(测试结果,不同的话请留言指出)
  schedule => "* * * * *"
#设定ES索引类型
  type => "cc_type"
  }
}

filter {
  json {
  source => "message"
  remove_field => ["message"]
  }
}

output {
  elasticsearch {
#ESIP地址与端口
  hosts => "192.168.1.1:9200"
#ES索引名称(自己定义的)
  index => "cc_index"
#自增ID编号
  document_id => "%{id}"
  }
  stdout {
#以JSON格式输出
  codec => json_lines
  }
}

参考 logstash-input-jdbc官方参考文档

jdbc.sql要执行的sql语句,选择哪些信息同步到ES中。

[root@5b9dbaaa148a logstash_jdbc_test]# cat jdbc.sql
select
  *
from cc
where cc.modified_at > :sql_last_value

cc.modified_at, 这个modified_at是我自己定义的更改时间字段,默认值default是now()当前时间。  而 :sql_last_value如果input里面use_column_value => true, 即如果设置为true的话,可以是我们设定的字段的上一次的值。  默认 use_column_value => false, 这样 :sql_last_value为上一次更新的最后时刻值。  也就是说,对于新增的值,才会更新。这样就实现了增量更新的目的。

实操发现: logstash-input-jdbc 能较好的实现mysql的insert、update的操作的增量、全量数据同步更新到ES, 但delete操作的实时同步没有很好的解决方案。