canal数据同步方案设计

1,214 阅读2分钟

背景:

项目中一部分数据如页面静态数据需要从redis中获取,以提高页面加载速度。页面数据的修改是通过管理画面修改mysql,通过定时任务或手动将mysql数据同步到redis,以供页面获取。这里数据同步不是增量同步,而是根据条件查询得到数据集后同步。网关中的一些参数同样是在mysql维护,然后定时或手动推送到redis,并通知网关刷新内存数据。有时增加一个数据的变动会出发多个同步操作,如增加一个api,既要将其在门户画面展示,又要推送到网关,如果想实时生效就需要两次手动操作。这样就很繁琐,因此设计一种实时或准实时将mysql同步至redis的方案。

方案1:

更新数据库的同时执行同步redis方法,如在增删改首页数据的方法添加注解,利用aop统一处理数据同步的逻辑。这种方案实际就是spring cache。但是这里不仅仅要将数据同步至redis,还要发布订阅事件,因此需要自己实现aop逻辑。

方案2:

利用canal,监听mysql数据变更进行数据同步和发布订阅事件。这样不必修改原代码,逻辑解耦。并且如果mysql修改失败不会触发同步操作。

综上采用方案2。

详细方案设计:

在canal定义一个destination监听数据库,当有感兴趣的数据变动时,通过feign调用对应服务的同步方法(这里的同步方法复用已有的手动调用方法,不用新写)。因为同步的是准全量数据,为避免mysql每次更新都查询,党一个数据变动后一分钟内没有新的数据变动,才触发同步操作。此外,通过apollo配置中心动态启停同步服务。

canal部署:

参照官网的方案,利用zookeeper进行服务协调,实现canal server,canal client的高可用。

由于测试环境分为SIT,QA和UAT,每个环境有单独的数据库,因此canal定义三个destination监听对应的数据库实例。

未来的优化方向:

  • Redis获取数据失败fallback到数据库
  • 增加一层内存缓存
  • 感知同步数据成功与否