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

背景

最近在学习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%左右。

你可能感兴趣的:(flask)