如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。 可用版本: 2.0.0+ 时间复杂度: 平摊 O(1) 返回值: 追加 value 之后, key 中字符串的长度。 对不存在的 key 执行 APPEND
- redis> EXISTS myphone# 确保 myphone 不存在
- (integer)0redis> APPEND myphone"nokia" # 对不存在的 key 进行 APPEND ,等同于SETmyphone"nokia"(integer)5 # 字符长度
- 对已存在的字符串进行 APPEND
- redis> APPEND myphone" - 1110" # 长度从 5 个字符增加到 12 个字符(integer)12redis>GETmyphone"nokia - 1110"
时间序列(Time series) APPEND 可以为一系列定长 (fixed-size) 数据 (sample) 提供一种紧凑的表示方式,通常称之为时间序列。 每当一个新数据到达的时候,执行以下命令: APPEND timeseries "fixed-size sample" 然后可以通过以下的方式访问时间序列的各项属性: ● STRLEN 给出时间序列中数据的数量 ● GETRANGE 可以用于随机访问。只要有相关的时间信息的话,我们就可以在 Redis 2.6 中使用 Lua 脚本和 GETRANGE 命令实现二分查找。 ● SETRANGE 可以用于覆盖或修改已存在的的时间序列。 这个模式的唯一缺陷是我们只能增长时间序列,而不能对时间序列进行缩短,因为 Redis 目前还没有对字符串进行修剪 (tirm) 的命令,但是,不管怎么说,这个模式的储存方式还是可以节省下大量的空间。 可以考虑使用 UNIX 时间戳作为时间序列的键名,这样一来,可以避免单个 key 因为保存过大的时间序列而占用大量内存,另一方面,也可以节省下大量命名空间。
- redis> APPEND ts"0043"(integer)4redis> APPEND ts"0035"(integer)8redis> GETRANGE ts0 3
- "0043"redis> GETRANGE ts4 7
- "0035"
计算给定字符串中,被设置为 1 的比特位的数量。 一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。 start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此类推。 不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。 可用版本: 2.6.0+ 时间复杂度: O(N) 返回值: 被设置为 1 的位的数量。
- redis> BITCOUNT bits
- (integer)0redis> SETBIT bits0 1 # 0001(integer)0redis> BITCOUNT bits
- (integer)1redis> SETBIT bits3 1 # 1001(integer)0redis> BITCOUNT bits
- (integer)2
模式:使用 bitmap 实现用户签到次数统计 Bitmap 对于一些特定类型的计算非常有效。 Bitmap 对于一些特定类型的计算非常有效。 假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户 A 上线了多少天,用户 B 上线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加 beta 测试等活动 —— 这个模式可以使用 SETBIT 和 BITCOUNT 来实现。 比如说,每当用户在某一天上线的时候,我们就使用 SETBIT ,以用户名作为 key ,将那天所代表的网站的上线日作为 offset 参数,并将这个 offset 上的为设置为 1 。 举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。 当要计算 peter 总共以来的上线次数时,就使用 BITCOUNT 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。 性能 前面的上线次数统计例子,即使运行 10 年,占用的空间也只是每个用户 10*365 比特位(bit),也即是每个用户 456 字节。对于这种大小的数据来说, BITCOUNT 的处理速度就像 GET 和 INCR 这种 O(1) 复杂度的操作一样快。 如果你的 bitmap 数据非常大,那么可以考虑使用以下两种方法: 1. 将一个大的 bitmap 分散到不同的 key 中,作为小的 bitmap 来处理。使用 Lua 脚本可以很方便地完成这一工作。 2. 使用 BITCOUNT 的 start 和 end 参数,每次只对所需的部分位进行计算,将位的累积工作 (accumulating) 放到客户端进行,并且对结果进行缓存 (caching)。
对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。 operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种: ● BITOP AND destkey key [key …] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。 ● BITOP OR destkey key [key …] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。 ● BITOP XOR destkey key [key …] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。 ● BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey 。 除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。 处理不同长度的字符串 当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0 。 空的 key 也被看作是包含 0 的字符串序列。 可用版本: 2.6.0+ 时间复杂度: O(N) 返回值: 保存到 destkey 的字符串的长度,和输入 key 中最长的字符串长度相等。 BITOP 的复杂度为 O(N) ,当处理大型矩阵 (matrix) 或者进行大数据量的统计时,最好将任务指派到附属节点 (slave) 进行,避免阻塞主节点。
- redis> SETBIT bits-1 0 1 # bits-1 = 1001(integer)0redis> SETBIT bits-1 3 1(integer)0redis> SETBIT bits-2 0 1 # bits-2 = 1011(integer)0redis> SETBIT bits-2 1 1(integer)0redis> SETBIT bits-2 3 1(integer)0redis> BITOP ANDand-resultbits-1bits-2(integer)1redis> GETBITand-result 0 # and-result = 1001(integer)1redis> GETBITand-result 1(integer)0redis> GETBITand-result 2(integer)0redis> GETBITand-result 3(integer)1
将 key 中储存的数字值减一。 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 本操作的值限制在 64 位 (bit) 有符号数字表示之内。 关于递增 (increment) / 递减(decrement) 操作的更多信息,请参见 INCR 命令。 可用版本: 1.0.0+ 时间复杂度: O(1) 返回值: 执行 DECR 命令之后 key 的值。 对存在的数字值 key 进行 DECR
- redis>SETfailure_times10OK
- redis> DECR failure_times
- (integer)9对不存在的key值进行 DECR
- redis> EXISTS count
- (integer)0redis> DECR count
- (integer) -1
- 对存在但不是数值的key进行 DECR
- redis>SETcompany YOUR_CODE_SUCKS.LLC
- OK
- redis> DECR company
- (error) ERR valueis notaninteger oroutofrange
DECRBY key decrement 将 key 所储存的值减去减量 decrement 。 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 操作。 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 本操作的值限制在 64 位 (bit) 有符号数字表示之内。 关于更多递增 (increment) / 递减(decrement) 操作的更多信息,请参见
可用版本: 1.0.0+ 时间复杂度: O(1) 返回值: 减去 decrement 之后, key 的值。 对已存在的 key 进行 DECRBY
- redis>SETcount100OK
- redis> DECRBY count20(integer)80对不存在的key进行DECRBY
- redis> EXISTS pages
- (integer)0redis> DECRBY pages10(integer) -10
返回 key 所关联的字符串值。 如果 key 不存在那么返回特殊值 nil 。 假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。 可用版本: 1.0.0+ 时间复杂度: O(1) 返回值: 当 key 不存在时,返回 nil ,否则,返回 key 的值。 如果 key 不是字符串类型,那么返回一个错误。 对不存在的 key 或字符串类型 key 进行 GET
- redis>GETdb
- (nil)
- redis>SETdb redis
- OK
- redis>GETdb"redis"对不是字符串类型的key进行GETredis> DEL db
- (integer)1redis> LPUSH db redis mongodb mysql
- (integer)3redis>GETdb
- (error) ERR Operation against akeyholding the wrong kindofvalue
对 key 所储存的字符串值,获取指定偏移量上的位 (bit)。 当 offset 比字符串值的长度大,或者 key 不存在时,返回 0 。 可用版本: 2.2.0+ 时间复杂度: O(1) 返回值: 字符串值指定偏移量上的位 (bit)。 对不存在的 key 或者不存在的 offset 进行 GETBIT, 返回 0 redis> EXISTS bit (integer) 0 redis> GETBIT bit 10086 (integer) 0 对已存在的 offset 进行 GETBIT redis> SETBIT bit 10086 1 (integer) 0 redis> GETBIT bit 10086 (integer) 1
返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。 负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推。 GETRANGE 通过保证子字符串的值域 (range) 不超过实际字符串的值域来处理超出范围的值域请求。 在 <= 2.0 的版本里,GETRANGE 被叫作 SUBSTR。 可用版本: 2.4.0+ 时间复杂度: O(N), N 为要返回的字符串的长度。 复杂度最终由字符串的返回值长度决定,但因为从已有字符串中取出子字符串的操作非常廉价(cheap),所以对于长度不大的字符串,该操作的复杂度也可看作 O(1)。 返回值: 截取得出的子字符串。
- redis>SETgreeting"hello, my friend"OK
- redis> GETRANGE greeting0 4 # 返回索引0-4的字符,包括4。"hello"redis> GETRANGE greeting -1-5 # 不支持回绕操作""redis> GETRANGE greeting -3-1 # 负数索引"end"redis> GETRANGE greeting0-1 # 从第一个到最后一个"hello, my friend"redis> GETRANGE greeting0 1008611 # 值域范围不超过实际字符串,超过部分自动被符略"hello, my friend"
将给定 key 的值设为 value ,并返回 key 的旧值 (old value)。 当 key 存在但不是字符串类型时,返回一个错误。 可用版本: 1.0.0+ 时间复杂度: O(1) 返回值: 返回给定 key 的旧值。 当 key 没有旧值时,也即是, key 不存在时,返回 nil 。
- redis> GETSET db mongodb# 没有旧值,返回 nil(nil)
- redis>GETdb"mongodb"redis> GETSET db redis# 返回旧值 mongodb
- "mongodb"redis>GETdb"redis"
模式 GETSET 可以和 INCR 组合使用,实现一个有原子性 (atomic) 复位操作的计数器(counter)。 举例来说,每次当某个事件发生时,进程可能对一个名为 mycount 的 key 调用 INCR 操作,通常我们还要在一个原子时间内同时完成获得计数器的值和将计数器值复位为 0 两个操作。 可以用命令 GETSET mycounter 0 来实现这一目标。
- redis> INCR mycount
- (integer)11redis> GETSET mycount0 # 一个原子内完成 GET mycount 和 SET mycount 0 操作
- "11"redis>GETmycount# 计数器被重置
- "0"
将 key 中储存的数字值增一。 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 本操作的值限制在 64 位 (bit) 有符号数字表示之内。 这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,所以 key 内储存的字符串被解释为十进制 64 位有符号整数来执行 INCR 操作。 可用版本: 1.0.0+ 时间复杂度: O(1) 返回值: 执行 INCR 命令之后 key 的值。
- redis>SETpage_view20OK
- redis> INCR page_view
- (integer)21redis>GETpage_view# 数字值在 Redis 中以字符串的形式保存
- "21"
模式:计数器 计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令。 比如在一个 web 应用程序中,如果想知道用户在一年中每天的点击量,那么只要将用户 ID 以及相关的日期信息作为键,并在每次用户点击页面时,执行一次自增操作即可。 比如用户名是 peter ,点击时间是 2012 年 3 月 22 日,那么执行命令 INCR peter::2012.3.22 。 可以用以下几种方式扩展这个简单的模式: ● 可以通过组合使用 INCR 和 EXPIRE ,来达到只在规定的生存时间内进行计数 (counting) 的目的。 ● 客户端可以通过使用 GETSET 命令原子性地获取计数器的当前值并将计数器清零,更多信息请参考 GETSET 命令。 ● 使用其他自增 / 自减操作,比如 DECR 和 INCRBY ,用户可以通过执行不同的操作增加或减少计数器的值,比如在游戏中的记分器就可能用到这些命令。 模式:限速器 限速器是特殊化的计算器,它用于限制一个操作可以被执行的速率(rate)。 限速器的典型用法是限制公开 API 的请求次数,以下是一个限速器实现示例,它将 API 的最大请求数限制在每个 IP 地址每秒钟十个之内:
- FUNCTIONLIMIT_API_CALL(ip)
- ts = CURRENT_UNIX_TIME()
- keyname = ip+":"+ts
- current =GET(keyname)IFcurrent !=NULL ANDcurrent >10 THEN
- ERROR "too many requests per second"
- END
- IFcurrent ==NULL THENMULTI
- INCR(keyname,1)
- EXPIRE(keyname,1)
- EXECELSEINCR(keyname,1)ENDPERFORM_API_CALL()
这个实现每秒钟为每个 IP 地址使用一个不同的计数器,并用 EXPIRE 命令设置生存时间 (这样 Redis 就会负责自动删除过期的计数器)。 注意,我们使用事务打包执行 INCR 命令和 EXPIRE 命令,避免引入竞争条件,保证每次调用 API 时都可以正确地对计数器进行自增操作并设置生存时间。 以下是另一个限速器实现:
- FUNCTIONLIMIT_API_CALL(ip):
- current =GET(ip)IFcurrent !=NULL ANDcurrent >10 THEN
- ERROR "too many requests per second"
- ELSEvalue = INCR(ip)IFvalue ==1 THENEXPIRE(ip,1)ENDPERFORM_API_CALL()END
这个限速器只使用单个计数器,它的生存时间为一秒钟,如果在一秒钟内,这个计数器的值大于 10 的话,那么访问就会被禁止。 这个新的限速器在思路方面是没有问题的,但它在实现方面不够严谨,如果我们仔细观察一下的话,就会发现在 INCR 和 EXPIRE 之间存在着一个竞争条件,假如客户端在执行 INCR 之后,因为某些原因 (比如客户端失败) 而忘记设置 EXPIRE 的话,那么这个计数器就会一直存在下去,造成每个用户只能访问 10 次,噢,这简直是个灾难! 要消灭这个实现中的竞争条件,我们可以将它转化为一个 Lua 脚本,并放到 Redis 中运行(这个方法仅限于 Redis 2.6 及以上的版本):
- local current
- current = redis.call("incr",KEYS[1])iftonumber(current) ==1 thenredis.call("expire",KEYS[1],1)end
通过将计数器作为脚本放到 Redis 上运行,我们保证了 INCR 和 EXPIRE 两个操作的原子性,现在这个脚本实现不会引入竞争条件,它可以运作的很好。 关于在 Redis 中运行 Lua 脚本的更多信息,请参考 EVAL 命令。 还有另一种消灭竞争条件的方法,就是使用 Redis 的列表结构来代替 INCR 命令,这个方法无须脚本支持,因此它在 Redis 2.6 以下的版本也可以运行得很好:
- FUNCTIONLIMIT_API_CALL(ip)
- current = LLEN(ip)IFcurrent >10 THEN
- ERROR "too many requests per second"
- ELSE
- IFEXISTS(ip) ==FALSEMULTI
- RPUSH(ip,ip)
- EXPIRE(ip,1)
- EXECELSERPUSHX(ip,ip)ENDPERFORM_API_CALL()END
新的限速器使用了列表结构作为容器, LLEN 用于对访问次数进行检查,一个事务包裹着 RPUSH 和 EXPIRE 两个命令,用于在第一次执行计数时创建列表,并正确设置地设置过期时间,最后, RPUSHX 在后续的计数操作中进行增加操作。
将 key 所储存的值加上增量 increment 。 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 本操作的值限制在 64 位 (bit) 有符号数字表示之内。 关于递增 (increment) / 递减(decrement) 操作的更多信息,参见 INCR 命令。 可用版本: 1.0.0+ 时间复杂度: O(1) 返回值: 加上 increment 之后, key 的值。 key 存在且是数字值
- redis>SETrank50OK
- redis> INCRBY rank20(integer)70redis>GETrank"70"
- key不存在时
- redis> EXISTS counter
- (integer)0redis> INCRBY counter30(integer)30redis>GETcounter"30"
- key不是数字值时
- redis>SETbook"long long ago..."OK
- redis> INCRBY book200(error) ERR valueis notaninteger oroutofrange
为 key 中所储存的值加上浮点数增量 increment 。 如果 key 不存在,那么 INCRBYFLOAT 会先将 key 的值设为 0 ,再执行加法操作。 如果命令执行成功,那么 key 的值会被更新为(执行加法之后的)新值,并且新值会以字符串的形式返回给调用者。 无论是 key 的值,还是增量 increment ,都可以使用像 2.0e7 、 3e5 、 90e-2 那样的指数符号 (exponential notation) 来表示,但是,执行 INCRBYFLOAT 命令之后的值总是以同样的形式储存,也即是,它们总是由一个数字,一个(可选的)小数点和一个任意位的小数部分组成(比如 3.14 、 69.768 ,诸如此类),小数部分尾随的 0 会被移除,如果有需要的话,还会将浮点数改为整数(比如 3.0 会被保存成 3 )。 除此之外,无论加法计算所得的浮点数的实际精度有多长, INCRBYFLOAT 的计算结果也最多只能表示小数点的后十七位。 当以下任意一个条件发生时,返回一个错误: ● key 的值不是字符串类型(因为 Redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型) ● key 当前的值或者给定的增量 increment 不能解释 (parse) 为双精度浮点数(double precision floating point number) 可用版本: 2.6.0+ 时间复杂度: O(1) 返回值: 执行命令之后 key 的值。 值和增量都不是指数符号
- redis>SETmykey10.50OK
- redis> INCRBYFLOAT mykey0.1
- "10.6"值和增量都是指数符号
- redis>SETmykey314e-2OK
- redis>GETmykey# 用 SET 设置的值可以是指数符号
- "314e-2"redis> INCRBYFLOAT mykey0 # 但执行 INCRBYFLOAT 之后格式会被改成非指数符号
- "3.14"可以对整数类型执行
- redis>SETmykey3OK
- redis> INCRBYFLOAT mykey1.1
- "4.1"后跟的0会被移除
- redis>SETmykey3.0OK
- redis>GETmykey# SET 设置的值小数部分可以是 0
- "3.0"redis> INCRBYFLOAT mykey1.000000000000000000000 # 但 INCRBYFLOAT 会将无用的 0 忽略掉,有需要的话,将浮点变为整数
- "4"redis>GETmykey"4"
返回所有 (一个或多个) 给定 key 的值。 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。 可用版本: 1.0.0+ 时间复杂度: O(N) , N 为给定 key 的数量。 返回值: 一个包含所有给定 key 的值的列表。
- redis>SETredis redis.comOK
- redis>SETmongodb mongodb.orgOK
- redis> MGET redis mongodb1)"redis.com"
- 2)"mongodb.org"redis> MGET redis mongodb mysql# 不存在的 mysql 返回 nil
- 1)"redis.com"
- 2)"mongodb.org"
- 3) (nil)
同时设置一个或多个 key-value 对。 如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。 MSET 是一个原子性 (atomic) 操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。 可用版本: 1.0.1+ 时间复杂度: O(N), N 为要设置的 key 数量。 返回值: 总是返回 OK (因为 MSET 不可能失败)
- redis> MSETdate "2012.3.30" time "11:00 a.m."weather"sunny"OK
- redis> MGETdate timeweather1)"2012.3.30"
- 2)"11:00 a.m."
- 3)"sunny"MSET 覆盖旧值例子
- redis>SETgoogle"google.hk"OK
- redis> MSET google"google.com"OK
- redis>GETgoogle"google.com"
同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 即使只有一个给定 key 已存在, MSETNX 也会拒绝执行所有给定 key 的设置操作。 MSETNX 是原子性的,因此它可以用作设置多个不同 key 表示不同字段 (field) 的唯一性逻辑对象(unique logic object),所有字段要么全被设置,要么全不被设置。 可用版本: 1.0.1+ 时间复杂度: O(N), N 为要设置的 key 的数量。 返回值: 当所有 key 都成功设置,返回 1 。 如果所有给定 key 都设置失败(至少有一个 key 已经存在),那么返回 0 。 对不存在的 key 进行 MSETNX
- redis>MSETNX rmdbs"MySQL"nosql"MongoDB"key-value-store "redis"(integer)1redis>MGET rmdbs nosql key-value-store
- 1)"MySQL"
- 2)"MongoDB"
- 3)"redis"
MSET 的给定 key 当中有已存在的 key
- redis> MSETNX rmdbs"Sqlite"language"python" # rmdbs 键已经存在,操作失败(integer)0redis> EXISTS language# 因为 MSET 是原子性操作,language 没有被设置(integer)0redis>GETrmdbs# rmdbs 也没有被修改
- "MySQL"
这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 可用版本: 2.6.0+ 时间复杂度: O(1) 返回值: 设置成功时返回 OK 。
- redis> PSETEX mykey1000 "Hello"OK
- redis> PTTL mykey
- (integer)999redis>GETmykey"Hello"
将字符串值 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)。 对不存在的键进行设置
- redis127.0.0.1:6379>SET key "value"OK
- redis127.0.0.1:6379>GET key
- "value"对已存在的键进行设置
- redis127.0.0.1:6379>SET key "new-value"OK
- redis127.0.0.1:6379>GET key
- "new-value"
使用 EX 选项
- redis127.0.0.1:6379> SETkey-with-expire-time "hello"EX10086OK
- redis127.0.0.1:6379>GET key-with-expire-time
- "hello"redis127.0.0.1:6379>TTL key-with-expire-time(integer)10069
使用 PX 选项
- redis127.0.0.1:6379>SET key-with-pexpire-time"moto"PX123321OK
- redis127.0.0.1:6379>GET key-with-pexpire-time"moto"redis127.0.0.1:6379> PTTLkey-with-pexpire-time
- (integer)111939使用 NX 选项
- redis127.0.0.1:6379>SET not-exists-key "value"NX
- OK# 键不存在,设置成功redis127.0.0.1:6379>GET not-exists-key
- "value"redis127.0.0.1:6379>SET not-exists-key "new-value"NX
- (nil)# 键已经存在,设置失败redis127.0.0.1:6379>GEt not-exists-key
- "value" # 维持原值不变使用 XX 选项
- redis127.0.0.1:6379> EXISTS exists-key(integer)0redis127.0.0.1:6379>SETexists-key "value"XX
- (nil)# 因为键不存在,设置失败redis127.0.0.1:6379>SETexists-key "value"OK# 先给键设置一个值redis127.0.0.1:6379>SETexists-key "new-value"XX
- OK# 设置新值成功redis127.0.0.1:6379>GETexists-key
- "new-value"NX 或 XX 可以和 EX 或者 PX 组合使用
- redis127.0.0.1:6379>SET key-with-expire-and-NX"hello"EX10086NX
- OK
- redis127.0.0.1:6379>GET key-with-expire-and-NX"hello"redis127.0.0.1:6379> TTLkey-with-expire-and-NX
- (integer)10063redis127.0.0.1:6379>SET key-with-pexpire-and-XX"old value"OK
- redis<
来源: http://blog.csdn.net/fuyuwei2015/article/details/70332262