[操作系统]如何设计百万级商品数据实时同步的秒级搜索系统?


前阵子老板安排了一个新任务 , 要建设一个商家商品搜索系统 , 能够为用户提供快速、准确的搜索能力 。
[操作系统]如何设计百万级商品数据实时同步的秒级搜索系统?
本文插图
图片来自 Pexels
设计要求在用户输入搜索内容时 , 要能从商家名称和商品名称两个维度去搜索 , 搜索出来的结果 , 按照准确率排序 , 并按商家所属商品的关联关系 , 来组合数据结构 , 同时提供 API 给业务系统调用 。
背景很简单 , 现实蛮复杂!我们面临以下几个难题:

  • 商家数据库和商品数据库是多台不同的服务器 , 并且数据量达百万级 , 如何才能实现跨数据库的数据同步呢?
  • 商家和商品的数据是有从属关系的 , 不然就会把肯德基的香辣鸡腿堡挂到麦当劳去 , 这就尴尬了!
  • 商家商品数据是经常更新的 , 比如修改价格、库存、上下架等 , 那搜索服务可不能搜出一堆过时的数据 , 如果客户明明搜出来的商品 , 点进去后却已下架了 , 那么客户就要吐槽了!如何实现搜索数据与源数据库增删改均实时同步呢?
带着以上三个问题 , 我们开始了搜索服务的整体架构设计 。
系统架构设计思路
为了设计出合适的系统架构 , 我们分析了现状:
首先 , 商家数据和商品数据分别存储在 2 个独立的 MySQL8 数据库 , 为满足商家数据和商品数据的关联 , 我们需要将两个库中所需要的表实时 ETL 到我们的搜索系统数据库 。
其次 , 数据从商家、商品数据库 ETL 到搜索系统数据库后 , 需要实时的组合成为商家关联商品数据结构 , 并以父子文档的格式 , 存储到 ES 中 。
最后 , 商家、商品数据库的增删改操作 , 需要实时的同步到 ES 中 , 也就是 ES 中的数据 , 需要支持实时的增加、删除和修改 。
为此 , 我们设计了 2 个 Canal 组件 , 第一个 Canal 实现数据 ETL , 把商家、商品数据库的某些表及字段 , 抽取到搜索服务数据库 。
再利用第二个 Canal , 读取搜索服务 MySQL 数据库的 Binlog , 实时传输到 Kafka 消息队列 , 再由 canal adapter 对数据进行关联、父子文档映射等 , 将处理好的数据存储到 ElasticSearch 中 。
具体系统架构设计如下图所示:
[操作系统]如何设计百万级商品数据实时同步的秒级搜索系统?
本文插图
商家商品搜索系统架构设计
项目实战
环境及软件说明
操作系统:CentOS 7 canal:canal.adapter-1.1.4 , canal.deployer-1.1.4 kafka:kafka_2.12-2.3.0 ElasticSearch:elasticsearch-6.3.2 kibana:kibana-6.3.2 用 Canal 实现数据 ETL 到 MySQL8
这个步骤是利用 Canal 从 2 个独立的 MySQL8 数据库中 , 抽取需要的表到搜索服务的 MySQL 数据库 。
①安装 canaldeployer
解压 canal.deployer-1.1.4.tar.gz , 并配置 canal deployer 。
进入 canaldeployer/conf 目录 , 修改 canal.properties 文件 , 主要配置 serverMode、MQ 和 destination 三部分 。
首先 , 我们 serverMode 修改为 Kafka 模式 , 增加系统缓冲能力以及提高系统稳定性:
[操作系统]如何设计百万级商品数据实时同步的秒级搜索系统?
本文插图
serverMode
接着 , 配置 Kafka 的 MQ 信息(Kafka 请自行安装):
[操作系统]如何设计百万级商品数据实时同步的秒级搜索系统?
本文插图
Kafka MQ 信息
最后 , 配置需要实例化的 instance , 这里配置了 3 个 , 表示 canal deploy 会启动这 3 个实例 , 同步 MySQL 的 Binlog 到 Kafka 的 Topic 内 。


推荐阅读