前阵子老板安排了一个新任务,要建设一个商家商品搜索系统,能够为用户提供快速、准确的搜索能力,在用户输入搜索内容时,要能从商家名称和商品名称两个维度去搜索,搜索出来的结果,按照准确率排序,并按商家所属商品的关联关系,来组合数据结构,同时提供API给业务系统调用。
背景很简单,现实蛮复杂!我们面临以下几个难题:
①商家数据库和商品数据库是多台不同的服务器,并且数据量达百万级,如何才能实现跨数据库的数据同步呢?
②商家和商品的数据是有从属关系的,不然就会把肯德基的香辣鸡腿堡挂到麦当劳去,这就尴尬了!
③商家商品数据是经常更新的,比如修改价格、库存、上下架等,那搜索服务可不能搜出一堆过时的数据,如果客户明明搜出来的商品,点进去后却已下架了,那么客户就要吐槽了!如何实现搜索数据与源数据库增删改均实时同步呢?
带着以上3个问题,我们开始了搜索服务的整体架构设计。
系统架构设计思路
为了设计出合适的系统架构,我们分析了现状。
首先,商家数据和商品数据分别存储在2个独立的MySQL8数据库,为满足商家数据和商品数据的关联,我们需要将两个库中所需要的表实时ETL到我们的搜索系统数据库。
其次,数据从商家、商品数据库ETL到搜索系统数据库后,需要实时的组合成为商家关联商品数据结构,并以父子文档的格式,存储到ES中。
最后,商家、商品数据库的增删改操作,需要实时的同步到ES中,也就是ES中的数据,需要支持实时的增加、删除和修改。
为此,我们设计了2个canal组件,第一个canal实现数据ETL,把商家、商品数据库的某些表及字段,抽取到搜索服务数据库;再利用第二个canal,读取搜索服务MySQL数据库的binlog,实时传输到kafka消息队列,再由canal adapter对数据进行关联、父子文档映射等,将处理好的数据存储到ElasticSearch中。
具体系统架构设计如下图所示。
商家商品搜索系统架构设计
项目实战
1、环境及软件说明
操作系统: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