使用redis仅保存最新的token并分析redis存储结构

来源:互联网 发布:淘宝情趣丝袜女模特 编辑:程序博客网 时间:2024/06/03 18:34

背景

最近在学习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 redisfrom itsdangerous import TimedJSONWebSignatureSerializer as SerializerSERY_KEY = 'youneverknow'MAX_LENGTH = 100000s1 = Serializer(SERY_KEY,expires_in=3600)s2 = Serializer(SERY_KEY,expires_in=36000)r = redis.StrictRedis('localhost',port=6379, db=0)t1 = Nonet2 = Nonet3 = Nonefor 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.97K10000条used_memory_human:7.47M100000条used_memory_human:73.02M#hash方式100条used_memory_human:613.55K10000条used_memory_human:9.33M100000条used_memory_human:88.49M

测试k-v读取时间代码

import redisimport datetimeimport randomr = redis.StrictRedis('localhost',port=6379, db=0)MAX_TIME = 1000000MAX_USER = 100000u = 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 redisimport datetimeimport randomr = redis.StrictRedis('localhost',port=6379, db=0)MAX_TIME = 1000000MAX_USER = 100000u = 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.080209100000次0:00:09.0160681000000次0:01:36.284822#hash方式1000次0:00:00.079736100000次0:00:08.3015831000000次0:01:33.479911

总结

从占用内存上说,k-v比hash少了17%。
但hash的查找又比k-v快了3%左右。

原创粉丝点击