当前位置: 首页 > 科技观察

Hiriver——MySQL数据变化监控分发框架

时间:2023-03-12 05:21:03 科技观察

什么是hiriver?hiriver是一个纯java开发的,高性能,基于解析mysql行基binlog技术的框架,用于监控mysql数据变化并分发这些变化。提供完整的框架,内置数据监控线程和数据消费线程,对外提供简单的Consumer接口。开发者可以根据自己的业务场景实现Consumer接口,无需关心线程问题。实现原理hiriver实现了mysql主从复制协议,伪装成mysql从库,收到binlog后根据mysqlbinlog协议进行解析,从而获取mysql的数据变化。由于基于mysql的主从复制协议,其监控数据变化的速度非常快,理论上和mysql本身的主从同步一样快,甚至更快。同时,不像在应用层监控数据变化,不需要考虑交易是否成功。当然,***限制***是mysqlbinlog的方式必须是***row***的方式。hiriver这个名字的由来是hiddenriver的缩写,中文名“地下通道”,比喻在应用层不受任何控制地在数据库后面导流数据。支持mysql版本hiriver支持mysql5.6.9+和mysql5.1+版本。强烈推荐使用5.6.9+版本,使用binlog文件名+位置来处理同步点。虽然5.6.9+版本提供了gtid功能,但它是唯一用来表示交易的id。理论上,基于它,可以实现HA功能。当mysql出现故障时,可以自动从一个mysql从库切换到另一个。并且不会丢失或重复数据,但在实际使用过程中,gtid仍然存在bug且不稳定,存在多个gtids时很难找到mysql识别的初始同步点。对于mysql5.6.9之前的版本,必须以binlog文件名和文件中的偏移位置作为同步点。javadochiriver组件mysql-proto组件使用教程quickstart概述hiriver模块组主要由2个组件和一个sample组成:mysql-proto、hiriver和hiriver-samplemysql-proto实现了mysql的client-server协议,包括Text协议和main从复制协议。Text协议是mysql正常读取数据的协议,是mysqljdbcdriver背后的协议。主从复制协议,顾名思义,就是主从之间复制数据的协议。hiriver是基于mysql-proto组件包的监控mysql变化、记录同步点、控制数据消耗的上层应用框架。是hiriver业务流程的实现。需要与spirng集成使用hiriver-sample使用hiriver-sample准备数据库环境1.创建自己的mysql5.6.282。开启rowbase和gtid模式(如果使用gtid作为同步点,必须开启)log-bin=mysql-binbinlog_format=Rowlog-slave-updates=ONenforce_gtid_consistency=truegtid_mode=ON3.创建自己的复制账户,创建repl数据库和表,快速使用-binlogname+偏移地址方式表示写入数据1.下载代码找到hiriver-sample模块,这是一个基于spring的web应用,有3个springxml配置文件,即:spring-boot.xml#spring容器描述入口文件spring-bin.xml#binlogname+偏移地址模式spring-gtid.xml#gtid模式2.修改示例中hiriver-sample.properties的参数,修改数据库相关属性,初始同步点,同步点存储路径和表名过滤黑白名单配置3.使用channel.0000.binlog初始化同步点,通过执行showmas可以得到channel.0000.binlog.pos属性terstatus命令获取相应的信息。修改后如图:4.修改spring-boot.xml中最后一个行为:5.使用tomcat/jetty或者mavenjetty插件运行示例快速使用-gtid方式下载代码,找到hiriver-sample模块,这是一个基于spring的web应用,有3个springxml配置文件,分别是:spring-boot.xml#spring容器描述入口文件spring-bin.xml#binlogname+偏移地址模式spring-gtid.xml#gtid模式2.修改示例中hiriver-sample.properties的参数,修改数据库相关属性、初始同步点、同步点存储路径和表名过滤黑白名单配置,其中channel_0000.gtid参数的配置需要从mysql中的querynumber中获取。执行showmasterstatus命令,得到如下结果:这是一个范围,你只需要使用8c80613e-ac5b-11e5-b170-148044d6636f:1or8c80613e-ac5b-11e5-b170-148044d6636f:8。修改后如图:修改spring-boot.xml中第一个行为:Runwithtomcat/jettyormavenjettyplug-in一个例子是详细的参数说明。底层socket控制参数(使用TransportConfig类描述)binlog读取参数(DefaultChannelStream类)数据库配置关键类描述底层通信类binlog转储类(BinlogStreamBlockingTransportImpl)实现mysqlbinlog转储协议,负责与mysql建立socket连接,完成用户名和密码验证后,执行数据转储命令,不断读取解析mysqlbinlog事件数据数据库数据读取类(TextProtocolBlockingTransportImpl)。mysql文本协议的实现,mysql文本协议是jdbc背后的协议,主要用来执行sql读取数据,也可以执行一些其他命令,比如读取表定义的元数据等。mysqljdbc之所以没有使用是因为两个原因:一是没有引入第三方包减少依赖;2是mysql的文本协议支持的指令比较多,比如COM_FIELD_LIST指令可以方便的获取表字段是否为空或者索引字段等信息,而jdbc是一个通用的API,不会暴露这些指令的实现。表名过滤类(BlackWhiteNameListTableFilter)支持黑白名单的过滤实现。按表名过滤时,表名格式为database.table(可以是正规的),以逗号分隔。当白名单和黑名单同时存在时,只有不在黑名单和白名单中的才会生效。例如,在properties文件中描述白名单:filert_white=test.account,test.user_sharding*白名单:filert_black=test.*bakbinlog行事件数据描述类(BinlogDataSet)binlog数据为二进制数据,遵循mysqlrowbasebinlog协议,在协议中,事件作为描述数据库变化的基本单位。这里的“变化”不仅仅是数据的修改,还有事务的开启和关闭,表的变化等等,在hiriver中,我们只关注表数据。Change,BinlogDataSet用来描述一条或多条数据的变化,类似于jdbc的RowSet。BinlogDataSet包括:channelIdsourceHostUrl,数据来自哪个数据库gtId,数据所在事务的gtid,如果不支持gtid模式,则为nullbinlogPos,当前数据所在事务的binlogfile+poslocated,不管是哪种模式,都要填nullisStartTransEvent,当前是否开启事务isPositionStoreTrigger,当前是否结束事务,为真时需要记录同步点。rowDataMap,行数据,每一行由BinlogResultRowcolumnDefMap描述,类定义描述BinlogResultRow里面有两个列表,一个记录变化前的数据,一个记录变化后的数据。数据消费类(Consumer)描述了消费BinlogDataSet数据的接口,留给业务实现者去实现。binlogstream(DefaultChannelStream)mysqlbinlogdump被抽象成一个stream,每个stream只针对一个mysql实例,这个stream叫做ChannelStream,ChannelStream负责不断从mysql实例中读取数据并进行过滤、解析和消费。DefaultChannelStream是ChannelStream的默认实现。在内部,它打开两个线程:提供者和消费者线程。Provider线程负责从数据库中读取数据,识别事务,根据表名进行过滤,解析成BinlogDataSet,放入ChannelBuffer;consumer线程负责从ChannelBuffer中读取数据,调用Consumer进行数据消费。当提供者线程产生数据的速率大于消费者线程消耗数据的速率时,数据就会积压在ChannelBuffer中。为了防止内存不堪重负,需要将ChannelBuffer实现为有界的。当ChannelBuffer达到上限时,提供者线程将被阻塞以生成新数据。数据。数据缓存类(DefaultChannelBuffer)ChannelStream中提供者线程和消费者线程的数据通信基础,是ChannelBuffer的默认实现。请记住,需要配置上限。交易识别类(TransactionRecognizer)用于识别交易的开始和结束,记录当前交易的开始位置。对于gtid和binlog文件名+pos这两种模式,提供了两种实现:GTIDTransactionRecognizer和BinlogNameAndPosTransactionRecognizer。