目录
Redis常用五大数据类型有哪些应用场景?
Redis 在互联网产品中使用的场景实在是太多太多,这里分别对 Redis 几种数据类型做了整理:
1)String:缓存、限流、分布式锁、计数器(点赞数,阅读数等)、分布式 Session 等。
2)Hash:用户信息、用户主页访问量、组合查询等。
3)List:简单队列、关注列表时间轴。
4)Set:赞、踩、标签等。
5)ZSet:排行榜、好友关系链表。
Redis数据类型-String字符串:
总结:
应用场景:
Redis字符串:
一次设置多个kv键值对:
mset k-v k-v k-v
一次获取多个key对应的value:
mget k1 k2
msetnx k1-v1 k2-v2
getrange key start end :
类似于get ,根据key获取对应的value值,只不过值被截取了,从start 到 end
setrange key offset value :相当于覆盖value值到旧的value值,从offset位置开始
expires:过期时间的意思;
Redis数据类型-List单键多值:
总结:
常用的场景是:
- 微博关注列表按照好友的关注顺序显示,微信消息的显示列表按照消息到达的先后顺序进行显示
- 可以使用List的栈模型,完成上述两个功能,新来的数据在最上面(栈顶)显示
- 栈模型用来解决最新消息问题
- 企业中多台服务器的日志打印顺序
- 可以使用List的队列模型,多个服务器按照日志的输出顺序同时记录到队列中
- 队列模型用来解决多路信息归并的问题
注意:使用list集合的话,不再是set命令了,而是push
List(列表)
①lpush(左插入)、lrange(查询集合)、rpush(右插入)操作
②lpop(左移除)、rpop(右移除)操作
③lindex(查询指定下标元素)、llen(获取集合长度) 操作
④lrem key count value(从左边删除count 个value)
⑥ltrim(截取元素)、rpoplpush(移除指定集合中最后一个元素到一个新的集合中)操作
⑦lset(更新)、linsert操作
范围:0 到 -1 是查询集合中所有元素:
Redis数据类型-Set单键多值:
这里的set和java中的set一样,与去重效果。
总结:
Set类型:
- Set类型主要用于数据不能重复,以及需要获取多个数据源交集、并集的场景
- 比如点赞用户、所有粉丝可以存储在Set中,这些用户不能重复
- 还可以使用Set实现共同关注、共同好友等交集、并集功能
微信抽奖小程序:
集合运算的应用:
Redis数据类型-Hash:
小总结:
购物车
使用Hash类型可以完成购物车的添加、浏览、更改数量、删除、清空等操作,如下图所示:
redis中的hash本质:Map<String,map<k,v> >
Redis数据类型-Zset:
总结:
有序集合 Zset 的底层实现?
zset 是 Redis 中一个非常重要的数据结构,其底层是基于跳表(skip list) 实现的。
跳表是一种随机化的数据结构,基于并联的链表,实现简单,插入、删除、查找的复杂度均为 O(logN)。简单说来跳表也是链表的一种,只不过它在链表的基础上增加了跳跃功能,正是这个跳跃的功能,使得在查找元素时,跳表能够提供 O(logN) 的时间复杂度。
跳表为了避免每次插入或删除带来的额外操作,不要求上下相邻两层链表之间的节点个数有严格的对应关系,而是为每个节点随机出一个层数(level)。而且新插入一个节点不会影响其它节点的层数。因此,插入操作只需要修改插入节点前后的指针,而不需要对很多节点都进行调整。
Redis配置文件:
Redis发布订阅:
subscribe chat1 # 订阅频道
publish chat1 "hell0 ni hao" # 发布消息
pubsub channels # 查看频道
pubsub numsub chat1 # 查看某个频道的订阅者数量
unsubscrible chat1 # 退订指定频道 或 punsubscribe java.*
psubscribe java.* # 订阅一组频道
Redis6新数据类型:
bitop:
创建maven工程:
关闭linux防火墙:
key不能重复:
五种类型分别对于哪种实现?
字符串(String)
字符串对象的 encoding 有三种,分别是:int、raw、embstr。
1)如果一个字符串对象保存的是整数值,并且这个整数值可以用 long 类型标识,那么字符串对象会讲整数值保存在 ptr 属性中,并将 encoding 设置为 int。比如 set number 10086 命令。
2)如果字符串对象保存的是一个字符串值,并且这个字符串的长度大于 44 字节,那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值,并将对象的编码设置为 raw。
3)如果字符串对象保存的是一个字符串值,并且这个字符串的长度小于等于 44 字节,那么字符串对象将使用 embstr 编码的方式来保存这个字符串。
embstr 的编码方式的一些优点:
embstr 存储形式是这样一种存储形式,它将 RedisObject 对象头和 SDS 对象连续存在一起,使用 malloc 方法一次分配。embstr 最小占用空间为 19(16+3),而 64-19-1(结尾的\0)=44,所以 embstr 只能容纳 44 字节。
1)embstr 编码将创建字符串对象所需的内存分配次数从 raw 编码的两次降低为一次。
2)释放 embstr 编码的字符串对象只需要调用一次内存释放函数,而释放 raw 编码的字符串对象需要调用两次内存释放函数。
3)因为 embstr 编码的字符串对象的所有数据都保存在一块连续的内存里面,所以这种编码的字符串对象比起 raw ,编码的字符串对象能够更好地利用缓存带来的优势。
哈希对象(hash)
哈希对象的编码有 ziplist 和 hashtable 两种。当哈希对象保存的键值对数量小于 512,并且所有键值对的长度都小于 64 字节时,使用压缩列表存储;否则使用 hashtable 存储。
列表对象(list)
列表对象的编码有 ziplist 和 linkedlist 两种。当列表的长度小于 512,并且所有元素的长度都小于 64 字节时,使用压缩列表存储,否则使用 linkedlist 存储。
集合对象(set)
列表对象的编码有 intset 和 hashtable 两种。当集合的长度小于 512,并且所有元素都是整数时,使用整数集合存储;否则使用 hashtable 存储。
有序集合对象(sort set)
有序集合对象的编码有 ziplist 和 skiplist 两种。当有序集合的长度小于 128,并且所有元素的长度都小于 64 字节时,使用压缩列表存储;否则使用 skiplist 存储。
intset(整数集合)和 ziplist(压缩列表)主要是为节省内存而设计的内存结构,它的优点就是节省内存,但缺点就是比其他结构要消耗更多的时间,所以 Redis 在数据量小的时候使用整数集合存储。