我正在创建一个API限制器,并且我在决定用于数据存储的系统时遇到了问题。
很明显,我需要一个易失性的存储,加上一个持久的存储。
在易失性上,我想存储如下键值:
read:14522145 100
read:99885669 16
read:78951585 100这是一个键,由:{action}:{client}和一个整数值(可用学分)组成。
关于持久性问题,我想要记录所有资源中断情况。
算法(伪代码)非常简单:
MAX_AMOUNT = 100
call(action, client, cost) {
key = action + ":" + client
if (volatileStorage.hasKey(key)) {
value = volatileStorage.getValue(key)
if (value >= cost) {
volatileStorage.setValue(key, value - cost)
return true
} else {
persistentStorage.logOutage(method, client, cost)
return false
}
} else {
volatileStorage.setValue(key, MAX_AMOUNT)
return call(action, client, cost)
}
}有一个并行进程,每个N秒运行每一个method,增加所有键{action}:*的M,最多O。
此外,我想从易失性存储中移除所有比P秒更旧的项目(自那以后没有修改)。
所以基本上每个动作都是action<N, M, O, P>。例如,读取用户每1秒增加5分,最多增加100个,并在60秒的不活动后删除:read_users<1, 5, 100, 60>。
所以我需要一个易挥发的存储器
read_users:*)的所有键,而不会超出定义的限制。和一个持久的存储:
欢迎任何建议。
发布于 2017-04-24 15:57:54
这不是一个答案,而是一个观点:有一些现有的速率限制器,你最好用它来代替你自己的。正确的实现是很棘手的,因此采用经过生产验证的实现不仅更容易,而且更安全。
例如,通用小区速率算法就是简单的魔术,它有几个Redis实现,包括:
当然,还有更多基于Redis的速率限制器--我使用Google来查找它们;)
https://stackoverflow.com/questions/43591677
复制相似问题