本文已参加「新人创作礼」活动, 一同敞开创作之路。

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

【Redis】五种基础数据结构及应用场景

一. 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

【Redis】五种基础数据结构及应用场景

(4) 原子操作

假设 value 值是一个整数,还能够对它进行自增操作。自增是有规模的,它的规模是 signed long 的最大最小值,超过了这个值,Redis 会报错

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

【Redis】五种基础数据结构及应用场景

2. string的运用场景

Redis运用场景:惯例key-value缓存运用、惯例计数:微信大众号阅览次数,粉丝数等、分布式锁等

(1)单值缓存

 set key value
 get key

(2)目标缓存

【Redis】五种基础数据结构及应用场景

set user:1 value(json格局数据)
mset user:1:name zhuge user:1:balance 1888
mget user:1:name user:1:balance

(3)计数器

【Redis】五种基础数据结构及应用场景

incr article:readcount:{文章id}
get article:readcount:{文章id}

(4)分布式锁

(5)web集群session同享

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

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

redis批量生成序列号进步性能

二. hash (哈希)

String类型 存储的困惑

  • 目标类数据的存储假设具有较为频频的更新需求,操作会显得笨重,存简单,改费事。
  • 为了差异与Redis中的键值对的称号,hash中的键成为field,而key特指Redis的键。

【Redis】五种基础数据结构及应用场景

hash类型

  • 新的存储需求:对一系列存储的数据进行编组,方便办理,典型运用存储目标信息
  • 需求的内存结构:一个存储空间保存多少个键值对数据
  • hash类型:底层运用哈希表结构完成数据存储,相当于 Java 语言里面的 HashMap,它是无序字典。内部完成结构上同 Java 的HashMap 也是一起的,相同的数组 + 链表二维结构。第一维 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)目标缓存

【Redis】五种基础数据结构及应用场景

hmset user {userId}:name value {userId}:balance value
hmset user {1}:name zhuge {1}:balance 1888

(2)购物车

  • 事务场景:电商网站购物车的设计与完成。

【Redis】五种基础数据结构及应用场景

  • 处理方案:
  • 以客户id作为key,每位用户创立一个hash存储结构存储对应的购物车信息。
  • 将产品编号作为field,购买数量作为value进行存储。
  • 增加产品:追加全新的field与value。 hset cart:101 1001 1
  • 阅读:遍历hash。 hgetall cart:101
  • 更改数量:自增/自减,设置value值。 hincrby cart:101 1001 1
  • 删去产品:删去field。 hdel cart:101 1001
  • 清空:删去key。

3. hash的优缺陷

  • 优点
  1. 同类数据归类整合贮存,方便数据办理。
  2. 比较string操作耗费内存与cpu更小。
  3. 比较string贮存更节省空间。
  • 缺陷
  1. 过期功能不能运用在field上,只能用在key上。
  2. Redis集群架构下不适合大规模运用。

redis集群架构

【Redis】五种基础数据结构及应用场景

三. List(列表)

  • 数据存储需求:存储多个数据,并对数据进入存储空间的次序进行区分
  • 需求的存储数据:一个存储空间保存多个数据,且经过数据能够体现进入次序
  • list类型:保存多个数据,底层运用双向链表存储结构完成
    【Redis】五种基础数据结构及应用场景

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. 常用数据结构

  • Stack(栈) = lpush + lpop → filo
  • Queue(行列) = lpush + rpop
  • Blocking MQ(堵塞行列) = lpush + brpop

3. list的运用场景

(1)最新音讯的展现

事务场景

  • 新浪微博、twitter中个人用于的重视列表需求依照用户的重视次序进行展现,粉丝列表需求将最近重视的粉丝列在前面。

    【Redis】五种基础数据结构及应用场景

  • 大众号、新闻、资讯类网站怎么将最新的新闻或资讯依照发生的事情次序展现。

    【Redis】五种基础数据结构及应用场景

  • 企业运营过程中,体系将发生出很多的运营数据,怎么保障堕胎服务器操作日志的统一次序输出?

处理方案

  • 依靠list的数据具有次序的特征对信息进行办理。
  • 运用行列模型处理多路信息汇总合并的问题。
  • 运用栈模型处理最新音讯的问题。
# 河北日报发了音讯,音讯id为1
lpush msg:user_id 1
# 央视网发了音讯,音讯id为2
lpush msg:user_id 2
# 检查最新大众号音讯
lrange msg:user_id 0 5

四. set(调集)

  • 新的存储需求:存储很多的数据,在查询方面供给更高的效率
  • 需求的存储结构:能够保存很多的数据,高效的内部存储机制,便于查询
  • set类型:与hash存储结构完全相同,仅存储键,不存储值(nil),而且值是不允许重复的。也便是只有键没有值的hash

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)微信抽奖小程序

【Redis】五种基础数据结构及应用场景

  1. 点击参加抽奖参加set调集
sadd key {user_id}
  1. 检查参加抽奖一切用户
smembers key
  1. 抽取count名中奖者
srandmember key [count] / spop key [count]

(2)随机引荐

redis运用于随机引荐类信息检索,例如热门歌单引荐,热门新闻引荐,热门旅行线路,运用APP引荐,大V引荐等。

事务场景:

每位用户初次运用进入头条时候会设置3项爱好的内容,可是后期为了增加用户的活跃度,爱好点,有必要让用户对其他信息类别逐渐发生爱好,增加客户留存度,怎么完成?

事务剖析:

  • 体系剖析出各个分类的最新或最热门信息条目并组织成set调集
  • 随机挑选其间部分信息
  • 合作用户重视信息分类中的热门信息组织展现的全信息调集

处理方案:

  • 随机获取调集中指定数量的数据
srandmember key [count]
  • 随机获取调集中的某个数据并将该数据移出调集
spop key

(3)一起老友

  • 脉脉为了促进用户间的交流,保障事务成单率的进步,需求让每位用户拥有很多的老友,事实上职场新人不具有更多的职场老友,怎么快速为用户堆集更多的老友?
  • 新浪微博为了增加用户热度,进步用户留存性,需求微博用户在重视更多的人,以此取得更多的信息或热门话题,怎么进步用户重视别人的总量?
  • QQ新用户入网年纪越来越低,这些用户的朋友圈交际圈十分小,往往集中在一所校园乃至一个班级中,怎么协助用户快速堆集老友用户带来更多的活跃度?
  • 微信大众号是微信信息流通的渠道之一,增加用户重视的大众号成为进步用户活跃度的一种方法,怎么协助用户堆集更多重视的大众号?
  • 美团外卖为了进步成单量,有必要协助用户挖掘美食需求,怎么引荐给用户最适合自己的美食?
    【Redis】五种基础数据结构及应用场景
    【Redis】五种基础数据结构及应用场景
    处理方案:
# 我重视的人
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)。

  • PV:网站被拜访次数,可经过刷新页面进步拜访量。
  • UV:网站被不同用户拜访的次数,可经过cookie核算拜访量,相同用户切换IP地址,UV不变。
  • IP:网站被不同IP地址拜访的总次数,可经过IP地址核算拜访量,相同IP不同用户拜访,IP不变。

处理方案:

针对不同的核算类型有不同的数据存储方法:

  • 使用set调集的数据去重特征,记载各种拜访数据
  • 树立string类型数据,使用incr核算日拜访量(PV)
  • 树立set模型,记载不同cookie数量(UV)
  • 树立set模型,记载不用IP数量(IP)

(5)是非名单

黑名单:

资讯类信息类网站寻求高拜访量,可是因为其信息的价值,往往简单被不法分子使用,经过爬虫技能,快速获取信息,个别特种行业网站信息经过爬虫获取剖析后,能够转换成商业秘要进行出售。例如第三方火车票、机票、酒店刷票代购软件、电商刷谈论、刷好评。 同时爬虫带来的伪流量也会给运营者带来错觉,发生过错的决议计划,有用防止网站被爬虫反复爬取成为每个网站都要考虑的基本问题。在依据技能层面区分出爬虫用户后,需求将此类用户进行有用的屏蔽,这便是黑名单的典型运用。 ps:不是说爬虫一定做摧毁性的作业,有些小型网站需求爬虫为其带来一些流量。

白名单:

关于安全性更高的运用拜访,仅仅靠黑名单是不能处理安全问题的,此刻需求设定可拜访的用户集体,依靠白名单做更为严苛的拜访验证。

处理方案:

  • 依据运营战略设定问题用户发现、辨别规矩
  • 周期性更新满意规矩的用户黑名单,参加set调集
  • 用户行为信息到达后与黑名单进行比对,承认行为去向
  • 黑名单过滤IP地址:运用于开放游客拜访权限的信息源
  • 黑名单过滤设备信息:运用于限制拜访设备的信息源
  • 黑名单过滤用户:运用于依据拜访权限的信息源

五. sorted_set(有序调集)

  • 新的存储需求:依据排序有利于数据的有用显现,需求供给一种能够依据本身特征进行排序的方法。
  • 需求的存储结构:新的存储模型,能够保存可排序的数据。
  • zset类型:在set的存储结构根底上增加可排序字段。
    【Redis】五种基础数据结构及应用场景

1. sorted_set的常用操作

(1)增加数据

# 将一个或多个 member 元素及其 score 值参加到有序集 key 傍边。
zadd key score member [[score member] [score member] …]
  • 假设某个 member 现已是有序集的成员,那么更新这个 member 的 score 值,并经过从头刺进这个 member元素,来保证该 member 在正确的方位上。
  • score 值能够是整数值或双精度浮点数。
  • 假设 key 不存在,则创立一个空的有序集并履行 ZADD 操作。
  • 当 key 存在但不是有序集类型时,回来一个过错。

(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]
  • 下标参数 start 和 stop 都以 0 为底,也便是说,以 0 表明有序集第一个成员,以 1 表明有序集第二个成员,以此类推。你也能够运用负数下标,以 -1 表明最后一个成员, -2 表明倒数第二个成员,以此类推。
  • 超出规模的下标并不会引起过错。 比如说,当 start 的值比有序集的最大下标还要大,或是 start > stop 时, zrange指令只是简略地回来一个空列表。 另一方面,假设 stop 参数的值比有序集的最大下标还要大,那么 Redis 将 stop 当作最大下标来处理。

(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)排行榜

【Redis】五种基础数据结构及应用场景

处理方案:

  • 点击新闻,点击量 +1
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用户也存在对应的办理方法。 网站会定期敞开投票、评论,限时进行,逾期作废。怎么有用办理此类过期信息。

处理方案:

  • 关于依据时刻线限制的使命处理,将处理时刻记载为score值,使用排序功能区分处理的先后次序
  • 记载下一个要处理的事情,当比照体系时刻发现当然仍后到期后移除redis中的记载,并记载下一个要处理的时刻
  • 当新使命参加时,断定并更新当前下一个要处理的使命时刻
  • 为进步sorted_set的性能,通常将使命依据特征存储成若干个sorted_set.例如1小时内,1天内,年度等,操作时逐渐进步,将行将操作的若干个使命归入到1小时内处理行列中
  • time指令获取当前体系时刻

如有问题或技能交流➕微:JavaBoy_1024