当前位置 : 主页 > 编程语言 > java >

【redis】常用命令整理

来源:互联网 收集:自由互联 发布时间:2022-06-30
文章目录 ​​前言​​ ​​登陆命令​​ ​​数据类型​​ ​​String(字符串)​​ ​​GET命令​​ ​​Set命令​​ ​​INCR命令​​ ​​Hash(哈希表)​​ ​​HSET命令​​ ​​


文章目录

  • ​​前言​​
  • ​​登陆命令​​
  • ​​数据类型​​
  • ​​String(字符串)​​
  • ​​GET命令​​
  • ​​Set命令​​
  • ​​INCR命令​​
  • ​​Hash(哈希表)​​
  • ​​HSET命令​​
  • ​​HGET命令​​
  • ​​HGETALL命令​​
  • ​​SortedSet(有序集合)​​
  • ​​ZREVRANGE命令​​
  • ​​ZADD命令​​



前言

redis常用命令汇总


登陆命令

redis登陆命令

redis-cli -h ip -p port

数据类型

String(字符串)

GET命令

GET key

返回 key 所关联的字符串值。
如果 key 不存在那么返回特殊值 nil 。
假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。

可用版本:
>= 1.0.0
时间复杂度:
O(1)
返回值:
当 key 不存在时,返回 nil ,否则,返回 key 的值。
如果 key 不是字符串类型,那么返回一个错误。# 对不存在的 key 或字符串类型 key 进行 GET

redis> GET db
(nil)

redis> SET db redis
OK

redis> GET db
"redis"


# 对不是字符串类型的 key 进行 GET

redis> DEL db
(integer) 1

redis> LPUSH db redis mongodb mysql
(integer) 3

redis> GET db
(error) ERR Operation against a key holding the wrong kind of value

Set命令

SET key value [EX seconds] [PX milliseconds] [NX|XX]

将字符串值 value 关联到 key 。

如果 key 已经持有其他值, SET 就覆写旧值,无视类型。

对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。

可选参数

从 Redis 2.6.12 版本开始, SET 命令的行为可以通过一系列参数来修改:

EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。

因为 SET 命令可以通过参数来实现和 SETNX 、 SETEX 和 PSETEX 三个命令的效果,所以将来的 Redis 版本可能会废弃并最终移除 SETNX 、 SETEX 和 PSETEX 这三个命令。

可用版本:
>= 1.0.0
时间复杂度:
O(1)
返回值:
在 Redis 2.6.12 版本以前, SET 命令总是返回 OK 。

从 Redis 2.6.12 版本开始, SET 在设置操作成功完成时,才返回 OK 。
如果设置了 NX 或者 XX ,但因为条件没达到而造成设置操作未执行,那么命令返回空批量回复(NULL Bulk Reply)。# 对不存在的键进行设置

redis 127.0.0.1:6379> SET key "value"
OK

redis 127.0.0.1:6379> GET key
"value"


# 对已存在的键进行设置

redis 127.0.0.1:6379> SET key "new-value"
OK

redis 127.0.0.1:6379> GET key
"new-value"


# 使用 EX 选项

redis 127.0.0.1:6379> SET key-with-expire-time "hello" EX 10086
OK

redis 127.0.0.1:6379> GET key-with-expire-time
"hello"

redis 127.0.0.1:6379> TTL key-with-expire-time
(integer) 10069


# 使用 PX 选项

redis 127.0.0.1:6379> SET key-with-pexpire-time "moto" PX 123321
OK

redis 127.0.0.1:6379> GET key-with-pexpire-time
"moto"

redis 127.0.0.1:6379> PTTL key-with-pexpire-time
(integer) 111939


# 使用 NX 选项

redis 127.0.0.1:6379> SET not-exists-key "value" NX
OK # 键不存在,设置成功

redis 127.0.0.1:6379> GET not-exists-key
"value"

redis 127.0.0.1:6379> SET not-exists-key "new-value" NX
(nil) # 键已经存在,设置失败

redis 127.0.0.1:6379> GEt not-exists-key
"value" # 维持原值不变


# 使用 XX 选项

redis 127.0.0.1:6379> EXISTS exists-key
(integer) 0

redis 127.0.0.1:6379> SET exists-key "value" XX
(nil) # 因为键不存在,设置失败

redis 127.0.0.1:6379> SET exists-key "value"
OK # 先给键设置一个值

redis 127.0.0.1:6379> SET exists-key "new-value" XX
OK # 设置新值成功

redis 127.0.0.1:6379> GET exists-key
"new-value"


# NX 或 XX 可以和 EX 或者 PX 组合使用

redis 127.0.0.1:6379> SET key-with-expire-and-NX "hello" EX 10086 NX
OK

redis 127.0.0.1:6379> GET key-with-expire-and-NX
"hello"

redis 127.0.0.1:6379> TTL key-with-expire-and-NX
(integer) 10063

redis 127.0.0.1:6379> SET key-with-pexpire-and-XX "old value"
OK

redis 127.0.0.1:6379> SET key-with-pexpire-and-XX "new value" PX 123321
OK

redis 127.0.0.1:6379> GET key-with-pexpire-and-XX
"new value"

redis 127.0.0.1:6379> PTTL key-with-pexpire-and-XX
(integer) 112999


# EX 和 PX 可以同时出现,但后面给出的选项会覆盖前面给出的选项

redis 127.0.0.1:6379> SET key "value" EX 1000 PX 5000000
OK

redis 127.0.0.1:6379> TTL key
(integer) 4993 # 这是 PX 参数设置的值

redis 127.0.0.1:6379> SET another-key "value" PX 5000000 EX 1000
OK

redis 127.0.0.1:6379> TTL another-key
(integer) 997 # 这是 EX 参数设置的值

使用模式

命令 SET resource-name anystring NX EX max-lock-time 是一种在 Redis 中实现锁的简单方法。

客户端执行以上的命令:

如果服务器返回 OK ,那么这个客户端获得锁。
如果服务器返回 NIL ,那么客户端获取锁失败,可以在稍后再重试。
设置的过期时间到达之后,锁将自动释放。

可以通过以下修改,让这个锁实现更健壮:

不使用固定的字符串作为键的值,而是设置一个不可猜测(non-guessable)的长随机字符串,作为口令串(token)。
不使用 DEL 命令来释放锁,而是发送一个 Lua 脚本,这个脚本只在客户端传入的值和键的口令串相匹配时,才对键进行删除。
这两个改动可以防止持有过期锁的客户端误删现有锁的情况出现。

以下是一个简单的解锁脚本示例:if redis.call("get",KEYS[1]) == ARGV[1]
then
return redis.call("del",KEYS[1])
else
return 0
end

这个脚本可以通过 EVAL …script… 1 resource-name token-value 命令来调用。

INCR命令

INCR key

将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。

这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,所以 key 内储存的字符串被解释为十进制 64 位有符号整数来执行 INCR 操作。

可用版本:
>= 1.0.0
时间复杂度:
O(1)
返回值:
执行 INCR 命令之后 key 的值。redis> SET page_view 20
OK

redis> INCR page_view
(integer) 21

redis> GET page_view # 数字值在 Redis 中以字符串的形式保存
"21"计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令。

比如在一个 web 应用程序中,如果想知道用户在一年中每天的点击量,那么只要将用户 ID 以及相关的日期信息作为键,并在每次用户点击页面时,执行一次自增操作即可。

比如用户名是 peter ,点击时间是 2012322 日,那么执行命令 INCR peter::2012.3.22 。

可以用以下几种方式扩展这个简单的模式:

- 可以通过组合使用 INCR 和 EXPIRE ,来达到只在规定的生存时间内进行计数(counting)的目的。
- 客户端可以通过使用 GETSET 命令原子性地获取计数器的当前值并将计数器清零,更多信息请参考 GETSET 命令。
- 使用其他自增/自减操作,比如 DECR 和 INCRBY ,用户可以通过执行不同的操作增加或减少计数器的值,比如在游戏中的记分器就可能用到这些命令。

模式:限速器

限速器是特殊化的计算器,它用于限制一个操作可以被执行的速率(rate)。

限速器的典型用法是限制公开 API 的请求次数,以下是一个限速器实现示例,它将 API 的最大请求数限制在每个 IP 地址每秒钟十个之内:

FUNCTION LIMIT_API_CALL(ip)
ts = CURRENT_UNIX_TIME()
keyname = ip+":"+ts
current = GET(keyname)

IF current != NULL AND current > 10 THEN
ERROR "too many requests per second"
END

IF current == NULL THEN
MULTI
INCR(keyname, 1)
EXPIRE(keyname, 1)
EXEC
ELSE
INCR(keyname, 1)
END

PERFORM_API_CALL()

这个实现每秒钟为每个 IP 地址使用一个不同的计数器,并用 EXPIRE 命令设置生存时间(这样 Redis 就会负责自动删除过期的计数器)。

注意,我们使用事务打包执行 INCR 命令和 EXPIRE 命令,避免引入竞争条件,保证每次调用 API 时都可以正确地对计数器进行自增操作并设置生存时间。

以下是另一个限速器实现:

FUNCTION LIMIT_API_CALL(ip):
current = GET(ip)
IF current != NULL AND current > 10 THEN
ERROR "too many requests per second"
ELSE
value = INCR(ip)
IF value == 1 THEN
EXPIRE(ip,1)
END
PERFORM_API_CALL()
END

这个限速器只使用单个计数器,它的生存时间为一秒钟,如果在一秒钟内,这个计数器的值大于 10 的话,那么访问就会被禁止。

这个新的限速器在思路方面是没有问题的,但它在实现方面不够严谨,如果我们仔细观察一下的话,就会发现在 INCR 和 EXPIRE 之间存在着一个竞争条件,假如客户端在执行 INCR 之后,因为某些原因(比如客户端失败)而忘记设置 EXPIRE 的话,那么这个计数器就会一直存在下去,造成每个用户只能访问 10 次,噢,这简直是个灾难!

要消灭这个实现中的竞争条件,我们可以将它转化为一个 Lua 脚本,并放到 Redis 中运行(这个方法仅限于 Redis 2.6 及以上的版本):

local current
current = redis.call("incr",KEYS[1])
if tonumber(current) == 1 then
redis.call("expire",KEYS[1],1)
end

通过将计数器作为脚本放到 Redis 上运行,我们保证了 INCR 和 EXPIRE 两个操作的原子性,现在这个脚本实现不会引入竞争条件,它可以运作的很好。

关于在 Redis 中运行 Lua 脚本的更多信息,请参考 EVAL 命令。

还有另一种消灭竞争条件的方法,就是使用 Redis 的列表结构来代替 INCR 命令,这个方法无须脚本支持,因此它在 Redis 2.6 以下的版本也可以运行得很好:

FUNCTION LIMIT_API_CALL(ip)
current = LLEN(ip)
IF current > 10 THEN
ERROR "too many requests per second"
ELSE
IF EXISTS(ip) == FALSE
MULTI
RPUSH(ip,ip)
EXPIRE(ip,1)
EXEC
ELSE
RPUSHX(ip,ip)
END
PERFORM_API_CALL()
END

新的限速器使用了列表结构作为容器, LLEN 用于对访问次数进行检查,一个事务包裹着 RPUSH 和 EXPIRE 两个命令,用于在第一次执行计数时创建列表,并正确设置地设置过期时间,最后, RPUSHX 在后续的计数操作中进行增加操作。

Hash(哈希表)

HSET命令

HSET key field value

key field value
key HSET
field


>= 2.0.0
O(1)
field 1
field 0 redis> HSET website google "www.g.cn" # 设置一个新域
(integer) 1

redis> HSET website google "www.google.com" # 覆盖一个旧域
(integer) 0

HGET命令

HGET key field

key field


>= 2.0.0

O(1)


key nil # 域存在

redis> HSET site redis redis.com
(integer) 1

redis> HGET site redis
"redis.com"


# 域不存在

redis> HGET site mysql
(nil)

HGETALL命令

HGETALL key

返回哈希表 key 中,所有的域和值。

在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。

可用版本:
>= 2.0.0
时间复杂度:
O(N), N 为哈希表的大小。
返回值:
以列表形式返回哈希表的域和域的值。
若 key 不存在,返回空列表。redis> HSET people jack "Jack Sparrow"
(integer) 1

redis> HSET people gump "Forrest Gump"
(integer) 1

redis> HGETALL people
1) "jack" # 域
2) "Jack Sparrow" # 值
3) "gump"
4) "Forrest Gump"

SortedSet(有序集合)

ZREVRANGE命令

ZREVRANGE key start stop [WITHSCORES]

返回有序集 key 中,指定区间内的成员。

其中成员的位置按 score 值递减(从大到小)来排列。
具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。
除了成员按 score 值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。

可用版本:
>= 1.2.0
时间复杂度:
O(log(N)+M), N 为有序集的基数,而 M 为结果集的基数。
返回值:
指定区间内,带有 score 值(可选)的有序集成员的列表。redis> ZRANGE salary 0 -1 WITHSCORES # 递增排列
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"

redis> ZREVRANGE salary 0 -1 WITHSCORES # 递减排列
1) "jack"
2) "5000"
3) "tom"
4) "4000"
5) "peter"
6) "3500"

填上WITHSCORES 可以把分数也返回

ZADD命令

ZADD key score member [[score member] [score member] ...]

将一个或多个 member 元素及其 score 值加入到有序集 key 当中。

如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。

score 值可以是整数值或双精度浮点数。

如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。

当 key 存在但不是有序集类型时,返回一个错误。

对有序集的更多介绍请参见 sorted set

在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素

可用版本:
>= 1.2.0
时间复杂度:
O(M*log(N)), N 是有序集的基数, M 为成功添加的新成员的数量。
返回值:
被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。# 添加单个元素

redis> ZADD page_rank 10 google.com
(integer) 1


# 添加多个元素

redis> ZADD page_rank 9 baidu.com 8 bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,且 score 值不变

redis> ZADD page_rank 10 google.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES # 没有改变
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,但是改变 score 值

redis> ZADD page_rank 6 bing.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES # bing.com 元素的 score 值被改变
1) "bing.com"
2) "6"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"

参考链接
​​​ http://doc.redisfans.com/index.html​​



上一篇:【PHP】字符串方法整理
下一篇:没有了
网友评论