黑帽联盟

 找回密码
 会员注册
查看: 630|回复: 0
打印 上一主题 下一主题

[mysql] mysql同步数据到redis

[复制链接]

895

主题

38

听众

3323

积分

管理员

Rank: 9Rank: 9Rank: 9

  • TA的每日心情
    无聊
    5 天前
  • 签到天数: 1644 天

    [LV.Master]伴坛终老

    go-mysql-transfergo-mysql-transfer是一款MySQL数据库实时增量同步工具。

    能够监听MySQL二进制日志(Binlog)的变动,将变更内容形成指定格式的消息,实时发送到接收端。从而在数据库和接收端之间形成一个高性能、低延迟的增量数据同步更新管道。


    特性
    • 简单,不依赖其它组件,一键部署
    • 集成多种接收端,如:Redis、MongoDB、Elasticsearch、RocketMQ、Kafka、RabbitMQ、HTTP API等,无需编写客户端,开箱即用
    • 内置丰富的数据解析、消息生成规则,支持模板语法
    • 支持Lua脚本扩展,可处理复杂逻辑,如:数据的转换、清洗、打宽
    • 集成Prometheus客户端,支持监控、告警
    • 集成Web Admin监控页面
    • 支持高可用集群部署
    • 数据同步失败重试
    • 支持全量数据初始化


    原理1、go-mysql-transfer将自己伪装成MySQL的Slave
    2、向Master发送dump协议获取binlog,解析binlog并生成消息
    3、将生成的消息实时、批量发送给接收端


    21.png

    下载
    地址: https://github.com/wj596/go-mysql-transfer.git

    编译运行
    同步数据到redis
    • 开启MySQL的binlog
    #Linux在my.cnf文件
    #Windows在my.ini文件
    [mysqld]
    # log_bin
    log-bin=mysql-bin # 开启 binlog
    binlog-format=ROW # 选择 ROW 模式
    server_id=1 # 配置 MySQL replaction 需要定义,不要和 go-mysql-transfer 的 slave_id 重复

    • 修改app.yml
      redis配置
    # app.yml
    redis_addrs: 127.0.0.1:6379 #地址,多个用逗号分隔
    #redis_group_type: cluster   # 集群类型 sentinel或者cluster
    #redis_master_name: mymaster # Master节点名称,如果group_type为sentinel则此项不能为空,为cluster此项无效
    #redis_pass: 123456 #redis密码
    #redis_database: 0  #redis数据库 0-16,默认0。如果group_type为cluster此项无效

    规则配置(使用lua脚本方式)
    #规则配置
    rule:
      -
        schema: gotest #数据库名称
        table: t_user #表名称
        lua_file_path: lua/t_user_redis.lua   #lua脚本文件

    • 源码编译& 运行
    go build
    ./go-mysql-transfer

    实例
    • 添加lua脚本
    local json = require("json")   -- 加载json模块
    local ops = require("redisOps") --加载redis操作模块

    local row = ops.rawRow()  --数据库当前变更的一行数据,table类型,key为列名称
    local action = ops.rawAction()  --当前数据库事件,包括:insert、updare、delete

    local id = row["id"] --获取ID列的值
    local userName = row["user_name"] --获取USER_NAME列的值
    print(id)
    print(userName)
    local key = "user_"..id -- 定义key

    if action == "delete" -- 删除事件
    then
        ops.DEL(key)
        ops.SREM("user_set",userName)
    else
        local createTime = row["create_time"] --获取CREATE_TIME列的值
        local result = {}  -- 定义一个table
        print(id)
        print(createTime)
        result["id"] = id
        result["userName"] = userName
        result["createTime"] = createTime
        result["source"] = "binlog" -- 数据来源
        local val = json.encode(result) -- 将newTable转为json
        ops.SET(key,val) -- 对应Redis的SET命令,第一个参数为key(支持string类型),第二个参数为value

        if action == "update" -- 修改事件
        then
            local oldRow = ops.rawOldRow()  --数据库变更之前的数据(修改之前的数据)
            local oldUserName = oldRow["user_name"] --获取USER_NAME列的值
            ops.SREM("user_set",oldUserName) -- 删除旧值
        end
       
        ops.SADD("user_set",userName) -- 对应Redis的SADD命令,第一个参数为key(支持string类型),第二个参数为value
    end

    • 创建数据表
    22.png

    • 添加mysql数据

    INSERT INTO t_user(id,create_time,user_name) VALUES(2,'2022-03-12 00:00:00','mingming')

    • go-mysql-transfer log输出

    2
    mingming
    2
    2022-03-12 00:00:00


    查看redis-cli


    127.0.0.1:6379> get user_2
    "{\"createTime\":\"2022-03-12 00:00:00\",\"id\":2,\"source\":\"binlog\",\"userName\":\"mingming\"}"


    同步数据成功.



    本文转载自:https://www.jianshu.com/p/5c15c41453cc







    帖子永久地址: 

    黑帽联盟 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与黑帽联盟享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和黑帽联盟的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、黑帽联盟管理员和版主有权不事先通知发贴者而删除本文

    勿忘初心,方得始终!
    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部