引言:

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 
表中数据为:

    1. mysql> use test;
      1. Reading table information for completion of table and column names
        1. You can turn off this feature to get a quicker startup with -A
            1. Database changed
              1. mysql> select * from cc;
                1. +----+--------------------+---------+---------------------+
                  1. | id | name | status | modified_at |
                    1. +----+--------------------+---------+---------------------+
                      1. | 1 | laoyang360 | ok | 0000-00-00 00:00:00 |
                        1. | 2 | test002 | ok | 2016-06-23 06:16:42 |
                          1. | 3 | dllaoyang | ok | 0000-00-00 00:00:00 |
                            1. | 4 | huawei | ok | 0000-00-00 00:00:00 |
                              1. | 5 | jdbc_test_update08 | ok | 0000-00-00 00:00:00 |
                                1. | 7 | test7 | ok | 0000-00-00 00:00:00 |
                                  1. | 8 | test008 | ok | 0000-00-00 00:00:00 |
                                    1. | 9 | test9 | ok | 0000-00-00 00:00:00 |
                                      1. | 10 | test10 | deleted | 0000-00-00 00:00:00 |
                                        1. +----+--------------------+---------+---------------------+
                                          1. 9 rows in set (0.01 sec)
                                        1.  

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

                                          1. [root@5b9dbaaa148a logstash_jdbc_test]# cat jdbc.conf
                                            1. input {
                                              1. stdin {
                                                1. }
                                                  1. jdbc {
                                                    1. # mysql jdbc connection string to our backup databse 后面的test对应mysql中的test数据库
                                                      1. jdbc_connection_string => "jdbc:mysql://192.168.1.1:3306/test"
                                                        1. # the user we wish to excute our statement as
                                                          1. jdbc_user => "root"
                                                            1. jdbc_password => "******"
                                                              1. # the path to our downloaded jdbc driver
                                                                1. jdbc_driver_library => "/elasticsearch-jdbc-2.3.2.0/lib/mysql-connector-java-5.1.38.jar"
                                                                  1. # the name of the driver class for mysql
                                                                    1. jdbc_driver_class => "com.mysql.jdbc.Driver"
                                                                      1. jdbc_paging_enabled => "true"
                                                                        1. jdbc_page_size => "50000"
                                                                          1. #以下对应着要执行的sql的绝对路径。
                                                                            1. statement_filepath => "/usr/local/logstash/bin/logstash_jdbc_test/jdbc.sql"
                                                                              1. #定时字段 各字段含义(由左至右)分、时、天、月、年,全部为*默认含义为每分钟都更新(测试结果,不同的话请留言指出)
                                                                                1. schedule => "* * * * *"
                                                                                  1. #设定ES索引类型
                                                                                    1. type => "cc_type"
                                                                                      1. }
                                                                                        1. }
                                                                                            1. filter {
                                                                                              1. json {
                                                                                                1. source => "message"
                                                                                                  1. remove_field => ["message"]
                                                                                                    1. }
                                                                                                      1. }
                                                                                                          1. output {
                                                                                                            1. elasticsearch {
                                                                                                              1. #ESIP地址与端口
                                                                                                                1. hosts => "192.168.1.1:9200"
                                                                                                                  1. #ES索引名称(自己定义的)
                                                                                                                    1. index => "cc_index"
                                                                                                                      1. #自增ID编号
                                                                                                                        1. document_id => "%{id}"
                                                                                                                          1. }
                                                                                                                            1. stdout {
                                                                                                                              1. #以JSON格式输出
                                                                                                                                1. codec => json_lines
                                                                                                                                  1. }
                                                                                                                                    1. }
                                                                                                                                        1. #要执行的sql语句。
                                                                                                                                          1. 选择哪些信息同步到ES中。
                                                                                                                                            1. [root@5b9dbaaa148a logstash_jdbc_test]# cat jdbc.sql
                                                                                                                                              1. select
                                                                                                                                                1. *
                                                                                                                                                  1. from
                                                                                                                                                    1. where cc.modified_at > :sql_last_value
                                                                                                                                                  1.  

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

                                                                                                                                                  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

                                                                                                                                                  原文地址:https://blog.csdn.net/zkf541076398/article/details/79973090

                                                                                                                                                  logstash-input-jdbc实现mysql 与elasticsearch实时同步(ES与关系型数据库同步)的更多相关文章

                                                                                                                                                  1. mysql 与elasticsearch实时同步常用插件及优缺点对比(ES与关系型数据库同步)

                                                                                                                                                    前言: 目前mysql与elasticsearch常用的同步机制大多是基于插件实现的,常用的插件包括:elasticsearch-jdbc, elasticsearch-river-MySQL , g ...

                                                                                                                                                  2. canal 实现Mysql到Elasticsearch实时增量同步

                                                                                                                                                    简介: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据 ...

                                                                                                                                                  3. 几篇关于MySQL数据同步到Elasticsearch的文章---第二篇:canal 实现Mysql到Elasticsearch实时增量同步

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

                                                                                                                                                  4. logstash input jdbc连接数据库

                                                                                                                                                    示例 以下配置能够实现从 SQL Server 数据库中查询数据,并增量式的把数据库记录导入到 ES 中. 1. 查询的 SQL 语句在 statement_filepath => " ...

                                                                                                                                                  5. MySQL系列(十二)--如何设计一个关系型数据库(基本思路)

                                                                                                                                                    设计一个关系型数据库,也就是设计RDBMS(Relational Database Management System),这个问题考验的是对RDBMS各个模块的划分, 以及对数据库结构的了解.只要讲述 ...

                                                                                                                                                  6. LogStash如何通过jdbc 从mysql导入elasticsearch

                                                                                                                                                    input { stdin { } jdbc { # mysql jdbc connection string to our backup databse jdbc_connection_string ...

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

                                                                                                                                                    文章转载自: https://blog.csdn.net/laoyang360/article/details/51747266 引言: elasticsearch 的出现使得我们的存储.检索数据更快 ...

                                                                                                                                                  8. 一脸懵逼学习HBase---基于HDFS实现的。(Hadoop的数据库,分布式的,大数据量的,随机的,实时的,非关系型数据库)

                                                                                                                                                    1:HBase官网网址:http://hbase.apache.org/ 2:HBase表结构:建表时,不需要指定表中的字段,只需要指定若干个列族,插入数据时,列族中可以存储任意多个列(即KEY-VA ...

                                                                                                                                                  9. JavaWeb学习笔记(十四)—— 使用JDBC处理MySQL大数据

                                                                                                                                                    一.什么是大数据 所谓大数据,就是大的字节数据,或大的字符数据.大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据 ...

                                                                                                                                                  随机推荐

                                                                                                                                                  1. B1047 理想的正方形 RMQ

                                                                                                                                                    大家吸取我的教训,想好再写.我码了好长时间,最后发现算法处理的是另一个问题,我处理的是正方形情况的,才能用我优化之后的记忆化搜索,然而矩形就凉了. 先看一下题吧: Description 有一个a*b ...

                                                                                                                                                  2. 74.资金管理-员工工资配置 extjs 页面

                                                                                                                                                    1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8&quo ...

                                                                                                                                                  3. 0604-面向对象、类与对象、类、static、构造方法/析构方法

                                                                                                                                                    一.面向对象 1.面向过程:一个人分步骤完成某个事情 2.面向对象:某件事情拆分为多个任务,由每个对象独立完成,最后调用整合为一个完整的项目 3.三要素:继承.封装.多态. 封装:私有化属性 提供公共 ...

                                                                                                                                                  4. hihoCoder 1033

                                                                                                                                                    题目链接: http://hihocoder.com/problemset/problem/1033 听说这个题是xiaodao出的~~ 我们要知道dp其实就是一个记忆化搜索的过程,如果某个子结构之前 ...

                                                                                                                                                  5. android ui篇

                                                                                                                                                    android ui篇主要做两件事情. 第一件事情就是能够自己去定义基本的简单的界面. 第二件事情就是能够使用开源library去构造一些复杂的界面. 第一件事情就需要对于布局等方面知识有着基本的掌握 ...

                                                                                                                                                  6. centos下使用shell+expect远程登录主机

                                                                                                                                                    # 安装expect yum install expect # 新建脚本文件running #!/usr/bin/expect spawn /usr/bin/ssh root@114.114.114. ...

                                                                                                                                                  7. 5.17领扣--Arrays.copyOf()方法

                                                                                                                                                    ?? 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同 ...

                                                                                                                                                  8. 使用curl 上传文件,multipart/form-data

                                                                                                                                                    使用curl 上传文件,multipart/form-data 1. 不使用-F,curl内置multipart/form-data功能: 2. 文件内容与真实数据无关,用abc代替数据,依然可以上传 ...

                                                                                                                                                  9. IN、EXISTS的相关子查询用INNER JOIN 代替--性能优化

                                                                                                                                                    如果保证子查询没有重复 ,IN.EXISTS的相关子查询可以用INNER JOIN 代替.比如: IN.EXISTS的相关子查询用INNER JOIN 代替--sql2000性能优化

                                                                                                                                                  10. dubbo之本地调用

                                                                                                                                                    本地调用 本地调用使用了 injvm 协议,是一个伪协议,它不开启端口,不发起远程调用,只在 JVM 内直接关联,但执行 Dubbo 的 Filter 链. 配置 定义 injvm 协议 <du ...