目录
一、安装Redis
二、Redis线程与高性能
2.1 Redis是单线程么?
2.2 Redis读写是单线程为何这么快?
2.3 Redis如何处理并发操作命令?
三、核心数据结构实战
3.1 字符串常用操作实战
SET 存入键值对
SETNX
SETEX
MSET 批量存入键值对
MSETNX
DECR 原子减1
DECRBY 原子减
INCR 原子加1
INCRBY 原子加
GET 取值
MGET 批量取值
更多命令连接
3.1.1 字符串应用场景
3.2 Hash常用操作实战
HSET 添加
HSETNX 添加
HMSET 批量添加
HGET 获取元素
HMGET 批量查询
HGETALL 获取所有
HINCRBY 增加整数
HINCRBYFLOAT 添加浮点数
HLEN 查Field数量
HDEL 删除Field
更多命令连接
3.2.1 hash常用应用场景
3.3 List常用操作实战
LSET 指定下标添加元素
LPUSH 将元素插入列表头
RPUSH 将元素插入列表尾
LPOP 取列表头元素
RPOP 取列表尾元素
BLPOP 阻塞式取列表头元素
BRPOP 阻塞式取列表尾元素
更多命令连接
3.3.1 List常用应用场景举例
3.4 SET常用操作实战
SADD 插入集合
SCARD 取元素数量
SPOP 随机移除元素
SREM 移除多个元素
SMEMBERS 取所有成员
SRANDMEMBER 取指定数量元素
SISMEMBER 判断元素是否存在
SUNION 多集合求并集
SUNIONSTORE 多集合求并集(存储)
SINTER 多集合求交集
SINTERSTORE 多集合求取交集(存储)
SDIFF 多集合求取差集
SDIFFSTORE 多集合求取差集(存储)
更多命令连接
3.4.1 集合常用应用场景举例
3.5 SortedSet常用操作实战
ZADD 加入有序集
ZCARD 取成员数量
ZINCRBY 运算
ZRANGE 取区间成员(升序)
ZRANGEBYSCORE 按分值排序取成员
ZRANK 取成员排名
ZREM 移除成员
ZREVRANGE 取区间成员(降序)
ZREVRANK 取成员提名(降序)
ZREVRANGEBYSCORE 取分值成员(逆序)
ZSCORE 取成员的分值
ZUNIONSTORE 合并多个有序集
更多命令连接
3.5.1 SortedSet应用场景举例
3.6 key常用操作实战
在MAC环境。
简单的Docker安装Redis见:安装Redis。
Redis是单线程主要体现在Redis的网络IO和键值对的读写是由一个线程来完成的。但实际Redis并不是单线程,如持久化、数据过期删除和数据同步等是由其它线程来完成的,即Redis是有多个线程的。
Redis的IO多路复用:redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到 文件事件分派器,事件分派器将事件分发给事件处理器。如下图所示:
redis默认的最大连接数为10000,用如下命令查看:
127.0.0.1:6379> config get maxclients
1) "maxclients"
2) "10000"
127.0.0.1:6379>
查看所有配置项可用命令config get *:
*****************% docker exec -it redis redis-cli
127.0.0.1:6379> CONFIG GET *
1) "rdbchecksum"
2) "yes"
3) "daemonize"
4) "no"
5) "io-threads-do-reads"
6) "no"
7) "lua-replicate-commands"
8) "yes"
9) "always-show-logo"
10) "no"
11) "protected-mode"
12) "no"
13) "rdbcompression"
14) "yes"
15) "rdb-del-sync-files"
16) "no"
17) "activerehashing"
18) "yes"
...
更多配置项详见redis.conf和修改redis的配置项信息。
SET key value [EX seconds | PX milliseconds | EXAT timestamp | PXAT milliseconds-timestamp | KEEPTTL ] [NX|XX]
添加字符串键值对。
可选参数。
127.0.0.1:6379> set time '2023-09-14'
OK
127.0.0.1:6379> get time
"2023-09-14"
# 设置过期时间EX 5 单位是秒
127.0.0.1:6379> set time '2023-09-14' EX 5
OK
127.0.0.1:6379> get time
"2023-09-14"
# 过5秒之后time已过期,获取不到
127.0.0.1:6379> get time
(nil)
# 设置过期时间PX 5000 单位是毫秒
127.0.0.1:6379> set time '2023-09-14' PX 5000
OK
127.0.0.1:6379> get time
"2023-09-14"
# 过5000毫秒之后time已过期,获取不到
127.0.0.1:6379> get time
(nil)
127.0.0.1:6379> set time '2023-09-14' NX
OK
# NX:key为time已存在,设置失败
127.0.0.1:6379> set time '2023-09-14' NX
(nil)
# XX:key为time已存在,设置成功
127.0.0.1:6379> set time '2023-09-14' XX
OK
# XX:key为time1不存在,设置失败
127.0.0.1:6379> set time1 '2023-09-14' XX
(nil)
时间复杂度为O(1)。
返回值:
SETNX key value(set if not exists的简写)
将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> setnx name zhangsan
(integer) 0
127.0.0.1:6379> set name zhangxan nx
(nil)
127.0.0.1:6379> get name
"lisi"
时间复杂度为O(1)。
返回值:
SETEX key seconds value
将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。如果 key 已经存在, SETEX 命令将覆写旧值。
该命令相当于以下两条命令 set key value; expire key seconds; 两条命令。
SET key value
EXPIRE key seconds # 设置生存时间
不同的是,SETEX是一个原子操作。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> setex name 10 xxian
OK
127.0.0.1:6379> get name
"xxian"
127.0.0.1:6379> get name
(nil)
时间复杂度为O(1)。
返回值:
MSET key value [key value ...]
批量存储字符串键值对(同时设置一个或多个 key-value 对),如果某个给定 key 已经存在,那么mset会用新值覆盖原来的旧值。
127.0.0.1:6379> mset name 'xxjava' age 25 address '贵州'
OK
127.0.0.1:6379> mget name age address
1) "xxjava"
2) "25"
3) "\xe8\xb4\xb5\xe5\xb7\x9e"
注:mset 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。
时间复杂度为O(N), N 为要设置的 key 数量。
返回值:
MSETNX key value [key value ...]
同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
即使只有一个给定 key 已存在, MSETNX 也会拒绝执行所有给定 key 的设置操作。(MSETNX是原子性)
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> msetnx a 1 b 2 c 3 d 4
(integer) 1
127.0.0.1:6379> mget a b c d
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> msetnx a 1 e 5 f 6 g 7
(integer) 0
# 不成功是因为key为a 的已经厦
时间复杂度O(N),N为KEY的数量。
返回值:
DECR key
将 key 中储存的数字值减一。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set age 100
OK
127.0.0.1:6379> decr age
(integer) 99
127.0.0.1:6379> get age
"99"
# key不存在
127.0.0.1:6379> decr name
(integer) -1
# key不为数字
127.0.0.1:6379> set name 'cxian'
OK
127.0.0.1:6379> decr name
(error) ERR value is not an integer or out of range
时间复杂度为O(1)。
返回值:
DECRBY key decrement
将 key 所储存的值减去减量 decrement 。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set age 100
OK
127.0.0.1:6379> DECRBY age 30
(integer) 70
# key不存在
127.0.0.1:6379> DECRBY name 30
(integer) -30
127.0.0.1:6379> set name 'cxian'
OK
# key不为数字
127.0.0.1:6379> DECRBY name 30
(error) ERR value is not an integer or out of range
127.0.0.1:6379>
时间复杂度为O(1)。
返回值:
INCR key
将 key 中储存的数字值增一。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
# key不存在
127.0.0.1:6379> incr age
(integer) 1
# key存在
127.0.0.1:6379> set age 100
OK
127.0.0.1:6379> incr age
(integer) 101
时间复杂度为O(1)。
返回值:
INCRBY key increment
所DECR相似,不同在于DECRBY是减,而INCRBY是相加。
GET key
返回 key 所关联的字符串值。
127.0.0.1:6379> flushdb
OK
# key不存在
127.0.0.1:6379> get age
(nil)
127.0.0.1:6379> set age '100'
OK
127.0.0.1:6379> get age
"100"
# key对应的值不为字符串get报错
127.0.0.1:6379> lpush fruits apple banana orange
(integer) 3
127.0.0.1:6379> get fruits
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(1)。
返回值:
MGET key [key ...]
依次返回所有(一个或多个)给定 key 的值。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set age 88
OK
127.0.0.1:6379> lpush fruits apple banana orange pear
(integer) 4
# fruits为集合和name不存在,返回nil
127.0.0.1:6379> mget age fruits name
1) "88"
2) (nil)
3) (nil)
时间复杂度O(N),N为key的数量。
返回值:
Redis 字符串操作实战(全)_小贤java的博客-CSDN博客SET存入字符串键值,对如果 key 已经持有其他值, set 就覆写旧值,无视类型。对于某个原本带有生存时间(TTL)的键来说, 当 set 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。时间复杂度为O(1)。SET 成功时才返回OK。SETNX key value(set if not exists的简写):将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。时间复杂度为O(1)。成功返回OK,否则返回nil。https://cxian.blog.csdn.net/article/details/133047878
对象缓存
分布式锁
// 伪代码,对某个项目id为1001的进行加锁
String key = "project:1001";
try {
// 返回1表示取锁成功
if (0 < SETNX key value) {
// TODO 业务逻辑
}
} finally {
// 执行完业务,删除key释放锁
DEL key;
}
// 伪代码,对某个项目id为1001的进行加锁
String key = "project:1001";
try {
// 设置key过期时间为10秒,返回1表示取锁成功
if (0 < (SETNX key value ex 10 nx)) {
// TODO 业务逻辑
}
} finally {
// 执行完业务,删除key释放锁
DEL key;
}
分布式系统全局序序号
统计数量
web集群session共享
HSET key field value
将哈希表 key 中的域 field 的值设为 value。
127.0.0.1:6379> flushdb
OK
# field不存在,hset成功返回 1
127.0.0.1:6379> hset person name 'cxian'
(integer) 1
127.0.0.1:6379> hset person age '22'
(integer) 1
# field已存在并覆盖值,hset成功返回 0
127.0.0.1:6379> hset person age '25'
(integer) 0
127.0.0.1:6379> set name 100
OK
# 对已存在的key执行hset报错
127.0.0.1:6379> hset name high 1.75
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复试度为O(1)。
返回值:
HSETNX key field value
将哈希表 key 中的域 field 的值设置为 value。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hsetnx person age 10
(integer) 1
# age已存在
127.0.0.1:6379> hsetnx person age 12
(integer) 0
时间复杂度O(1)。
返回值:
HMSET key field value [field value ...]
同时将多个 field-value (域-值)对设置到哈希表 key 中。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hmset person age 12 name cxian
OK
127.0.0.1:6379> hmget person age name
1) "12"
2) "cxian"
时间复杂度O(N),N为field-value的数量。
返回值:
HGET key field
返回哈希表 key 中给定域 field 的值。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hset person age 88
(integer) 1
127.0.0.1:6379> hget person age
"88"
# key不存在或field不存在
127.0.0.1:6379> hget person1 age
(nil)
127.0.0.1:6379> hget person age1
(nil)
时间复杂度O(1)。
返回给定域的值。
HMGET key field [field ...]
返回哈希表 key 中,一个或多个给定域的值。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hset person age 88
(integer) 1
127.0.0.1:6379> hget person age
"88"
127.0.0.1:6379> hmget person age name address
1) "88"
2) "cxian"
3) (nil)
# key不存在
127.0.0.1:6379> hmget person1 age name
1) (nil)
2) (nil)
时间复杂度O(N),N为field的数量。
返回值:
HGETALL key
返回哈希表 key 中,所有的域和值。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> hset person age 88
(integer) 1
127.0.0.1:6379> hget person age
"88"
127.0.0.1:6379> hset person name cxian
(integer) 1
127.0.0.1:6379> hgetall person
1) "age" # field
2) "88" # value
3) "name"
4) "cxian"
# key不存在
127.0.0.1:6379> hgetall person1
(empty array)
时间复杂度O(N),N为哈希表的大小。
返回值:
HINCRBY key field increment
为哈希表 key 中的域 field 的值加上增量 increment。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
# key和field不存在
127.0.0.1:6379> hincrby person age 22
(integer) 22
127.0.0.1:6379> hget person age
"22"
# increment为负数
127.0.0.1:6379> hincrby person age -10
(integer) 12
127.0.0.1:6379> hget person age
"12"
127.0.0.1:6379>
127.0.0.1:6379> hset person name cxian
(integer) 1
# field对应值不为数字
127.0.0.1:6379> hincrby person name 12
(error) ERR hash value is not an integer
时间复杂度O(1)。
返回值:
HINCRBYFLOAT key field increment
为哈希表 key 中的域 field 加上浮点数增量 increment 。
127.0.0.1:6379> hincrbyfloat person age 23.8
"35.8"
127.0.0.1:6379> hincrbyfloat person age -8.9
"26.9"
HLEN key
返回哈希表 key 中域的数量。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> hmset person age 23 name cxian
OK
127.0.0.1:6379> hlen person
(integer) 2
时间复杂度O(1)。
返回值:
HDEL key field [field ...]
删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
127.0.0.1:6379> hgetall person
1) "age"
2) "23"
3) "name"
4) "cxian"
127.0.0.1:6379> hdel person age
(integer) 1
# field不存在 或 key不存在
127.0.0.1:6379> hdel person age1
(integer) 0
127.0.0.1:6379> hgetall person
1) "name"
2) "cxian"
时间复杂度O(N),N为field的数量。
返回值:
Redis 哈希表操作实战(全)_小贤java的博客-CSDN博客HMSET key field value [field value ...]:同时将多个 field-value (域-值)对设置到哈希表 key 中。HDEL key field [field ...]:删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。HMGET key field [field ...]:返回哈希表 key 中,一个或多个给定域的值。HGET key field:返回哈希表 key 中给定域 field 的值。HKEYS key:返回哈希表 key 中的所有field。https://cxian.blog.csdn.net/article/details/133076502
对象缓存
比string更好的是hash是一个key
hash有更好的操作
商城购物车
操作
hash与String相比
LSET key index value
将列表 key 下标为 index 的元素的值设置为 value。
127.0.0.1:6379> flushdb
OK
# key不存在
127.0.0.1:6379> lset mylist 0 apple
(error) ERR no such key
# 初始化key 并插入值
127.0.0.1:6379> lpush mylist app
(integer) 1
127.0.0.1:6379> lindex mylist 0
"app"
# 用lset
127.0.0.1:6379> lset mylist 0 apple
OK
127.0.0.1:6379> lindex mylist 0
"apple"
时间复杂度为O(N)
返回值
LPUSH key value [value ...]
将一个或多个值 value 插入到列表 key 的表头。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush mylist apple banana orange pear
(integer) 4
# 重复插入
127.0.0.1:6379> lpush mylist apple banana orange pear
(integer) 8
# 查看列表数据
127.0.0.1:6379> lrange mylist 0 -1
1) "pear"
2) "orange"
3) "banana"
4) "apple"
5) "pear"
6) "orange"
7) "banana"
8) "apple"
时间复杂度为O(1)。
返回值:
RPUSH key value [value ...]
将一个或多个值 value 插入到列表 key 的表尾(最右边)。
LPOP key
移除并返回列表 key 的头元素。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush mylist apple banana orange pear
(integer) 4
127.0.0.1:6379> llen mylist
(integer) 4
127.0.0.1:6379> lpop mylist
"pear"
# 头元素已不存在
127.0.0.1:6379> lrange mylist 0 -1
1) "orange"
2) "banana"
3) "apple"
127.0.0.1:6379> lpop mylist
"orange"
127.0.0.1:6379> lpop mylist
"banana"
127.0.0.1:6379> lpop mylist
"apple"
# 列表为空 或 key不存在时
127.0.0.1:6379> lpop mylist
(nil)
127.0.0.1:6379> lpop mylist1
(nil)
时间复杂度为O(1)。
返回值:
RPOP key
操作与LPOP相似
BLPOP key [key ...] timeout
列表的阻塞式(blocking)弹出原语
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush mylist apple # 初始化列表并添加一个元素
(integer) 1
127.0.0.1:6379> blpop mylist 10
1) "mylist"
2) "apple"
127.0.0.1:6379> blpop mylist 10
(nil)
(10.05s) # 超时秒数,未取出数据退出
127.0.0.1:6379> lpush mylist apple # 添加一个元素
(integer) 1
# 而mylist2不存在 跳过;mylist存在且不为空,紧接着 command 列表的第一个元素被弹
127.0.0.1:6379> blpop mylist2 mylist 10
1) "mylist" # 弹出元素所属的列表
2) "apple" # 弹出元素所属的值
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi # 开启个事务
OK
127.0.0.1:6379(TX)> blpop mylist mylist2 1000 # 对不存在key进行blpop
QUEUED
127.0.0.1:6379(TX)> exec # 提交事务
1) (nil) # 不阻塞立即返回
127.0.0.1:6379> lpush mylist apple # 创建mylist并初始化一个元素
(integer) 1
127.0.0.1:6379> multi # 开启个事务
OK
127.0.0.1:6379(TX)> blpop mylist mylist2 1000 # 对非空列表进行blpop
QUEUED
127.0.0.1:6379(TX)> exec # 提交事务
1) 1) "mylist" # 返回元素所在的列表
2) "apple" # 返回元素
127.0.0.1:6379> multi # 开启个事务
OK
127.0.0.1:6379(TX)> blpop mylist mylist2 1000 # 对空列表进行blpop
QUEUED
127.0.0.1:6379(TX)> exec # 提交事务
1) (nil) # 不阻塞直接返回nil
时间复杂度为o(1)。
返回值:
BRPOP key [key ...] timeout
操作与BLPOP相似
Redis 列表操作实战(全)_小贤java的博客-CSDN博客LTRIM key start stop:只保留指定区间 [start, stop] 内的元素,不在指定区间之内的元素都将被删除。LRANGE key start stop:返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。LPUSHX key value:将值 value 插入到列表 key 的表头,当且仅当 key 存在并且是一个列表。LSET key index value:将列表 key 下标为 index 的元素的值设置为 value。https://cxian.blog.csdn.net/article/details/133062756
栈(Stack)
队列(Queue)
阻塞队列(Block Queue)
LPUSH + BRPOP 实现
SADD key member [member ...]
将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd myset a b c d e f g h i j k l m n # 向key中添加集合元素,key不存在则自动创建空的key集合
(integer) 14
127.0.0.1:6379> set name lisi # 初始化非集合key
OK
127.0.0.1:6379> sadd name zhangsan # 向非集合中执行sadd
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N), N 是被添加的元素的数量。
返回值:
SCARD key
返回集合中的元素数量
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> scard myset2 # 不存在key
(integer) 0
127.0.0.1:6379> sadd myset a b c d e f g h i j k l m n
(integer) 14
127.0.0.1:6379> scard myset # 存在集合key
(integer) 14
127.0.0.1:6379> set name lisi # 初始化非集合key
OK
127.0.0.1:6379> scard name # 对非集合key执行scard命令
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(1)。
返回值:
SPOP key
移除并返回集合中的一个随机元素。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd myset a # 初始化集合
(integer) 1
127.0.0.1:6379> spop myset
"a"
127.0.0.1:6379> spop myset # 集合为空
(nil)
127.0.0.1:6379> spop myset2 # 不存在的key
(nil)
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> spop name # key 不为集合
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(1)。
返回值:
SREM key member [member ...]
移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd myset a b c d e # 初始化集合
(integer) 5
127.0.0.1:6379> srem myset a b c d # 移除 a b c d
(integer) 4
127.0.0.1:6379> srem myset a b c d e
(integer) 1 # 移除 a b c d e,不存在元素忽视了
127.0.0.1:6379> srem myset2 a
(integer) 0 # 移除不存在key似为空集合
127.0.0.1:6379> set name list
OK
127.0.0.1:6379> srem name 1 # key不为集合,报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度为O(N), N 为给定 member 元素的数量。
返回值:
SMEMBERS key
返回集合 key 中的所有成员。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd s1 a b c d e
(integer) 5
127.0.0.1:6379> smembers s1
1) "d"
2) "b"
3) "a"
4) "c"
5) "e"
127.0.0.1:6379> smembers s2
(empty array)
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> smembers name
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N), N 为集合的基数。
返回值:
SRANDMEMBER key [count]
取指定数量count的元素。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd s1 a b c
(integer) 3
127.0.0.1:6379> srandmember s1
"a"
127.0.0.1:6379> srandmember s1 2
1) "a"
2) "b"
127.0.0.1:6379> srandmember s1 5
1) "b"
2) "a"
3) "c"
127.0.0.1:6379> srandmember s1 -5
1) "a"
2) "c"
3) "a"
4) "c"
5) "c"
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> srandmember lisi
(nil)
时间复杂度:
如果提供了 count 参数,那么为 O(N) ,N 为返回数组的元素个数。
返回值:
SISMEMBER key member
判断 member 元素是否集合 key 的成员。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd s1 a b c # 初始化集合
(integer) 3
127.0.0.1:6379> sismember s1 a # 查看是否存在
(integer) 1
127.0.0.1:6379> sismember s1 f
(integer) 0
127.0.0.1:6379> sismember s2 f # 不存在key似为空集合
(integer) 0
127.0.0.1:6379> set name cxian
OK
127.0.0.1:6379> sismember name f # 对非集合key操作,报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(1)。
返回值:
SUNION key [key ...]
返回一个集合的全部成员,该集合是所有给定集合的并集。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd myset a b # 初始化集合
(integer) 2
127.0.0.1:6379> sadd myset2 a b c d # 初始化集合
(integer) 4
127.0.0.1:6379> sunion myset myset2 myset3 # myset3不存在被似为空集合
1) "d"
2) "a"
3) "b"
4) "c"
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> sunion myset name # 有key存在且不为集合,报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N), N 是所有给定集合的成员数量之和。
返回值:
SUNIONSTORE destination key [key ...]
与SUNION操作相似
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd s1 a b # 初始化集合
(integer) 2
127.0.0.1:6379> sadd s2 c
(integer) 1
127.0.0.1:6379> sunionstore dest s1 s2 s3 # 取并集
(integer) 3
127.0.0.1:6379> smembers dest # 查看dest信息
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> set name cxian
OK
127.0.0.1:6379> sunionstore dest s1 s2 s3 name # 有非命令key报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N), N 是所有给定集合的成员数量之和。
返回值:
SINTER key [key ...]
返回所有给定集合的交集。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd s1 a b c d e # 初始化集合
(integer) 5
127.0.0.1:6379> sadd s2 b e f g # 初始化集合
(integer) 4
127.0.0.1:6379> sinter s1 s2 # 取交集
1) "e"
2) "b"
127.0.0.1:6379> sinter s1 s2 s3 # 取交集,有不存在的key似为空集
(empty array)
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> sinter s1 s2 name # 存在不为集合的key报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N * M), N 为给定集合当中基数最小的集合, M 为给定集合的个数。
返回值:
SINTERSTORE destination key [key ...]
跟SINTER操作相似。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd s1 a b d # 初始化集合
(integer) 3
127.0.0.1:6379> sadd s2 d e f # 初始化集合
(integer) 3
127.0.0.1:6379> sinterstore dest s1 s2
(integer) 1
127.0.0.1:6379> smembers dest # 查看集合dest
1) "d"
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> sinterstore dest s1 s2 name # 存在不为集合的key
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N * M), N 为给定集合当中基数最小的集合, M 为给定集合的个数。
返回值:
SDIFF key [key ...]
取给定集合之间的差集。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd myset a b c d e # 初始化几个集合key
(integer) 5
127.0.0.1:6379> sadd myset2 d e
(integer) 2
127.0.0.1:6379> sadd myset3 c d
(integer) 2
127.0.0.1:6379> sdiff myset myset2 myset3 # 取三个集合的差集
1) "b"
2) "a"
127.0.0.1:6379> sdiff myset myset2 myset3 myset4 # 取4个集合的差集,其中一个不存在似为空集合
1) "b"
2) "a"
127.0.0.1:6379> set name lisi # 定义一个非集合key
OK
127.0.0.1:6379> sdiff myset myset2 myset3 myset4 name # 有一个key不为集合
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N), N 是所有给定集合的成员数量之和。
返回值:
SDIFFSTORE destination key [key ...]
与SDIFF操作相拟。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd s1 'baidu' 'google' 'alibaba' 'banana' # 初始化集合
(integer) 4
127.0.0.1:6379> sadd s2 'apple' 'banana' 'orange' # 初始化集合
(integer) 3
127.0.0.1:6379> sdiffstore dest s1 s2 # 求差集并保存到dest中
(integer) 3
127.0.0.1:6379> smembers dest # 查看dest中元素
1) "baidu"
2) "google"
3) "alibaba"
127.0.0.1:6379> set name cxian
OK
127.0.0.1:6379> sdiffstore dest s1 name # 存在不为集合的key报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N), N 是所有给定集合的成员数量之和。
返回值:
Redis 集合操作实战(全)_小贤java的博客-CSDN博客SREM key member [member ...]:移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。SUNION key [key ...]:返回一个集合的全部成员,该集合是所有给定集合的并集。时间复杂度O(N * M), N 为给定集合当中基数最小的集合, M 为给定集合的个数。时间复杂度O(N * M), N 为给定集合当中基数最小的集合, M 为给定集合的个数。时间复杂度O(N), N 是所有给定集合的成员数量之和。https://cxian.blog.csdn.net/article/details/133092126
抽奖活动
CSDN文章点赞收藏(举例假设,不知官方具体实现)
CSDN共同关注可能认识人(举例假设,不知官方具体实现)
简单的搜索等。
ZADD key score member [[score member] [score member] ...]
将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd z1 8 a 1 b 5 c # 对一个不存在的key操作
(integer) 3
127.0.0.1:6379> zadd z1 2 b # 添加已存在的元素
(integer) 0
127.0.0.1:6379> set name cxian
OK
127.0.0.1:6379> zadd name 1 a # 对非有序集key操作,报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂订O(M*log(N)), N 是有序集的基数, M 为成功添加的新成员的数量。
返回值:
ZCARD key
返回有序集 key 的基数。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd z1 8 a 1 b 5 c
(integer) 3
127.0.0.1:6379> zcard z1 # 对非空有序集执行zcard命令
(integer) 3
127.0.0.1:6379> zcard z2 # 对不存在key执行zcard命令
(integer) 0
127.0.0.1:6379> set name cxian
OK
127.0.0.1:6379> zcard name # 对非有序集执行zcard命令
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(1)。
返回值:
ZINCRBY key increment member
为有序集 key 的成员 member 的 score 值加上增量 increment 。
127.0.0.1:6379[9]> flushdb
OK
127.0.0.1:6379[9]> zadd s1 1000 name
(integer) 1
127.0.0.1:6379[9]> zscore s1 name
"1000"
127.0.0.1:6379[9]> zincrby s1 100 name
"1100"
127.0.0.1:6379> set s3 100
OK
127.0.0.1:6379> zincrby s3 1 name
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度为O(log(N))。
返回值:
ZRANGE key start stop [WITHSCORES]
返回有序集 key 中,指定区间内的成员。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd s1 100 member1
(integer) 1
127.0.0.1:6379> zadd s1 200 member2
(integer) 1
127.0.0.1:6379> zrange s1 0 1 # 显示敬意0到1的成员
1) "member1"
2) "member2"
127.0.0.1:6379> zrange s1 0 5 # stop 下标超出最大下标时的情况
1) "member1"
2) "member2"
127.0.0.1:6379> zrange s1 -1 -1 # 负数情况
1) "member2"
127.0.0.1:6379> zrange s1 2 1 # start 大于 end 情况
(empty array)
127.0.0.1:6379> zrange s1 4 5 # start 大于 成员数量情况
(empty array)
127.0.0.1:6379> zrange s1 0 1 withscores # 添加withscores 选项情况
1) "member1"
2) "100"
3) "member2"
4) "200"
127.0.0.1:6379> set name cxian
OK
127.0.0.1:6379> zrange name 0 1 # 对非有序集合执行zrange命令情况
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(log(N)+M), N 为有序集的基数,而 M 为结果集的基数。
返回值:
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。
127.0.0.1:6379[9]> flushdb
OK
127.0.0.1:6379[9]> zadd s1 2500 name1
(integer) 1
127.0.0.1:6379[9]> zadd s1 5000 name2
(integer) 1
127.0.0.1:6379[9]> zadd s1 12000 name3 # 初始化有序集合
(integer) 1
127.0.0.1:6379[9]> zrangebyscore s1 -inf +inf
1) "name1"
2) "name2"
3) "name3"
127.0.0.1:6379[9]> zrangebyscore s1 -inf +inf withscores
1) "name1"
2) "2500"
3) "name2"
4) "5000"
5) "name3"
6) "12000"
127.0.0.1:6379[9]> zrangebyscore s1 -inf 3000 withscores
1) "name1"
2) "2500"
127.0.0.1:6379[9]> zrangebyscore s1 5000 +inf withscores
1) "name2"
2) "5000"
3) "name3"
4) "12000"
127.0.0.1:6379[9]> zrangebyscore s1 8000 +inf withscores
1) "name3"
2) "12000"
127.0.0.1:6379[9]> zrangebyscore s1 8000 +inf
1) "name3"
127.0.0.1:6379[9]> ZRANGEBYSCORE s1 (8000 400000
1) "name3"
时间复杂度O(log(N)+M), N 为有序集的基数, M 为被结果集的基数。
返回值:
ZRANK key member。
返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd s1 5 member1
(integer) 1
127.0.0.1:6379> zadd s1 3 member2
(integer) 1
127.0.0.1:6379> zadd s1 8 member3
(integer) 1
127.0.0.1:6379> zrank s1 member1 # 对有序集执行zrank情况
(integer) 1
127.0.0.1:6379> set s2 cxian
OK
127.0.0.1:6379> zrank s3 member1 # 对不存在key情况
(nil)
127.0.0.1:6379> set s3 beijing # 初始化非有序集合
OK
127.0.0.1:6379> zrank s3 bj # 对非有序集合情况
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(log(N))。
返回值:
ZREM key member [member ...]
移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd s1 5 member1
(integer) 1
127.0.0.1:6379> zadd s1 3 member2
(integer) 1
127.0.0.1:6379> zadd s1 8 member3 # 初始化有序集
(integer) 1
127.0.0.1:6379> zrem s1 member1 member2 # 成员存在情况
(integer) 2
127.0.0.1:6379> zrem s1 member5 # 成员不存在情况
(integer) 0
127.0.0.1:6379> zrem s2 member5 # key不是有序集情况,报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(M*log(N)), N 为有序集的基数, M 为被成功移除的成员的数量。
返回值:
ZREVRANGE key start stop [WITHSCORES]
返回有序集 key 中,指定区间内的成员。
127.0.0.1:6379> zadd grade 65 lining
(integer) 1
127.0.0.1:6379> zadd grade 64 verctor
(integer) 1
127.0.0.1:6379> zadd grade 71 unix # 初始化集合
(integer) 1
127.0.0.1:6379> zrange grade 0 -1 withscores # 查看有序集信息
1) "verctor"
2) "64"
3) "lining"
4) "65"
5) "unix"
6) "71"
127.0.0.1:6379> zrevrange grade 0 -1 withscores # 执行zrevrange命令情况
1) "unix"
2) "71"
3) "lining"
4) "65"
5) "verctor"
6) "64"
127.0.0.1:6379> zrevrange name 0 -1 # 非有序集key执行zrevrange命令情况报错
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(log(N)+M), N 为有序集的基数,而 M 为结果集的基数。
返回值:
ZREVRANK key member
返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。
127.0.0.1:6379> zrange grade 0 -1 # 查看集合信息
1) "verctor"
2) "lining"
3) "unix"
127.0.0.1:6379> zrevrank grade lining # 取lining的排名
(integer) 1
127.0.0.1:6379> zrevrank grade baidu # 成员不存在
(nil)
127.0.0.1:6379> get grade1
(nil)
127.0.0.1:6379> zrevrank grade1 baidu # key不存在
(nil)
127.0.0.1:6379> zrevrank name baidu # key存在且不为有序集合
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(log(N))。
返回值:
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。
127.0.0.1:6379> zrange grade 0 -1 withscores # 查看有序集合信息
1) "verctor"
2) "64"
3) "lining"
4) "65"
5) "unix"
6) "71"
127.0.0.1:6379> zrevrangebyscore grade 90 60 withscores # 执行zrevrangebyscore命令
1) "unix"
2) "71"
3) "lining"
4) "65"
5) "verctor"
6) "64"
时间复杂度O(log(N)+M), N 为有序集的基数, M 为结果集的基数。
返回值:
ZSCORE key member
返回有序集 key 中,成员 member 的 score 值。
127.0.0.1:6379> zrange grade 0 -1
1) "verctor"
2) "lining"
3) "unix"
127.0.0.1:6379> zscore grade lining # 取存在成员的情况
"65"
127.0.0.1:6379> zscore grade lining2 # 取不存在成员的情况
(nil)
127.0.0.1:6379> zscore grade2 lining2 # 取不存在key不存在成员的情况
(nil)
127.0.0.1:6379> set grade3 beijing
OK
127.0.0.1:6379> zscore grade3 lining2 # 取存在key不为有序集全情况
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(1)。
返回值:
语法:ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。
127.0.0.1:6379> zrange grade 0 -1 withscores # 查看有序集成员信息
1) "verctor"
2) "64"
3) "lining"
4) "65"
5) "unix"
6) "71"
127.0.0.1:6379> zrange grade2 0 -1 withscores # 查看有序集成员信息
1) "ll"
2) "30"
3) "un"
4) "35"
5) "vc"
6) "50"
127.0.0.1:6379> zunionstore dest 2 grade grade2 weights 2 2 # 执行zunionstore
(integer) 6
127.0.0.1:6379> zrange dest 0 -1 withscores # 查看 dest 信息
1) "ll"
2) "60" # 分值已乘以2(原数据是30)
3) "un"
4) "70" # 分值已乘以2(原数据是35)
5) "vc"
6) "100" # 分值已乘以2(原数据是50)
7) "verctor"
8) "128"
9) "lining"
10) "130"
11) "unix"
12) "142"
127.0.0.1:6379> del grade3
(integer) 1
127.0.0.1:6379> zunionstore dest 3 grade grade2 grade3 # 不存在key情况
(integer) 6
127.0.0.1:6379> zadd grade 12 ll # 在grade中添加和grade2相同的成员
(integer) 1
127.0.0.1:6379> zscore dest ll # 查看dest的成员ll的分值
"42"
127.0.0.1:6379> set grade3 beiging
OK
127.0.0.1:6379> zunionstore dest 3 grade grade2 grade3 # key不是有序集合情况
(error) WRONGTYPE Operation against a key holding the wrong kind of value
时间复杂度O(N)+O(M log(M)), N 为给定有序集基数的总和, M 为结果集的基数。
返回值:
Redis 有序集合操作实战(全)_小贤java的博客-CSDN博客有序集成员按 score 值递减(从大到小)的次序排列。时间复杂度O(N*K)+O(M*log(M)), N 为给定 key 中基数最小的有序集, K 为给定有序集的数量, M 为结果集的基数。时间复杂度O(log(N)+M), N 为有序集的基数, M 为值在 min 和 max 之间的元素的数量。时间复杂度O(N)+O(M log(M)), N 为给定有序集基数的总和, M 为结果集的基数。时间复杂度O(M*log(N)), N 为有序集的基数, M 为被成功移除的成员的数量。https://cxian.blog.csdn.net/article/details/133122491
统计流量
当日浏览量排行前十
命令:ZREVRANGE csdn:article:20230921 0 9 WITHSCORES
详见:Redis key操作实战(全)_小贤java的博客-CSDN博客DEL key [key ...]:删除给定的一个或多个key。EXPIRE key seconds:为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。RESTORE key ttl serialized-value:反序列化给定的序列化值,并将它和给定的 key 关联。TTL key:以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)PERSIST key:将这个 key 从(带生存时间 key )的过期时间删除。https://cxian.blog.csdn.net/article/details/133039041