Redis简介
Redis是一个高性能的内存非关系型数据库,存储方式采用键值对的方式存储数据。主要有5个数据类型,分别是字符串,列表,散列,无序集合,有序集合。( 本文出自《redis实战》)
实战用途
- 登陆和cookies缓存
将用户登陆后的Token和用户浏览的项目,以散列的形式存放到Redis中,这样可以提高服务器的反应能力,减少数据库的IO查询。
//存储最近登陆用户的token,user信息,浏览项目(只保留前25个)
def store_Token(conn, Token, user, item=None):
timestamp = time.time()
conn.hset('login:', Token, user)
conn.zadd('recent:',Token, timestamp)
if item:
conn.zaad('viewed:' + Token, item, timestamp)
conn.zremrangebyrank('viewd:' + Token, 0, -26)
复制代码
//清理 session的缓存,大小限制位100000个,该函数建议在一个守护进程中运行。
QUIT = False
LIMIT = 100000
def clean_sessions(conn):
while not QUIT:
size = conn.zcard("recent:")
if sizes < LIMIT:
time.sleep(1)
continue
end_index = min(size - LIMIT, 100)
Tokens = conn.zrange('rencent:', 0, end_index-1)
session_keys = []
for token in Tokens:
session_keys.append('view:' + token)
conn.delete(*session_keys)
conn.hdel("login:", *tokens)
conn.zrem("recent:", *tokens)
复制代码
- redis购物车
//将用户购物车的项目以散列的形式放到redis中
def add_to_cart(conn,session,item ,count):
if count < 0:
conn.hrem("cart:" + session, item)
esle:
conn.hset("cart:" + session, item, count)
//定期清理购物车,避免耗尽服务器内存
QUIT = Fasle
LIMIT = 100000
def clean_full_sessions(conn):
while nort QUIT:
size = conn.zcard("recent:")
if size < LIMIT:
time.sleep(1)
continue
else:
end_index = min(size- LIMIT, 100)
sessions = conn.zrange("recent:", 0, end_index -1)
session_keys = []
for sess in sessions:
session_keys.append('viewd:' + sess)
session_keys.append('cart:' + sess)
conn.delete(*session_keys)
conn.hdel('login:', *sessions)
conn.zrem("recent:", *sessions)
复制代码
- 网页缓存
def cache_request(conn ,request, callback):
if not can_cache(request):
callback(request)
pake_key = 'cache' + hash_request(request)
content = conn.get(pake_key)
if not content:
content = callback(request)
conn.setex(pake_key, content)
esle:
return content
复制代码
------------------------------分割线--------------------------
- 数据行缓存
def schedule_row_cache(conn, row_id, delay):
conn.zadd("delay:", row_id, delay)
conn.zadd('schecule:', row_id, tiem.time())
def cache_rows(conn):
while not QUIT:
next = conn.zrange('schedule:', 0,0, withsorces=true)
now = time.time()
if not next or nextp[0][1] > now:
time.sleep(0.5)
continue
row_id = next[0][0]
delay = conn.zscore("delay:",row_id)
if delay <= 0:
conn.zrem('delay:', row_id)
conn.zrem('schedule:', row_id)
conn.delete('inv:' + row_id)
continue
row = Inventory.get(row_id)
conn.zadd('schedule:', row_id, time.time() + delay)
conn.set("inv:" + row_id, jsom.dumps(row.dicts())
continue
复制代码
- 网页分析
def updeta_token(conn, token, user, item=None):
timestamp = time.time()
conn.hset('login:', token, user)
conn.zadd('recent:', token, timestamp)
if item:
conn.zadd('viewed:' + token, item, timestamp)
conn.zremrangbyrank('viewed:' + token, 0, -26)
conn.zincrby('viewed:' + token, -1)
//守护程序,删除排名200000后的项目
def recale_viewed(conn):
while not QUIT:
conn.zremrangbyrank("viewed:", 0, -200001)
conn.zinterstore("viewed:", {"viewed:", 0.5})
time.sleep(300)
//判断是否可被缓存
def can_cache(conn, request):
item_id = extract_item_id(request)
if not item_id or is_dynamic(request):
return false
rank = conn.zrank('viewed:', item_id)
return rank is not None and rank < 1000
复制代码