栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

亿级流量的缓存方案-缓存同步-Cannal实战

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

亿级流量的缓存方案-缓存同步-Cannal实战

目录
  • 一、缓存同步策略
    • 1、基于MQ的异步通知
    • 2、基于Canal的异步通知
  • 二、Cannal
    • 1、介绍
    • 2、mysql的主从同步原理
    • 3、Canal同步原理
  • 三、实战
    • 1、配置binlog主从同步
    • 2、创建docker网络mynet
    • 3、docker安装canal
      • 拉去镜像
      • 创建容器
      • 查看运行日志
      • 查看是否跟mysql连接成功
    • 4、监听Canal
      • 引入依赖
      • 编写配置
      • 监听表的binlog消息,更新redis
    • 总结
  • 五、代码

一、缓存同步策略

缓存数据同步的常见三种方式:

  • 设置有效期:给缓存设置有效期,到期后自动删除。再次查询时更新

    • 优势:简单,方便
    • 缺点:时效性差,缓存过期之前可能不一致
    • 场景:更新频率交底,时效性要求低的业务
  • 同步双写:在修改数据库的同时,直接修改缓存

    • 优势:时效性强,缓存与数据库强一致
    • 缺点:有代码侵入,耦合度高
    • 场景:对一致性,时效性要求较高的缓存数据
  • 设置有效期:修改数据库时发送事件通知,相关服务监听到通知后修改缓存数据

    • 优势:低耦合,可能同时通知多个缓存服务
    • 缺点:时效性一般,可能存在中间不一致状态
    • 场景:时效性要求一般,有多个服务需要同步
1、基于MQ的异步通知

2、基于Canal的异步通知

二、Cannal 1、介绍

canal,译意为水道/管道/沟渠,是阿里巴巴旗下的一款开源项目,基于JAVA开发。主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。
以下参考canal官网:https://github.com/alibaba/canal。
但是canal的数据同步不是全量的,而是增量。基于binary log增量订阅和消费,canal可以做:

  • 数据库镜像
  • 数据库实时备份
  • 索引构建和实时维护
  • 业务cache(缓存)刷新
  • 带业务逻辑的增量数据处理
2、mysql的主从同步原理

canel是基于mysql的主从同步来实现的,MySql主从同步的原理如下:

3、Canal同步原理

Canal就是把自己伪装成Mysql的一个slave节点,从而监听master的binary log变化。再把得到的变化信息通知给Canal的客户端,进而完成对其他数据库的同步。

三、实战 1、配置binlog主从同步

参考:Mysql入门及高级用法

2、创建docker网络mynet
docker network create mynet
# 让mysql加入mynet
docker network connect mynet mysql
3、docker安装canal 拉去镜像
docker pull canal/canal-server:v1.1.5
创建容器
docker run -p 11111:11111 --name canal 
-e canal.destinations=heima 
-e canal.instance.master.address=mysql:3306  
-e canal.instance.dbUsername=canal  
-e canal.instance.dbPassword=canal  
-e canal.instance.connectionCharset=UTF-8 
-e canal.instance.tsdb.enable=true 
-e canal.instance.gtidon=false  
-e canal.instance.filter.regex=heima\..* 
--network mynet 
-d canal/canal-server:v1.1.5

-e canal.destinations=heima canal集群的名字
-e canal.instance.master.address mysql信息
-e canal.instance.filter.regex=heima…* 表示监听heima这个数据库下的所有表

表名称监听器支持的语法
filter.regexmysql 数据解析关注的表,Perl正则表达式.
多个正则之间以逗号(,)分隔,转义符需要双斜杠()
常见例子:

  1. 所有表:.* or .…
  2. canal schema下所有表: canal…*
  3. canal下的以canal打头的表:canal.canal.*
  4. canal schema下的一张表:canal.test1
  5. 多个规则组合使用然后以逗号隔开:canal…*,mysql.test1,mysql.test2
查看运行日志
docker logs -f canal
查看是否跟mysql连接成功

先进入容器

root@sony-HP-Notebook:/usr/local/mysql/conf# docker exec -it canal bash
[root@8296a3ed2f83 admin]# ls
app.sh  bin  canal-server  health.sh  node_exporter  node_exporter-0.18.1.linux-arm64

查看cannel的运行日志

[root@8296a3ed2f83 admin]# tail -f canal-server/logs/canal/canal.log
2022-06-09 18:42:37.617 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## set default uncaught exception handler
2022-06-09 18:42:37.684 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## load canal configurations
2022-06-09 18:42:37.706 [main] INFO  com.alibaba.otter.canal.deployer.CanalStarter - ## start the canal server.
2022-06-09 18:42:37.785 [main] INFO  com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[172.22.0.6(172.22.0.6):11111]
2022-06-09 18:42:40.519 [main] INFO  com.alibaba.otter.canal.deployer.CanalStarter - ## the canal server is running now ......

查看heima库的连接日志

tail -f canal-server/logs/heima/heima.log

4、监听Canal

Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端

引入依赖

第三方开源的canal-starter,地址:https://github.com/NormanGyllenhaal/canal-client


    top.javatool
    canal-spring-boot-starter
    1.2.1-RELEASE

编写配置

destination要对应之前docker启动时候集群的名字

canal:
  destination: heima
  server: 127.0.0.1:11111
监听表的binlog消息,更新redis
@CanalTable("tb_item")
@Component
public class ItemHandler implements EntryHandler {

    @Autowired
    private RedisHandler redisHandler;
    @Autowired
    private Cache itemCache;

    @Override
    public void insert(Item item) {
        // 写数据到JVM进程缓存
        itemCache.put(item.getId(), item);
        // 写数据到redis
        redisHandler.saveItem(item);
    }

    @Override
    public void update(Item before, Item after) {
        // 写数据到JVM进程缓存
        itemCache.put(after.getId(), after);
        // 写数据到redis
        redisHandler.saveItem(after);
    }

    @Override
    public void delete(Item item) {
        // 删除数据到JVM进程缓存
        itemCache.invalidate(item.getId());
        // 删除数据到redis
        redisHandler.deleteItemById(item.getId());
    }
}
总结

五、代码

仓库:https://gitee.com/edevp/item-service

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/961510.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号