2. 场景与玩法@数据结构
Last updated
Was this helpful?
Last updated
Was this helpful?
举两个需要限流的场景, 一个是系统的处理能力快跟不上了, 需要阻止请求继续对系统施压, 另一个是指比如某个用户在一个时间段内点赞数量过多, 需要停止他的继续操作.
一种简单的方法是搞滑动窗口+zset, 时间作为score. 假设我们设置5秒内不会回帖超过10次, 每次用户想回复的时候, 我们都更新一下窗口: 按照score排序, 删除5秒窗口外的内容, 统计窗口内剩余内容数量有没有超过10
以上限流措施能用, 但是稍显粗糙, Redis自带一种工具叫redis-cell, 这种工具能提供一种更为完善的限流措施:
这种机制我们称之为"漏斗", 一个用户对应一个漏斗, 对应上面的例子, 用户xiaohan一开始会有15条回帖的机会, 并且伴随着两秒一条的速度在增加. 如果你回帖过快, 快于生产的速度, 很快你的回帖机会就用光了, 你只能等两秒以后你才能再有一次机会回帖了.
我们能迅速排序数组, 并找出一个点周围的点, 但如果这个点是(x,y)
呢? 怎么找出一个点周围的点呢? 这个问题非常有意思, 比如你有一晚寂寞难耐打开探探刷周围的人, 如果这个工程师学过Redis那么他一下就能算出你周围有那些人,科技改变生活redis很重要lmao
当然你也可以select name from users where x0-r < x < x0+r and y0-r < y < y0+r
再给(x,y)加复合索引, 但小学生都知道x用了索引y就用不了索引了, 所以还是不够快.
专业的探探er都知道GeoHash
算法, 鸡儿哈希, 嗯有一定道理... 我们的确不能给二维排序, 那么我们需要一种算法, 能将二维的点映射到一维, 且在二维里更近的点, 映射到一维以后也更近.
在GeoHash中我们先把区域切成一个四个象限, 分别用00/01/11/10表示四个象限, 接着我们把第一象限再切成四个子象限, 那么四个子象限就是 00-00/ 00-01 / 00-11 / 00-10, 重复以上步骤, 我们能得到:
P1点的坐标是: 001100
P2点的坐标是: 001110
将P1/P2转换成整数就能发现两个点从二维就很近, 计算成一维同样很近, 打成我们的目标. 在Redis里面我们刚刚计算出的整数作为zset的score, 按顺序输出他们就是很近的.