redis(缓存)
原因:大面积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 有一个很好的特性,它可以在多台服务器上共享一个缓存机器。这意味着你可以在多台服务器上运行一个缓存进程。在每台服务器的重复缓存中。利用特性特性在
在这个实例中,两个缓存是通过运行在 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(