背景
最近在学习restful api的开发,遇到这样的问题,书上使用itsdangerous生成token,但是同一个用户可以短时间内生成多个token,而这些token在有效期内都是可以使用的。现在就是要实现的需求是仅最新的token有效。老的token失效。
说明
假设一共开发了三种客户端:WEB,ANDROID,IOS,同一种客户端的token只保存最新的一份。
思路
使用数据库保存token,每次生成token时仅需更新token,验证时候先验证token是否有效,再去数据库查找是否是最新的token。
设计
数据库使用redis,提高查询速率。
现在需要确定使用hash还是k-v更好一些。
存法:
hash:
token:uid{
WEB:tokenweb,
ANDROID:tokenandroid,
IPHONE:tokeniphone,
}
k-v:
token:uid:WEB:tokenweb
token:uid:ANDROID:tokenandroid
token:uid:IPHONE:tokeniphone
以下代码实现存一定数目的token:
import redis
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
SERY_KEY = 'youneverknow'
MAX_LENGTH = 100000
s1 = Serializer(SERY_KEY,expires_in=3600)
s2 = Serializer(SERY_KEY,expires_in=36000)
r = redis.StrictRedis('localhost',port=6379, db=0)
t1 = None
t2 = None
t3 = None
for i in range(MAX_LENGTH):
t1 = s1.dumps({'id':i}).decode('utf-8')
t2 = s2.dumps({'id':i}).decode('utf-8')
t3 = s2.dumps({'id':i}).decode('utf-8')
#k-v方式存
# r.set('token:%d:WEB'%i, t1)
# r.set('token:%d:Android'%i, t2)
# r.set('token:%d:IPHONE'%i, t3)
d = {
'WEB':t1,
'ANDROID':t2,
'IPHONE':t3,
}
#hash方式存
r.hmset('token:%d'%i,d)
内存使用结果:
#k-v方式
100条
used_memory_human:595.97K
10000条
used_memory_human:7.47M
100000条
used_memory_human:73.02M
#hash方式
100条
used_memory_human:613.55K
10000条
used_memory_human:9.33M
100000条
used_memory_human:88.49M
测试k-v读取时间代码
import redis
import datetime
import random
r = redis.StrictRedis('localhost',port=6379, db=0)
MAX_TIME = 1000000
MAX_USER = 100000
u = range(MAX_USER)
l = ['WEB','ANDROID','IPHONE']
s = datetime.datetime.now()
for i in range(MAX_TIME):
r.hget('token:%d'%random.choice(u),random.choice(l))
e = datetime.datetime.now()
print(e-s)
测试hash读取时间代码
import redis
import datetime
import random
r = redis.StrictRedis('localhost',port=6379, db=0)
MAX_TIME = 1000000
MAX_USER = 100000
u = range(MAX_USER)
l = ['WEB','ANDROID','IPHONE']
s = datetime.datetime.now()
for i in range(MAX_TIME):
r.get('token:%d:%s'%(random.choice(u),random.choice(l)))
e = datetime.datetime.now()
print(e-s)
查询次数所用时间
#k-v方式
1000次
0:00:00.080209
100000次
0:00:09.016068
1000000次
0:01:36.284822
#hash方式
1000次
0:00:00.079736
100000次
0:00:08.301583
1000000次
0:01:33.479911
总结
从占用内存上说,k-v比hash少了17%。
但hash的查找又比k-v快了3%左右。