数据库监控监听

嘿嘿 又知道多一点点 说来有些惭愧 现在才写  各方面因素造成的延迟

实时监控mysql表除了canal还有什么,还有很多,比如

mysql-binlog-connector-java

GitHub - liufeiit/mysql-binlog-connector-java: mysql-binlog-connector-java

 java库,基于复制协议解析读取mysql二进制日志(实时订阅/消费)

自然canal还有这个client还有下面要提到都是需要开启binlog的show variables like 'log_bin';

log_bin=mysql-bin
binlog-format=ROW#格式 statement row mixed
server-id=1#sql从哪个server写入

<dependency>
    <groupId>com.github.shyiko</groupId>
    <artifactId>mysql-binlog-connector-java</artifactId>
    <version>0.2.2</version>
</dependency>
binlog

row:仅保存被修改的细节,每一行数据的变化:前/后数据,被修改行的实际数据,不记录上下文

statement:记录每条会修改数据的sql语句和执行结果,执行语句 上下文环境,函数会有问题

mixed:混合简单的statement 复杂row,对于insert update delete的binlog事件类型=query事件

事件

query与数据库关,begin / drop  table / truncate table

table_map:记录下一个操作对应的表信息

xid:标记事务提交

原理

  1. 创建BinaryLogClient,设置主机 port user password等必要参数
  2. 客户端连接mysql,发送dump请求,开始从指定位置发送日志事件,可指定日志的起始和结束位置,及需要订阅的事件类型、数据库名称或表名称等过滤条件
  3. BinaryLogClient接收到事件,解析转换为Java对象,尝试回调一个或多个事件监听器。每个监听器可以实现自己的逻辑,如将事件记录到文件、将事件写入队列或执行自定义代码等
  4. 应用程序可随时关闭客户端连接,MySQL将停止向客户端发送事件,并且客户端将在退出之前自动处理所有未处理的事件

write_rows插入数据 update_rows delete_rows 具体看代码,很清晰 但是也有点小问题 评论区指出吧大佬们!

这个执行起来很简单,主要的代码在下面了

建议宝贝直接debug看看参数,进方法里面看看源码 yyds

public static void main(String[] args) throws IOException {
        /**
         * BinaryLogClient 类是 MySQL 提供的一个底层使用了 MySQL 原生协议和通信机制的 Java 客户端,用于监听 MySQL 数据库的二进制日志(Binary Log),并实现实时的数据同步
         */
        BinaryLogClient client = new BinaryLogClient("IP", 3306, "账号", "密码");
        /**
         * EventDeserializer 是一个接口,将 Event 数据从序列化格式反序列化为对象
         */
        EventDeserializer eventDeserializer = new EventDeserializer();
        eventDeserializer.setCompatibilityMode(
                // 时间戳表示 自 Unix 纪元(1970 年 1 月 1 日 UTC)以来的毫秒数
              EventDeserializer.CompatibilityMode.DATE_AND_TIME_AS_LONG,
                //通过使用字节数组来表示字符和二进制数据,保留其编码和格式信息
              EventDeserializer
                  .CompatibilityMode.CHAR_AND_BINARY_AS_BYTE_ARRAY
        );
 
        client.setEventDeserializer(eventDeserializer);
        //serverId是一个客户端与MySQL实例之间的唯一标识符
        //有多个客户端同时订阅同一个MySQL实例上的二进制日志,那么每个客户端的serverId应该是唯一的
        client.setServerId(serverId);
        //设置需要读取的Binlog的文件以及位置,否则,client会从"头"开始读取Binlog并监听
 
       //client.setBinlogFilename("mysql-bin.000001");
       //client.setBinlogPosition("/data/");
 
        Thread thread = new Thread(() -> {
            client.registerEventListener(event -> {
                final EventData data = event.getData();
                if (data instanceof WriteRowsEventData) {
                    WriteRowsEventData writeRowsEventData = (WriteRowsEventData) data;
                } else if (data instanceof UpdateRowsEventData) {
                    UpdateRowsEventData updateRowsEventData = (UpdateRowsEventData) data;
                } else if (data instanceof DeleteRowsEventData) {
                    DeleteRowsEventData deleteRowsEventData = (DeleteRowsEventData) data;
                } else if (data instanceof QueryEventData) {
                    QueryEventData queryEventData = (QueryEventData) data;
                    String database = queryEventData.getDatabase();
                    if ("jeecg-boot".equals(database)) {
                        //这个地方要dubug具体看一下如何取值
                        String sql = queryEventData.getSql();
                        if (sql != null && sql.length() >= 10) {
                                     
                            String[] s = sql.split(" ");
                            String type = s[0];
                            String tableName = null;
                            type = type.toUpperCase();
                            switch (type) {
                                case "INSERT":
                                    break;
                                case "DELETE":
                                    break;
                                case "UPDATE":
                                    tableName = s[1];
                                    break;
                                default:
                                    break;
                            }
 
                            if (tableName != null) {
                                tableName = tableName.replaceAll("`", "").replaceAll("'", "").replaceAll("\\.", "").toLowerCase();
                                if (TABLE_NAME.contains(tableName)) {

                                }
                            }
                        }
                    }
                }
            });

           client.registerLifecycleListener(new BinaryLogClient.LifecycleListener() {
                @Override
                public void onConnect(BinaryLogClient client) {
                    logger.info("Connected to MySQL server");
                }

                @Override
                public void onCommunicationFailure(BinaryLogClient client, Exception ex) {
                    logger.error("Communication failure with MySQL server", ex);
                }

                @Override
                public void onEventDeserializationFailure(BinaryLogClient client, Exception ex) {
                    logger.error("Event deserialization failure", ex);
                }

                @Override
                public void onDisconnect(BinaryLogClient client) {
                    logger.warn("Disconnected from MySQL server");
                    // 在这里添加重新连接或其他处理逻辑
                }
            });

            try {
                client.connect();
            } catch (IOException e) {
                //
            }
        });
        return thread;
    }
  }

durid

这个引入依赖jar,配置文件替换驱动 基本操作就不说了

  配置文件需要配置filters监控统计拦截filters:stat监控统计 log4j日志记录 wall防御sql注入

使用log4j记录日志,引入log4j的maven坐标

@Configuration
public class DruidConfig(){
   
    @ConfigurationProperties(prefix="spring.datasource")
    @Bean
    public DataSource DruidDatasource(){
      return new DruidDataSource();
    }

    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
      //servlet配置,web.xml对servlet配置
      ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
      Map<String,String> hashMap = new HashMap<>();
      hashMap.put("loginUsername","demo1");
      hashMap.put("loginPassword","123");
      hashMap.put("allow","");
      bean.setInitParameters(hashMap);
      return bean;
    }
   
}

访问http://localhost:8080/druid

https://blog.51cto.com/u_12897/8658359

canal之前写了

debezium:增量的数据抽取及转换

分布式哦服务,依赖基于日志的CDC(Change Data Capture)变更数据捕捉 技术实现的组件!

支持全量、增量同步,同时支持 MySQL、PostgreSQL、Oracle 等数据库

CDC

主动查询:

    数据源字段中 上次更新的时间戳 版本号等信息

    下游不断查询 上次记录 对比

    确定数据是否有变动,需要同步,实时性不高

事件接收:基于binlog 触发器trigger / 日志 transaction log/binary log/write-ahead log实现

    当数据源变动 附加表上的触发器 binlog等途径 将操作记录下来

    通过数据库底层协议  订阅消费 事件,重放数据库变动记录,实现同步,实时性高

    

主流数据源基本上都是支持的,mysql mongodb postgreSQL Oracle SQLServer Db2

  每个数据库表中的所有行级更改 记录在 更改事件流中(捕获事务日志变更数据)

   程序读取 流 获取 更改的事件

Kafka Connect

Kafka Connect 作为 Kafka broker之外的单独服务运行

   Kafka 连接器是已打包好的 JAR ,只需下载这些文件到 Kafka Connect 指定的插件目录,做好配置,就可以直接用一条命令启动 Kafka Connect,支持分布式,通过心跳确认节点状态,自动协调,
   Debezium连接器(上面的Debezium  MySQL及Debezium  PostgreSQL)属源连接器, Debezium 连接器部署到 Kafka Connect 中

    MySQL 订阅 binlog;Postgres,订阅逻辑复制流,将这些更改传播到相应的Kafka主题中

    默认情况下, 每个捕获的表都有一个主题

默认情况下,来自同一个数据库表的更改将写入名称与表名相对应的 Kafka 主题。如果需要,我们可以通过配置 Debezium 的主题路由转换来调整目标主题名称

快照:可选,拍摄数据库当前状态的初始快照。执行快照有不同的模式,支持增量快照,可以在连接器运行时触发

  • 锁的方式:不同引擎 不同锁方式,mysql最小化锁表,读取表元data全局锁表避免minimal
  • 局部快照,自定义快照语句加上where条件
  • 增量快照,只读取部分 随时增加新表/触发快照,实时变更
  • 信号表dbz_signal,特定格式 插入数据触发增量

过滤器:包含/排除列表过滤器 配置 捕获 的模式 表 列的集合,指定需要同步哪些表 列

屏蔽:来自特定列的值

监控:jmx进行监控

消息转换:消息路由 过滤 事件扁平化

数据处理

不同系统不同表现方式,decimal.handling.mode

  • precise,精确读取,默认,如 JSON 把 DECIMAL变成Base64 编码的字符串;用Java 的 BigDecimal 类来精确存储数据,需在消费侧使用 BigDecimal 来读取这个原始值
  • double,即转换成双精度浮点数,可能会损失精度,但是消费侧可直接使用
  • string,即转换成字符串,在消费侧通常都可以用很简单的形式来把字符串转换回原格式

DATETIME存的是 BIGINT,及部分语言、数据库无UNSIGNED BIGINT格式溢出的问题

排错

权限问题;不同库 debezium不同权限要求

binlog失效/清除问题,导致连接器终止

集群节点配置错误,自动脚本配置

dbhistory主题配置错误,无数据库变更记录,消息无法通过数据结构检查,删除重启任务

Debezium Server

可配置的、即用型的应用程序,将更改事件从源数据库流式传输到各种消息传递基础设施之上

Embedded Engine

嵌入到我们的自定义 Java 应用程序中的库。在应用程序本身中使用更改事件(无需部署完整的Kafka和Kafka Connect集群)或将更改流式传输到 Amazon Kinesis 等替代消息传递代理有用

Debezium日常分享系列之:Debezium 通知-CSDN博客

https://blog.csdn.net/zhengzaifeidelushang/category_11240845.html?spm=1001.2014.3001.5482

Flink CDC

GitHub - apache/flink-cdc: Flink CDC is a streaming data integration tool

2.X引入增量快照读取机制,全新的数据读取方式,并发读取 chunk粒度checkpoint

   flink据表主键划分多个块chunk

exactly-once:checkpint精确一次性处理

无主键表处理:无主键表,利用额外字段识别数据记录唯一性

public static void main(String[] args) throws Exception {

        //1.获取Flink执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);

        //通过FlinkCDC构建SourceFunction
        DebeziumSourceFunction<String> sourceFunction = MySqlSource.<String>builder()
                .hostname("hadoop102")
                .port(3306)
                .username("root")
                .password("123456")
                .databaseList("cdc_test")	//监控的数据库
                .tableList("cdc_test.user_info")	//监控的数据库下的表
                .deserializer(new StringDebeziumDeserializationSchema())//反序列化
                .startupOptions(StartupOptions.initial())
                .build();
        DataStreamSource<String> dataStreamSource = env.addSource(sourceFunction);

        //3.数据打印
        dataStreamSource.print();

        //4.启动任务
        env.execute("FlinkCDC");
    }

捕获*表中发生的变更,前后记录 flink cdc connector 直接在flink 以非约束模式stream使用

内置了bebezium引擎,抽取日志获取变更的能力,changelog转换为flink sql认识的rowData数据

Flink CDC详细教程(介绍、原理、代码样例)-CSDN博客

springBoot-MyBatis-Plus-binlog日志监听BinaryLogClient-CSDN博客

https://www.cnblogs.com/zhangpan1244/p/11329817.html

https://blog.51cto.com/u_16175522/9046382

百度安全验证

Debezium 特性深入介绍 | 亚马逊AWS官方博客

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值