一、set类型
- 与list列表类型比较
redis集合(set)类型和list列表类型类似,都可以用来存储多个字符串元素的集合。但是和list不同的是set集合当中不允许重复的元素。而且set集合当中元素是没有顺序的,不存在元素下标。 - 特点
redis的set类型是使用哈希表构造的,因此复杂度是O(1),它支持集合内的增删改查,并且支持多个集合间的交集、并集、差集操作。可以利用这些集合操作,解决程序开发过程当中很多数据集合间的问题。 - 内部编码有两种
1)inset(整数集合):当集合元素个数小于set-max-ziplist-entries配置(默认512个),redis会使用intset作为集合的内部实现来减少内存的使用。注意:只针对集合内元素都为整数的情况,只要出现非整数元素则会采用hashtable。
2)Hashtable(哈希表):当集合类型无法满足intset的条件时(集合元素中存在非整数元素或者整数元素个数超过set-max-ziplist-entries配置(默认512个)),redis会使用hashtable作为集合的内部实现;
127.0.0.1:6379> sadd num 1 2 3 4 5 #创建整数集合
(integer) 5
127.0.0.1:6379> object encoding num
"intset"
127.0.0.1:6379> sadd num a #在整数集合中加入非整数元素
(integer) 1
127.0.0.1:6379> object encoding num
"hashtable"
127.0.0.1:6379> sadd string aa #创建非整数集合
(integer) 1
127.0.0.1:6379> object encoding string
"hashtable"
二、set类型的应用场景
1、 抽奖
- srandmember、spop 这两个命令功能非常相似,都是从集合中返回一个元素值。
不同点:srandmember不会从集合中删除返回的元素,但是spop会删除。 这两个命令可以分别实现不同的抽奖算法。 - 例如:
集合中有100个元素,值从数字1到数字100.我们定义抽到的是数字1的话,即表示中奖。
使用srandmember的话,不管之前抽过多少次,下次抽中的概率都是1%。
使用spop的话,则每次抽中的概率都不一样。第一个人抽中概率是1%,当第一个人没抽中的话,第二个人抽中概率就是1/99,以此类推。
2、商品筛选
127.0.0.1:6379> sadd muster1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd muster 3 4 8 9 7 6
(integer) 6
127.0.0.1:6379> sadd muster3 1 2 3 4 8 9 7 6
(integer) 8
127.0.0.1:6379> sdiff muster muster1 #获得两个集合的差集
1) "6"
2) "7"
3) "8"
4) "9"
127.0.0.1:6379> sdiff muster muster1 muster3#获得三个集合的差集
(empty array)
127.0.0.1:6379> sinter muster muster1 muster3#获得三个集合的交集
1) "3"
2) "4"
127.0.0.1:6379> sunion muster muster1 muster3#获得三个集合的并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
9) "9"
#########获取交集、并集、差集并赋值给指定的key
127.0.0.1:6379> sinterstore newMuster muster muster1
(integer) 2
127.0.0.1:6379> smembers newMuster
1) "3"
2) "4"
127.0.0.1:6379> sunionstore newMuster1 muster1 muster
(integer) 9
127.0.0.1:6379> smembers newMuster1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
9) "9"
127.0.0.1:6379> sdiffstore newMuster2 muster muster1
(integer) 4
127.0.0.1:6379> smembers newMuster2
1) "6"
2) "7"
3) "8"
4) "9"
三、慢查询
- 许多存储系统(例如MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阈值,就将这条命令的相关信息(例如:发生时间、耗时、命令的详细信息)记录下来,Redis也提供了类似的功能。
- slowlog-log-slower-than:指定执行时间超过多少微秒(1秒等于
127.0.0.1:6379> config set slowlog-log-slower-than 0 #设置执行时间大于0微秒的会被记录
OK
127.0.0.1:6379> config set slowlog-max-len 10 #慢日志记录条数为10条
OK
127.0.0.1:6379> sdiffstore newMuster2 muster muster1
(integer) 4
127.0.0.1:6379> slowlog get #查询慢日志
1) 1) (integer) 3 #标识
2) (integer) 1609769029 #命令执行时的时间戳
3) (integer) 11 #运行的时间
4) 1) "sdiffstore" #执行的命令
2) "newMuster2"
3) "muster"
4) "muster1"
5) "127.0.0.1:44500"
6) ""
四、管道(pipeline)
- redis的客户端和服务器之间是通过TCP协议连接的,不论是客户端向redis发送命令还是客户端接收redis的执行结果,都需要网络通信,都需要一定时间,由于网络性能的不同往返时间也不同,大致的来说这个时间相当于redis处理一条简单命令(比如插入一个值到链表)的时间。如果我们执行较多的命令,一来一回,这个往返时间累加起来还是对性能有一定影响的。
- 由于redis是单线程,所以在执行多个命令时,都需要等待上一条命令执行完,才能执行下一条命令。因此,redis底层通信协议提供了对管道技术的支持。通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖于之前命令的执行结果时就可以将这组命令一起通过管道发出。管道通过减少客户端与Redis的通信次数来实现降低往返时延累计值的目的。