String
单值缓存
- set key value
- get key
对象缓存
- set user:1001 value(json格式数据)
- mset user:1001:name zhangsan user:1001:age 20
- mget user:1001:name mget user:1001:age
分布式锁
- setnx product:1001 lock //返回1代表加锁成功 0表示失败
- del product 1001 //完成业务逻辑之后一定要释放锁
- set product:1001 lock ex 10 nx //设置超时时间,防止意外导致死锁
应用场景
计数器
- incr article:readcount:{文章id}
- get article:readcount:{文章id}
web集群分布式共享session
- spring session + redis实现session共享
分布式系统全局序列号
- incrby orderId 1000 //redis批量生产序列号 提升性能
Hash
存储结构图
user为key,1:name 为 filed 张三 为value
在实现结构上同java的hashmap相同,都是数组+链表的结构,并会将产生hash碰撞的元素用链表连接起来。
不同的是,rehash时,redis为了提升性能,同时不能阻塞服务,采用了渐进式rehash的策略。
渐进性rehash:
在rehash的同时,保留新旧两个hash结构,查询时会同时查询两个hash结构,然后再后续的定时任务以及hash操作指令中,循序渐进地将旧hash的内容一点点地迁移到新的hash结构中。搬迁完毕之后,新的会取而代之,该数据结构被自动清楚,回收内存。1
常用命令
- hset key filed value //存储一个哈希表key的键值
- hsetnx key field value //存储一个不存在的哈希表key的键值
- hmset key field value [field value …] //在一个哈希表key中存储多个键值对
- hget key field //获取key对应filed的键值
- hmget key field [field…] //批量获取key对应filed的键值
- hdel key field [field …] //删除key中的多个filed
- hlen key //返回哈希表中key的数量
- hgetAll key //返回哈希表key中的所有键值
- hincrby key field increment //为哈希表key中field键的值加上增量increment
应用场景
对象缓存
- hmset user {userId}:name zhangsan {userId}:age 24
- hmget user {userId}:name {userId}:age
电商购物车
- 以用户id为key
- 商品id为field
- 商品数量为value
购物车操作
- 添加商品:hset cart:1001 100088 1
- 增加数量:hincrby cart:1001 100088 1
- 商品总数:hlen cart:1001
- 删除商品:hdel cart:1001 100088
- 获取购物车中所有商品:hgetall cart:1001
优缺点
- 优点:
- 同类数据归类整合存储,方便数据管理
- 相比string操作消耗内存与cpu更小
- 相比string存储更节省空间
- 缺点:
- 过期功能不能使用在field上,只能用在key上
- redis集群架构下不适合大规模使用
List
常用命令(有左边操作的就有对应右边操作的)
- lpush key value [value…] //将一个或多个值添加到list的表头(每次添加都是插入到最左边)
- lpushx key value //如果该List存在就将value插入最左边
- lpop key //移除list表头的元素,并返回
- blpop key [key…] timeout //从key列表的表头取出一个元素,如果为空,则一直阻塞等到超时timeout,如果timeout为0则无限等待(阻塞但不影响redis服务端处理其他命令)
- llen key //返回list中的元素个数
- lindex key index //返回一个指定索引位置的元素
- linsert key before | after pivot value //插入一个元素 在另一个元素(遇到的第一个指定元素pivot)的之前或之后
- lrange key start stop //返回列表中指定区间内的元素
应用场景
常用的数据结构
- stack = lpush+lpop
- queue = lpush + rpop
- blocking mq(阻塞队列)= lpush +brpop
微博和微信公众号消息流
- 一个订阅的问题,比如微博关注了一个大V或者微信上关注一个公众号。当大V或者公众号发出动态的时候可以使用list,让订阅者获取消息
- 场景结构
- 每个用户拥有两个list,一个是自己的动态推送list,另一个是自己的关注动态推送List
- 消息获取方式
-
方式一:订阅者主动获取关注者的推送list
我关注了局座和LOL赛事。那么当我去查看关注列表动态时,主动的去从我订阅的用户的动态list中获取推送信息。但是,这里应该有一个中间缓存,完成这些推送信息的时间排序。
-
方式二:关注者主动将消息push到订阅者的关注list中
这样做的好处是不必再进行一次时间排序,但是缺点是,如果自己的关注者很多,那么这样就会造成很大的开销。而方式一更加适合这种关注者多的用户场景,因为同一时间并非所有关注者都要进行消息的获取,减轻压力。
-
set
常用操作
- sadd key member [ member…] //往集合key中存入元素,元素存在即忽略
- srem key member [ member…] //删除集合key中的元素
- smembers key //获取集合key中所有元素
- scard key //获取集合key中元素个数
- sismember key member //判断元素是否存在集合中
- srandmember key [count] //从集合中取出count个数的元素,随机的,并不会删除
- spop key [count] //随机删除count个数的元素,并将删除元素返回
运算操作 - sinter key [key…] //交集运算
- sinterstore destination key [key …] //将交集运算结果存入新集合destination中(如果集合destination已经存在,则会清空后再将结果存入)
- sunion key [key …] //并集运算
- sunionstore destination key [key …] //并集结果存入destination中
- sdiff key [key …] //差集运算
- sdiffstore destination key [key …] //差集结果存入destination中
应用场景
微信抽奖小程序
- 点击参与抽奖,加入到集合中 sadd key {userId}
- 查看参与抽奖的所有用户 smembers key
- 抽取count名中奖者 srandmember key [count] /spop key [count]
朋友圈点赞、收藏、标签
- 点赞 sadd like:{消息id} {用户id}
- 取消点赞 srem like:{消息id} {用户id}
- 检查用户是否点过赞 sismember like:{消息id} {用户id}
- 获取点赞的用户列表 smembers like:{消息id}
- 获取点赞用户数 scard like:{消息id}
集合操作实现微博微信关注模型
- 关羽关注的人: 关羽Set->{赵云、曹操、吕布、黄忠}
- 赵云关注的人: 赵云Set ->{黄忠、吕布、张飞、关羽}
- 曹操关注的人:曹操Set -> {小乔、大乔、赵云、关羽}
- 关羽和赵云共同关注的人:sinter 关羽Set 赵云Set ->{吕布、黄忠}
- 关羽关注的人也关注赵云:sismember 曹操Set 赵云
- 关羽可能认识的人:sdiff 曹操Set 关羽Set -> {小乔、大乔}
集合操作实现电商商品筛选
zset
常用操作
- zadd key score member [[score member ]… ] //往有序集合中添加带分值的元素
- zrem key member [member …] //从有序集合中删除元素
- zscore key member //返回member分值
- zincrby key increment member //为member的分值加上 increment
- zcard key //返回元素个数
- zrange key start stop [withscores] //正序获取集合中从start到stop的元素
- zrevrange key start stop [withscores] //倒序获取集合中从start到stop的元素
集合操作 - zunionstore destkey numkeys key [key …] //并集计算
- zinterstore destkey numkeys key [key …] //交集计算