Elastic实战:通过logstash-input-jdbc实现mysql8.0全量/增量同步至ES7.x

55555
优质创作者: 后端开发技术领域
领域专家: 数据库技术领域
2022-03-24 19:42:21

0. 引言

上一期我们讲解了如何通过canal实现增量/全量同步,但因为canal本身基于binlog。所以在binlog开启之前的历史数据是不会同步的。

因此要实现真正的全量同步,还需要针对binlog开启之前的历史数据进行全量同步。

而实现这种全量同步的常用方案有:
1、业务代码实现
2、logstash-input-jdbc实现
3、其他同步组件实现,如datax

本期我们就来讲讲如何通过logstash来同步mysql数据到es

1. 环境

mysql 8.0
ES 7.13.0
kibana 7.13.0
logstash 7.13.0
jdk1.8  

2. 下载

2.1 下载logstash

因为logstash-jdbc-input是logstash的一个插件,因此需要先安装logstash

针对es、logstash、kibana的安装可参考我另外一篇博客:
ELK搭建:实现分布式微服务的日志监控,这里不再累述

2.2 mysql驱动器

因为logstash-jdbc-input是需要mysql驱动器的,且我的mysql是8.0版本,所以需要将驱动器上传到服务器上,这里选择scp的方式上传

scp mysql-connector-java-8.0.22.jar root@172.16.188.6:/var/local/logstash/lib

3. 安装配置

logstash5.x版本以上可以直接使用logstash-jdbc-input插件,不用安装ruby等环境

我这里使用的是logstash7.13.0,这个版本已经不用在安装jdbc插件了,可以直接使用,如果执行安装语句反而会报错:

Installation aborted, plugin 'logstash-input-jdbc' is already provided by 'logstash-integration-jdbc'

安装配置我们可以参考官方文档,善用官方文档能帮助我们避免、排查绝大部分错误!!!一定要学会使用官方文档。特别是Elastic Stack的官方文档是很详细的
logstash-output-elasticsearch官方文档
logstash-input-jdbc官方文档

1、创建mysql-es.conf配置文件

vim config/mysql-es.conf

文件内容

input {
   jdbc { 
    #数据库连接参数
      jdbc_connection_string => "jdbc:mysql://172.16.188.1:3306/bladex?useSSL=false"
      # mysql用户名
      jdbc_user => "root"
      # mysql密码
      jdbc_password => "123456"
      # mysql驱动器jar包
      jdbc_driver_library => "/var/local/logstash/lib/mysql-connector-java-8.0.22.jar"
      # 驱动类名
      jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
      # 开启分页
      jdbc_paging_enabled => "true"
      # 最大页码
      jdbc_page_size => "50000"
      # 用于同步的查询sql
      statement_filepath => "/var/local/logstash/config/mysql/user.sql"
      # 直接书写sql语句
      # statement => "select * from user"
      # 数据标签,用于标记不同的索引数据
      type => "user" 
      # 加上jdbc时区, 要不然logstash的时间会不准确
      jdbc_default_timezone => "Asia/Shanghai"
      # 设置列名区分大小写, 默认全小写
      lowercase_column_names => "false"
    }
}
output {
     if[type] == "user"{
       elasticsearch {
        # elasticsearch url
           hosts => ["172.16.188.7:9200"]
           # 下面两个参数可以开启更新模式
           #action => "update"
           #doc_as_upsert => true
           # 索引名
           index => "user"
           # 文档id 设置成数据库的id
           document_id => "%{id}"
           # 设置文档类型为doc,否则会报错keyword无法匹配到text
           document_type => "_doc"
       }
    }
    stdout {
        # 以json格式输出到控制台,方便调试
        codec => json_lines
    }
} 

如果需要增量更新的话,则需要在input/jdbc下添加如下配置

 #如果要使用其它字段追踪,而不是用时间开启这个配置
      use_column_value => true
      #设置要追踪的字段
      tracking_column_type => "timestamp"
      tracking_column => "create_time"
      # 是否记录sql_last_value
      record_last_run => true
      #上一个sql_last_value值的存放文件路径, 必须要在文件中指定字段的初始值
      last_run_metadata_path => "/var/local/logstash/config/mysql/user.metadata"
      # cron表达式, 全是*表示每秒都判断是否有更新
      schedule => "* * * * *"

2、创建user.sql文件

mkdir config/mysql
vim config/mysql/user.sql

文件内容

SELECT
        t.id, 
        t.code,
        t.email,
        t.real_name AS realName,
        t.role_id AS roleId,
        t.post_id AS postId,
        t.dept_id AS deptId
FROM
        blade_user t
WHERE  t.create_time > :sql_last_value

3、以mysql-es.conf文件启动logstash

./bin/logstash -f config/mysql-es.conf 

4、控制台打印出数据

在这里插入图片描述


5、kibana中查询索引,会发现数据已经同步了

在这里插入图片描述


6、需要注意的是如果你配置的是全量同步,也就是没有配置schedule选项的话,是只会执行一遍的,然后logstash就会自动关闭。不要看到logstash自动关闭了就认为自己配置错误了。这在官方文档中是有说明的

schedule

There is no schedule by default. If no schedule is given, then the statement is run exactly once

实际上这也是符合真实场景的,一遍将所有数据同步了也就足够了

后续要再执行增量同步可以按照上述的配置。但是处于性能考虑,可以使用基于binlog的canal来实现增量同步,效果更高。具体配置可参考我另一篇博客:
Elastic实战:通过canal1.1.5实现mysql8.0数据增量/全量同步到elasticsearch7.x

3.1 如何同时启动多个配置文件

一个配置文件代表一张表的同步,如果有多张表要进行同步呢,如何同时启动?
我们可以用到pipeline来实现

vim config/pipeline.yml

修改内容
如下内容就是要启动的多个配置文件

- pipeline.id: ServiceComplaintSuggestion
  path.config: "config/mysql/ServiceComplaintSuggestion.conf"
- pipeline.id: BladeUser
  path.config: "config/mysql/BladeUser.conf"
- pipeline.id: Project
  path.config: "config/mysql/Project.conf"
- pipeline.id: ServiceCommentOwner
  path.config: "config/mysql/ServiceCommentOwner.conf"
- pipeline.id: TransportCargo
  path.config: "config/mysql/TransportCargo.conf"
- pipeline.id: ServiceConsulte
  path.config: "config/mysql/ServiceConsulte.conf"
- pipeline.id: OrderGeneral
  path.config: "config/mysql/OrderGeneral.conf"
- pipeline.id: BladeDept
  path.config: "config/mysql/BladeDept.conf"
- pipeline.id: TransportOrder
  path.config: "config/mysql/TransportOrder.conf"
- pipeline.id: ServiceCommentDriver
  path.config: "config/mysql/ServiceCommentDriver.conf"
- pipeline.id: CertificateCarDrivingPermit
  path.config: "config/mysql/CertificateCarDrivingPermit.conf"

重新启动logstash,注意这里启动的方式发生了变化,就没有用f参数指定配置文件了

./bin/logstash

4. logstash-input-jdbc安装常见报错

1. Field [_id] is a metadata field and cannot be added inside a document. Use the index API request parameters

解决:
将 document_id => "%{_id}"调整为 document_id => "%{id}"

2. mapper [code] cannot be changed from type [keyword] to [text]

解决:
需要在url中添加上‘_doc’,比如post user/_doc/1
在logstash中修改配置如下:

elasticsearch { 
           document_type => "_doc"
       }

需要注意的是在官方文档中的解释(基于7.13.0版本)

Value type is string
There is no default value for this setting.
This option is deprecated

for elasticsearch clusters 8.x: no value will be used;
for elasticsearch clusters 7.x: the value of _doc will be used;
for elasticsearch clusters 6.x: the value of doc will be used;
for elasticsearch clusters 5.x and below: the event’s type field will be used, if the field is not present the value of doc will be used.

所以这个document_type是没有默认值的,在8.x版本会完全弃用失效。6.x版本时应该设置为doc,7.x版本应该设置为_doc

3. logstash-input-jdbc同步mysql数据,列名全小写怎么处理

解决:
input-jdbc默认设置列名全小写,但有时我们需要它区分大小写,比如同步数据到es中时,那么就需要手动关闭小写设置

input {
   jdbc { 
        lowercase_column_names: false
    }
}

4. [ERROR][logstash.outputs.elasticsearch][main]Encountered a retryable error (will retry with exponential backoff)

解决:
这个报错是因为es报错导致的

第一种情况

首先查看es中的报错日志,比如我这里遇到的是

There are no ingest nodes in this cluster, unable to forward request to an ingest node

问题很明显,是因为我使用了pipeline,但是集群中没有ingest节点,所以在es配置文件中添加上ingest角色即可

node.roles: [master,data,remote_cluster_client,ingest]

第二种情况

ouput.elasticsearch的默认action是create。当数据更新时,需要开启update

action => "update"
doc_as_upsert => true

5. Logstash stopped processing because of an error: (SystemExit) exit

解决:
配置文件有问题,检查下input和ouput的配置。一定要细心

...全文
724 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
内容概要:本文系统研究了基于交替方向乘子法(ADMM)的多主体综合能源系统分布式协同优化方法,旨在实现多个能源主体之间的高效、隐私保护的能量协同管理。通过建立各主体的局部优化模型,并引入一致性约束条件,利用ADMM算法将集中式优化问题分解为多个分布式子问题进行迭代求解,从而在保证各主体数据隐私的同时达成全局协同优化目标。研究涵盖了模型构建、算法实现、收敛性分析及数值仿真全过程,并提供了完整的Matlab代码实现,有效复现了相关学术成果,具有较强的可验证性与可拓展性。; 适合人群:具备一定数学建模能力与优化理论基础,熟悉Matlab编程,从事综合能源系统、分布式优化算法、电力系统调度等相关方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 掌握ADMM算法在多主体能源系统协同优化中的建模与实现方法;② 构建支持隐私保护的分布式能源调度系统;③ 利用开源代码开展算法改进、性能测试或应用于实际系统的二次开发与科研论文复现; 阅读建议:建议结合凸优化与分布式计算的基础知识,深入理解增广拉格朗日函数构造、对偶更新与收敛判据的设计原理,在代码调试过程中重点关注惩罚参数选取、变量分裂策略及通信机制的实现细节,以全面掌握算法的核心机制与工程应用要点。

29,032

社区成员

发帖
与我相关
我的任务
社区描述
Elastic开源社区是一个提供Elastic Stack全栈技术分享、技术交流、课程直播、Elastic认证工程师考试培训的平台。 在这里你可以结识更多技术大牛,掌握第一手学习资源。
社区管理员
  • 九川老师
  • wu@55555
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

本站福利

  • Elastic认证工程师 生根中国!
  • 体系、全面的学习资料(每天同步更新)
  • Elastic 8.x 最新全栈课程资料 实时更新
  • 每天活跃的技术大佬定期更新的 技术分享

成员须知

  • 对社区有贡献的活跃用户的 定制礼物放送
  • 和行业大佬零距离:不定期组织 线下活动

试试用AI创作助手写篇文章吧