`
huangz
  • 浏览: 320384 次
  • 性别: Icon_minigender_1
  • 来自: 广东-清远
社区版块
存档分类
最新评论

Redis命令参考(Commands Reference)中文翻译【String部分】

阅读更多

注意:此文档已经过期,请移步到 http://huangz.iteye.com/blog/1123512 查看最新翻译。

 

String部分

APPEND key value

    如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。
    如果key不存在,APPEND就简单地将指定key设为value,就像SET key value一样。

    复杂度:
        O(1)
        平摊复杂度O(1)是建立于要追加(appended)的value不大(small)的情况下,不管原字符串有多大。因为Redis所使用的动态字符串库,每次重分配都使用双倍的空间。(这大>概可以理解为:如果你有一个10个字符的字符串,你追加一个长度<=10的字符串,复杂度是O(1),但如果追加一个>=10个字符的字符串,就不能保证复杂度一定是O(1)了。 —— 译注)

    返回值:
        追加value之后字符串的长度。

redis> EXISTS myphone  # 确保myphone不存在
(integer) 0

redis> APPEND myphone "nokia"  # 对不存在的key进行APPEND,等同于SET myphone "nokia"
(integer) 5

redis> APPEND myphone " - 1110"  # 真正的APPEND
(integer) 12  # 长度从5个字符增加到12个字符

redis> GET myphone
"nokia - 1110"
 

GETRANGE key start end

    返回key所储存值的子字符串,截取范围由start和end(包含在内)两个偏移量决定。
    负数偏移量表示从字符串最后开始计数,-1表示最后一个字符,-2表示倒数第二个,以此类推。
    GETRANGE通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。

    复杂度:
        O(N),N为要返回的字符串的长度。
        复杂度最终由返回值长度决定,但因为从已有字符串中建立子字符串的操作非常廉
价(cheap),所以对于长度不大的字符串,该操作的复杂度也可看作O(1)。

        注意:在<=2.0的版本里,GETRANGE被叫作SUBSTR。

    返回值:
        子字符串的内容

redis> SET greeting "hello, my friend"
OK

redis> GETRANGE greeting 0 4  # 返回索引0-4的字符,包括4。
"hello"

redis> GETRANGE greeting -1 -5  # 不支持回绕操作
""

redis> GETRANGE greeting -3 -1  # 负数索引
"end"

redis> GETRANGE greeting 0 -1  # 从第一个到最后一个
"hello, my friend"

redis> GETRANGE greeting 0 1008611  # 值域范围不超过实际字符串,超过部分自动被符略
"hello, my friend"
 

MSET key value [key value ...]

    为给定的key设置各自的值(value)。
    当key相同时,MSET会用新值覆盖旧值,如果你不希望覆盖同名key,请参考MSETNX命令。  
    MSET是一个原子性(atomic)操作,所有给定key都在同一次中被设置,某些给定key被更新而另一些给定key没有改变的情况不会发生。

    复杂度:
        O(N),N为要设置的key数量。

    返回值:
        总是返回OK(因为MSET不可能失败)

redis> KEYS *  # 这是个空数据库
(empty list or set)

redis> MSET date "2011.4.18" time "9.09a.m." weather "sunny"
OK

redis> KEYS *   # 指定的三个key-value对被插入
1) "time"
2) "weather"
3) "date"

redis> SET blog "huangz.iteye.com"  # MSET覆盖旧值的例子
OK

redis> MSET blog "www.SideEffect.me"
OK

redis> GET blog
"www.SideEffect.me"
 

SETNX key value

    假如给定的key不存在,则将key设置为给定的字符串值。
    若给定的key已经存在,则SETNX不做任何动作。
    SETNX是"SET if Not eXists"(如果不存在,则SET)的简写。

    复杂度:
        O(1)

    返回值:
        如果设置成功,返回1.
        设置失败,返回0.

redis> EXISTS job  # job不存在
(integer) 0

redis> SETNX job "programmer"  # job设置成功
(integer) 1

redis> SETNX job "code-farmer"  # job设置失败
(integer) 0

redis> GET job  # 没有被覆盖
"programmer"
  
    设计模式(Design pattern): 将SETNX用作锁(locking)

    SETNX可以用于加锁(locking primitive)。比如说,要对关键字(key)foo加锁,客户端可以尝试以下方式:

    SETNX lock.foo <current Unix time + lock timeout + 1>

    如果SETNX返回1,说明客户端已经获得了锁,key设置的Unix时间则指定了锁失效的时间。之后客户端可以通过DEL lock.foo 来释放锁。

    如果SETNX返回0,说明key已经被其他客户端上锁了。如果锁是非阻塞(non blocking lock)的,我们可以选择返回调用,或者进入一个重试循环,直到成功获得锁或重试超时(timeout)。

    处理死锁(deadlock)

    上面的锁算法有一个问题:如果因为客户端失败、崩溃或其他原因导致没有办法释放锁的话,怎么办?
    这种状况可以通过检测发现——因为上锁的key保存的是unix时间戳,假如key值的时间戳小于当前的时间戳,表示锁已经不再有效。  

    当有多个客户端同时检测一个锁是否过期并尝试释放它的时候,我们不能简单粗暴地DEL死锁的key,再用SETNX上锁,因为这时有一个竞争条件(race condition)形成了。

        C1和C2读取lock.foo并检查时间戳,SETNX都返回0,因为它已经被C3锁上了,但C3在上锁之后就崩溃(crashed)了。
        C1向lock.foo发送DEL命令。
        C1向lock.foo发送SETNX并成功。
        C2向lock.foo发送DEL命令。
        C2向lock.foo发送SETNX并成功。
        出错:因为竞争条件的关系,C1和C2两个都获得了锁。

    幸好,以下算法可以避免以上问题。来看看我们聪明的C4客户端怎么办:

        C4向lock.foo发送SETNX命令。
        因为崩溃掉的C3还锁着lock.foo,所以Redis向C4返回0 。
        C4向lock.foo发送GET命令,查看lock.foo的锁是否过期。如果不,则休眠(sleep)一段时间,并在之后重试。
        另一方面,如果lock.foo内的unix时间戳比当前时间戳老(GET lock.foo < current Unix timestamp),C4执行以下命令:

        GETSET lock.foo <current Unix timestamp + lock timeout + 1>

        因为GETSET的作用,C4可以检查看GETSET的返回值,确定lock.foo之前储存的旧值仍是那个过期时间戳,如果是的话,那么C4获得锁。

        如果其他客户端,比如C5,比C4更快地执行了GETSET操作并获得锁,那么C4的GETSET操作返回的就是一个未过期的时间戳(C5设置的时间戳)。C4只好从第一步开始重试。
        注意,即便C4的GETSET操作对key进行了修改,这对未来也没什么影响。
        (这里是不是有点问题?C4的确是可以重试,但C5怎么办?它的锁的过期被C4修改了。——译注)

    重要提示: 为了让这个加锁算法更健壮(more robust),获得锁的客户端应该常常检查过期时间以免锁被诸如DEL等原因被意外解开,因为客户端失败的情况非常复杂,不仅仅是崩溃这么简单,还可能是客户端因为某些操作被阻塞了相当长时间,紧接着DEL操作被尝试执行(但这时锁却在另外的客户端手上)。


DECR key

    key中储存的数字值减一。
    如果key不存在,以0为起始值,然后执行减一操作。
    如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
    本操作只能对64位有符号数字使用。

    更多增一/减一操作信息,参见INCR命令。

        复杂度:
            O(1)

        返回值:
            减去一之后key的值

redis> SET failure_times 10
OK

redis> DECR failure_times
(integer) 9

redis> GET failure_times
"9"

redis> EXISTS count  # 测试对不存在的key值进行DECR
(integer) 0

redis> DECR count
(integer) -1
 

GETSET key value

    将给定key的值设为value,并返回旧值。
    当key存在但不是字符串类型时,返回一个错误。

        复杂度:
            O(1)

        返回值:
            返回给定key之前储存的旧值(oldd value)。
            当key没有旧值时,返回nil。

redis> EXISTS mail 
(integer) 0

redis> GETSET mail xxx@google.com  # 因为mail之前不存在,没有旧值,返回nil
(nil)

redis> GETSET mail xxx@yahoo.com  # mail被更新,旧值被返回
"xxx@google.com"
 
    设计模式

    GETSET可以和INCR组合使用,实现一个有原子性(atomic)复位操作的计数器(counter)。
    举例来说,每次当某个事件发生时,进程可能对一个名为mycount的key调用INCR操作,时不时我们还要在一个原子内同时完成获得计数器的值和将计数器复位为0两个操作。
    可以用命令GETSET mycounter 0来实现这一目标。

redis> INCR mycount 
(integer) 11

redis> GETSET mycount 0  # 一个原子内完成GET mycount和SET mycount 0操作
"11"

redis> GET mycount
"0"
  

MSETNX key value [key value ...]

    一次性设置多个key-value对,当且仅当key不存在。
    即便只有一个key已存在,MSETNX也会拒绝所有传入key的设置操作
    MSETNX是原子性的,因此它可以用作设置不同key表示不同字段(fields)的唯一性逻辑对象(unique logic object),所有字段要么全被设置,要么全不被设置。

        复杂度:
            O(N),N为要设置的key的数量。

        返回值:
            若所有key都成功设置,返回1.
            若所有key都设置失败(最少有一个key已经存在),那么返回0.

redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1

redis> MSETNX rmdbs "Sqlite" language "python"  # rmdbs键已经存在,操作失败
(integer) 0

redis> EXISTS language  # 因为操作是原子性的,language也没有被设置
(integer) 0

redis> GET rmdbs  # rmdbs没有被修改
"MySQL"

redis> MGET rmdbs nosql key-value-store  
1) "MySQL"
2) "MongoDB"
3) "redis"
 

SETRANGE key offset value

   用value覆写(Overwrite)给定key所储存的字符串值,从偏移量offset开始。
   不存在的key当作空白字符串处理。
   SETRANGE命令会确保字符串足够长以便将value设置在指定的偏移量上,如果给定key原来储存的字符串长度比偏移量小(比如字符串只有5个字符长,但你设置的offset是10),那么原字符和偏移量之>间的空白将用零比特(zerobytes,"\x00")来填充。
   注意你能使用的最大偏移量是2^29-1(536870911),因为Redis的字符串被限制在512兆(megabytes)内。如果你需要使用比这更大的空间,你得使用多个key。

   警告:当生成一个很长的字符串时,Redis需要分配内存空间,该操作有时候可能会造成服务器阻塞(block)。在2010年的Macbook Pro上,设置偏移量为536870911(512MB内存分配),耗费约300毫秒,
设置偏移量为134217728(128MB内存分配),耗费约80毫秒,设置偏移量33554432(32MB内存分配),耗费约30毫秒,设置偏移量为8388608(8MB内存分配),耗费约8毫秒。
   注意若首次内存分配成功之后,再对同一个key调用SETRANGE操作,无须再重新内存。

        复杂度:
            对小(small)的字符串,平摊复杂度O(1)。
            否则为O(M),M为value参数的长度。

        返回值:
            被SETRANGE修改之后,字符串的长度。

    模式
        因为有了SETRANGE和GETRANGE命令,你可以将Redis字符串用作具有O(1)随机访问时间的线性数组。这在很多真实用例中都是非常快速且高效的储存方式。

redis> SET greeting "hello world" 
OK

redis> SETRANGE greeting 6 "Redis"
(integer) 11

redis> GET greeting
"hello Redis"

redis> EXISTS empty_string
(integer) 0

redis> SETRANGE empty_string 5 "Redis!"  # 对不存在的key使用SETRANGE
(integer) 11

redis> GET empty_string  # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
 

DECRBY key decrement

    将key所储存的值减以decrement。
    如果key不存在,key被初始化为0,然后执行DECRBY操作。
    如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
    本操作只能对64位有符号数字使用。
    
        复杂度:
            O(1)

        返回值:
            减去decrement之后,key的值

redis> SET count 100
OK

redis> DECRBY count 20
(integer) 80

redis> EXISTS pages 
(integer) 0

redis> DECRBY pages 10  # 对不存在的pages进行DECRBY
(integer) -10
 

INCR key

    key中储存的数字值增一。
    如果key不存在,以0为起始值,然后执行增一操作。
    如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
    本操作只能对64位有符号数字使用。

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

        复杂度:
            O(1)

        返回值:
            增一之后key所储存的值。

redis> SET page_view 20
OK

redis> INCR page_view
(integer) 21

redis> GET page_view
"21"
 

SET key value

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

        复杂度:
            O(1)

        返回值:
            总是返回OK,因为SET不可能失败。

redis> SET apple www.apple.com
OK

redis> GET apple
"www.apple.com"
 

STRLEN key

    返回key所储存的字符串值的长度。
    当key储存的不是字符串值时,返回一个错误。

        复杂度:
            O(1)

        返回值:
            返回字符串值的长度。
            如果key不存在,返回0 。

redis> SET mykey "Hello world"
OK

redis> STRLEN mykey
(integer) 11

redis> STRLEN nonexisting
(integer) 0
 

GET key 
    
    返回key的值(value)。
    如果key不存在则返回特殊值nil。
    假如key的值不是字符串,返回一个错误,因为GET只能用于处理字符串值。

        复杂度:
            O(1)

        返回值:
            key的值。
            如果key不存在,返回nil。

redis> GET fake_key
(nil)

redis> SET animate "anohana"
OK

redis> GET animate
"anohana"
 

INCRBY key increment

    将key所储存的值加上increment。
    如果key不存在,key被初始化为0,然后执行INCRBY操作。
    如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
    本操作只能对64位有符号数字使用。
    
        复杂度:
            O(1)

        返回值:
            加上increment之后,key的值。

redis> SET rank 50  # 设置rank为50
OK

redis> INCRBY rank 20  # 给rank加上20
(integer) 70

redis> GET rank  
"70"

redis> EXISTS counter
(integer) 0

redis> INCRBY counter 30  # 对不存在的key进行INCRBY操作
(integer) 30

redis> GET counter
"30"
 

SETBIT key offset value 

    对key所储存的字符串值,设置或清除指定偏移量上的位。

    位的设置或清除取决于value参数,可以是0也可以是1。
    当key不存在时,自动生成一个新的字符串值。
    字符串会增长(grown)以确保它可以将value保存在指定的偏移量上。offset参数必须大于或等于0,小于2^32(bit映射被限制在512MB内)。当字符串值增长时,空白位置以0填充。

    警告: 对使用大的offset的SETBIT操作来说,内存分配可能造成Redis服务器被阻塞。(具体参考SETRANGE命令,"警告"部分。)

        复杂度:
            O(1)

        返回值:
            指定偏移量原来储存的位。

redis> SETBIT eight 0 1  # 保存一个二进制的8(1000)
(integer) 0

redis> SETBIT eight 1 0
(integer) 0

redis> SETBIT eight 2 0
(integer) 0

redis> SETBIT eight 3 0
(integer) 0

redis> GET eight  # 看来redis认得二进制
"\x80"
 

GETBIT key offset 

    对key所储存的字符串值,获取指定偏移量上的bit位。
    当offset比字符串值的长度大,或者key不存在,返回0 。
    
        复杂度:
            O(1)

        返回值:
            字符串值指定偏移量上的bit位。

redis> EXISTS active_flag
(integer) 0

redis> GETBIT active_flag 0  # key不存在时
(integer) 0

redis> SETBIT active_flag 0 1
(integer) 0

redis> GETBIT active_flag 0
(integer) 1
 

MGET key [key ...] 

    返回所有给定key的值。
    如果某个指定key不存在,那么返回特殊值nil。因此,该操作永不失败。

        复杂度:
            O(1)
            
        返回值:
            一个包含所有给定key的值的列表。

redis> MSET name huangz twitter twitter.com/huangz1990 blog www.SideEffect.me  #用MSET一次储存多个值
OK

redis> MGET name twitter blog
1) "huangz"
2) "twitter.com/huangz1990"
3) "www.SideEffect.me"

redis> EXISTS fake_key
(integer) 0

redis> MGET name fake_key  # 当MGET中有不存在key的情况
1) "huangz"
2) (nil)
 

SETEX key seconds value 

    将值(value)保存到key,并为key设置过期时间(以秒为单位)。  

    这个命令等同于以下两个命令:
        SET key value
        EXPIRE key seconds
    不同之处是,SETEX是一个原子操作,SET和EXPIRE两个操作会在同一时间内完成,该命令在Redis用作缓存时,非常常用。

        复杂度:
            O(1)

        返回值:
            设置成功时返回OK。
            当seconds参数不合法时,返回一个错误。

redis> SETEX cache_user_id 60 10086
OK

redis> GET cache_user_id  # 值
"10086"
 
redis> TTL cache_user_id  # 过期时间
(integer) 49
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics