暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【reids系列】01-redis基本数据结构

fuzy 2021-06-01
275

String类型

  • Redis中key和value的大小不能超过512M

  • redis中的过期时间不会因为修改超过而被刷新,只有当执行set del getset
    命令时,命令会清除超时时间

基本操作

> set mykey somevalue
OK
> get mykey 
"somevalue"

#
设置带有过期时间的key
redis> SET key-with-expire-time "hello" EX 10086
OK
redis> GET key-with-expire-time
"hello"
redis> TTL key-with-expire-time
(integer) 10069

#
key不存在时会成功
> set mykey newval nx
(nil)
> set mykey newval xx
OK

#
字符串自增 INCR 命令将字符串值解析成整型,将其加一,最后将结果保存为新的字符串值;它是线程安全的
> set counter 100
OK
> incr counter
(integer) 101

存储实现原理

set hello world
为例,每个键值对都会有一个dictEntry
,它的结构如下图:

image-20210601222318969

如图所示,key存储在SDS中,value存储在redisObject
对象中(五种常用的数据类型都是通过redisObject
来存储的)

SDS

redis中存储字符串的一种实现,它有几种结构分别用于存储不同长度的字符串。
字符串类型的内部编码有三种:

1、int,存储 8 个字节的长整型(long,2^63-1)。

2、embstr, 代表 embstr 格式的 SDS(Simple Dynamic String 简单动态字符串), 存储小于 44 个字节的字符串。

3、raw,存储大于 44 个字节的字符串

应用场景

  • 热点数据缓存(例如报表,明星出轨),对象缓存,全页缓存。可以提升热点数据的访问速度。

  • 分布式Session

    <dependency>
      <groupId>org.springframework.session</groupId>
      <artifactId>spring-session-data-redis</artifactId>
    </dependency>

  • 分布式锁
    set key value EX 10 NX:如果key存在则设置失败,否则10m后key过期。

  • 全局ID

    incrby userid 1000

  • 计数器

Hash类型

image-20210111205330282

如图,Hash类型属于键值对类型,但value字段只能存储字符串,不能存储其他类型。

基本操作

#语法 hmset key field value field1 value1 [...]
> hmset user:1000 username antirez birthyear 1977 verified 1
OK
> hget user:1000 username
"antirez"
> hget user:1000 birthyear
"1977"
> hgetall user:1000
1) "username"
2) "antirez"
3) "birthyear"
4) "1977"
5) "verified"
6) "1"

应用场景

String可以做的事情,Hash都可以做(Hash更节省空间,一个key就能存储一个对象的数据)。另外还有其他适用场景,比如根据用户查询购物车信息,我们可以设置以下结构:
key:用户 id;field:商品 id;value:商品数量。
对应的操作可以设置以下命令操作来完成购物车操作:

  • 购物车商品+1:hincr。

  • 购物车商品-1:hdecr。

  • 删除购物车:hdel。

  • 全选:hgetall。

  • 获取商品数量:hlen。

List类型

Redis lists基于LinkedList实现。也就是说该数据结构既有栈的特性也有队列的特性。

基本操作

#lrange 命令:lrange key start end:start和end都可以为负数,这是告知redis从尾部开始计数;
> rpush mylist A
(integer) 1
> rpush mylist B
(integer) 2
> lpush mylist first
(integer) 3
> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"

>
 rpush mylist a b c
(integer) 3
> rpop mylist
"c"
> rpop mylist
"b"
> rpop mylist
"a"

常用场景

  • 在博客引擎实现中,你可为每篇日志设置一个list,在该list中推入博客评论,等等。

List的阻塞操作

可以使用Redis来实现生产者和消费者模型,如使用LPUSH和RPOP来实现该功能。但会遇到这种情景:list是空,这时候消费者就需要轮询来获取数据,这样就会增加redis的访问压力、增加消费端的cpu时间,而很多访问都是无用的。为此redis提供了阻塞式访问 BRPOP 和 BLPOP 命令。消费者可以在获取数据时指定如果数据不存在阻塞的时间,如果在时限内获得数据则立即返回,如果超时还没有数据则返回null, 0表示一直阻塞。同时redis还会为所有阻塞的消费者以先后顺序排队。

Set类型

Redis Set 是 String 的无序排列。SADD
指令把新的元素添加到 set 中。对 set 也可做一些其他的操作,比如测试一个给定的元素是否存在,对不同 set 取交集,并集或差,等等。最大存储数量 2^32-1

基本操作

  • 添加一个或者多个元素:sadd myset a b c d e f g

  • 获取所有元素:smembers myset

  • 统计元素个数:scard myset

  • 随机获取一个元素 srandmember key

  • 随机弹出一个元素 spop myset

  • 移除一个或者多个元素 srem myset d e f

  • 查看元素是否存在 sismember myset a

> sadd myset 1 2 3
(integer) 3
> smembers myset
1. 3
2. 1
3. 2
#检测元素是否存在
> sismember myset 3
(integer) 1

应用场景

示例一:微博点赞

用 like:t1001 来维护 t1001 这条微博的所有点赞用户

点赞了这条微博:sadd like:t1001 u3001

取消点赞:srem like:t1001 u3001

是否点赞:sismember like:t1001 u3001

点赞的所有用户:smembers like:t1001

点赞数:scard like:t1001

示例二:商品打标签

用 tags:i5001 来维护商品所有的标签

sadd tags:i5001 画面清晰细腻

sadd tags:i5001 真彩清晰显示屏

sadd tags:i5001 流畅至极

示例三:商品筛选

获取差集:sdiff set1 set2

获取交集:sinter set1 set2

获取并集:sunion set1 set2

ZSet类型

sorted set,有序的 set,每个元素有个 score;score 相同时,按照 key 的 ASCII 码排序。

基本操作

  • 添加元素:zadd myzset 10 java 20 php 30 ruby 40 cpp 50 python

  • 获取全部元素:zrange myzset 0 -1 withscores || zrevrange myzset 0 -1 withscores

  • 根据分值区间获取元素:zrangebyscore myzset 20 30

  • 移除元素:zrem myzset php cpp

  • 统计元素个数:zcard myzset

  • 获取元素:zsocre myzset java

应用场景

id 为 6001 的新闻点击数加 1:zincrby hotNews:20190926 1 n6001

获取今天点击最多的 15 条:zrevrange hotNews:20190926 0 15 withscores

BitMaps

BitMaps
最大的优点之一是,在存储信息时,它们通常可以极大地节省空间。例如,在用增量用户id表示不同用户的系统中,仅使用512MB内存就可以记住40亿用户的一位信息。通常应用在用户访问统计和在线用户统计这块。

Hyperloglogs

提供了一种不太准确的基数统计方法,比如统计网站的 UV,存在 一定的误差。

Streams

5.0 推出的数据类型。支持多播的可持久化的消息队列,用于实现发布订阅功能,借 鉴了 kafka 的设计。

文章转载自fuzy,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论