V2EX vebuqi
 vebuqi 最近的时间轴更新
vebuqi

vebuqi

V2EX 第 88503 号会员,加入于 2014-12-26 00:27:06 +08:00
根据 vebuqi 的设置,主题列表只有在你登录之后才可查看
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
vebuqi 最近回复了
随机来一个
2021-04-11 11:18:25 +08:00
回复了 waibunleung 创建的主题 程序员 请教诸位一个 redis 统计访问量增速的问题
@waibunleung

单个视频的访问量用两个 key 来存储,过期时间设置成两个周期,也就是 20 分钟
写入时,每次都对当前周期内的 key 写入
读取时,读取上个周期的后半部分和这个周期的前半部分

如:
现在是 10:56,则目前数据库中的 key 有两个,v:${id}:cnt:bit:1040 (过期时间还有 4 分钟) 和 v:${id}:cnt:bit:1050 (过期时间还有 14 分钟),1040 代表 10:4X 周期内的计数,10:50 代表 10:5X 周期内的计数

若 10:56 新增 10 个,则对 v:${id}:cnt:bit:1050 内第 6 个域 incr 10 即可
若读取最近 10min 的访问量,则取前一个 key 的后 3 个域( 10:47 、10:48 、10:49 )和当前 key 的前 7 个域( 10:50 ~ 10:56 ),然后求和

这样的话就避免了你提到的问题,但增加了一倍的存储(两个 key )

再复杂一点的方案,单 key 中前 N 位用 1 个单独的域,记录上次写入时间,每次写入前,根据当前时间和上次写入时间判断是否要重置之前的某个 /某些域,然后再进行写入+(重置)的操作。这样的话,存储能降到一个 key,但写入时多了一次操作,时间换空间了,适用于 写少读多的场景,所以最好是聚合写
2021-04-10 22:47:33 +08:00
回复了 waibunleung 创建的主题 程序员 请教诸位一个 redis 统计访问量增速的问题
遇到过类似的问题,说下解决的方法

假设我们需要存储视频近 10 分钟内的访问量

存储方面,我们可以把 10 分钟,分割成 10 个 1 分钟,使用 Redis 的 bitmap 来存储这 10 个量

在命令方面,redis 的 BITFIELD 命令可以对 bitmap 的多个域同时操作,对每个域支持 GET 、SET 、INCRBY 子命令,可以满足需求

如图:

![image.png]( https://i.loli.net/2021/04/10/LBkiMupGR6ctXoT.png)


我们把 bitmap 分割成 10 个域,每个域代表 1 分钟的访问量,那么每次获取某个视频的访问量时,可以取到这 10 个域的值求和即可

假设每分钟视频的访问量的上限是 255 ( 2^8,这里是为了控制溢出,值可以无限大小,只要是 2 的正整数倍即可)


新增访问量时,只需计算应该往哪个 /哪些域( offset )里增加就可以了,如 22:13 的视频 123456 的访问量新增 17,根据时间计算 offset 为 3,命令:

`BITFIELD v:123456:cnt:bit OVERFLOW SAT INCRBY u8 0 17

这条命令返回对 offset 为 0 的域进行了+17 的操作,u8 表示按照 10 个 bit 分域,上限 255,0 标识 offset,即第 0 分钟,`OVERFLOW SAT`表示如果 incr 后的结果超过上限(这里是 2^8 ),那么结果保持在最大值 255 ( 8 位全 1 )



获取视频 123456 近 10 分钟的访问量,命令:

`BITFIELD v:123456:cnt:bit GET u8 GET u8 1 GET u8 2 GET u83 GET u8 4 GET u8 5 GET u8 6 GET u8 7 GET u8 8 GET u8 9`

这条命令会返回每个域(即每分钟)的值,求和后即为近 10 分钟的累计访问量

BITFIELD 的每个子命令的复杂度是 O(1)的,如果访问 /操作 N 个视频的近 10 分钟的访问量,也就是操作 N 次 Redis 即可



方案的优点

1. 省空间,bitmap 占用空间很小
2. 支持批量,BITFIELD 的子命令可以多个同时操作

缺点:

1. 不是严格的滑动窗口,有一定的精度损失

这个可以通过拆细粒度来解决,如 10 秒(甚至 1 秒)一个域,相应地,这样会增加一定的存储

2. 设计时需要考虑单个单位时间内的上限,超过上限时,统计不准,因为我们在溢出控制时使用了饱和算法( SAT )

这个可以在设计初期尽量预留一个保险的值,当然了,越大的话,存储也会越大

3. 对于读写分离的场景(即读从写主),BITFIELD 被 Redis 标识为写命令,所以所有的 BITFIELD 都会在主节点上执行

这个问题我们遇到了,但没有造成很高的负载,所以没有处理;不过阿里云有篇文章可以参考: https://developer.aliyun.com/article/757841
2020-08-26 12:33:29 +08:00
回复了 zhxjdwh 创建的主题 求职 [广州] 找一份工作, Java 开发, 5 年经验
联系方式?
另外,只考虑广州吗,其它城市看不看,比如北京
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2979 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 11ms UTC 10:52 PVG 18:52 LAX 03:52 JFK 06:2
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86