J¶
计数器(counter)¶
应用
计数器一般用于访问量、下载量、投票数等各种计数用途,和自增唯一id(autoincrementing unique identifier)不同的是,计数器的值不但可以被增加,还可以被清零(比如发现有作弊行为),或者被减少(比如部分计数无效),所以计数器生成的值也不是唯一的。
定义
一个计数器,至少应该拥有以下四个操作:
- 增加数值
- 减少数值
- 清零
- 查看当前数值
实现
计数器可以用以下两种方式实现:
- String类函数,INCR,INCRBY,DECR,DECRBY,还有GET和SET。
- Hash类函数,HINCRBY,HSET和HGET。
String实现¶
# coding:utf-8
# file: ./j/counter/string_implement.py
from redis import Redis
INITIAL_VALUE = 0
class Counter:
def __init__(self, name, client=Redis()):
self.name = name
self.client = client
def incr(self, increment=1):
# redis-py 用 incr 代替 incrby,所以可以指定增量
value = self.client.incr(self.name, increment)
return int(value)
def decr(self, decrement=1):
# redis-py 用 decr 代替 decrby,所以可以指定减量
value = self.client.decr(self.name, decrement)
return int(value)
def set(self, value):
self.client.set(self.name, value)
def get(self):
value = self.client.get(self.name)
return INITIAL_VALUE if value is None else int(value)
def reset(self):
self.set(INITIAL_VALUE)
Hash实现¶
Hash实现和String实现稍有不同,Hash实现还需提供一个key
作Hash的键。另外,Hash只有HINCRBY而没有HDECRBY命令,但是我们可以通过代码0-decrement
将负数作为“增量”,传入HINCRBY命令,来达到做减法的效果。
# file: ./j/counter/hash_implement.py
from redis import Redis
INITIALI_VALUE = 0
KEY = 'counter'
class Counter:
def __init__(self, field, client=Redis(), key=KEY):
self.key = key
self.field = field
self.client = client
def incr(self, increment=1):
value = self.client.hincrby(self.key, self.field, increment)
return int(value)
def decr(self, decrement=1):
value = self.client.hincrby(self.key, self.field, 0-decrement)
return int(value)
def set(self, value):
self.client.hset(self.key, self.field, value)
def get(self):
value = self.client.hget(self.key, self.field)
return INITIALI_VALUE if value is None else int(value)
def reset(self):
self.set(INITIALI_VALUE)