Mac中安装并使用logstash、canal(mysql安装于docker容器中)

最近在做项目使用到了logstash和canal,记录一下安装步骤

一、安装logstash

1、官网下载: 官网地址,我这里演示下载的是7.17.10版本

第一步:在这里插入图片描述
第二步:

在这里插入图片描述

第三步:

在这里插入图片描述

2、解压:

在这里插入图片描述

3、事件Demo:

第一步:进入到bin目录下打开终端:

在这里插入图片描述

第二步:运行logstash命令:
./logstash -e "input { stdin { } } output { stdout {} }"

在这里插入图片描述
第三步:运行成功
在这里插入图片描述

第四步:输入”zgytest“,成功

在这里插入图片描述

4、以自定义配置文件启动:

第一步:进入到config目录中

在这里插入图片描述

第二步:复制logstash-sample.conf,重命名成mytask.conf

在这里插入图片描述

第三步:编辑mytask.conf
input {
  udp {
    port => 514
    type => "syslog"
  }
}

output {
  stdout { codec => rubydebug }
}
第四步:启动
./logstash -f /Users/zgy/Downloads/logstash-7.17.10/config/mytask.conf

启动成功
在这里插入图片描述

二、安装canal

1、进入github:canal

在这里插入图片描述
下拉后找到Download
在这里插入图片描述
我这里演示的是安装1.1.6的版本:
点击下载

在这里插入图片描述
在这里插入图片描述

2、下载完后解压:

在这里插入图片描述
进入到bin目录中打开终端,执行

./startup.sh 

启动canal成功
在这里插入图片描述

3、快速开始:https://github.com/alibaba/canal/wiki/QuickStart

首先找到mysql的安装目录,找到配置文件:my.cnf或my.ini,由于我是在docker中安装的mysql(mysql8版本),所以以下步骤适用于在docker中安装的mysql

第一步:由于在容器中还要额外的安装vim命令,才能去编码配置文件,所以我们这里直接把配置文件从容器中拷贝到本地:
docker cp mysql-docker:/etc/my.cnf /Users/zgy/Downloads/Java/es/my.cnf

mysql-docker:是我的容器名
/etc/my.cnf :是在容器中配置文件的路径
/Users/zgy/Downloads/Java/es/my.cnf:是我要把配置文件拷贝到本地的路径
第二步:编辑拷贝到本地的配置文件

添加如下配置
在这里插入图片描述

第三步:再把编辑好的配置文件拷贝到容器中
docker cp  /Users/zgy/Downloads/Java/es/my.cnf mysql-docker:/etc/my.cnf
第四步:重新启动容器,使配置项生效
第五步:授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限, 如果已有账户可直接 grant,在数据库中执行以下命令
CREATE USER canal IDENTIFIED BY 'canal';  
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
-- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
FLUSH PRIVILEGES;
第六步:在项目中引入依赖:
<!-- https://mvnrepository.com/artifact/com.alibaba.otter/canal.client -->
<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.client</artifactId>
    <version>1.1.4</version>
</dependency>
第七步:编写示例:
import java.net.InetSocketAddress;
import java.util.List;


import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.common.utils.AddressUtils;
import com.alibaba.otter.canal.protocol.Message;
import com.alibaba.otter.canal.protocol.CanalEntry.Column;
import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
import com.alibaba.otter.canal.protocol.CanalEntry.RowData;


public class SimpleCanalClientExample {


public static void main(String args[]) {
    // 创建链接
    CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(AddressUtils.getHostIp(),
                                                                                        11111), "example", "", "");
    int batchSize = 1000;
    int emptyCount = 0;
    try {
        connector.connect();
        connector.subscribe(".*\\..*");
        connector.rollback();
        int totalEmptyCount = 120;
        while (emptyCount < totalEmptyCount) {
            Message message = connector.getWithoutAck(batchSize); // 获取指定数量的数据
            long batchId = message.getId();
            int size = message.getEntries().size();
            if (batchId == -1 || size == 0) {
                emptyCount++;
                System.out.println("empty count : " + emptyCount);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
            } else {
                emptyCount = 0;
                // System.out.printf("message[batchId=%s,size=%s] \n", batchId, size);
                printEntry(message.getEntries());
            }

            connector.ack(batchId); // 提交确认
            // connector.rollback(batchId); // 处理失败, 回滚数据
        }

        System.out.println("empty too many times, exit");
    } finally {
        connector.disconnect();
    }
}

private static void printEntry(List<Entry> entrys) {
    for (Entry entry : entrys) {
        if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {
            continue;
        }

        RowChange rowChage = null;
        try {
            rowChage = RowChange.parseFrom(entry.getStoreValue());
        } catch (Exception e) {
            throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(),
                                       e);
        }

        EventType eventType = rowChage.getEventType();
        System.out.println(String.format("================&gt; binlog[%s:%s] , name[%s,%s] , eventType : %s",
                                         entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),
                                         entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),
                                         eventType));

        for (RowData rowData : rowChage.getRowDatasList()) {
            if (eventType == EventType.DELETE) {
                printColumn(rowData.getBeforeColumnsList());
            } else if (eventType == EventType.INSERT) {
                printColumn(rowData.getAfterColumnsList());
            } else {
                System.out.println("-------&gt; before");
                printColumn(rowData.getBeforeColumnsList());
                System.out.println("-------&gt; after");
                printColumn(rowData.getAfterColumnsList());
            }
        }
    }
}

private static void printColumn(List<Column> columns) {
    for (Column column : columns) {
        System.out.println(column.getName() + " : " + column.getValue() + "    update=" + column.getUpdated());
    }
}
第八步:启动

在这里插入图片描述

第九步:变更数据库数据,canal监听

成功监听
在这里插入图片描述

碰到的问题:
canal启动了,示例也启动了,但是canal监听不到数据库中的数据发生的变化
解决方案
去终端登录下前面创建的canal用户

mysql -u canal -p -h 127.0.0.1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值