我正在创建一个API Limiter,我在决定使用什么系统进行数据存储时遇到了问题。
很明显,我需要一个易失性存储,再加上持久存储。
在volatile上我想存储一个像这样的键值:
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:*
)匹配的所有密钥,而不会超出定义的限制。和持久存储:
欢迎任何建议。
答案 0 :(得分:1)
这不是一个答案,而是一个观点:现有的速率限制器最好不要使用而不是制作自己的速率限制器。做到这一点很棘手,因此采用经过生产验证的实施不仅更容易,而且更安全。
例如,Generic cell rate algorithm简直就是简单的魔术,并且有几个Redis实现,包括:
当然,还有更多基于Redis的速率限制器 - 我使用Google来查找它们;)