Skip to content

基础数据结构

Redis有5中基础数据类型:String、List、Set、Hash、ZSet

String

String是Redis中最简单的数据结构。String是动态的字符,是可以修改的字符串,内部的结构类似与Java中的ArrayList,采用的预分配冗余空间的方式 来减少内存的频繁分配;分配空间通常是要高于实际的字符串长度,当字符串的长度小于1M的时候,扩容都是扩容原来的1倍,字符串最大的长度是512M

  • get:
  • set:
  • del:
  • mget: 查询多个value eg: mget key1 key2 key3
  • mset: 创建多个key-value eg: mset key1 value1 key2 value2
  • setex: 创建一个key-value同时设置过期时间,等于执行set+expire eg: setex key1 5 value1 #5秒后过期
  • setnx: 如果不存在就创建,存在就不创建,常用在分布式锁 eg: setnx key1 value1 # key1存在就不创建
  • incr: 如果value是一个整数,可以通过这个命令进行自增操作: eg: incr age 5 # 加5,不传就自增1

List

Redis中的list相当于Java中的LinkedList,使用的是链表,插入删除数据很快,O(1),但是索引定位很慢 O(n), 当列表pop出最后一个元素后,数据对象会被回收。

  • rpush
  • lpush
  • llen : 查看list长度
  • lpop
  • rpop
  • lindex: 查询指定索引的元素
  • lrange: 范围查询 eg: lrange 0 -1 #查询全部元素 index=-1 表示最后元素, -2表示倒数第二个元素
  • ltrim: 保留指定区间的元素 eg: ltrim 0 10

快速链表:

再深入学习list会发现redis的list底层还不是简单的LinkedList,而是快速链表。

首先在元素比较少的时候会申请一片连续的空间,这个结构就是ziplist。元素就存放在连续的空间中, 当元素增多后会再申请一个ziplist, 两个ziplist使用链表链接,这样就综合了数组和链表的优势。

Hash

相当于Java中的HashMap,内部的实现也是一致的,采用的链表+数组的结构。 不同点:

  • Redis的Key只能是字符串
  • rehash的方式不同,hashmap在数据很大的时候,rehash是一个很耗时的过程,需要一次性全部rehash,而Redis为了高性能不能阻塞服务, 采用的是渐进式的策略,在rehash的时候同时保留新老两个hash结构,查询的时候会查询两个hash结构,然后在定时任务中以及hash指令中逐渐迁移到新的hash结构中。

常用的命令:

  • hset
  • hget
  • hgetall
  • hlen
  • hmset: 批量set
  • hincrby: 对hash结构中的单个key自增 eg: hincrby herman age 1

Set

与Java中的Set集合一致,无序,去重

  • sadd
  • smembers: 查看集合全部元素
  • sismember: 查看某个值是否存在集合
  • scard: 查看长度,相当于count
  • spop: 弹出

ZSet

这是Redis最有特色的数据结构,内部的value是唯一的,同时可以给每个value设置个score,zset会按照设置score进行排序。底层实现使用的跳跃链表。

  • zadd
  • zrange: 查找指定范围的元素,eg: zrange 0 10 #查询出排序后的前10个元素
  • zrevrange: 逆序查询指定范围的元素
  • zcard: 相当于count()
  • zscore: 查询指定元素的分数 eg: zscore books "java concurrency"
  • zrangebyscore: 通过分数范围查询元素集合
  • zrem: 删除元素

跳跃链表:

zset内部排序功能是通过跳跃链表来实现的,因为zset需要实现随机插入和删除,所以不太好使用数组来实现。

我们需要这个链表按照score排序,这就是说每当有元素需要插入的时候就定位到正确的位置才能保证有序,如果使用链表就只能够遍历,性能差。 跳跃链表就是在链表的基础上添加了分层;最下面的一层会把所有的元素串起来,然后每隔几个元素机会挑选出一个组长,再把这些组长通过链表串起来, 再从组长中选择代表串联起来,最终就形成了金字塔结构。

在定位元素的是先从顶层开始,然后下潜到下一级定位,一致下潜到最底层找到元素。

跳跃链表采用的是随机策略来决定新元素可以兼职到第几层。

容器型数据结构通用规则

  • expire: 对某个key设置过期时间,支持以上全部的数据结构
  • 如果容器中没有元素,会立即删除释放内存
  • 如果容器存在就不会创建,eg: rpush操作刚开始没有容器会创建再rpush进元素

原文链接: http://herman7z.site