Logstash数据同步组件
1. 什么是Logstash
ELK里的L
思考一个场景
我们现在需要对数据库的一些数据进行统一的采集并入库,这个时候怎么做?
-
通过手动逐条写入
-
通过Java程序批量查询并写入
认识一下Logstash
Logstash是elastic技术栈中的一员,他是一个数据采集引擎,可以从数据库采集数据到ES中,我们可以通过设置自增id主键或时间来控制数据的自动同步,这个id或者时间就是用于给logstash进行识别的
-
id:假设现在有1000条数据,Logstash识别后会进行一次同步,同步完后会记录最后的id为1000,以后数据库新增数据,id都会一直累加,Logstash会有定时任务,发现有id大于1000,就会增量到ElasticSearch中
-
时间:同理,一开始同步完1000条数据,每条数据都有一个字段,为time,初次同步完毕后,记录这个time,下次同步的时候进行时间的比对,如果有超过这个时间的,那么就可以做同步了,这里可以做同步新增数据的更新,或修改元数据的时候,因为同一条数据的修改时间会被识别,所以可以用这个做逻辑删除和数据更新,而id则不能
logstash-input-jdbc
-
logstash的数据库驱动插件
-
本插件可以用于同步数据库中的数据,es6.x起已经自带了,并集成在了logstash中,所以可以直接配置数据的驱动配置即可
-
同步之前建议先把需要同步的数据的index和mapping先创建好,如果没有提前创建,logstash会根据自己的判断进行mapping和index的创建
-
需要把jdk进行提前安装,将mysql的jdbc驱动包放到指定目录下
注意:logstash要和elasticsearch的版本强一致
2. Logstash数据同步配置
1、下载安装包**
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.5.2.tar.gz
2、安装JDK**
3、进行文件配置**
# 解压后在logstash的根目录创建一个同步文件夹,存放同步命令
mkdir sync
# 在sync目录下创建同步命令文件
vi logstash-db-sync.conf
# 将数据库驱动 mysql-connector-java-5.1.19-bin.jar 也放到sync文件目录下
我们来看一下logstash的配置文件内容:logstash-db-sync.conf
input {
jdbc {
# 设置 MySql/MariaDB 数据库url以及数据库名称
jdbc_connection_string => "jdbc:mysql://192.168.0.8:3306/icoding_mall?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true"
# 用户名和密码
jdbc_user => "gavin"
jdbc_password => "123456"
# 数据库驱动所在位置,可以是绝对路径或者相对路径
jdbc_driver_library => "/usr/local/logstash/sync/mysql-connector-java-5.1.49.jar"
# 驱动类名
jdbc_driver_class => "com.mysql.jdbc.Driver"
# 开启分页
jdbc_paging_enabled => "true"
# 分页每页数量,可以自定义
jdbc_page_size => "1000"
# 执行的sql文件路径
statement_filepath => "/usr/local/logstash/sync/icoding-task.sql"
# 设置定时任务间隔 含义:分、时、天、月、年,全部为*默认含义为每分钟跑一次任务
schedule => "* * * * *"
# 索引类型
type => "_doc"
# 是否开启记录上次追踪的结果,也就是上次更新的时间,这个会记录到last_run_metadata_path的文件
use_column_value => true
# 记录上一次追踪的结果值
last_run_metadata_path => "/usr/local/logstash/sync/track_time"
# 如果 use_column_value 为true, 配置本参数,追踪的column名,可以是自增id或者时间
tracking_column => "update_time"
# tracking_column 对应字段的类型
tracking_column_type => "timestamp"
# 是否清除 last_run_metadata_path 的记录,true则每次都从头开始查询所有的数据库记录
clean_run => false
# 数据库字段名称大写转小写
lowercase_column_names => false
}
}
output {
elasticsearch {
# es地址
hosts => ["192.168.0.6:9200"]
# 同步的索引名
index => "index_product"
# 设置_doc ID和数据相同,如果注释掉就自动生成_doc的ID
document_id => "%{product_id}"
}
# 这里输出调试,正式运行时可以注释掉
stdout {
codec => json_lines
}
}
需要说明的点:
-
tracking_column_type:支持两种类型的
-
numeric(默认)
-
timestamp:如果想用时间字段来进行数据的更新导入,一定要用timestamp类型
-
icoding-task.sql的编写
select
product_id,
product_title,
url_handle,
first_image_src,
second_image_src,
original_price,
sale_price,
spu,
short_description,
detail_description,
version,
is_delete,
create_emp,
update_emp,
create_time,
update_time
from im_product
where `status`=1
and
is_delete=0
and
update_time> :sql_last_value
4、启动logstash**
# 在logstash根目录的bin文件夹下
./logstash -f /usr/local/logstash/sync/logstash-db-sync.conf
3. Logstash实现场景需要注意的地方
-
建议大家使用更新时间来做临界值
-
数据库中物理删除数据是无法同步到ES中的
-
数据的逻辑删除上,其实只是更新了数据的状态而已
-
logstash在导入数据前最好将index创建好并将mapping设置完成,如果ES事先没有索引或mapping,logstash会自动创建,但不会按照我们的习惯使用分词器