当前位置: 首页 > article >正文

使用Redis做数据缓存

目的

本关目的:使用Redis实现数据缓存。

相关知识

本文将将会你掌握:1.将数据加入缓存队列,2.缓存数据。

在我之前的文章中提到了实现了使用 Redis 做动态页面缓存,以此提高访问速度,但同时我们也提到了还有少部分动态页面是不可以对整个页面进行缓存的,例如商品页面,用户详情页面等。尽管这些页面不可以使用页面缓存,但我们仍可以对其中动态内容所需要的数据进行缓存,从而加快动态页面绘制时读取数据的速度,减少页面载入所需的时间。

使用 Redis 做数据缓存的做法是:

  • 编写一个将数据加入缓存队列的函数
    • 通过一个有序集合 cache:list 存储数据加入缓存的时间
      • 成员为数据 ID(唯一标识)
  • 分值为当前时间(time.time()
    • 通过一个有序集合 cache:delay 存储数据更新周期
      • 成员为数据 ID(唯一标识)
  • 分值为更新周期,单位为秒
  • 编写一个定时缓存数据的函数
    • 将数据转换成 JSON 格式
    • 然后将上述 JSON 存储到 Redis 
    • 根据缓存更新周期定时更新 Redis 中的缓存键

JSON

一种轻量级的数据交换格式。大多数编程语言都能高效地编码/解码 JSON 格式的数据。

将数据加入缓存队列

有序集合 cache:list 作为缓存队列,其需要依赖数据更新周期有序集合 cache:delay,加入某数据的更新周期不存在,那么我们则需要删除掉该数据的缓存。在这里,我们采用一种更便捷的方式避免数据缓存和取消数据缓存,那就是将该数据的更新周期设置为小于等于 0

将数据加入缓存队列需要同时操作这两个有序集合:

def add_cache_list(data_id, delay):
conn.zadd('cache:delay', data_id, delay)
conn.zadd('cache:list', data_id, time.time())
缓存数据

我们将数据加入到缓存队列后,就将有序集合 cache:list 的分值看作下一次要更新的时间,所以我们可以根据分值对有序集合 cache:list 进行排序,并连同分值一起取出从小到大顺序的第一个成员(最可能需要更新的成员):

conn.zrange('cache:list', 0, 0, withscores=True)

其中 withscores=True 会告诉 Redis 在返回成员时一同返回成员的分值,返回一个由零或一个元组组成的列表,例如:[(member1, score1)]

接下来,我们再判断该成员的分值:

  • 成员不存在/成员分值大于当前时间(还没有达到下一次更新的时间)
    • 等待 100 毫秒
    • 继续后续操作
  • 从有序集合 cache:delay 中取出该成员的更新周期
    • 若更新周期小于等于 0
  • 从有序集合 cache:delay 中删除该成员
  • 从有序集合 cache:list 中删除该成员
  • 删除该成员的缓存键 cache:data:*,其中 * 是数据 ID(唯一标识)
    • 若更新周期大于 0:
      • 将当前时间加上该成员的更新周期,重新存入有序集合 cache:list 中
      • 从数据库中获取到该数据值(这里可以使用伪造数据替代,例如:{'id':id, 'data':'fake data'}
      • 更新该成员的缓存键 cache:data:*,值为:上述数据编码成 JSON 格式 json(dumps(data))

将这些过程编写为 cache_row() 方法:

def cache_data():
    # 从有序集合'cache:list'中获取排名第一的元素及其分数(score)
    next = conn.zrange('cache:list', 0, 0, withscores=True)
    # 获取当前时间
    now = time.time()
    # 如果没有下一个元素或者下一个元素的时间戳大于当前时间,则休眠0.1秒
    if not next or next[0][1] > now:
        time.sleep(0.1)

    # 获取下一个元素的ID
    data_id = next[0][0]
    # 获取该元素在有序集合'cache:delay'中的分数,即延迟值
    delay = conn.zscore('cache:delay', data_id)
    # 如果延迟值小于等于0,则表示数据已过期
    if delay <= 0:
        # 从'cache:delay'集合中移除该数据的ID
        conn.zrem('cache:delay', data_id)
        # 从'cache:list'集合中移除该数据的ID
        conn.zrem('cache:list', data_id)
        # 删除键为'cache:data:' + data_id的相关数据
        conn.delete('cache:data:' + data_id)
    else:
        # 创建一个包含虚假数据的字典对象
        data = {'id': data_id, 'data': 'fake data'}
        # 更新有序集合'cache:list'中该数据的时间戳,使其在延迟之后再次被处理
        conn.zadd('cache:list', data_id, now + delay)
        # 将虚假数据存储在键为'cache:data:' + data_id的Redis键中
        conn.set('cache:data:' + data_id, json.dumps(data))

http://www.kler.cn/a/159106.html

相关文章:

  • java 读取 有时需要sc.nextLine();读取换行符 有时不需要sc.nextLine();读取换行符 详解
  • 【网络安全】网络安全防护体系
  • 【人工智能】迁移学习在深度学习中的应用:用Python实现自定义数据集图像分类
  • LeetCode 90-子集Ⅱ
  • 爬虫——JSON数据处理
  • Python学习笔记(2)正则表达式
  • 数据结构和算法专题---3、失效算法与应用
  • 在Windows操作系统上使用rtsp simple server和ffmpeg推送录屏视频流
  • jsp在线辅助教育系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • 「X」Embedding in NLP|Token 和 N-Gram、Bag-of-Words 模型释义
  • 单点登录方案调研与实现
  • 【5】PyQt按钮
  • leetcode203. 移除链表元素
  • JavaScript <md5加密的两种不同输出结果分析>--案例(二点一)
  • 统计项目代码行数轻松搞定:使用 Node.js 脚本自动统计代码量
  • 智慧环保:视频监控平台EasyCVR与AI智能分析在环保领域的应用
  • Python OS模块常用方法整理
  • 实现一个add方法,用于计算俩个较大的数相加或者相乘
  • 请求函数的封装---工具函数
  • Java中快速失败 (fail-fast) 机制
  • 装修流程篇
  • C++ 预处理详解
  • Siemens-NXUG二次开发-打开与关闭prt文件[Python UF][20231206]
  • IBNR详解及基于R的计算逻辑
  • Python 元组详解(tuple)
  • python字符串格式化--数字精度控制和快速写法