一个bug引发的一连串问题

一、bug描述

在这里插入图片描述

点击资讯页面,展示资讯列表,等过段时间往下拉查看下一页时,发现第二页的资讯信息发布时间比第一页的资讯信息更晚一些,从而出现上图的问题。

二、bug原因

资讯数据处理流程:首先由爬虫爬取各个网站的资讯数据,落到A表,然后经过定时任务处理后放到B表,之后flink监听B表中有新增数据,就会把这条新增的数据放到es中,最后用户访问页面请求接口展示出这条数据。

已知信息:
1、由于各个网站数据源的数据刷新频率不同,为了降低成本,所以有的爬虫是一分钟爬取一次,有的是几分钟爬取一次,有的是一两个小时爬取一次。
2、从A表处理到B表的定时任务是每分钟执行一次。
3、资讯列表是通过发布时间倒序排列的。

排查过程:

  1. 一开始以为是es查询的Bouncing Result问题,因为有部分数据的发布时间是相同的,后来发现第二页的数据发布时间是不同的,所以排除这个问题。
  2. 然后想起来动态索引是实时的,所以会实时添加数据,比如总共有100条数据,第一页会展示1-10条数据,后来索引新增了5条数据,导致第二页查询出来第5-15条数据。这个时候需要在前端请求时添加过滤条件,即在下一次请求时携带上一次请求最后一条数据的发布时间。
  3. 后来又捋了一遍逻辑,发现还有个问题,由于页面展示时取的是发布时间,而发布时间是由各个网站数据源爬取出来的,此时会出现一种情况,比如一个网站上A数据的发布时间是5点,爬虫爬取的时间是6点,经过处理后放到es中的发布时间也是5点,而页面是根据发布时间倒序的,所以会导致用户查看资讯列表时,一直往下拉到5点才能看到这条数据。

Bouncing Results:
想象一下有两个文档有同样值的时间戳字段,搜索结果用 timestamp 字段来排序。 由于搜索请求是在所有有效的分片副本间轮询的,那就有可能发生主分片处理请求时,这两个文档是一种顺序, 而副本分片处理请求时又是另一种顺序。
这就是所谓的Bouncing Results问题: 每次用户刷新页面时,搜索结果表现是不同的顺序。

三、解决办法

跟产品商量后可以把数据源的发布时间改为落到B表的createTime时间,同时在前端请求时添加查询小于第一页最后一条的createTime时间,并且设置es的preference参数,让同一个用户始终使用同一个分片,保证用户每次查询的结果是相同的,避免Bouncing Results问题。

preference取值:
1、_primary:该操作将只在主分片上执行,性能会打折扣,达不到性能的水平扩展。
2、_primary_first:优先在主分片执行,如果主分片挂掉,会在副分片上执行请求。
3、_replica:该操作将只在副分片上执行。
4、_replica_first:优先在副分片执行,如果副分片挂掉,会在主分片上执行请求。
5、_local:优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点没有IO问题但有可能造成负载不均问题。
6、_prefer_nodes:abc,xyz:倾向于使用提供的节点id上执行。
7、_shards:2,3:该操作限制在指定的分片2、3上执行,这种方式可以与其他方式相结合,但必须首先出现:_shards:2,3|_primary
8、_only_nodes:该操作限制在指定的节点上执行。
9、Custom (string) value:自定义值,可以保证同样的请求,被分配到同样的分片上面,从而保证请求结果的稳定性,比如用户ID。
10、不配置:默认采用轮询的方法查询主副分片

四、参考资料

1.https://www.elastic.co/guide/cn/elasticsearch/guide/current/_search_options.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值