概述

常用 5 种数据类型 string, list, set, hash, zset Redis 核心数据结构和应用_并集

1. string

string 常用操作

set key value
get key

对象缓存

1. set user:1 value(Json 格式化数据)
2. mset user:1:name huawei user1:balance 2000
mget user:1:name user:1balance

分布式锁

setnx product:10001 true        // 返回 1 代表获取锁成功
setnx product:10001 true // 返回 0 代表获取锁失败
.... 执行业务逻辑
del product:10001 // 执行完业务释放锁
set product:10001 true ex 10 nx // 防止意外中断导致最终死锁

计数器

Redis 核心数据结构和应用_并集_02

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

web 集群 session 共享

spring session + redis 实现 session 共享

分布式全局序列号

incrby orderId 1000 // redis 批量生成序列号提升性能 批量生成 ID, 这里有一个步长,通过空间换取时间的概念,来减少和 Redis 的交互,提升新跟那个

字符串常用操作

set key value               // 存入字符串键值对
mset key value [key value] // 批量存储字符串键值对
setnx key value // 存入一个不存在的字符串键值对
get key // 获取一个字符串键值对
mget key [key ..] // 批量获取字符串键值对
del key [key ...] // 删除一个键
expire key seconds // 设置一个键的过期时间(秒)

原子加减

incr key                    // 将 key 中存储的一个数字加1
decr key // 将 key 中存储的一个数字减1
incrby key increment // 将 key 所存储的值加上 increment
decrby key decrement // 将 key 所存储的值减去 increment

2. hash

hash 常用操作

hset key field value                       // 存储一个哈希表 key 的键值
hsetnx key field value // 存储一个不存在的哈希表 key 的键值
hmset key field [field value ... ] // 在一个 哈希表 key 中存储多个键值对
hget key field [field ... ] // 批量获取哈希表 key 中的 field 键值
hdel key field [field ... ] // 删除哈希表中的 field 键值
hlen key // 返回哈希表中 key 的field 的数量
hgetall key // 返回哈希表中 key 所有的键值
hincrby key field increment // 为哈希表 key 中 field 键的值增量 increment
注意:大量的数据存储在一个 key 种,容易存在 BigKey 问题,可以做分段处理

Hash 应用场景

对象缓存

hmset user {userid}:name zhangsan {userid:}:balance 1888
hmset user 1:name zhangsan 1:balance 1888
hmget user 1:name 1:balance

电商购物车

  1. 以用户id 为key
  2. 商品 id 为 field
  3. 商品数量为 value

购物车操作:

  1. 添加商品 hset cart:1001 1088 1
  2. 增加数量 hincrby cart:1001 1088 1
  3. 商品总数 hlen cart:1001
  4. 删除商品 hdel cart:1001 1088
  5. 获取所有展示的商品 hgetall cart:1001

Redis 核心数据结构和应用_常用操作_03

Hash 的优点

  1. 同类数据归整合存储,方便数据管理
  2. 相比 String 操作消耗内存与 CPU 更小
  3. 相比 String 存储更节省空间

Hash 的缺点

  1. 过期功能不能在 field 上, 只能在 Key 上
  2. Redis 集群架构不太适合大规模使用

3. list

List 常用操作

lpush key value [value...]         // 将一个或者多个值value 插入到 key 列表的表头(最左边)
rpush key value [value...] // 将一个或者多个值value 插入到 key 列表的表尾(最右边)
lpop key // 移除并返回 key 列表的头元素
rpop key // 移除并返回 key 列表的尾元素
lrang key srat stop // 返回列表 key 中指定区间内的元素, 区间内的偏移量 startstop 指定
blpop key [key ,,,] timeout // 从 key 列表头弹出一个元素,若列表中没有元素,阻塞等待timeout 秒,如果timeout = 0, 一直阻塞等待
brpop key [key ...] timeout // 从 key 列表尾弹出一个元素,若列表中没有元素,阻塞等待timeout 秒,如果timeout = 0, 一直阻塞等待

使用场景

stack(栈) lpush + lpop = fifo

Queue (队列) lpush + rpop

Blocking MQ (阻塞队列) = LPUSH + BRPOP

微博和微信消息流

张三关注了 36氪 , 汽车之间等公众号 Redis 核心数据结构和应用_Redis_04

  1. 36 氪发推送消息,消息id 1001
lpush msg:{zhangsan id} 1001
  1. 汽车之家推送消息, 消息id 1002
lpush msg:{zhangsan id} 1002
  1. 获取最新消息
lrange msg:{zhangsan id} 0 4

遇到的问题:如果大 V 关注的用户上几千万,那么我们就可以分批次发消息

  1. 先发在线的用户
  2. 再后台分批次发其他用户

4. set

Set 常用操作

sadd key member [member ...]  // 往集合key 中存入数据,如果元素存在则忽略若key 不存在则新建
srem key member [member ...] // 从集合 key 中删除元素
smember key // 获取集合 Key 中所有元素
scard key // 获取集合 key 中的元素个数
simember key member // 判断 member 元素是否存在与集合 key 中
srangmembre key [count] // 从集合中选出 count 个元素。 元素不从 key 中删除
spop key [count] // 从集合 key 中选出 count 个元素, 元素从 key 中删除

Set 运算操作

sinter key [key..]                                  // 交集运算
sinterstore destination key [key ...] // 将交集结果存入新的集合 destination 中
sunion key [key ...] // 并集运算
sunionstore destination key [key ...] // 将并集结果存入新的集合 destination 中
sdiff key [key ...] // 差集运算
sdiffstore destination key [key ...] // 将差集结果存入新集合 destination 中

使用场景

1)微信抽奖功能

  1. 点击参与加入集合
sadd key {userId}
  1. 查看参与抽奖的所有用户
smembers key
  1. 抽取 count 名中间者
srandmember key [count] / spop key [count]
srandmember 抽奖完成后,那么就没有这个用户了
spop 抽奖完成一个这个用户就没有了

2) 微信新浪微博点赞,收藏,标签

Redis 核心数据结构和应用_Redis_05

  1. 点赞
sadd like:{消息id} {用户id}
  1. 取消点赞
srem like:{消息id} {用户id}
  1. 检查用户是否点赞
sismember like:{消息id} {用户id}
  1. 获取点赞的用户列表
smembers like:{消息id}
  1. 获取点赞用户数
scard like:{消息id}

集合操作

sinter set1 set2 set3 -> {c}  //交集
sumion set1 set2 set3 -> {a, b, c, d ,e} // 并集
sdiff set1 set2 set3 -> {a} // 差集, 第一个集合减去后面集合的并集

集合操作实现微博关注模型

Redis 核心数据结构和应用_常用操作_06

  1. 张三关注的人
zhangsan -> {lisi , wangmazi}
  1. 李四关注的人
lisi -> {zhaoliu, wangmazi}
  1. 王麻子关注的人
wangmazi -> {lisi, zhangsan, wangwu}
  1. 张三和李四共同关注的人
sinter zhangsan lisi -> {wangmazi}
  1. 张三罐组的人也关注了李四
sismember zhangsan lisi
sisimember wangmazi lisi
  1. 我可能认识的人
sdiff  lisi zhangsan -> {zhaoliu}

集合操作实现电商商品筛选

Redis 核心数据结构和应用_常用操作_07

sadd brand:huawei P40
sadd brand:xiaomi mi-11
sadd brand:iPhone iphone11
sadd os:android P40 mi-11
sadd cpu:brand:intel P40 mi-11
sadd ram:8G mi-11 iphone11
sinter os:andorid cpu:brand:intel ram:8G -> {P40, mi-11}

5. zset

zset 常用操作

zadd key score member [[score member] ... ]      // 往有序集合 key 中加入代分值元素
zrem key member [member ... ] // 从有序集合 key 中删除元素
zscore key score // 返回有序集合 key 元素 member 的分值
zrange key start stop [withscores] // 正序获取有序集合 key 下标 start 下标到 stop 下标的元素
zrevrages key start stop [withscores] // 倒序获取有序集合 key 从 start 下标到 stop 下标的元素
zset 集合操作
zunionstore destkey numkeys key [key ...] // 并集计算
zunionstore destkey numkeys key [key ...] // 并集计算

热搜推荐

Redis 核心数据结构和应用_并集_08

  1. 点击新闻
zincrby hotnews:20210120 1 中国航天2021开门红
  1. 展示当日排行前 10
zrevrange hotnews:20210120 0 9 withscores
  1. 七日搜索榜单计算
zunionstore hotnews:20210114 - hotnews:20210120  10
  1. 展示七日排行前十
zrevrange hotnews:20210114 - hotnews:20210120  0 9 withscores