月初面试,碰到了一个比较实际的问题:
在Mysql数据库中,每天都会生成10w条数据,但是,由于内存限制,导致了Redis中只能存储最多1W条的数据信息,如何确保这1w条数据是最热门的数据?
个人解决方案:
-
数据存储方案:
既然热门数据,那么就需要有排序,使用redis中的zset数据类型是很自然的想法。数据中的某个唯一字段作为zset中的value,而点击次数作为score,记为click_zset。这样就可选出最热门的数据。而数据,则直接用HashMap存储。
时效的问题:
既然只能存1w条数据且需要是热门数据,那么,点击次数是一方面,时效性也是一方面,如何保证?可以另起一个zset,数据的字段为value,而每次点击时更新当前时间戳为其score,记为time_zset这样,就可以记录时间。在后台跑一个任务,间隔一定时间段删除两个zset中长时间没有发生点击事件的键,并删除hash数据,为产生的新数据腾出数据空间。新数据产生怎么办?
如果有空间,则保存到自己的hashmap,并将key存到两个zset中。
而没有空间时,就应该在click_zset中取出点击次数排在最前第1w位后面的键,删除对应的hash数据。然后看这1w个score的值,然后把key放入两个zset中即可。点击事件产生了怎么办?
点击事件发生时,让其在click_zset中的score加1,然后看其在不在前1w个key中,如果在,首先要看该数据是否已经存在redis中,有的话就不用做什么工作,没有的话则需要取出第1W个点击次数最大的key10000,然后删除key10000所对应的数据,把当前key对应的数据取出存入redis中。
逻辑有点混乱,大致意思是这样,请大家指点。