7-Redis中的数据类型及应用

Redis中的数据类型

  • string 类型

    • string 类型是redis 的最基本类型 ,一个key 对应一个 value .

    • string 是二进制安全的 不存在编码和传输问题,这样string 可以储存任何数据,如字符串,或者序列化的对象等.

    • string 是Redis中最基本的数据类型,一个键最大能存储512MB.

    • 应用场景

      String 通常用于保存单个字符串,或JSON数据
      String 可以保存图片内容
      计数器 (本身具有原子性操作)  
      分布式锁
      
  • Hash (哈希)类型

    • Redis hash 是一个string 类型的fieid 和 value 的映射表 , hash 特别适合用于储存对象

    • Redis 中每个hash 可以储存2的32方-1 40多亿 个键值对,可以看成key value 的map容器,该类型非常适合用于储存对象的信息,如name ,password,age 等.该类型的数据仅占用很少的磁盘空间(相对于json )

    • 应用场景

      常用于存储对象
      使用HASH 类型省去了序列化和并发的问题,不会重复存储用户ID这样的信息[user:123:name]例如这样
      临时购物车
      
  • List (列表) 类型

    • Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) ,一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

    • 应用场景

      1. 消息队列
      
        list类型的lpop和rpush(或者反过来,lpush和rpop)能实现队列的功能,故而可以用Redis的list类型实现简单的点对点的消息队列。不过我不推荐在实战中这么使用,因为现在已经有Kafka、NSQ、RabbitMQ等成熟的消息队列了,它们的功能已经很完善了,除非是为了更深入地理解消息队列,不然我觉得没必要去重复造轮子。
      
      2. 排行榜
      
        list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如京东每日的手机销量排行、学校每次月考学生的成绩排名、斗鱼年终盛典主播排名等,每日计算一次,存储在list类型中,接口访问时,通过page和size分页获取打擂金曲。但是,并不是所有的排行榜都能用list类型实现,只有定时计算的排行榜才适合使用list类型存储,与定时计算的排行榜相对应的是实时计算的排行榜,list类型不能支持实时计算的排行榜,之后在介绍有序集合sorted set的应用场景时会详细介绍实时计算的排行榜的实现。
      
      3. 最新列表
      
        list类型的lpush命令和lrange命令能实现最新列表的功能,每次通过lpush命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表,如朋友圈的点赞列表、评论列表。
      
        但是,并不是所有的最新列表都能用list类型实现,因为对于频繁更新的列表,list类型的分页可能导致列表元素重复或漏掉,举个例子,当前列表里由表头到表尾依次有(E,D,C,B,A)五个元素,每页获取3个元素,用户第一次获取到(E,D,C)三个元素,然后表头新增了一个元素F,列表变成了(F,E,D,C,B,A),此时用户取第二页拿到(C,B,A),元素C重复了。只有不需要分页(比如每次都只取列表的前5个元素)或者更新频率低(比如每天凌晨更新一次)的列表才适合用list类型实现。对于需要分页并且会频繁更新的列表,需用使用有序集合sorted set类型实现。另外,需要通过时间范围查找的最新列表,list类型也实现不了,也需要通过有序集合sorted set类型实现,如以成交时间范围作为条件来查询的订单列表。
      
  • Set (集合) 类型

    • string 类型的无序集合,集合成员是唯一的,Redis 中的set 是通过哈希表实现的,所以添加删除查找的复杂度都是O(1) 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

    • 应用场景

      1. 好友/关注/粉丝/感兴趣的人集合
      
        set类型唯一的特点使得其适合用于存储好友/关注/粉丝/感兴趣的人集合,集合中的元素数量可能很多,每次全部取出来成本不小,set类型提供了一些很实用的命令用于直接操作这些集合,如
      
          a. sinter命令可以获得A和B两个用户的共同好友
      
              b. sismember命令可以判断A是否是B的好友
      
              c. scard命令可以获取好友数量
      
              c. 关注时,smove命令可以将B从A的粉丝集合转移到A的好友集合
      
        需要注意的是,如果你用的是Redis Cluster集群,对于sinter、smove这种操作多个key的命令,要求这两个key必须存储在同一个slot(槽位)中,否则会报出 (error) CROSSSLOT Keys in request don't hash to the same slot 错误。Redis Cluster一共有16384个slot,每个key都是通过哈希算法CRC16(key)获取数值哈希,再模16384来定位slot的。要使得两个key处于同一slot,除了两个key一模一样,还有没有别的方法呢?答案是肯定的,Redis提供了一种Hash Tag的功能,在key中使用{}括起key中的一部分,在进行 CRC16(key) mod 16384 的过程中,只会对{}内的字符串计算,例如friend_set:{123456}和fans_set:{123456},分别表示用户123456的好友集合和粉丝集合,在定位slot时,只对{}内的123456进行计算,所以这两个集合肯定是在同一个slot内的,当用户123456关注某个粉丝时,就可以通过smove命令将这个粉丝从用户123456的粉丝集合移动到好友集合。相比于通过srem命令先将这个粉丝从粉丝集合中删除,再通过sadd命令将这个粉丝加到好友集合,smove命令的优势是它是原子性的,不会出现这个粉丝从粉丝集合中被删除,却没有加到好友集合的情况。然而,对于通过sinter获取共同好友而言,Hash Tag则无能为力,例如,要用sinter去获取用户123456和456789两个用户的共同好友,除非我们将key定义为{friend_set}:123456和{friend_set}:456789,否则不能保证两个key会处于同一个slot,但是如果真这样做的话,所有用户的好友集合都会堆积在同一个slot中,数据分布会严重不均匀,不可取,所以,在实战中使用Redis Cluster时,sinter这个命令其实是不适合作用于两个不同用户对应的集合的(同理其它操作多个key的命令)。
      
        2. 随机展示
      
        通常,app首页的展示区域有限,但是又不能总是展示固定的内容,一种做法是先确定一批需要展示的内容,再从中随机获取。如下图所示,酷狗音乐K歌擂台赛当日的打擂歌曲共29首,首页随机展示5首;昨日打擂金曲共200首,首页随机展示30首。
      
      
        set类型适合存放所有需要展示的内容,而srandmember命令则可以从中随机获取几个。
      
      
        3. 黑名单/白名单
      
        经常有业务出于安全性方面的考虑,需要设置用户黑名单、ip黑名单、设备黑名单等,set类型适合存储这些黑名单数据,sismember命令可用于判断用户、ip、设备是否处于黑名单之中。
        
        > https://www.cnblogs.com/pangzizhe/ 引用cnblogs胖子哲
      
  • Sorted set (有序集合) 类型 访问是非常快的

    • Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

    • 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

    • 有序集合的成员是唯一的,但分数(score)却可以重复。

    • sorted sets里面当items内容大于64的时候同时使用了hashskiplist两种设计实现。这也会为了排序和查找性能做的优化。

    • 添加和删除都需要修改skiplist,所以复杂度为O(log(n)),仅仅是查找元素的话可以直接使用hash,其复杂度为O(1)

    • 应用场景

      游戏排名 
      热点话题
      用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
      
  • HyperLogLog 命令 只关注数量不关注内容
    可以用于每日访问用户计数,用户升级等

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值