本文共 1454 字,大约阅读时间需要 4 分钟。
前篇介绍了核心数据如何被用于计算,本篇介绍数据是如何准备的。抓取/录入的数据会先入到数据库,为保证数据查询的速度建立了缓存层,需要探讨数据从库到缓存的方案。要解决变更监听、分片路由、数据一致性、搜索时延等问题。
变更监听使用集团的数据同步的中间件。
由于单台服务器无法容纳所有数据、性能也不足以应对多个用户的并发请求,数据分布在集群上。数据分发、请求分配到哪些服务器依照一定的路由策略。
消息的乱序、丢消息都可能导致数据不一致。我们采用了类似乐观锁的机制以解决乱序。定期做一致性检查和消息补发,再度让数据一致。
搜索时延是衡量搜索系统的指标之一,要尽可能的缩短从数据变更到用户搜索到相应结果的时间。这一话题将在其他篇说明。
一、变更监听
数据源头是数据库。无论代理商录入,还是从航信抓取,先持久化到库里,再异步的同步到服务器的缓存。方案直接用集团精卫,从解析数据库binlog的精卫中间件接收消息。
二、数据分发
1、划分标准
(1)、由于每个请求都会包含出发、到达,可以按出发、到达划分。
(2)、不包含出发、到达的数据,每台机器上都有一份(前提是基于业务上此类数据占比很低)
(3)、包含多出发、到达或含通配的数据,可以采取分发到每台机器,再分别过滤掉节点不匹配的数据。
(4)、同一出发、到达数据仍然太多,按照业务上的维度再划分一次,比如按运价类型划分。
配图:B2C的运价和B2B的运价位于不同业务分组;B2C业务分组下又划分了8个分片分组,同一分片分组包含4个负载均衡等效节点,每个节点容纳8片数据;第几分片=hash(出发+到达)%64
2、分发三类消息
(1)、新增
可以分片,先确定业务分组,再算出的分片分组,发送该分片分组下所有节点
不可分片,发送到业务分组下的所有节点
(2)、删除
和增类似
(3)、修改
分片字段未修改,和增类似
分片字段已修改,按删除消息发送历史数据,按新增消息发送最新数据
配图:修改消息(变更分片字段值)分别触发删除和新增消息
三、应对消息乱序
为保证消息处理速度无法采用有序队列,但无序会造成缓存与数据库不一致。例如先增后删,增的消息后到达,已从库里删除的数据在缓存里依然存在。
使用乐观锁机制解决此问题。收到一条数据时,与其对应缓存数据的时间戳进行对比,只有当收到的数据时间戳更新时,才做操作。如果缓存数据已经被删除,则无法对比,所以需要将删除的数据时间戳放在另外的删除缓存保留一小段时间。
配图:收到修改消息,缓存中不存在,则查删除缓存
四、一致性检查
丢消息是不可避免的。消息中间件丢则缓存负载均衡节点之间状态不一致;集团精卫丢则所有缓存负载均衡节点的状态一致,但与数据库不一致。
1、由谁来检查?
每个负载均衡节点都查数据库,会给数据库带来不必要的压力,可以由数据分发节点分别请求负载均衡节点和数据库。
2、由谁触发检查任务?
搜索请求的出发、到达体现了航线的热门程度,可以用来触发对应的检查任务。
出发、到达一直没人搜怎么办?可以使用频率更低些的航班更新消息来触发,来避免第一次搜到的结果是不一致的。
3、怎么控制检查频率?
可以将已分配的任务本身缓存,并设置最小查询间隔为缓存过期时间。缓存能查到任务则代表近期已执行任务,不需再次委派。
4、不包含分片字段的一类数据如何处理?
通常由每个负载均衡节点自查,应该带着分库分表的字段查,频率设置低一些,可以考虑使用分布式锁来控制整个集群的并发
配图:带分片的检查。一个缓存节点与其他不一致,收到补发消息
转载地址:http://amqcx.baihongyu.com/