Redis作为Nosql的代表,想必大家已经再熟悉不过了,除了作为缓存来使用,Redis还提供了其他很多有用的功能,例如可作为消息队列、分布式锁、不隆过滤器、限流等功能使用。今天先来说一说redis作为缓存使用,提供了5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈 希) 和 zset (有序集合)。

一、string (字符串)

字符串 string 是 Redis 最简单的数据结构。Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一key值来获取相应的 value 数据。不同类型的数据结构的差异就在于value 的结构不一样。字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体 使用 JSON 序列化成字符串,然后将序列化后的字符串塞进 Redis 来缓存。同样,取用户 信息会经过一次反序列化的过程。Redis 的字符串是动态字符串,是可以修改的字符串,内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,字符串最大长度为 512M。使用命令如下:

设置键值对:set [key] [value]

获取对应键的值:get [key]

批量操作键值对:mset [key] [value] [key] [value] [key] [value] ...

批量获取对应键的值:mget [key] [key] [key]...

批量操作可以节省网络耗时开销。

可以对 key 设置过期时间,到点自动删除,这个功能常用来控制缓存的失效时间。在保证缓存是热点数据或者保证缓存和数据库一致性的解决方案时,设置失效时间是必不可少的。还有就是整数的自增或者自减功能,如果 value 值是一个整数,可以对它进行自增操作。自增是有范围的,它的范围是signed long 的最大最小值,超过了这个值,Redis 会报错。

设置过期可以用set+expire的组合,但是保证不了原子性,如果想保证原子性,就用setex命令:

关于自增和自减:

incr/decr:自增/自减 1

incrby/decrby [key] [num]:自增/自减 num

二、list (列表)

Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组。链表由于有前后节点,特点是插入和删除快,查询慢;数组由于有索引,所以特点是查询快,但是插入和删除慢;这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n)。当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理。

操作命令:

Lpush——先进后出,在列表头部插入元素Rpush——先进先出,在列表的尾部插入元素Lrange——出栈,根据索引,获取列表元素Lpop——左边出栈,获取列表的第一个元素Rpop——右边出栈,获取列表的最后一个元素Lindex——根据索引,取出元素Llen——链表长度,元素个数Lrem——根据key,删除n个valueLtrim——根据索引,删除指定元素Lset——根据index,设置valueLinsert before——根据value,在之前插入值Linsert after——根据value,在之后插入值BLPOP/BRPOP key -- 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止BRPOPLPUSH source destination timeout -- 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。LPUSHX -- 将一个值插入到已存在的列表头部

命令lindex 相当于 Java 链表的 get(int index)方法,它需要对链表进行遍历,性能随着参数 index 增大而变差。如果再深入一点,你会发现 Redis 底层存储的还不是一个简单的linkedlist, 而是称之为快速链表 quicklist 的一个结构。首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是 ziplist,也即是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成 quicklist。因为普通的链表需要的附加指针空间太大,会比较浪费空间,而且会加重内存的碎片化。快速列表既满足了快速的插入删除性能,又不会出现太大的空间冗余。

三、hash (字典)

Redis 的字典相当于 Java 语言里面的 HashMap,它是无序字典。内部实现结构上同 Java 的 HashMap 也是一致的,同样的数组 + 链表二维结构。第一维 hash 的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。所以特点也是和Java中Map结构相似。不同的是,Redis 的字典的值只能是字符串,另外它们 rehash 的方式不一样,因为 Java 的 HashMap 在字典很大时,rehash 是个耗时的操作,需要一次性全部 rehash。Redis 为了高性能,不能堵塞服务,所以采用了渐进式 rehash 策略。渐进式 rehash 会在 rehash 的同时,保留新旧两个 hash 结构,查询时会同时查询两个 hash 结构,然后在后续的定时任务中以及 hash 的子指令中,循序渐进地将旧 hash 的内容 一点点迁移到新的 hash 结构中。当 hash 移除了最后一个元素之后,该数据结构自动被删除,内存被回收。

操作命令:

HSET key field value -- 将哈希表 key 中的字段 field 的值设为 value HSETNX key field value -- 只有在字段 field 不存在时,设置哈希表字段的值。HVALS key -- 获取哈希表中所有值HSCAN key cursor [MATCH pattern] [COUNT count] -- 迭代哈希表中的键值对。HMSET key field1 value1 [field2 value2 ] -- 同时将多个 field-value (域-值)对设置到哈希表 key 中。HMGET key field1 [field2] -- 获取所有给定字段的值HLEN key -- 获取哈希表中字段的数量HKEYS key -- 获取所有哈希表中的字段HINCRBYFLOAT key field increment -- 为哈希表 key 中的指定字段的浮点数值加上增量 increment HINCRBY key field increment -- 为哈希表 key 中的指定字段的整数值加上增量 increment HGETALL key -- 获取在哈希表中指定 key 的所有字段和值HGET key field -- 获取存储在哈希表中指定字段的值HEXISTS key field -- 查看哈希表 key 中,指定的字段是否存在HDEL key field1 [field2] -- 删除一个或多个哈希表字段

四、set (集合)

Redis 的集合相当于 Java 语言里面的 HashSet,它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL,Java中的HashSet也是基于一个value为null的HashMap。当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。 set 结构可以用来做有去重需求需要实现的功能,可以保证唯一性。

操作命令:

SADD key member1 [member2] -- 向集合添加一个或多个成员SCARD key -- 获取集合的成员数SDIFF key1 [key2] -- 返回给定所有集合的差集SDIFFSTORE destination key1 [key2] -- 返回给定所有集合的差集并存储在 destination 中SINTER key1 [key2] -- 返回给定所有集合的交集SINTERSTORE destination key1 [key2] -- 返回给定所有集合的交集并存储在 destination 中SISMEMBER key member -- 判断 member 元素是否是集合 key 的成员SMEMBERS key -- 返回集合中的所有成员SMOVE source destination member -- 将 member 元素从 source 集合移动到 destination 集合SPOP key -- 移除并返回集合中的一个随机元素SRANDMEMBER key [count] -- 返回集合中一个或多个随机数SREM key member1 [member2] -- 移除集合中一个或多个成员SUNION key1 [key2] -- 返回所有给定集合的并集SUNIONSTORE destination key1 [key2] -- 所有给定集合的并集存储在 destination 集合中SSCAN key cursor [MATCH pattern] [COUNT count] -- 迭代集合中的元素

spop命令是随机移除一个value,这一操作,刚好是baidu从bat中给移除去了,冥冥之中自有天意呀!不过baidu的技术还是最牛逼的!

五、zset (有序列表)

zset 是 Redis 提供的最为特色的数据结构,它类似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。它的内部实现用的是一种叫着“跳跃列表”的数据结构。当zset 中最后一个 value 被移除后,数据结构自动删除,内存被回收。

操作命令:

ZADD key score1 member1 [score2 member2] -- 向有序集合添加一个或多个成员,或者更新已存在成员的分数ZCARD key -- 获取有序集合的成员数ZCOUNT key min max -- 计算在有序集合中指定区间分数的成员数ZINCRBY key increment member -- 有序集合中对指定成员的分数加上增量 incrementZINTERSTORE destination numkeys key [key ...] -- 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中ZLEXCOUNT key min max -- 在有序集合中计算指定字典区间内成员数量ZRANGE key start stop [WITHSCORES] -- 通过索引区间返回有序集合指定区间内的成员ZRANGEBYLEX key min max [LIMIT offset count] -- 通过字典区间返回有序集合的成员ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] -- 通过分数返回有序集合指定区间内的成员ZRANK key member -- 返回有序集合中指定成员的索引ZREM key member [member ...] -- 移除有序集合中的一个或多个成员ZREMRANGEBYLEX key min max -- 移除有序集合中给定的字典区间的所有成员ZREMRANGEBYRANK key start stop -- 移除有序集合中给定的排名区间的所有成员ZREMRANGEBYSCORE key min max -- 移除有序集合中给定的分数区间的所有成员ZREVRANGE key start stop [WITHSCORES] -- 返回有序集中指定区间内的成员,通过索引,分数从高到低ZREVRANGEBYSCORE key max min [WITHSCORES] -- 返回有序集中指定分数区间内的成员,分数从高到低排序ZREVRANK key member -- 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序ZSCORE key member -- 返回有序集中,成员的分数值ZUNIONSTORE destination numkeys key [key ...] -- 计算给定的一个或多个有序集的并集,并存储在新的 key 中ZSCAN key cursor [MATCH pattern] [COUNT count] -- 迭代有序集合中的元素(包括元素成员和元素分值)

zset 内部的排序功能是通过"跳跃列表"数据结构来实现的,它的结构非常特殊,也比较复杂。因为 zset 要支持随机的插入和删除,所以它不好使用数组来实现。

redis zset转set 反序列化失败_关于Redis中的五种数据结构,要知其然知其所以然...相关推荐

  1. redis zset转set 反序列化失败_7000字 Redis 超详细总结、笔记!建议收藏

    Redis 简介 Redis 是完全开源免费的,遵守 BSD 协议,是一个高性能的 key - value 数据库 Redis 与 其他 key - value 缓存产品有以下三个特点: Redis ...

  2. bootstraptable获取所有数据_关于Redis中的五种数据结构,要知其然知其所以然

    Redis作为Nosql的代表,想必大家已经再熟悉不过了,除了作为缓存来使用,Redis还提供了其他很多有用的功能,例如可作为消息队列.分布式锁.不隆过滤器.限流等功能使用.今天先来说一说redis作 ...

  3. redis zset转set 反序列化失败_Redis只往zset有序集合添加不存在的数据:关键字索引查询构建+源码分析...

    Redis的有序集合Sorted Set(zset),可以很方便地用来构建关键字索引表,可以很方便地实现支持超大规模并发的关键字组合条件查询. 比如有套博客系统,博客文章存放在 hash 类型 art ...

  4. 浅谈Redis五种数据结构的底层原理

    概念 Redis作为一个开源的用C编写的非关系型数据库,基于优秀的CRUD效率,常用于软件系统的缓存,其本身提供了以下五种数据格式: string:字符串 list:列表 hash:散列表 set:无 ...

  5. 字符动图_图解redis五种数据结构底层实现(动图哦)

    redis有五种基本数据结构:字符串.hash.set.zset.list.但是你知道构成这五种结构的底层数据结构是怎样的吗?今天我们来花费五分钟的时间了解一下.(目前redis版本为3.0.6) 动 ...

  6. 万字长文的Redis五种数据结构详解(理论+实战),建议收藏。

    本文脑图 前言 Redis是基于c语言编写的开源非关系型内存数据库,可以用作数据库.缓存.消息中间件,这么优秀的东西一定要一点一点的吃透它. 关于Redis的文章之前也写过三篇,阅读量和读者的反映都还 ...

  7. Redis五种数据结构详解

    Redis是基于c语言编写的开源非关系型内存数据库,可以用作数据库.缓存.消息中间件,这么优秀的东西一定要一点一点的吃透它. Redis的五种数据结构包括以下五种: String:字符串类型 List ...

  8. Redis系列三、redis的五种数据结构和相关指令之Hash

    本节中将介绍Redis支持的主要数据结构,以及相关的常用Redis命令.redis是一种基于键值对(key-value)的内存数据库,redis数据结构可以分为string.hash.list.set ...

  9. Redis入门总结(一):redis配置文件,五种数据结构,线程模型和持久化方式

    (尊重劳动成果,转载请注明出处:https://yangwenqiang.blog.csdn.net/article/details/90321396冷血之心的博客) 关注微信公众号(文强的技术小屋) ...

最新文章

  1. JavaMVC 模式
  2. Nestjs OpenAPI(Swagger)
  3. TrackID识别音乐的应用不能用了
  4. 客户端svn出现authorization failed异常
  5. 成长的路上,痛并快乐着
  6. Silverlight实例教程 - Validation用户提交数据验证捕获
  7. 自定义用户控件的使用
  8. linux 检测蓝牙 rssi,蓝牙LE信号强度Linux
  9. ros openwrt 分流_常平:推进“截污大会战”补贴助力企业雨污分流
  10. 多线程设计模式(二):Future模式
  11. 数据挖掘实践(金融风控)——task4:建模调参
  12. paip.svn不能提交CLEARUP不起作用解决方法
  13. ubuntu出现qt.qpa.plugin报错
  14. 干货技巧:pdf文件怎么转换成jpg图片?
  15. asp.net mvc3 简单的文件上传下载
  16. 《卫报》评全球最具影响力博客50强 徐静蕾入选
  17. 递归函数--猴子摘桃问题的解题思路
  18. RCNN到faster RCNN 简介
  19. 尚硅谷 VUE 尚品汇项目实战问题解决方式整理(Vue3 版)
  20. Java系统线上生产问题排查一把梭,华为高级java面试题

热门文章

  1. Android开发技巧——PagerAdapter再简单的包
  2. 【转】移动客户端测试总结
  3. 如何更改rhevm中admin的密码
  4. SHELL字符串使用总结
  5. Agile Web Application Development with Yii 1.1 and PHP5
  6. 使用ubuntu 10.04中的中文乱码问题解决
  7. word 中间页插入页码
  8. C++引用计数(reference counting)技术简介(2)
  9. object对象进行深拷贝
  10. 在线中文繁简体转换工具