文章转载自:

https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484358&idx=1&sn=3a783479bb6a1852589f4c4cf3c5d310&chksm=eaa82beedddfa2f822db1492e5f82f7f43d877f2abed6340adbbbe471a7b824b089179147145&scene=21#wechat_redirect

题记

来自Elasticsearch中文社区的问题——

MySQL中表无唯一递增字段,也无唯一递增时间字段,该怎么使用logstash实现MySQL实时增量导数据到es中?

logstash和kafka_connector都仅支持基于自增id或者时间戳更新的方式增量同步数据。

回到问题本身:如果库表里没有相关字段,该如何处理呢?

本文给出相关探讨和解决方案。

1、 binlog认知

1.1 啥是 binlog?

binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的redo/undo log是完全不同的日志;其主要是用来记录对mysql数据更新或潜在发生更新的SQL语句,并以"事务"的形式保存在磁盘中。

作用主要有:

1)复制:达到master-slave数据一致的目的。

2)数据恢复:通过mysqlbinlog工具恢复数据。

3)增量备份。

1.2 阿里的Canal实现了增量Mysql同步

[在这里插入图片描述]

一图胜千言,canal是用java开发的基于数据库增量日志解析、提供增量数据订阅&消费的中间件。

目前,canal主要支持了MySQL的binlog解析,解析完成后才利用canal client 用来处理获得的相关数据。目的:增量数据订阅&消费。

综上,使用binlog可以突破logstash或者kafka-connector没有自增id或者没有时间戳字段的限制,实现增量同步。

2、基于binlog的同步方式

1)基于kafka Connect的Debezium 开源工程,地址:. https://debezium.io/

2)不依赖第三方的独立应用: Maxwell开源项目,地址:http://maxwells-daemon.io/

由于已经部署过conluent(kafka的企业版本,自带zookeeper、kafka、ksql、kafka-connector等),本文仅针对Debezium展开。

3、Debezium介绍

Debezium是捕获数据实时动态变化的开源的分布式同步平台。能实时捕获到数据源(Mysql、Mongo、PostgreSql)的:新增(inserts)、更新(updates)、删除(deletes)操作,实时同步到Kafka,稳定性强且速度非常快。

特点:

1)简单。无需修改应用程序。可对外提供服务。

2)稳定。持续跟踪每一行的每一处变动。

3)快速。构建于kafka之上,可扩展,经官方验证可处理大容量的数据。

4、同步架构

[在这里插入图片描述]

如图,Mysql到ES的同步策略,采取“曲线救国”机制。

步骤1: 基Debezium的binlog机制,将Mysql数据同步到Kafka。

步骤2: 基于Kafka_connector机制,将kafka数据同步到Elasticsearch。

5、Debezium实现Mysql到ES增删改实时同步

软件版本:

confluent:5.1.2;
Debezium:0.9.2_Final;
Mysql:5.7.x.
Elasticsearch:6.6.1

5.1 Debezium安装

confluent的安装部署参见:http://t.cn/Ef5poZk,不再赘述。

Debezium的安装只需要把debezium-connector-mysql的压缩包解压放到Confluent的解压后的插件目录(share/java)中。

MySQL Connector plugin 压缩包的下载地址:

https://debezium.io/docs/install/

注意重启一下confluent,以使得Debezium生效。

5.2 Mysql binlog等相关配置。

Debezium使用MySQL的binlog机制实现数据动态变化监测,所以需要Mysql提前配置binlog。

核心配置如下,在Mysql机器的/etc/my.cnf的mysqld下添加如下配置。

1[mysqld]

2

3server-id = 223344

4log_bin = mysql-bin

5binlog_format = row

6binlog_row_image = full

7expire_logs_days = 10

然后,重启一下Mysql以使得binlog生效。

1systemctl start mysqld.service

5.3 配置connector连接器。

配置confluent路径目录 : /etc

创建文件夹命令 :

1mkdir kafka-connect-debezium

在mysql2kafka_debezium.json存放connector的配置信息 :

1[root@localhost kafka-connect-debezium]# cat mysql2kafka_debezium.json

2{

3 "name" : "debezium-mysql-source-0223",

4 "config":

5 {

6 "connector.class" : "io.debezium.connector.mysql.MySqlConnector",

7 "database.hostname" : "192.168.1.22",

8 "database.port" : "3306",

9 "database.user" : "root",

10 "database.password" : "XXXXXX",

11 "database.whitelist" : "kafka_base_db",

12 "table.whitlelist" : "accounts",

13 "database.server.id" : "223344",

14 "database.server.name" : "full",

15 "database.history.kafka.bootstrap.servers" : "192.168.1.22:9092",

16 "database.history.kafka.topic" : "account_topic",

17 "include.schema.changes" : "true" ,

18 "incrementing.column.name" : "id",

19 "database.history.skip.unparseable.ddl" : "true",

20 "transforms": "unwrap,changetopic",

21 "transforms.unwrap.type": "io.debezium.transforms.UnwrapFromEnvelope",

22 "transforms.changetopic.type":"org.apache.kafka.connect.transforms.RegexRouter",

23 "transforms.changetopic.regex":"(.*)",

24 "transforms.changetopic.replacement":"$1-smt"

25 }

26}

注意如下配置:

"database.server.id",对应Mysql中的server-id的配置。

"database.whitelist" : 待同步的Mysql数据库名。

"table.whitlelist" :待同步的Mysq表名。

重要:“database.history.kafka.topic”:存储数据库的Shcema的记录信息,而非写入数据的topic、

"database.server.name":逻辑名称,每个connector确保唯一,作为写入数据的kafka topic的前缀名称。

坑一:transforms相关5行配置作用是写入数据格式转换。

如果没有,输入数据会包含:before、after记录修改前对比信息以及元数据信息(source,op,ts_ms等)。

这些信息在后续数据写入Elasticsearch是不需要的。(注意结合自己业务场景)。

格式转换相关原理:http://t.cn/EftoaIi

5.4 启动connector

1curl -X POST -H "Content-Type:application/json"

2--data @mysql2kafka_debezium.json.json

3http://192.168.1.22:18083/connectors | jq

5.5 验证写入是否成功。

5.5.1 查看kafka-topic

1 kafka-topics --list --zookeeper localhost:2181

此处会看到写入数据topic的信息。

注意新写入数据topic的格式:database.schema.table-smt 三部分组成。

本示例topic名称:

full.kafka_base_db.account-smt

5.5.2 消费数据验证写入是否正常

1./kafka-avro-console-consumer --topic full.kafka_base_db.account-smt --bootstrap-server 192.168.1.22:9092 --from-beginning

至此,Debezium实现mysql同步kafka完成。

6、kafka-connector实现kafka同步Elasticsearch

6.1、Kafka-connector介绍

见官网:https://docs.confluent.io/current/connect.html

Kafka Connect是一个用于连接Kafka与外部系统(如数据库,键值存储,检索系统索引和文件系统)的框架。

连接器实现公共数据源数据(如Mysql、Mongo、Pgsql等)写入Kafka,或者Kafka数据写入目标数据库,也可以自己开发连接器。

6.2、kafka到ES connector同步配置

配置路径:

1/home/confluent-5.1.0/etc/kafka-connect-elasticsearch/quickstart-elasticsearch.properties

配置内容:

1"connector.class": "io.confluent.connect.elasticsearch.ElasticsearchSinkConnector",

2"tasks.max": "1",

3"topics": "full.kafka_base_db.account-smt",

4"key.ignore": "true",

5"connection.url": "http://192.168.1.22:9200",

6"type.name": "_doc",

7"name": "elasticsearch-sink-test"

6.3 kafka到ES启动connector

启动命令

1confluent load elasticsearch-sink-test

2-d /home/confluent-5.1.0/etc/kafka-connect-elasticsearch/quickstart-elasticsearch.properties

6.4 Kafka-connctor RESTFul API查看

Mysql2kafka,kafka2ES的connector详情信息可以借助postman或者浏览器或者命令行查看。

1curl -X GET http://localhost:8083/connectors

7、坑复盘。

坑2: 同步的过程中可能出现错误,比如:kafka topic没法消费到数据。

排解思路如下:

1)确认消费的topic是否是写入数据的topic;

2)确认同步的过程中没有出错。可以借助connector如下命令查看。

1curl -X GET http://localhost:8083/connectors-xxx/status

坑3: Mysql2ES出现日期格式不能识别。

是Mysql jar包的问题,解决方案:在my.cnf中配置时区信息即可。

坑4: kafka2ES,ES没有写入数据。

排解思路:

1)建议:先创建同topic名称一致的索引,注意:Mapping静态自定义,不要动态识别生成。

2)通过connetor/status排查出错原因,一步步分析。

8、小结

binlog的实现突破了字段的限制,实际上业界的go-mysql-elasticsearch已经实现。

对比:logstash、kafka-connector,虽然Debezium“曲线救国”两步实现了实时同步,但稳定性+实时性能相对不错。

推荐大家使用。大家有好的同步方式也欢迎留言讨论交流。

几篇关于MySQL数据同步到Elasticsearch的文章---第一篇:Debezium实现Mysql到Elasticsearch高效实时同步的更多相关文章

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

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

  2. WINDOWS下更改MYSQL数据路径(datadir)后服务启动1067解决不能改变mysql数据库存储位置

    晚上安装完MYSQL(系统:深度WINXPSP2, MYSQL版本:5.1.32)后,用MYSQL自带的配置工具配置完发现默认的数据存放路径是:C:/Documents and Settings/Al ...

  3. [转]分析MySQL数据类型的长度【mysql数据字段 中length和decimals的作用!熟悉mysql必看】

    转载自:http://blog.csdn.net/daydreamingboy/article/details/6310907 分析MySQL数据类型的长度 MySQL有几种数据类型可以限制类型的&q ...

  4. canal整合springboot实现mysql数据实时同步到redis

    业务场景: 项目里需要频繁的查询mysql导致mysql的压力太大,此时考虑从内存型数据库redis里查询,但是管理平台里会较为频繁的修改增加mysql里的数据 问题来了: 如何才能保证mysql的数 ...

  5. Linux下Rsync+Inotify-tools实现数据实时同步

    Linux下Rsync+Inotify-tools实现数据实时同步 注意:下面的三个案例都是rsync 每次都是全量的同步(这就坑爹了),而且 file列表是循环形式触发rsync ,等于有10个文件 ...

  6. mysql 数据操作 单表查询 目录

    mysql 数据操作 单表查询 mysql 数据操作 单表查询 简单查询 避免重复DISTINCT mysql 数据操作 单表查询 通过四则运算查询 mysql 数据操作 单表查询 concat()函 ...

  7. mysql 数据操作 多表查询 目录

    mysql 数据操作 多表查询 准备 多表连接查询介绍 mysql 数据操作 多表查询 多表连接查询 笛卡尔积 mysql 数据操作 多表查询 多表连接查询 内连接 mysql 数据操作 多表查询 多 ...

  8. mysql 数据操作 单表查询 where 约束 目录

    mysql 数据操作 单表查询 where约束 between and or mysql 数据操作 单表查询 where约束 is null in mysql 数据操作 单表查询 where约束 li ...

  9. inotify和rsync实现数据实时同步

    数据的实时同步 实现实时同步 要利用监控服务(inotify),监控同步数据服务器目录中信息的变化 发现目录中数据产生变化,就利用rsync服务推送到备份服务器上 实现实时同步的方法 ino ...

随机推荐

  1. 4-3 Spring MVC框架-02

    Spring MVC框架-02 Ⅰ.RESTful基础 是一种设计风格和开发方式 1.get和post请求区别: get post 获取请求 上传请求 请求参数在地址栏URL 请求参数在请求体里面 U ...

  2. day05 Java网络编程socket 与多线程

    java网络编程 java.net.Socket Socket(套接字)封装了TCP协议的通讯细节,是的我们使用它可以与服务端建立网络链接,并通过 它获取两个流(一个输入一个输出),然后使用这两个流的 ...

  3. NAT模式 LVS负载均衡群集部署

    NAT模式 LVS负载均衡群集部署的操作步骤 实验环境准备: 负载调度器:内网关 ens33:172.16.10.1,外网关 ens37:12.0.0.1 Web节点服务器1:172.16.10.10 ...

  4. Solution -「构造」专练

    记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...

  5. AtCoder Beginner Contest 260 G // imos(累积和算法)

    题目传送门:G - Scalene Triangle Area (atcoder.jp) 题意: 给定大小为N*N的OX矩阵,若矩阵的(s,t)处为O,其覆盖范围为:满足以下条件的所有位置(i,j) ...

  6. 操作表查询&操作表创建&操作表删除&操作表修改

    2.操作表 C(create):创建 语法: create table 表明( 列名1 数据类型1, 列名2 数据烈性2, .... 列名n 数据类型n ); create table Student ...

  7. scrollTop实例

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  8. React报错之map() is not a function

    正文从这开始~ 总览 当我们对一个不是数组的值调用map()方法时,就会产生"TypeError: map is not a function"错误.为了解决该错误,请将你调用ma ...

  9. NC20242 [SCOI2005]最大子矩阵

    题目链接 题目 题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大. 注意:选出的k个子矩阵 不能相互重叠. 输入描述 第一行为n,m,k(1 ≤ n ≤ 100 ...

  10. 详解ConCurrentHashMap源码(jdk1.8)

    ConCurrentHashMap是一个支持高并发集合,常用的集合之一,在jdk1.8中ConCurrentHashMap的结构和操作和HashMap都很类似: 数据结构基于数组+链表/红黑树. ge ...