业务进行分析
我们首先对业务场景进行定义,如何快速的从 1000w 数据中找到 10 个数据作为中奖用户,重复100次,每次作为我们终将的名单,切每一个用户不能重复中奖。基于这个过程我们如何把这个过程高效的实现呢?
数据库实现:
使用数据库是最直接的方法,但在处理大规模数据时,性能可能成为瓶颈。
代码语言:javascript复制select id from User where status=0 order by rand() limit 10
update user set status=1 where id in(...)
使用Redis实现:
使用Set数据结构来存储中奖用户,可以提高抽奖效率。具体实现如下:
- 使用Redis Set: 将中奖用户的ID存储在Redis的Set数据结构中,确保不会有重复的用户。
sadd usrlist uuid1
sadd usrlist uuid2
- 抽奖逻辑优化: 通过Redis提供的spop命令,从Set中弹出指定数量的元素,实现高效的抽奖。
spop usrlist 10
需要注意的问题
在使用redis方案时候,需要考虑一下问题:
- 1000w数据如何预热到缓存中?
- 1000w数据大概占用多少空间?
- 整体的性能大概是多少?
对于上面几个问题我们分别来看:
- 预热我们可以采用job定时预热的模式,采用 sharding 多线程的方式写入redis
- 对于占用空间问题,如果一个userId 占用 n 个字节,1000w大概占用1000w/1024/1024 n=5n mb。经过测算,如果userid 采用长整型的话,预计占用 58 =40Mb.
- Redis的Set底层主要使用了两种数据结构进行存储:intset(整数集合)和hashtable(哈希表)。这两个数据结构的删除都是 O(1),所以效率非常高。