Python实战案例:elasticsearch与数据库mysql的同步(上)

Python实战案例:elasticsearch与数据库mysql的同步(上)

在一些企业的面试中,常常遇到elasticsearch全文检索方面的问题,这也是企业最常遇到的问题。由于Elasticsearch就是专门用于搜索的,所以我们会将新增的数据放入Elasticsearch中用于搜索,也就有了这样的常见的场景,需要将Mysql中的数据同步到Elasticsearch中。

从方法上来讲,Mysql数据同步到ES中可分为两种,分别是全量同步和增量同步。全量同步表示第一次建立好ES索引之后,将Mysql中所有数据一次性导入到ES中。增量同步表示Mysql中产生新的数据,这些新的数据包括三种情况,就是新插入Mysql中的数据,更新老的数据,删除的数据,这些数据的变动与新增都要同步到ES中。

一、mysql与elaticsearch同步的方案介绍

对于mysql与elasticsearch同步的方案有以下几种。

1、基于Mysql的binlog日志订阅:binlog日志是Mysql用来记录数据实时的变化。如下图所示。

这种方案以binlog同步数据库的变化,当有数据发生变化时,可以变化的数据消息放在队列中,然后从队列中分别取出信息进行处理,这种方式就有了生产者消费者模式的思想,这样,接收binlog变化日志的任务就由kafka消息队列负责,当有新的日志信息消费后,再对elasticseach中的数据进行更新。基于Mysql的binlog日志订阅就是这样完成mysql与elasticsearch同步数据变化的。

对于这样的方式主要binlog同步组件。目前实现的有国内的阿里巴巴开发的canal。

2.使用go-mysql-elasticsearch。

go-mysql-elasticsearch是一款使用go语言开发的同步数据到ES的工具。

3、ES官方数据收集和同步组件logstash

对于以上三种方法来说,我们以python语言实现为主,因此主要介绍第一种基于Mysql的binlog日志订阅方法。

二、mysql中binlog日志的开启

这里以windows系统为例,在windows中安装mysql后,mysql的配置文件my.ini被放置在“C:\ProgramData\MySQL\MySQL Server 5.6”中。打开my.ini文件后,需要将文件中“#log-bin”前面的“#”号去掉。如下图所示。

去掉前面的#号后,在windows的服务中重新进行开启mysql服务。

当mysql的服务重启后,可以进入到mysql数据库的控制台,通过如下命令可以显示当前bin-log的值。

show  global  variables  like   “%log_bin%”

在mysql控制台执行上述命令后运行结果如下图所示。

除了设置logbin外,还需要设置logformat这个mysql环境下的系统变量值,设置前可以先显示binlog_format变量的值,显示该变量值的命令如下。

show  global  variables  like  “%log_format%”

运行上述命令后的结果如下图所示。

从图中可以得知,binlogformat的原来的值默认为STATEMENT,通过set global命令可以设置binlogformat的值,具体set global命令的完整格式如下。

set  global  binlog_format=”ROW”

这里将binlog_format变量的值设置成“ROW”,即行模式。

再次调用show global variables like “%logformat%”命令后可以显示出binlogformat变量修改之后的值。

在mysql数据库中,完成了“logbin”和“binlogformat”这两个系统变量的设置后,对数据库的每次操作就会产生binlog日志文件,python需要的就是保持读取该文件的状态,只要binlog日志文件发生变化,就可以读取出相关的信息。

三、python使用mysql-replication模块实现对binlog日志的实时监控

binlog日志文件配置成功后,python是可以使用mysql-replication模块对binlog日志进行实时监控的。Mysql-replication的安装方法如下:

pip3 install mysql-repliation

mysql-replication中有一个BinLogStreamReader类,该类对binlog日志进行流式的实时读取,参数中connetionsettings完成对数据库参数的配置,serverid是为服务器起一个id,我们实验的服务器只有一台,这个id可任意。only_schema参数起到了监控数据库中指定的数据库名称,onlyevents参数限定对指定数据库中的任意表进行增删改的操作,一般同步数据库肯定是对数据库中的记录进行了增删改,所以一般onlyevents常用的就是增删改的events操作,删除对应的events是DeleteRowsEvent,更新对应的events就是UpdateRowsEvent,增加对应的events就是WriteRowsEvent。

当python把BinLogStreamReader类实例化后,传入相应的参数,数据库日志中的内容就会被返回到一个变量中,把这个变量进行遍历,对其中遍历到的每一行进行数据的提取,每行中的values键存储的就是日志增加的数据信息。对应的代码如下。

from pymysqlreplication import BinLogStreamReader
from pymysqlreplication.row_event import (
    DeleteRowsEvent,
    UpdateRowsEvent,
    WriteRowsEvent,

)
import json
import sys
MYSQL_SETTINGS={
    "host":"localhost",
    "user":"root",
    "password":"admin"
}
stream=BinLogStreamReader(connection_settings=MYSQL_SETTINGS,server_id=4,blocking=True,only_schemas=["booksme"],only_events=[DeleteRowsEvent,WriteRowsEvent,UpdateRowsEvent])
for binlogevent in stream:
    for row in binlogevent.rows:
        event={"schema":binlogevent.schema,"table":binlogevent.table}
        if isinstance(binlogevent,DeleteRowsEvent):
            event["action"]="delete"
            event["data"]=row["values"]
        elif isinstance(binlogevent,WriteRowsEvent):
            event["action"]="insert"
            event["data"]=row["values"]
        elif isinstance(binlogevent,UpdateRowsEvent):
            event["action"]="update"
            event["data"]=row["values"]
        print(json.dumps(event,ensure_ascii=False))
        sys.stdout.flush()

代码中的数据库使用的是booksme,其中有一张book表,其中包含了一些书的名字和价格。如下图所示。

现在运行读取binlog日志文件的python程序,对这个数据库中的book表插入一条数据,看一下binlog日志文件的python程序控制台最终的输出结果,如下图所示。

由图中可以看出,对数据库中删除了一本“聊斋”的书,然后又添加了一本“聊斋”的,添加的书定价为110.10,这样的信息在数据库添加的同时,在pycharm程序的控制台也做了删除和添加内容的输出。

这就通过python的mysql-replication模块实现了程序同步到了数据库的变化。

四、kafka环境的搭建

前面python程序已经获取到了binlog的日志信息,现在需要指派一个生产者去把这个信息订阅发布出去,然后由消费者对得到的信息进行消费,消费的结果就是同步到elasticsearch中,这里生产者消费者模式的队列常常采用kafka,对于kafka的安装步骤做一下说明。

如果要实现kafka服务器,必须有zookeeper服务器的支持。zookeeper可以到官网上去下载zookeeper程序。如下图所示。

在这里面可以点击“Download”即可下载zookeeper,下载后直接解压到一个指定的文件夹中,如被解压到D盘根目录下的zookeeper目录下,也就是D:\zookeeper。在此zookeeper目录下找到“zoosample.cfg”文件,将其重命名为“zoo.cfg”,打开“zoo.cfg”找到并编辑dataDir=D:\zookeeper\tmp,这里放置数据的地方。接下来需要添加系统变量:ZOOKEEPERHOME=D:\zookeeper。如下图所示。

接下来,编辑path系统变量,添加路径:%ZOOKEEPER_HOME%\bin。如下图所示。

打开新的cmd,输入“zkServer“,运行Zookeeper。如下图所示。

zookeeper安装成功后,从kafka官方网站中下载kafka,如下图所示。

解压并进入Kafka目录,这里解压到D的kafka目录下。

进入kafka的config目录找到文件server.properties并打开,在文件中找到并编辑log.dirs=D:\kafka\kafka-logs。

kafka目录中bin目录下有windows目录,kafka-server-start.bat就是kafka服务的启动文件。指定kafka配置文件server.prperties的路径即可启动kafka服务。命令如下。

kafka-server-start.bat ..\..\config\server.properties

命令启动后的结果图片如下图所示。

如果在启动中提示media.properties的错误,可以将bin中windows目录下config配置目录中的文件全部删除,或者修改media.properties中的设备号,如下图文件结构的显示。

在bin的windows目录中分别有文件kafka-console-producer负责生产者的启动,文件kafka-console-consumer负责消费者的启动,用生产者的启动文件启动服务器,并启动topic,topic也是消息机制中生产者和消费者中订阅/发布的关键,利用topic可以实现生产者消费者模式的重复消费。

使用kafka-console-producer在topic中发送消息的命令如下。

kafka-console-producer.bat --broker-list localhost:9092 --topic test

这里的--broker-list就是生产者和消费者联系的中间者broker。broker就是缓存代理,Kafka集群中的一台或多台服务器统称broker。

运行命令后的结果如下图所示。

再次启动一个cmd窗口,执行kafka-console-consumer消费者指令,指令如下。

kafka-console-consumer --bootstrap-server localhost:9092 --topic test

运行该指令后的结果如图所示。

现在可以在producer生产者的cmd窗口中“>”号后面输入任意一句话,如下图所示。

在consumer消费者的cmd窗口中对应输出如下图的结果。

由图可以看出,生产者有一个消息的发布,消费者就有一个消息的显示。

代码对应的github地址:https://github.com/wawacode/mysqlelasticsearchsynchronism

教程对应的视频地址:

     mysql与elasticsearch同步1-数据库binlog的设置及python读取

      https://www.bilibili.com/video/BV1wz4y127fd/

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值