Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。

基础的数据结构(五种基础数据结构及应用场景)(1)

一. string (字符串)

字符串 string 是 Redis 最简单的数据结构。Redis 所有的数据结构都是以唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结构的差异就在于 value 的结构不一样。字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体使用 JSON 序列化成字符串,然后将序列化后的字符串塞进 Redis 来缓存。同样,取用户信息会经过一次反序列化的过程。

1. string的常用操作(1) 键值对

# 存入字符串键值对 set key value # 获取一个字符串键值对 get key # 删除 del key 复制代码

(2) 批量操作键值对

可以批量对多个字符串进行读写,节省网络耗时开销

# 批量存储字符串键值对 mset ket value [key value .....] # 批量获取字符串键值对 mget key [key ......] 复制代码

(3) 过期和 set 命令扩展

# 设置一个键(key)的过期时间(seconds) expire key seconds # setex 等价于 set expire setex key seconds value # 存入一个不存在的字符串键值对 setnx key value 复制代码

基础的数据结构(五种基础数据结构及应用场景)(2)

(4) 原子操作

如果 value 值是一个整数,还可以对它进行自增操作。自增是有范围的,它的范围是 signed long 的最大最小值,超过了这个值,Redis 会报错

# 将 key 中存储的值加1 incr key # 将 key 中存储的值减1 decr key # 将 key 中存储的值加increment incrby key increment # 将 key 中存储的值减decrement decrby key decrement 复制代码

基础的数据结构(五种基础数据结构及应用场景)(3)

2. string的应用场景

Redis应用场景:常规key-value缓存应用、常规计数:微信公众号阅读次数,粉丝数等、分布式锁等

(1)单值缓存

set key value get key 复制代码

(2)对象缓存

基础的数据结构(五种基础数据结构及应用场景)(4)

set user:1 value(json格式数据) mset user:1:name zhuge user:1:balance 1888 mget user:1:name user:1:balance 复制代码

(3)计数器

基础的数据结构(五种基础数据结构及应用场景)(5)

incr article:readcount:{文章id} get article:readcount:{文章id} 复制代码

(4)分布式锁(5)web集群session共享

这里推荐王松大神的一篇文章: wangsong.blog.csdn.net/article/det…

(6)分布式系统全局序列号

redis批量生成序列号提升性能

二. hash (哈希)

String类型存储的困惑

基础的数据结构(五种基础数据结构及应用场景)(6)

hash类型1. hash的常用操作(1)操作单个数据

# 添加修改数据 hset key field value # 获取数据 hget key field # 删除数据 hdel key field1 [field2 ...] 复制代码

(2)操作多个数据

# 添加/修改多个数据 hmset key field1 value1 field2 calue2 #获取多个数据 hmget key field1 field2 … # 获取哈希表key中field的数量 hlen key # 获取哈希表key中所有的键值 hgetall key # 获取哈希表中是否存在指定的字段 hexists key field 复制代码

(3)原子操作

# 将 field 中存储的值加 increment hincrby key field increment # float 值 hincrbyfloat key field increment 复制代码

2. hash的应用场景(1)对象缓存

基础的数据结构(五种基础数据结构及应用场景)(7)

hmset user {userId}:name value {userId}:balance value hmset user {1}:name zhuge {1}:balance 1888 复制代码

(2)购物车

基础的数据结构(五种基础数据结构及应用场景)(8)

3. hash的优缺点
  1. 同类数据归类整合储存,方便数据管理。
  2. 相比string操作消耗内存与cpu更小。
  3. 相比string储存更节省空间。
  1. 过期功能不能使用在field上,只能用在key上。
  2. Redis集群架构下不适合大规模使用。

redis集群架构

基础的数据结构(五种基础数据结构及应用场景)(9)

三. List(列表)1. list的常用操作(1)添加/修改数据

# 将一个或多个值value插入到key列表的表头(最左边) lpush key value1 [value2 …] # 将一个或多个值value插入到key列表的表尾(最右边) rpush key value1 [value2 …] 复制代码

(2)获取并移除数据

# 移除并返回key列表的头元素 lpop key # 移除并返回key列表的尾元素 rpop key 复制代码

(3)获取数据

# 获取列表key中指定区间内的元素,从左数第start到stop个元素,从0开始 lrange key start stop # 查询第i个元素 lindex key index # list的长度 llen key 复制代码

(4)规定时间内获取并移除数据

# 从key列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待 blpop key1 [key2 ...] timeout # 从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待 brpop key1 [key2 ...] timeout 复制代码

开两个客户端,一个设置15s内获取list1中的值,此时list1位空一直等待(阻塞),在15秒内另一个客户端存入到list1中数据,此时就被获取到。

(5)移除指定数据

# 根据参数count的值,移除列表中与参数value相等的元素。count为移除的数量,value为移除哪个值 lrem key count value 复制代码

2. 常用数据结构3. list的应用场景(1)最新消息的展示

业务场景

解决方案

# 河北日报发了消息,消息id为1 lpush msg:user_id 1 # 央视网发了消息,消息id为2 lpush msg:user_id 2 # 查看最新公众号消息 lrange msg:user_id 0 5 复制代码

四. set(集合)1. set的常用操作(1)添加数据

# 将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略。若key不存在,则创建一个只包含member元素作成员的集合 sadd key member [member ...] 复制代码

(2)获取数据

# 获取集合 key 中的所有成员 smembers key # 获取集合key中元素的数量 scard key # 判断集合key中是否存在member元素 sismember key member # 获取集合key中的count个随机元素,并从集合key中移除 spop key [count] # 获取集合key中的count个随机元素,不从集合key中移除 srandmember key [count] 复制代码

(3)删除数据

# 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略 srem key member [member ...] 复制代码

2. set的运算操作(1)交集

返回一个集合的全部成员,该集合是所有给定集合的交集。 sinter key

代码示例:

redis> smembers group_1 1) "LI LEI" 2) "TOM" 3) "JACK" redis> smembers group_2 1) "HAN MEIMEI" 2) "JACK" redis> sinter group_1 group_2 1) "JACK" 复制代码

将交集结果保存到destination集合,如果destination集合已经存在,则将其覆盖。destination可以是key本身。 sinterstore destination key [key …]

代码示例:

redis> smembers songs 1) "good bye joe" 2) "hello,peter" redis> smembers my_songs 1) "good bye joe" 2) "falling" redis> sintrestore song_interset songs my_songs (integer) 1 redis> smembers song_interset 1) "good bye joe" 复制代码

(2)并集

返回一个集合的全部成员,该集合是所有给定集合的并集。 sunion key [key ...]

代码示例:

redis> smembers songs 1) "Billie Jean" redis> smembers my_songs 1) "Believe Me" redis> sunion songs my_songs 1) "Billie Jean" 2) "Believe Me" 复制代码

将并集结果保存到destination集合,如果destination集合已经存在,则将其覆盖。destination可以是key本身。 sunionstore destination key [key …]

代码示例:

redis> smembers NoSQL 1) "MongoDB" 2) "Redis" redis> smembers SQL 1) "sqlite" 2) "MySQL" redis> sunionstore db NoSQL SQL (integer) 4 redis> smembers db 1) "MySQL" 2) "sqlite" 3) "MongoDB" 4) "Redis" 复制代码

(3)差集

返回一个集合的全部成员,该集合是所有给定集合之间的差集。 sdiff key [key ...]

代码示例:

redis> smembers peters_movies 1) "bet man" 2) "start war" 3) "2012" redis> smembers joes_movies 1) "hi, lady" 2) "Fast Five" 3) "2012" redis> sdiff peters_movies joes_movies 1) "bet man" 2) "start war" 复制代码

将差集结果保存到destination集合,如果destination集合已经存在,则将其覆盖。destination可以是key本身。 sdiffstore destination key [key …]

代码示例:

redis> smembers joes_movies 1) "hi, lady" 2) "Fast Five" 3) "2012" redis> smembers peters_movies 1) "bet man" 2) "start war" 3) "2012" redis> sdiffstore joe_diff_peter joes_movies peters_movies (integer) 2 redis> smembers joe_diff_peter 1) "hi, lady" 2) "Fast Five" 复制代码

3. set的应用场景(1)微信抽奖小程序

基础的数据结构(五种基础数据结构及应用场景)(10)

  1. 点击参加抽奖加入set集合

sadd key {user_id} 复制代码

  1. 查看参与抽奖所有用户

smembers key 复制代码

  1. 抽取count名中奖者

srandmember key [count] / spop key [count] 复制代码

(2)随机推荐

redis应用于随机推荐类信息检索,例如热点歌单推荐,热点新闻推荐,热点旅游线路,应用APP推荐,大V推荐等。

业务场景:

每位用户首次使用进入头条时候会设置3项爱好的内容,但是后期为了增加用户的活跃度,兴趣点,必须让用户对其他信息类别逐渐产生兴趣,增加客户留存度,如何实现?

业务分析:解决方案:

srandmember key [count] 复制代码

spop key 复制代码

(3)共同好友

# 我关注的人 redis> smembers mySet 1) "zhuge" 2) "yangguo" 3) "sima" # 杨过关注的人 redis> smembers yangguoSet 1) "zhuge" 2) "sima" 3) "luban" 4) "guojia" # 司马关注的人 redis> smembers simaSet 1) "zhuge" 2) "yangguo" 3) "guojia" 4) "luban" 5) "xunyu" 复制代码

# 我和杨过共同关注 redis> sinter yangguoSet mySet 1) "zhuge" 2) "sima" 复制代码

# 我关注的人也关注杨过 redis> sismember simaSet yangguo (integer) 1 复制代码

redis> sdiff mySet yangguoSet 1) "luban" 2) "guojia" 复制代码

(4)访问量统计去重

公司对旗下新的网站做推广,统计网站的PV (访问量),UV (独立访客),IP (独立IP)。

解决方案:

针对不同的统计类型有不同的数据存储方式:

(5)黑白名单黑名单:

资讯类信息类网站追求高访问量,但是由于其信息的价值,往往容易被不法分子利用,通过爬虫技术,快速获取信息,个别特种行业网站信息通过爬虫获取分析后,可以转换成商业机密进行出售。例如第三方火车票、机票、酒店刷票代购软件、电商刷评论、刷好评。 同时爬虫带来的伪流量也会给经营者带来错觉,产生错误的决策,有效避免网站被爬虫反复爬取成为每个网站都要考虑的基本问题。在基于技术层面区分出爬虫用户后,需要将此类用户进行有效的屏蔽,这就是黑名单的典型应用。 ps:不是说爬虫一定做摧毁性的工作,有些小型网站需要爬虫为其带来一些流量。

白名单:

对于安全性更高的应用访问,仅仅靠黑名单是不能解决安全问题的,此时需要设定可访问的用户群体,依赖白名单做更为苛刻的访问验证。

解决方案:五. sorted_set(有序集合)1. sorted_set的常用操作(1)添加数据

# 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。 zadd key score member [[score member] [score member] …] 复制代码

(2)获取数据

# 获取有序集 key 中,成员 member 的 score 值 zscore key member # 获取有序集 key 的成员的数量。 zcard key # 获取有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。 zcount key min max 复制代码

# 正序(从小到大)获取有序集 key 中,指定区间内[start到stop]的成员。 zrange key start stop [WITHSCORES] # 倒序(从大到小)获取有序集 key 中,指定区间内[start到stop]的成员。 zrevrange key start stop [WITHSCORES] 复制代码

(3)删除数据

# 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。 zrem key member [member …] 复制代码

# 移除有序集 key 中,指定排名(rank)区间内的所有成员。 zremrangebyrank key start stop # 移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。 zremrangebyscore key min max 复制代码

示例:

redis> ZADD salary 2000 jack (integer) 1 redis> ZADD salary 5000 tom (integer) 1 redis> ZADD salary 3500 peter (integer) 1 redis> ZREMRANGEBYRANK salary 0 1 # 移除下标 0 至 1 区间内的成员 (integer) 2 redis> ZRANGE salary 0 -1 WITHSCORES # 有序集只剩下一个成员 1) "tom" 2) "5000" 复制代码

redis> ZRANGE salary 0 -1 WITHSCORES # 显示有序集内所有成员及其 score 值 1) "tom" 2) "2000" 3) "peter" 4) "3500" 5) "jack" 6) "5000" redis> ZREMRANGEBYSCORE salary 1500 3500 # 移除所有薪水在 1500 到 3500 内的员工 (integer) 2 redis> ZRANGE salary 0 -1 WITHSCORES # 剩下的有序集成员 1) "jack" 2) "5000" 复制代码

(4)原子操作

# 为有序集 key 的成员 member 的 score 值加上增量 increment 。 zincrby key increment member 复制代码

示例:

redis> ZSCORE salary tom "2000" redis> ZINCRBY salary 2000 tom # tom 加薪啦! "4000" 复制代码

2. sorted_set集合操作(1)并集

# 计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。 zunionstore destination numkeys key [key …] 复制代码

示例:

redis> ZRANGE programmer 0 -1 WITHSCORES 1) "peter" 2) "2000" 3) "jack" 4) "3500" 5) "tom" 6) "5000" redis> ZRANGE manager 0 -1 WITHSCORES 1) "herry" 2) "2000" 3) "mary" 4) "3500" 5) "bob" 6) "4000" redis> ZUNIONSTORE salary 2 programmer manager WEIGHTS 1 3 # 公司决定加薪。。。除了程序员。。。 (integer) 6 redis> ZRANGE salary 0 -1 WITHSCORES 1) "peter" 2) "2000" 3) "jack" 4) "3500" 5) "tom" 6) "5000" 7) "herry" 8) "6000" 9) "mary" 10) "10500" 11) "bob" 12) "12000" 复制代码

(2)交集

# 计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。 zinterstore destination numkeys key [key …] 复制代码

示例:

redis > ZADD mid_test 70 "Li Lei" (integer) 1 redis > ZADD mid_test 70 "Han Meimei" (integer) 1 redis > ZADD mid_test 99.5 "Tom" (integer) 1 redis > ZADD fin_test 88 "Li Lei" (integer) 1 redis > ZADD fin_test 75 "Han Meimei" (integer) 1 redis > ZADD fin_test 99.5 "Tom" (integer) 1 redis > ZINTERSTORE sum_point 2 mid_test fin_test (integer) 3 redis > ZRANGE sum_point 0 -1 WITHSCORES # 显示有序集内所有成员及其 score 值 1) "Han Meimei" 2) "145" 3) "Li Lei" 4) "158" 5) "Tom" 6) "199" 复制代码

3. sorted_set应用场景(1)排行榜

基础的数据结构(五种基础数据结构及应用场景)(11)

解决方案:

zincrby hotNews:20210104 1 特朗普通话语音曝光 复制代码

zrevrange hotNews:20210104 0 9 WITHSCORES 复制代码

zunionstore hotNews:20210104-2021010110 7 hotNews:20210104 hotNews:20210105 ... hotNews:20210110 复制代码

zrevrange hotNews:20210104-2021010110 0 9 WITHSCORES 复制代码

(2)会员短期体验之过期失效

基础服务 增值服务类网站会设定各位会员的试用,让用户充分体验会员优势。例如观影试用VIP、游戏VIP体验、云盘下载体验VIP、数据查看体验VIP,当VIP体验到期后,如何有效管理此类信息。即便对于正式VIP用户也存在对应的管理方式。 网站会定期开启投票、讨论,限时进行,逾期作废。如何有效管理此类过期信息。

解决方案:,