yulu

队列设计--为不同用户推荐不同内容 redis

功能需求:

最近app在做一个为用户自动推荐电台的功能,要求是

  1. 登录用户,根据用户不同,其听到的电台不同,且用户听的越频繁的电台在用户点击下一曲时出现的概率越大。
  2. 非登录用户,官方随机推荐。收听次数越多的电台越容易被推荐。
需求分析:

一开始可能会联想到创建两类池子,一类池子是官方推荐的电台的集合,另一类池子是每个用户自己的电台池子。假如,以每个电台的id作为key,以收听数作为权重值的话,要想满足收听数越多越容易被推荐有点复杂。
所以,我们可以考虑一下实现两类队列,一类队列用来存储官方电台,一类队列用来存储用户自己常听的电台。当用户点击下一曲的时候,按照一定概率决定是从官方队列里面取电台,还是从用户自己的队列里面取电台。决定好从哪一个队列中取数据,再从这个队列中随机的取出一个数据给用户。

  • 如果用户完整的听完此电台,则将此电台加入用户的队列。
  • 如果用户没有听完电台点击下一曲,则将此电台从用户的队列中移除。

这样既保证了每个用户很大概率不会听到同一个电台,有保证了再最开始让用户听到热门电台的概率比较大,同时听到自己喜欢的电台的概率也比较大

代码流程:

说了这么多还是直接看代码架构吧,细节就不展示了,我用的是redislist来实现队列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function getRandomNumber()
{
#TODO:计算随机数
}
function buildRatio()
{
#TODO:计算比例
}
function addAdminQueue()
{
#TODO:为官方队列添加电台
}
function updateQueue()
{
#TODO:更新队列
}
function randomGetFromQueue()
{
#TODO:从用户或官方队列随机取数据
}
function showNext()
{
#TODO:step1 获取下一首
#step2: 用户是否喜欢当前所听的电台,若喜欢添加到用户队列,否则从用户队列里面删除当前电台。
#step3:return next
}