redis缓存购物车在django项目中的应用

一、Redis 简介

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

二、Redis 与其他 key - value 缓存产品有以下三个特点:

  1. Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  2. Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  3. Redis支持数据的备份,即master-slave模式的数据备份。

三、Redis 优势

  1. 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  2. 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  3. 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  4. 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

四、Redis与其他key-value存储有什么不同?

  1. Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
  2. Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

五、redis相比memcached有哪些优势?

  1. memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
  2. redis的速度比memcached快很多
  3. redis可以持久化其数据

六、Memcache与Redis的区别都有哪些?

  1. 存储方式
    Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。
    Redis有部份存在硬盘上,这样能保证数据的持久性。
  2. 数据支持类型
    Memcache对数据类型支持相对简单。
    Redis有复杂的数据类型。
  3. value大小
    redis最大可以达到1GB,而memcache只有1MB

七、Redis 常见的性能问题都有哪些?如何解决?

  1. Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
  2. Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
  3. Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
  4. Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内

八、redis 最适合的场景

Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:

  1. Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  2. Redis支持数据的备份,即master-slave模式的数据备份。
  3. Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

应用场景:

  1. 会话缓存(Session Cache)
    最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?
    幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。
  2. 全页缓存(FPC)
    除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。
    再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。
    此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。
  3. 队列
    Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
  4. 排行榜/计数器
    Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:
    当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:
    ZRANGE user_scores 0 10 WITHSCORES
    Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的。

九、购物车实例

意义
这里我们使用redis中的 Hashes 数据类型存储购物车的相关数据
目的是将高频访问的页面,利用reids缓存部分数据,以减轻数据库的压力
使用方法
具体如何使用参照下面的方法,按照 记录名:键:值

  1. 下载django-reids依赖包

    pip install django_redis
    
  2. settings配置

    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": 1000}
               # "PASSWORD": "123",
           }
       }
    }
    
  3. veiws.py

    from django_redis import get_redis_connection
    
    # 添加购物车
    class AddCart(APIView):
        def post(self, request):
            mes = dict()
            data = request.data.copy()
            print(data)
            # 查询购物车是否存在
            ------连接 redis 数据库---------
            conn = get_redis_connection('default')
            # 获取 cart(key) 键 goods_id(field) 属性的值(value)
            cart = conn.hget('cart'+data['user_id'], data['goods_id'])
            # 模型类添加数据的方法
            # cart = models.Cart.objects.filter(user_id=data['user_id'], goods_id=data['goods_id']).first()
            if cart:
                cart = json.loads(cart)
                cart['count'] = int(data['count'])
                # cart.count = data['count']
                # print(conn.hkeys('cart'+ data['user_id']))
                # 设置 cart 键 goods_id 属性的值  cart键 goods_id(值,键)json.dumps(cart)值
                conn.hset('cart'+data['user_id'], data['goods_id'], json.dumps(cart))
                # cart.save()
                mes['code'] = 200
                mes['message'] = '修改成功'
            else:
                goods = models.Goods.objects.filter(id=data['goods_id']).first()
                goods_name = goods.name
                price = goods.price
                image = goods.pic
                conn.hset('cart'+data['user_id'], data['goods_id'], json.dumps
                ({'count': data['count'],
                  'checked': 0,
                  'goods_name': goods_name,
                  'price': float(price),
                  'image': image,
                  'goods_id': int(goods.id)
                  }))
                # 加入购物车
                # c = CartSerializers(data=data)
                # if c.is_valid():
                #     c.save()
                mes['code'] = RET.OK
                mes['message'] = '添加成功'
            return Response(mes)
    
    1. hash类型 hash⽤于存储对象,对象的结构为属性、值 值的类型为string 增加、修改 设置单个属性
      hset key field value
    1. 例1:设置键 user的属性name为itheima
      hset user name itheima
    1. MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
      Redis被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用
      原因:
      强制关闭Redis快照导致不能持久化。 解决方案:
      运行config set stop-writes-on-bgsave-error no 命令后,关闭配置项stop-writes-on-bgsave-error解决该问题。
    1. 设置多个属性
      hmset key field1 value1 field2 value2 …
      例2:设置键u2的属性name为itcast、属性age为11
      hmset u2 name itcast age 11
    1. 获取指定键所有的属性
      hkeys key
      例3:获取键u2的所有属性
      hkeys u2
    1. 获取⼀个属性的值
      hget key field
      例4:获取键u2属性’name’的值
      hget u2 ‘name’
    1. 获取多个属性的值
      hmget key field1 field2 …
      例5:获取键u2属性’name’、'age的值
      hmget u2 name age
    1. 获取所有属性的值
      hvals key
      例6:获取键’u2’所有属性的值
      hvals u2
    1. 删除 删除整个hash键及值,使⽤del命令 删除属性,属性对应的值会被⼀起删除
      hdel key field1 field2 …
      例7:删除键’u2’的属性’age’
      hdel u2 age
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值