怎么使用Binlog

技术怎么使用Binlog本篇内容介绍了“怎么使用Binlog”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!不知道是否你还

本文介绍了“如何使用Binlog”的知识。很多人在实际案例的操作中会遇到这样的困难。让边肖带领你学习如何处理这些情况。希望大家认真阅读,学点东西!

我不知道你是否还被以下问题困扰着:

使用redis或其他中间件进行缓存时,经常会发现缓存中的数据与数据库中的数据不一致,只能通过定时任务或缓存过期的方式进行一些限制。

当你用ES作为搜索工具,用双写的方法,你还是担心ES和数据库不是同一个事务。

当需要迁移数据时,仍然使用双写的方法。如果同一个数据库没问题,如果不同的数据库不能保证事务,那么数据一致性也是一个问题,所以会写很多修复作业和检查作业。

相信这些问题在很多学生的业务中都遇到过,或者可能经常会增加很多工作量或者导致一些数据不一致的失败。那么如何才能简单的解决这些问题呢?

让我们思考一下这个问题的本质。有必要确保我们的数据与我们的mysql一致,无论是在redis还是es中,这本质上是数据的副本。想到数据复制,熟悉Mysql的朋友会说:Mysql的主备不也是数据复制吗?如果我们模仿Mysql的主备份副本,我们将很容易同步我们的数据。

Mysql主从

既然可以模仿Mysql主从复制来满足我们的需求,那么就需要了解mysql主从的原理,如下图所示:

怎么使用Binlog

Stpe 1: mysql作为主控,需要在每次事务更新数据之前,将操作记录串行写入binlog文件,并存储在本地磁盘中。

步骤2:在我们的从服务器中打开一个输入输出线程,它将连续读取binlog。如果进度已经追上了主人,就去睡觉,等待主人生成新的事件。所有读取的数据都将写入中继日志。

第三步:SqlThread将读取中继日志,并依次执行日志中的SQL事件,以便与主数据库中的数据保持一致。

在主从复制过程中,最重要的是binlog,从库会根据binlog的信息复制一份主库的数据副本。

如果我们能够在业务代码中获取binlog,并通过binlog的数据复制到redis或es,那么我们就完全不用担心数据的一致性问题。

binlog

Binlog(binlog,binlog)顾名思义就是Mysql中的二进制日志,它记录了Mysql为改变数据库而执行的所有操作。Binlog也是服务器层生成的日志,与我们的存储引擎无关。无论您使用哪种存储引擎,都可以使用我们的binlog。

binlog格式

binlog有三种格式,分别是:语句、行和混合。您可以通过显示像“binlog _ format”这样的变量来检查当前数据库的binlog格式,这是一个如下图所示的行格式的binlog:

怎么使用Binlog

声明

语句也是一种语句类型,它记录将数据修改到binlog中的每个Sql。

?优点:空间比例最小,不会记录未修改的字段。与其他模式相比,它减少了大量的日志照明,并提高了输入/输出性能。

?缺点:异构系统使用不方便。比如复制redis缓存时,很难模拟mysql的从操作,需要重新检查数据。而且slave也有问题,比如使用了一些UUID函数,而且在slave回放的时候,不能保证双方是一致的。我们可以查看声明日志。这里我们可以输入命令:显示主人状态;检查我们的主服务器当前使用的binlog,如下图所示:

怎么使用Binlog

然后使用“MySQL-bin.00003”中的show binlog事件命令查看该日志中的内容:

/366/432401.jpg" alt="怎么使用Binlog">

我们可以发现我们所有的操作都会在一个完整的事务中进行,如果事务没有提交是不会出现在我们的binlog当中的,这个大家可以下来进行实验一下,我们在数据库中的更新原始sql都会被完全的记录下来。

Row

Row模式和Statement不同,他会记录每一行被修改后的所有的数据:

  • 优点:异构系统也能比较方便的同步数据,并且不会出现UUID函数的那种问题,无论什么情况都能被复制。

  • 缺点:数据量比较多,比如update语句,他还会记录更新前的每一个字段和更新后的每一个字段。造成日志量比较大,对I/O有一定的影响。

同样的我们也查看一下其中的内容:

怎么使用Binlog

在show binlog events in  'mysql-bin.000004'命令中,我们发现在事务中是查看不了我们具体的数据的,这个时候就需要我们工具帮忙了mysqlbinlog,他也在mysql的bin目录下我们直接调用就好了,输入命令/usr/local/mysql/bin/mysqlbinlog  --base64-output=decode-rows -v mysql-bin.000004,我们可以看见:

怎么使用Binlog

这里展示的是一个update语句,他不仅显示了原始值,也展示了修改后的值。

这里要注意的是binlog_row_image用于决定row是否会记录原始值,默认是FULL代表会记录,也就是我们上面的这种情况,还有个参数是minimal,代表只记录更新后的值。

Mixed

在mixed模式下,MySQL默认仍然采用statement格式进行记录,但是一旦它判断可能会有数据不一致的情况(UUID函数)发生,则会采用row格式来记录。

我们目前默认使用的是Row模式,在Row模式下可以比较方便的将数据异构,其实Row模式对I/O影响在业务当中来说感知并不是特别明显。

Canal

当我们知道binlog是什么之后,我们就需要怎么去使用这个binlog。binlog的同步工具常见的有:databus,canal,maxwell,阿里云dts等等,在这里我们就不比较他们各自的优劣点了,重点去介绍canal。

canal(github地址:https://github.com/alibaba/canal),译意为水道/管道/沟渠,主要用途是基于 MySQL  数据库增量日志解析,提供增量数据订阅和消费

早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010  年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。后面在阿里云中逐渐演化称DTS项目。

怎么使用Binlog

canal大体原理也是模仿mysql的slave,从master上不断的去拉取binlog,然后将binlog可以投放到不同的地方,比如我们常见的消息队列:kafka,rocketmq等等。当然在阿里云的付费dts上面也是可以直接同步到redis,es或者其他的一些存储介质当中。

canal的简单使用可以查看quickStart:https://github.com/alibaba/canal/wiki/QuickStart  ,这里不做过多的介绍。接下来主要是更多的介绍canal的整体架构,以及实现的原理等等。

Canal整体架构

怎么使用Binlog

CanalServer:一个Jvm就可以理解成一个CanalServer,如果是集群模式的Canal的话 那么就会有多个CanalServer。

CanalInstance:  可以理解为一个作业为一个Instance,比如有一个把A库的binlog同步到A消息队列,B库的binlog同步到B的消息队列,那么这就是两个不同的Instance,至于哪个Instance在哪个CanalServer上跑,需要看谁先在ZK抢占到临时节点,如果分配得足够均匀得话,可以在集群模式下缓解很多压力。

CanalParser: 用于拉取mysql-binlog,并进行解析。

EventSink: 将解析的数据进行处理加工(过滤,合并等)。

CanalEventStore: 这个有点类似slave中的relay  log,用于将日志进行中继存储,但是在canal中目前只支持了在内存中存储,目前不支持落盘存储。

CanalParser,EventSink,CanalEventStore这三个都是属于Canal中非常重要的组件,他们之间的关系如下:

怎么使用Binlog

CanalParser产生数据让EventSink进行加工,加工后的数据会存储在CanalEventStore中,然后MQ从CanalEventStore中不断的拉取最新数据,然后投递到MQ。

CanalParser

我们来讲讲在CanalParser中Canal是如何伪装成slave去拉数据的,在AbstractEventParser.java这个类中有如下步骤:

  • Step1: 构建一个数据库链接,并且生成一个slaveId,用于标示自己slave的身份。

  • Step2: 获取数据库的元信息,比如binlogFormat,binRowImage等等。

  • Step3: 通过show variables like 'server_id' 命令,获取我们需要监听binlog服务的serverId。

怎么使用Binlog

Step4: 获取这一次需要消费的位置,如果有存储上一次的就从上一次中获取,如果没有的话需要通过show master  status命令中获取到的最新的Position进行消费。

怎么使用Binlog

Step5: 进行dump操作,模拟slave发送注册slave请求,以及dump  binlog请求,然后用一个死循环不断的从binlog中拉取数据:

怎么使用Binlog

Step6: 将获取到的二进制数据,根据mysql binlog协议转换成logEntry,方便后续处理。

EventSink

EventSink会将上面获取到的logEntry来进行加工:

  • 过滤:

  • 过滤空的事务

  • 过滤心跳

  • 自定义过滤

记录,这里使用了Prometheus,来进行数据的统计上报。

合并,现在有很多分库分表的业务需要,他们的数据来源都是从不同的Parser中来的,但是最后都需要汇总到同一个EventStore中。在这个场景需要注意的我们可以需要注意的是会做时间归并控制,也就是尽量让每个分库的数据汇总后都是递增的方式提交,避免出现某个分库的数据比其他的领先或者落后很多。

EventStore

我们先看看EventStore中提供的接口:

怎么使用Binlog

可以看见EventStore其实就是一个简单的存储,在canal中提供了MemoryEventStoreWithBuffer,在内存中进行中转的数据,其中的原理是通过RingBuffer(无锁,高性能队列)实现的,有关于RingBuffer的信息可以参考我之前的文章你应该知道的Disruptor,在3.1中有对RingBuffer进行详细讲解。

然后CanalMq通过EventStore不断的获取数据,来进行数据发送。

怎么使用Binlog

“怎么使用Binlog”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/53885.html

(0)

相关推荐

  • 如何在word,如何在Word文档中画线

    技术如何在word,如何在Word文档中画线方法一:插入直线形状如何在word。1、首先打开Word文档,选择插入-形状,然后选择线条中的直线,也可以选择其它各种线型。2、在Word中点击一点,按住鼠标向右托就可以画出直

    生活 2021年10月20日
  • c++32位程序和64位程序的区别有哪些

    技术c++32位程序和64位程序的区别有哪些这篇文章主要讲解了“c++32位程序和64位程序的区别有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“c++32位程序和6

    攻略 2021年11月1日
  • Node js是什么

    技术Node js是什么这篇文章主要介绍“Node js是什么”,在日常操作中,相信很多人在Node js是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node js是什么”的疑惑有

    攻略 2021年11月12日
  • react: 高阶函数及函数柯里化

    技术react: 高阶函数及函数柯里化 react: 高阶函数及函数柯里化1.高阶函数若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。
    若A函数,调用的返回值依然是一个函数,那么A就可以称之

    礼包 2021年12月2日
  • 怎么理解show status的计数器

    技术怎么理解show status的计数器本篇内容介绍了“怎么理解show status的计数器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔

    攻略 2021年11月15日
  • srvctl怎样添加新的监听和端口并静态注册

    技术srvctl怎样添加新的监听和端口并静态注册本篇文章给大家分享的是有关srvctl怎样添加新的监听和端口并静态注册,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来

    攻略 2021年11月30日