memcache&redis是什么?在内存中存取数据
应用场景:
缓存:实时性要求不高的数据,可以做缓存
一般公司的首页是做了缓存的。
memcache&redis相同点:
都是k-v的形式
memcache&redis有哪些区别?
memcache:
类型单一 v只能是字符串
redis:五大类型
k==“字符串”
k==list
k==hash
k==set
k==order set
持久化:
memcache:断电内存清空
redis:支持持久化
核心:redis单核,memcache多核
如果只做页面缓存:用memcache就行,因为只缓存字符串
-------------------------------------哪个好?--------------------------------------------------------------------
Redis作者的原话:
没有必要过多关心性能,因为二者的性能都已经足够高了。
由于Redis只使用单核,而memcache可以使用多核,所以在比较上,平均
每一个核上Redis在存储小数据时比memcache性能更高。而在100k以上的数据中
memcache性能要高于redis,虽然redis也在存储大数据性能上进行优化,但比起memcache
还是稍有逊色,说了这么多,结论是无论你使用哪一个,
每秒处理请求的次数都不会成为瓶颈(比如瓶颈可能会在网卡)
如果要说内存使用效率,使用简单的key-value存储的话,memcache的内存利用率更高,
而如果redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率
会高于memcache,当然这和你的应用场景和数据特性有关。
如果你对数据持久化和数据同步有所要求,那么推荐你选择redis,因为这两个特性memcache都不具备
即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择redis也是明智的。
如果需要缓存能够支持更复杂的结构和操作,redis是不错的选择
-----------------------------------------------------------------------------------------------------------------------
10、gets 和 cas
如商城商品剩余个数,假设该值保存在memcache中,product_count = 900
A用户刷新页面从memcache中读取到product_count = 900 ---> mc.get('product_count')==900
B用户刷新页面从memcache中读取到product_count = 900 ---> mc.get('product_count')==900
如果A、B用户均购买商品(A和B用户获取到的product_count都是一样的)
A用户修改商品剩余个数 product_count=899 --> mc.set('product_count', 899)
B用户修改商品剩余个数 product_count=899 --> mc.set('product_count', 899)
如此一来缓存内的product_count便不在正确,两个用户购买商品后,商品剩余还是 899
如果使用set和get来操作以上过程,那么程序就会如上述所示情况!
如果想要避免此情况的发生,只要使用 gets 和 cas 即可,如:
#!/usr/bin/env python # -*- coding:utf-8 -*- import memcache mc = memcache.Client(['10.211.55.4:12000'], debug=True, cache_cas=True) v = mc.gets('product_count') # ... # 如果有人在gets之后和cas之前修改了product_count,那么,下面的设置将会执行失败,剖出异常,从而避免非正常数据的产生 mc.cas('product_count', "899")
Ps:本质上每次执行gets时,会从memcache中获取一个自增的数字,通过cas去修改gets的值时,会携带之前获取的自增值和memcache中的自增值进行比较,如果相等,则可以提交,如果不想等,
那表示在gets和cas执行之间,又有其他人执行了gets(获取了缓冲的指定值), 如此一来有可能出现非正常数据,则不允许修改。
Django的缓存:
Django缓存将一个某个views的返回值保存至内存或者memcache中,某时间段内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。
Django中提供了6种缓存方式:一般用后面三种
- 开发调试(可以设置保存缓存的key格式)
- 内存
- 文件
- 数据库
- Memcache缓存(python-memcached模块)
- Memcache缓存(pylibmc模块)
- Redis缓存
Memcache缓存(python-memcached模块)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 此缓存使用python-memcached模块连接memcache CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': 'unix:/tmp/memcached.sock', } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': [ '172.19.26.240:11211', '172.19.26.242:11211', ] } }
Memcache缓存(pylibmc模块)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 此缓存使用pylibmc模块连接memcache CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 'LOCATION': '127.0.0.1:11211', } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 'LOCATION': '/tmp/memcached.sock', } } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 'LOCATION': [ '172.19.26.240:11211', '172.19.26.242:11211', ] } }
Redis缓存(依赖:pip3 install django-redis)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "密码", } } }
from django_redis import get_redis_connection conn = get_redis_connection("default")
a. 全站使用
使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存 MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', # 其他中间件... 'django.middleware.cache.FetchFromCacheMiddleware', ] CACHE_MIDDLEWARE_ALIAS = "" CACHE_MIDDLEWARE_SECONDS = "" CACHE_MIDDLEWARE_KEY_PREFIX = ""
b. 单独视图缓存
方式一:15分钟过期 from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ... 方式二: from django.views.decorators.cache import cache_page urlpatterns = [ url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)), ]
c、局部视图使用
a. 引入TemplateTag {% load cache %} b. 使用缓存 {% cache 5000 缓存key %} 缓存内容 {% endcache %}