有这样的一个需求:限制每个IP对每个资源的访问
1.单个资源访问间隔超过30s;
2.单个资源一天最多能访问10次;
3.单个ip过来访问的时候,需要最快速度返回访问计数信息(或者说是屏蔽资源列表)
基于第三要求,设计为
ipKey {
srcKey:(int)counter,/记录资源访问次数
srcTimestamp:long(timestamp)//记录最后访问时间
}
5台机器 每个机器开两个16G实例,一主一从,可用80G空间
约12万QPS,每小时消耗5G多(每个master1G多/小时),集群吃不消。
于是调优结构,改成如下
ipKey{
srcKey:"counter:second of today" //字符串形式保持,"{计数器}:{当天第几秒}"
}
在达到目的的情况下尽量压缩redis空间。
其中cnt,和timestamp 可以通过字符串反算出来,咱知道性能方面 内存>>磁盘IO>>网络IO
这个修改不仅提升了redis的利用率,还大大缩减了网络IO,这点反算成本(在内存上进行),算不了什么。
优化结构后 一天数据约10来G,省下不小服务器资源
这个是基于这边的用途:
1.本身需要读取时间戳判断,现在改成读字符串,性能上没损失
2.只是作为限制资源,所以计数器不要求十分精准(get出来,判断好,set回去,高并发,大家都懂)
3.不适用于本身需要直接在redis上计数的计数器(incr之类的,那种场景只能用int)
另外,memcache也是类似的
网友评论