缓存雪崩:

原因:大面积key同时到期失效、高并发打到数据库直接崩溃

解决方案:

1、热点key不设置过期时间、只进行更新操作

2、过期时间设为随机时间

缓存穿透:

原因:恶意攻击访问不存在的key,绕过redis直接访问数据库,造成崩溃

解决方案:进行参数校验,只接受合格请求、防止恶意攻击

先从缓存中取数据,如果缓存中取不到就直接通过数据库来取数据,如果取不到,我们可以将key和value都是null写入到缓存中,设置一定的时间,可以有效的防止恶意用户反复用同一个ID来暴力攻击,其实我们也可以在网关层做出相应的控制,因为用户不可能在短时间内做出大量的多次请求的,当出现非正常频率的请求的IP或者机器的时候,可以对这些IP和机器进行限制

缓存击穿:

原因:热点key并发数一直很高,突然到期了,请求直接打到db数据库,导致崩溃

解决方案:设置缓存永不过期就好了,这应该是最简单粗暴的方法了,或者通过互斥锁也是可以解决这种

 

Django 自带强大的缓存系统,可以让你保存动态页面,这样就不必为每次请求计算。为了方便,Django 提供了不同级别的缓存粒度。你可以缓存特定视图的输出,你可以只缓存难以生成的部分,或者你可以缓存整个网站。

设置缓存¶

缓存系统需要少量的设置。也就是说,你必须告诉它你的缓存数据应该放在哪里 —— 是在数据库中,还是在文件系统上,或者直接放在内存中。这是一个重要的决定,会影响你的缓存的性能;是的,有些缓存类型比其他类型快。

 

优点:减少计算

缺点:断电消失(不安全)

四种模式:

数据库
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
    }
}

与其他缓存后端不同,数据库缓存不支持在数据库级别自动剔除过期条目。相反,每次调用add()set()或时都会剔除过期的缓存条目。touch()

创建缓存表¶

在使用数据库缓存之前,必须通过下面的命令创建缓存表:

python manage.py createcachetable

文件

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
    }
}

本地内存

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    }
}

redis

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',
    }
}

Redis 服务器通常受到身份验证的保护。为了提供用户名和密码,请将它们LOCATION与 URL 一起添加:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://username:password@127.0.0.1:6379',
    }
}

如果您在复制模式下设置了多个 Redis 服务器,则可以将服务器指定为分号或逗号分隔的字符串,或者作为列表。使用多台服务器时,写入操作在第一台服务器(领导者)上执行。读取操作在随机选择的其他服务器(副本)上执行:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': [
            'redis://127.0.0.1:6379', # leader
            'redis://127.0.0.1:6378', # read-replica 1
            'redis://127.0.0.1:6377', # read-replica 2
        ],
    }
}

 

服务器内存(可多节点)

Memcached 有一个很好的特性,它可以在多台服务器上共享一个缓存机器。这意味着你可以在多台服务器上运行一个缓存进程。在每台服务器的重复缓存中。利用特性特性在LOCATION中包含所有服务器,可以是分号,也可以是服务器上的一个字符串,可以是字符串。

在这个实例中,两个缓存是通过运行在 IP 实例地址 172.19.26.240 和 172.19.26.242 上的 Memcached 共享的,这个实例都在 11211 端口上:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
        'LOCATION': [
            '172.19.26.240:11211',
            '172.19.26.242:11211',
        ]
    }
}

 

 

django   cache


django.core.cache.cache¶
作为快捷方式,可以通过django.core.cache.cache引用进行缓存缓存:

>>> from django.core.cache import cache
这个对象等价于caches['default']。
cache.set(键,值,超时= DEFAULT_TIMEOUT,版本=无)¶
>>> cache.set('my_key', 'hello, world!', 30)
cache.get(键,默认=无,版本=无)¶
>>> cache.get('my_key')
'hello, world!'
cache.add(键,值,超时= DEFAULT_TIMEOUT,版本=无)¶
在不存在的时候,使用add()方法可以添加键。它与set()相同的参数,但如果指定的键已经存在,将不会尝试更新缓存
>>> cache.set('add_key', 'Initial value')
>>> cache.add('add_key', 'New value')
>>> cache.get('add_key')
'Initial value'
  • cache.``get_many版本=无)¶ 

这里也有get_many()接口,返回一个字典,其中包含你的键,这些键真实存在中(并且没有)请求:

>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}
  • cache.``set_many(字典,超时) ¶ 

使用set_many()传递键值对的字典,可以更有效的设置多个值。

>>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}
  • cache.``delete版本=无)¶ 

你可以使用delete()地删除键,以清空特定对象的显示缓存:

>>> cache.delete('a')
True

如果键被成功删除,将返回delete(),否则返回False

  • cache.``delete_many版本=无)¶ 

如果你想清除很多键,给delete_many()一个提交列表就可以清除。

>>> cache.delete_many(['a', 'b', 'c'])
  • cache.``clear() ¶ 

注意,如果你想删除缓存里的所有键,使用cache.clear()。,clear()将删除缓存里的,而不只是你应用里设置的那些键。

>>> cache.clear()
  • cache.``touch超时= DEFAULT_TIMEOUT版本=无)¶ 

cache.touch()为设置一个新键的过渡时间。

>>> cache.touch('a', 10)
True
  • cache.``incr增量= 1版本=无)¶ 
  • cache.``decr(键,增量= 1,版本=无)¶ 

incr()使用或方法你可以decr()来递增或递减一个存在的默认值。情况下,存在的数值键值将递增或递减1。 。如果你一直存在或递减一个不存在的缓存键,则会出现 ValueError 错误。

>>> cache.set('num', 1)
>>> cache.incr('num')
2
>>> cache.incr('num', 10)
12
>>> cache.decr('num')
11
>>> cache.decr('num', 5)
6
  • cache.``close() ¶ 

如果close()你现在可以和方法实现了,关闭缓存的连接。

>>> cache.close(