python web(bottle框架)知行合一之-简单知识付费平台-”全栈“实践(12)---缓存处理-分页获取课程列表信息接口
PS:笔记只是为了更好表达我怎么语言表述,有些时候可能难免废话一推!
因知识有限, 如有错误, 欢迎指正!
每日细语:传说中,痴心的眼泪会倾城~
续言
这里为什么需要使用到缓存?关于缓存的重要性其实对应用层系统设计来说是必不可少的,因为频繁数据库链接和打开对数据库系统来说压力还是有的~所以我们在应用层中尽量还是需要引入缓存相关机制,避免频繁进行数据库操作处理。
那缓存其实又分内存的缓存和其他redis或其他缓存,那我们这里就有必要封装处理一下相关缓存操作,这里我自己使用的redis来进行处理缓存。
缓存常用的操作有:
- 缓存设置
- 缓存获取
- 缓存清除
- 缓存按key清除
- 缓存有效期设置
- 缓存写入磁盘
而对于缓存来说还是也会遇到一些问题如:
- 缓存穿透
- 缓存击穿
- 缓存雪崩
对于上述几个缓存可能遇到的问题点,大家百度一下,其实都会有相关的答案,我这里且不会做太多的深入说明,百度都知道的东西,好像再讲也没什么意思!
解决参考:
https://blog.csdn.net/fei33423/article/details/79027790
关于缓存库
个人的推荐使用这个封装好的库,当然其实也可以自己封装一个!
https://github.com/hustcc/wrapcache
相关的使用介绍其实github说的也很详细了!我这里也就不细说!
我们直接安装使用即可!
不过需要说明的一点就是一般它的装饰器的方式的话,是对整个函数的结果进行缓存,而对于的KEY设置是什么,我暂时还不清楚!
所以我们使用的话一般直接的使用API的方式!
缓存redis_cache_helper.py工具类封装:
1:安装对应的wrapcache库
2:编写工具模块
#!/usr/bin/evn python
# coding=utf-8
"""
Author = zyx
@Create_Time: 2018/4/25 22:39
@version: v1.0.0
@Contact: 308711822@qq.com
@File: redis_cache_helper.py
@文件功能描述:
"""
import wrapcache
import redis
from wrapcache.adapter.RedisAdapter import RedisAdapter
def init(_redis):
REDIS_POOL = redis.ConnectionPool(host=_redis.get('host', ''), port=_redis.get('post', ''),
db=_redis.get('db', ''),
password=_redis.get('password', ''),
socket_timeout=1, socket_connect_timeout=1)
REDIS_INST = redis.Redis(connection_pool=REDIS_POOL, charset='utf8')
RedisAdapter.db = REDIS_INST
def set(key='', value='', timeout=3000):
print('key', key)
print('v', value)
return wrapcache.set(key, value, timeout=timeout, adapter=RedisAdapter)
def get(key):
return wrapcache.get(key, adapter=RedisAdapter)
def remove(key):
return wrapcache.remove(key, adapter=RedisAdapter)
# clear all the cache.
def flush():
return wrapcache.flush(adapter=RedisAdapter)
from business_logic.configs import redis_config
if __name__ == '__main__':
init(_redis=redis_config.REDIS)
3:启动的时候初始化好redis的配置
4:编写对应的redis_config模块
const = {
# 服务地址
'host': 'localhost',
# 服务端口
'post': 6379,
# 服务密码
'password': '',
# 数据库序号
'db': 2
}
5:修改获取课程的course_logic.py逻辑处理
from business_logic.db_model.knowledgepay_model import session_scope, Course
from base_framework.cache import redis_cache_helper
# 分页查询
def get_course_paginate(page_num=1):
# 缓存的Key
cache_key_course_paginate = 'get_course_paginate' + str(page_num)
# 获取缓存值
result_list = redis_cache_helper.get(cache_key_course_paginate)
# 判断是否有值
if result_list:
is_ends = False
if not result_list:
is_ends = True
# 直接的从缓存中返回
print('直接的从缓存中返回')
return result_list, is_ends
# 否则从数据库中进行读取
print('否则从数据库中进行读取')
with session_scope():
result = Course.select().dicts().order_by(Course.id).paginate(int(page_num), 4)
result_list = []
is_ends = False
if result:
for row in result:
result_list.append(row)
if not result_list:
is_ends = True
# 把对应的结果保存到缓存中
redis_cache_helper.set(cache_key_course_paginate, result_list, timeout=10)
return result_list, is_ends
course_logic.py细节小优化
#!/usr/bin/evn python
# coding=utf-8
"""
Author = zyx
@Create_Time: 2018/4/25 11:23
@version: v1.0.0
@Contact: 308711822@qq.com
@File: course_logic.py
@文件功能描述:
"""
from business_logic.db_model.knowledgepay_model import session_scope, Course
from base_framework.cache import redis_cache_helper
# 分页查询
def get_course_paginate(page_num=1):
# 缓存的Key
cache_key_course_paginate = 'get_course_paginate' + str(page_num)
# 获取缓存值
result_list = redis_cache_helper.get(cache_key_course_paginate)
# 判断是否有值
if result_list:
print('直接的从缓存中返回')
if result_list == 'null':
return [], True # 查询没有结果的时候
return result_list, False
# 否则从数据库中进行读取
print('否则从数据库中进行读取')
with session_scope():
result = Course.select().dicts().order_by(Course.id).paginate(int(page_num), 4)
if not result:
# 把对应的结果保存到缓存中---缓存穿透:处理
redis_cache_helper.set(cache_key_course_paginate, "null", timeout=20)
return [], True # 查询没有结果的时候
# for row in result: result_list.append(row)
result_list = [v for v in result] # 使用列表推导式
# 把对应的结果保存到缓存中
redis_cache_helper.set(cache_key_course_paginate, result_list, timeout=10)
# 返回最终查询结果
return result_list, False
测试
结束
以上笔记纯属个人学习实践总结,有兴趣的同学可以加群一起学习讨论QQ:308711822