小门板儿

Menu

python实现数据缓存

1、缓存基础知识

1.1、什么是缓存

缓存是一种将计算结果临时存储起来的技术,以便在后续相同或类似的请求中直接使用该结果,而不必重新计算。缓存可以存储在内存、磁盘或其他介质上,以提高系统的性能和响应速度。

1.2 缓存的工作原理

缓存的工作原理是将计算结果与对应的输入参数关联起来,并存储在缓存中。当下次使用相同的参数进行计算时,首先检查缓存中是否存在对应的结果,如果存在,则直接返回缓存中的结果,而不必重新计算。

1.3 缓存的优势和适用场景

使用缓存可以提高系统性能和响应速度,减少计算资源的消耗。缓存适用于以下场景:

2. Python中的缓存技术

2.1 使用字典作为缓存

在Python中,最简单的缓存实现方式是使用字典。将计算结果与输入参数作为键值对存储在字典中,以便后续使用。

cache = {}

def calculate_value(key):
   # 检查缓存中是否存在对应的结果
   if key in cache:
       return cache[key]

       # 如果缓存中不存在结果,则进行计算
   value = expensive_calculation(key)

   # 将计算结果存储到缓存中
   cache[key] = value

   return value

2.2 使用functools.lru_cache实现LRU缓存

Python标准库functools中的lru_cache装饰器提供了LRU(Least Recently Used)缓存的实现。它使用字典作为缓存存储,并根据最近使用的规则进行缓存淘汰。

from functools import lru_cache

@lru_cache(maxsize=3)
def foo(n):
   print(f"Running foo({n})")
   return n

print(foo(1))  # 输出:Running foo(1) \n 1
print(foo(2))  # 输出:Running foo(2) \n 2
print(foo(3))  # 输出:Running foo(3) \n 3
print(foo(1))  # 输出:1
print(foo(2))  # 输出:2
print(foo(3))  # 输出:3
print(foo(4))  # 输出:Running foo(4) \n 4
print(foo(1))  # 输出:Running foo(1) \n 1

在这个例子中,我们设定 maxsize=3,也就是只缓存最近的三个结果。当我们连续调用 foo(1)foo(2)foo(3) 时,这三个结果都被缓存了下来。再次调用这三个函数时,由于结果已经在缓存中,函数并没有被重新执行。但是当我们调用 foo(4) 时,由于缓存已满,所以最早被缓存的 foo(1) 的结果被移除了。再次调用 foo(1) 时,函数需要被重新执行。

这个例子说明了 functools.lru_cache 的 LRU 特性:当缓存达到上限时,最近最少使用的缓存会被移除。

3. 缓存的最佳实践

3.1 缓存过期时间的设置

缓存的过期时间是指缓存结果在多长时间后失效。根据实际需求,可以根据以下几种方式设置缓存的过期时间:

3.2 缓存失效策略

缓存失效策略决定了何时将缓存结果标记为无效,需要重新计算。常见的缓存失效策略包括:

3.3 缓存与数据库的一致性

在使用缓存时,需要注意缓存与数据库之间的一致性。当数据库中的数据发生变化时,缓存中的对应结果也应该同步更新或失效,以保持一致性。

4. 实例演示

4.1 使用缓存优化函数调用

from functools import lru_cache

@lru_cache(maxsize=100)
def calculate_sum(a, b):
  print("Calculating sum...")
  return a + b

result1 = calculate_sum(1, 2) # 第一次计算,输出"Calculating sum..."
result2 = calculate_sum(1, 2) # 第二次计算,直接从缓存中获取结果,无输出

4.2 缓存HTTP响应数据

import time
import requests
from cachetools import TTLCache
# 创建具有过期时间的缓存
cache = TTLCache(maxsize=100, ttl=5)  # 过期时间为5秒

def get_data(url):
   if url in cache:
       print('使用缓存数据')
       print(cache[url])
       return cache[url]

   response = requests.get(url)
   data = response.status_code
   print('接口请求返回数据')
   print(data)

   cache[url] = data  # 存储结果到缓存

   return data

get_data('https://www.baidu.com')
get_data('https://www.baidu.com')
time.sleep(6)
get_data('https://www.baidu.com')

输出结果:

第一次调用get_data(url)后,将数据缓存下来,第二次接口请求时,由于结果已经在缓存中,函数并没有被重新执行,但在第三次调用函数时,因为缓存已经过期,会再次调用函数

接口请求返回数据
200
使用缓存数据
200
接口请求返回数据
200

4.3 缓存数据库查询结果

在数据库访问中,经常需要缓存查询结果,以减少对数据库的频繁查询。

from cachetools import TTLCache
import sqlite3

# 创建具有过期时间的缓存
cache = TTLCache(maxsize=100, ttl=60) # 过期时间为60秒

def get_user(id):
  if id in cache:
      return cache[id]

  connection = sqlite3.connect("database.db")
  cursor = connection.cursor()

  query = "SELECT * FROM users WHERE id = ?"
  cursor.execute(query, (id,))
  result = cursor.fetchone()

  cache[id] = result # 存储结果到缓存

  return result

综上:通过合理地使用缓存,我们可以提高系统性能和响应速度,减少计算资源的消耗

参考来源:https://www.zhihu.com/question/590835641/answer/3111863083

— 于 共写了2945个字
— 标签:

评论已关闭。