数据库
首页 > 数据库> > 从数据库随机遍历数据的一次实践

从数据库随机遍历数据的一次实践

作者:互联网

背景

  1. 根据条件,每天给每个用户推荐十名合适的用户(用户当天第一次登录时触发),已经推荐过的不允许再次推荐。
  2. 每天定时给设置了允许自动推荐的用户跑推荐逻辑。
  3. 要求被推荐人具备随机性,否则有些人每天被重复推荐多次,有些人虽然满足条件却长时间遍历不到。

其它解决方案以及利弊

  1. 采用mysql的随机排序函数,每次查出来的数据都不一致,因此达到随机性。缺点采用随机排序的方式,可能会有部分数据始终遍历不到,无法做到极端情况下将所有用户数据都遍历一遍,因此得到的遍历结果如果不满足十人,并不能表示没有十人满足推荐要求。
  2. 一次性将用户数据的userId从数据库全部load出来,并作随机排序。之后根据随机排序后的userId列表遍历。由于load出来的userId列表具备随机性,并且后续查找数据会顺序从列表中分批次查找,这样既具备随机性,又能做到全覆盖查找。缺点是需要查出所有Id,如果用户量大,加上每天有自动推荐的逻辑(一次性需要处理的用户多),对于JVM内存来说也是比较大的负担。

最终解决方案

如下图,在用户表中有6条记录,在逻辑上将表理解成一个环,推荐前随机生成一次下标,指向开始分页的起点random。如果一次分页找三条,先找5和6,然后重置random下标为0,继续往后遍历,直到遍历完整一圈为止。
在这里插入图片描述
这种解决方案既有随机属性,又能在极端情况下遍历所有的用户数据,也不需要将表数据全量load到内存。其实在实践中发现,70%以上的概率只需要分页一次就可以找到十名被推荐人,90%以上概率可以在分页两次内返回。

提高接口的并发处理能力

因为接口存在定时批量推荐的逻辑,可能会由于一次需要处理的数据太多,导致长时间占用系统资源。因此高效的处理方案也是必要的。

  1. 批量推荐前,如果需要推荐的用户太多,需要分批进行推荐,将不同批的人采用负载均衡策略,分布到不同的服务端。
  2. 服务端处理一批推荐人信息时,使用线程池并行处理。

标签:随机性,遍历,数据库,用户,随机,数据,推荐
来源: https://blog.csdn.net/qq_36180997/article/details/119912392