文章转载自:

https://blog.csdn.net/laoyang360/article/details/51747266

引言:

elasticsearch 的出现使得我们的存储、检索数据更快捷、方便。但很多情况下,我们的需求是:现在的数据存储在mysql、oracle等关系型传统数据库中,如何尽量不改变原有数据库表结构,将这些数据的insert,update,delete操作结果实时同步到elasticsearch(简称ES)呢?

本文基于以上需求点展开实战讨论。

1.对delete操作的实时同步泼冷水

到目前为止,所有google,stackoverflow,elastic.co,github上面搜索的插件和实时同步的信息,告诉我们:目前同步delete还没有好的解决方案。

折中的解决方案如下:

方案探讨:https://discuss.elastic.co/t/delete-elasticsearch-document-with-logstash-jdbc-input/47490/9

http://stackoverflow.com/questions/34477095/elasticsearch-replication-of-other-system-data/34477639#34477639

方案一,

在原有的mysql数据库表中,新增一个字段status, 默认值为ok,如果要删除数据,实则用update操作,status改为deleted.

这样,就能同步到es中。es中以status状态值区分该行数据是否存在。deleted代表已删除,ok代表正常。

方案二,

使用go elasticsearch 插件实现同步,如:。但是我实操发现,该插件不稳定,bug较多。我也给源码作者提出了bug。

Bug详见:https://github.com/siddontang/go-mysql-elasticsearch/issues/46

关于删除操作的最终讨论解决方案(截止2016年6月24日):

http://stackoverflow.com/questions/35813923/sync-postgresql-data-with-elasticsearch/35823497#35823497

首先,软件删除而非物理删除数据,新增一个 flag 列,标识记录是否已经被删除,这样,相同的记录也会存在于Elasticsearch。可以执行简单的term查询操作,检索出已经删除的数据信息。

其次,若需要执行cleanup清理数据操作(物理删除),只需要在数据库和ES中同时删除掉标记位deleted的记录即可。如:mysql执行:delete from cc where cc.flag=’deleted’; ES同样执行对应删除操作。

2.如何使用 插件实现insert,update 的同步更新操作?

我的上一篇博文:http://blog.csdn.net/laoyang360/article/details/51694519 做了些许探讨。

除了上篇文章提到的三个插件,这里推荐试用过比较好用的logstash的一款插件,名称为: logstash-input-jdbc

3.如何安装logstash-input-jdbc插件?

【注意啦,注意啦20170920】:logstash5.X开始,已经至少集成了logstash-input-jdbc插件。所以,你如果使用的是logstash5.X,可以不必再安装,可以直接跳过这一步。

参考:http://blog.csdn.net/yeyuma/article/details/50240595#quote

网友博文已经介绍很详细,不再赘述。

基本到这一步:

cd /opt/logstash/

sudo bin/plugin install logstash-input-jdbc

到此,基本就能成功。若不能请留言。

4,如何实现实时同步?

4.1 前提:mysql存在的数据库及表

数据库名为:test

test下表名为:cc

表中数据为:

mysql> use test;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> select * from cc;

+----+--------------------+---------+---------------------+

| id | name | status | modified_at |

+----+--------------------+---------+---------------------+

| 1 | laoyang360 | ok | 0000-00-00 00:00:00 |

| 2 | test002 | ok | 2016-06-23 06:16:42 |

| 3 | dllaoyang | ok | 0000-00-00 00:00:00 |

| 4 | huawei | ok | 0000-00-00 00:00:00 |

| 5 | jdbc_test_update08 | ok | 0000-00-00 00:00:00 |

| 7 | test7 | ok | 0000-00-00 00:00:00 |

| 8 | test008 | ok | 0000-00-00 00:00:00 |

| 9 | test9 | ok | 0000-00-00 00:00:00 |

| 10 | test10 | deleted | 0000-00-00 00:00:00 |

+----+--------------------+---------+---------------------+

9 rows in set (0.01 sec)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

4.2 需要两个文件:1)jdbc.conf; 2)jdbc.sql.

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

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

}

}

要执行的sql语句。

选择哪些信息同步到ES中。

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

select

*

from

where cc.modified_at > :sql_last_value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

[注意啦!注意啦!注意啦!]

cc.modified_at, 这个modified_at是我自己定义的更改时间字段,默认值default是now()当前时间。

而 :sql_last_value如果input里面use_column_value => true, 即如果设置为true的话,可以是我们设定的字段的上一次的值。

默认 use_column_value => false, 这样 :sql_last_value为上一次更新的最后时刻值。

也就是说,对于新增的值,才会更新。这样就实现了增量更新的目的。

有童鞋问,如何全量更新呢? 答案:就是去掉where子句即可。

步骤1:

在logstash的bin路径下新建文件夹logstash_jdbc_test,并将上两个文件 1)jdbc.conf,2)jdbc.sql.模板拷贝到里面。

步骤2:

按照自己的mysql地址、es地址、建立的索引名称、类型名称修改conf,以及要同步内容修改sql。

步骤3:

执行logstash, 如下:

[root@5b9dbaaa148a plugins]# ./logstash -f ./logstash_jdbc_test/jdbc.conf

步骤4:

验证同步是否成功。

可以通过: 如下图所示:

这里写图片描述

5,注意事项

如果你要测试go-mysql-elasticsearch可能会遇到下面三个Bug及解决方案如下:

【Bug1】

How to Setting The Binary Log Format

http://dev.mysql.com/doc/refman/5.7/en/binary-log-setting.html

【Bug2】

what is inner http status address

https://github.com/siddontang/go-mysql-elasticsearch/issues/11

【Bug3】

[2016/06/23 10:19:38] canal.go:146 [Error] canal start sync binlog err: ERROR 1236 (HY000): Misconfigured master - server id was not set

http://dba.stackexchange.com/questions/76089/error-1236-from-master-after-restored-replication

6,小结

实操发现: logstash-input-jdbc 能较好的实现mysql的insert、update的操作的增量、全量数据同步更新到ES。

但delete操作的实时同步没有很好的解决方案,如果你有,且都测试ok的话,请留言告诉我,不吝赐教!

————————————————

版权声明:本文为CSDN博主「铭毅天下」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/laoyang360/java/article/details/51747266

几篇关于MySQL数据同步到Elasticsearch的文章---第五篇:logstash-input-jdbc实现mysql 与elasticsearch实时同步深入详解的更多相关文章

  1. 几篇关于MySQL数据同步到Elasticsearch的文章---第四篇:使用go-mysql-elasticsearch同步mysql数据库信息到ElasticSearch

    文章转载自: https://www.cnblogs.com/dalaoyang/p/11018541.html 1.go-mysql-elasticsearch简介 go-mysql-elastic ...

  2. 几篇关于MySQL数据同步到Elasticsearch的文章---第三篇:logstash_output_kafka:Mysql同步Kafka深入详解

    文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484411&idx=1&sn=1f5a371 ...

  3. Java第三十五天,用JDBC操作MySQL数据库(一),基础入门

    一.JDBC的概念 Java DataBase Connectivity 从字面意思我们也不难理解,就是用Java语言连接数据库的意思 JDBC定义了Java语言操作所有关系型数据库的规则(接口).即 ...

  4. 《手把手教你》系列基础篇(七十五)-java+ selenium自动化测试-框架设计基础-TestNG实现DDT - 中篇(详解教程)

    1.简介 上一篇中介绍了DataProvider如何传递参数,以及和一些其他方法结合传递参数,今天宏哥接着把剩下的一些常用的也做一下简单的介绍和分享. 2.项目实战1 @DataProvider + ...

  5. 《手把手教你》系列基础篇(八十五)-java+ selenium自动化测试-框架设计基础-TestNG自定义日志-下篇(详解教程)

    1.简介 TestNG为日志记录和报告提供的不同选项.现在,宏哥讲解分享如何开始使用它们.首先,我们将编写一个示例程序,在该程序中我们将使用 ITestListener方法进行日志记录. 2.Test ...

  6. k8s系列文章第五篇(docker-compose)

    更多精彩内容,猛搓这里 目录 一.Docker Compose 1.前言 2.官方介绍 1.Compose 中有两个重要的概念 2.三步骤 3.Compose是Docker官方的开源项目,需要安装! ...

  7. 转一篇:Hyper-V和VMware的高可用实时迁移技术详解

    ESX里以集群的ha.drs.dpm功能实现 HYPER-V里以集群+共享存储实现. ~~~~~~~~~~ 微软公司的Hyper-V虚拟化管理程序一经面世就引发了业界的普遍关注.本文意在对Hyper- ...

  8. 这篇文章主要为大家详细介绍了jQuery密码强度验证控件使用详解的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    本文实例为大家分享了jQuery密码强度验证控件,供大家参考,具体内容如下 <html>   <head>     <meta http-equiv="Cont ...

  9. 同步mysql数据到ElasticSearch的最佳实践

    Elasticsearch是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据.ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全 ...

随机推荐

  1. 千位分隔符在web开发中的作用

    有千位分隔符会被认为是数字,否则在移动端会被直接识别成手机号 在开发实战中主流实现方式是添加meta标签 <meta name="format-detection" cont ...

  2. BUCK 电路PSIM仿真模型搭建之二 (传递函数模块的使用)

    1. 利用S函数模块进行环路仿真 将PI 写成 截止频率的表示形式 Kp* (Ti*s+1)/Ti*s  ,  这里Kp = 20,  Ti = 0.0001  ,  写入仿真模型参数框 仿真结果: ...

  3. Solution -「最大权闭合子图」做题随笔

    T1 小 M 的作物 先从简化题目入手,考虑先去掉 \(c\) 的额外收益.然后尝试将所有作物种在 \(B\), 则目前得到了 \(\sum \limits_{i = 1} ^n b_i\) 的收益. ...

  4. 基于ABP实现DDD--仓储实践

      由于软件系统中可能有着不同的数据库,不同的ORM,仓储思想的本质是解耦它们.在ABP中具体的实现仓储接口定义在领域层,实现在基础设施层.仓储接口被领域层(比如领域服务)和应用层用来访问数据库,操作 ...

  5. 【Unity基础知识】基础游戏单位GameObject中常用的属性和API

    一.GameObject中的成员变量 主要思想:得到该脚本依附的GameObject的相关信息 现有: Lesson4的代码: using System.Collections; using Syst ...

  6. jdbc 02: 连接mysql,并实现删除与更新

    jdbc连接mysql,并实现删除与更新 package com.examples.jdbc.o2_删除与更新; import java.sql.*; //连接与插入 /* jdbc删除操作 */ p ...

  7. Schur不等式(舒尔不等式)

    舒尔( Schur \texttt{Schur} Schur)不等式1 具体内容 Schur \texttt{Schur} Schur 不等式: x , y , z x,y,z x,y,z 为非负实数 ...

  8. 20220716-Markdown语法学习

    目录 1.标题部分 2.目录 3.字体部分 4.引用 5.列表 6.代码块 7.表格 8.脚注 9.水平线 效果: 10.引用链接 11.URLs 12.图片 13.emoji 效果: 14.html ...

  9. mysql show操作

    SHOW CHARACTER SET 显示所有可用的字符集 SHOW CHARACTER SET; SHOW CHARACTER SET LIKE 'latin%'; SHOW COLLATION 输 ...

  10. 用户认证(Authentication)进化之路:由Basic Auth到Oauth2再到jwt

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_98 用户认证是一个在web开发中亘古不变的话题,因为无论是什么系统,什么架构,什么平台,安全性是一个永远也绕不开的问题 在HTTP ...