避免缓存雪崩思路及方法
- 思路:缓存雪崩是指大量缓存同时过期,导致大量请求直接打到数据库,引起数据库压力骤增甚至崩溃。解决思路是分散缓存过期时间,避免集中过期。
- 具体实现方法:在设置缓存过期时间时,添加一个随机值。例如原本过期时间是60分钟,可以设置为55 - 65分钟之间的随机值。在Python中使用
pymemcache
库示例如下:
import pymemcache
import random
client = pymemcache.client.base.Client(('localhost', 11211))
expiry_time = 60 * 60 # 1小时
random_offset = random.randint(-5 * 60, 5 * 60) # 随机 -5到5分钟
total_expiry = expiry_time + random_offset
client.set('key', 'value', expire=total_expiry)
避免缓存穿透思路及方法
- 思路:缓存穿透是指查询一个不存在的数据,由于缓存不命中,每次都去数据库查询,导致数据库压力增大。解决方法有布隆过滤器和空值缓存。
- 具体实现方法:
- 布隆过滤器:在查询数据前,先通过布隆过滤器判断数据是否存在。若布隆过滤器判断不存在,则直接返回,不再查询数据库。以Python的
bitarray
和mmh3
库实现简单布隆过滤器示例:
import bitarray
import mmh3
class BloomFilter:
def __init__(self, num_items, false_positive_rate):
self.false_positive_rate = false_positive_rate
self.num_items = num_items
self.num_bits = int(-(num_items * \
(math.log(false_positive_rate))) / (math.log(2) ** 2))
self.hash_count = int((self.num_bits / num_items) * math.log(2))
self.bit_array = bitarray.bitarray(self.num_bits)
self.bit_array.setall(0)
def add(self, item):
for i in range(self.hash_count):
index = mmh3.hash(item, i) % self.num_bits
self.bit_array[index] = 1
def check(self, item):
for i in range(self.hash_count):
index = mmh3.hash(item, i) % self.num_bits
if not self.bit_array[index]:
return False
return True
# 使用示例
bf = BloomFilter(num_items=10000, false_positive_rate=0.01)
bf.add('example_key')
if bf.check('example_key'):
# 这里可以接着查Memcached和数据库
pass
else:
# 直接返回,数据不存在
pass
- **空值缓存**:当查询数据库发现数据不存在时,也将这个空值缓存起来,并设置一个较短的过期时间,下次查询相同数据时,直接从缓存返回空值,避免查询数据库。例如:
client = pymemcache.client.base.Client(('localhost', 11211))
result = client.get('key')
if result is None:
# 查询数据库
db_result = get_from_db('key')
if db_result is None:
# 缓存空值,设置短过期时间
client.set('key', None, expire=60)
return None
else:
client.set('key', db_result, expire=3600)
return db_result
else:
return result
def get_from_db(key):
# 实际数据库查询逻辑
pass
保证高性能和数据一致性思路及方法
- 思路:高性能要求减少缓存操作的耗时,数据一致性要确保缓存数据和数据库数据保持同步。
- 具体实现方法:
- 高性能:优化网络连接,例如采用长连接方式减少连接建立开销;合理设置Memcached服务器的内存分配,避免频繁内存交换;批量操作缓存,减少客户端与服务端交互次数。如在Python中批量设置缓存:
client = pymemcache.client.base.Client(('localhost', 11211))
data = {'key1': 'value1', 'key2': 'value2'}
for key, value in data.items():
client.set(key, value)
- **数据一致性**:采用读写锁机制,在更新数据时,先获取写锁,更新数据库后再更新缓存,更新完成后释放写锁;读数据时获取读锁,确保在读取过程中数据不被修改。或者采用缓存失效机制,当数据库数据更新时,立即让对应的缓存失效。例如在数据库更新操作后,执行`client.delete('key')`删除对应的缓存数据。