Redis總結

akbarken發表於2013-11-13

redis是一個key-value儲存系統。和Memcached類似。

1>它支援儲存的value型別相對更多,包括string(字串)、list(連結串列)、set(集合)、zset(sorted set --有序集合)和hashs(雜湊型別)。

2>這些資料型別都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。

在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是快取在記憶體中。

3>區別的是redis會週期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步。

Redis提供了豐富的命令(command)對資料庫和各種資料型別進行操作,這些command可以在Linux終端使用。在程式設計時,比如使用Redis 的Java語言包,這些命令都有對應的方法。下面將Redis提供的命令做一總結。

官網命令列表:http://redis.io/commands (英文)

1、連線操作相關的命令

  • quit:關閉連線(connection)
  • auth:簡單密碼認證

2、對value操作的命令

  • exists(key):確認一個key是否存在
  • del(key):刪除一個key
  • type(key):返回值的型別
  • keys(pattern):返回滿足給定pattern的所有key
  • randomkey:隨機返回key空間的一個key
  • rename(oldname, newname):將key由oldname重新命名為newname,若newname存在則刪除newname表示的key
  • dbsize:返回當前資料庫中key的數目
  • expire:設定一個key的活動時間(s)
  • ttl:獲得一個key的活動時間
  • select(index):按索引查詢
  • move(key, dbindex):將當前資料庫中的key轉移到有dbindex索引的資料庫
  • flushdb:刪除當前選擇資料庫中的所有key
  • flushall:刪除所有資料庫中的所有key

3、對String操作的命令

  • set(key, value):給資料庫中名稱為key的string賦予值value
  • get(key):返回資料庫中名稱為key的string的value
  • getset(key, value):給名稱為key的string賦予上一次的value
  • mget(key1, key2,…, key N):返回庫中多個string(它們的名稱為key1,key2…)的value
  • setnx(key, value):如果不存在名稱為key的string,則向庫中新增string,名稱為key,值為value
  • setex(key, time, value):向庫中新增string(名稱為key,值為value)同時,設定過期時間time
  • mset(key1, value1, key2, value2,…key N, value N):同時給多個string賦值,名稱為key i的string賦值value i
  • msetnx(key1, value1, key2, value2,…key N, value N):如果所有名稱為key i的string都不存在,則向庫中新增string,名稱key i賦值為value i
  • incr(key):名稱為key的string增1操作
  • incrby(key, integer):名稱為key的string增加integer
  • decr(key):名稱為key的string減1操作
  • decrby(key, integer):名稱為key的string減少integer
  • append(key, value):名稱為key的string的值附加value
  • substr(key, start, end):返回名稱為key的string的value的子串

4、對List操作的命令

  • rpush(key, value):在名稱為key的list尾新增一個值為value的元素
  • lpush(key, value):在名稱為key的list頭新增一個值為value的 元素
  • llen(key):返回名稱為key的list的長度
  • lrange(key, start, end):返回名稱為key的list中start至end之間的元素(下標從0開始,下同)
  • ltrim(key, start, end):擷取名稱為key的list,保留start至end之間的元素
  • lindex(key, index):返回名稱為key的list中index位置的元素
  • lset(key, index, value):給名稱為key的list中index位置的元素賦值為value
  • lrem(key, count, value):刪除count個名稱為key的list中值為value的元素。count為0,刪除所有值為value的元素,count>0從頭至尾刪除count個值為value的元素,count<0從尾到頭刪除|count|個值為value的元素。 lpop(key):返回並刪除名稱為key的list中的首元素 rpop(key):返回並刪除名稱為key的list中的尾元素 blpop(key1, key2,… key N, timeout):lpop命令的block版本。即當timeout為0時,若遇到名稱為key i的list不存在或該list為空,則命令結束。如果timeout>0,則遇到上述情況時,等待timeout秒,如果問題沒有解決,則對keyi+1開始的list執行pop操作。
  • brpop(key1, key2,… key N, timeout):rpop的block版本。參考上一命令。
  • rpoplpush(srckey, dstkey):返回並刪除名稱為srckey的list的尾元素,並將該元素新增到名稱為dstkey的list的頭部

5、對Set操作的命令

  • sadd(key, member):向名稱為key的set中新增元素member
  • srem(key, member) :刪除名稱為key的set中的元素member
  • spop(key) :隨機返回並刪除名稱為key的set中一個元素
  • smove(srckey, dstkey, member) :將member元素從名稱為srckey的集合移到名稱為dstkey的集合
  • scard(key) :返回名稱為key的set的基數
  • sismember(key, member) :測試member是否是名稱為key的set的元素
  • sinter(key1, key2,…key N) :求交集
  • sinterstore(dstkey, key1, key2,…key N) :求交集並將交集儲存到dstkey的集合
  • sunion(key1, key2,…key N) :求並集
  • sunionstore(dstkey, key1, key2,…key N) :求並集並將並集儲存到dstkey的集合
  • sdiff(key1, key2,…key N) :求差集
  • sdiffstore(dstkey, key1, key2,…key N) :求差集並將差集儲存到dstkey的集合
  • smembers(key) :返回名稱為key的set的所有元素
  • srandmember(key) :隨機返回名稱為key的set的一個元素

6、對zset(sorted set)操作的命令

  • zadd(key, score, member):向名稱為key的zset中新增元素member,score用於排序。如果該元素已經存在,則根據score更新該元素的順序。
  • zrem(key, member) :刪除名稱為key的zset中的元素member
  • zincrby(key, increment, member) :如果在名稱為key的zset中已經存在元素member,則該元素的score增加increment;否則向集合中新增該元素,其score的值為increment
  • zrank(key, member) :返回名稱為key的zset(元素已按score從小到大排序)中member元素的rank(即index,從0開始),若沒有member元素,返回“nil”
  • zrevrank(key, member) :返回名稱為key的zset(元素已按score從大到小排序)中member元素的rank(即index,從0開始),若沒有member元素,返回“nil”
  • zrange(key, start, end):返回名稱為key的zset(元素已按score從小到大排序)中的index從start到end的所有元素
  • zrevrange(key, start, end):返回名稱為key的zset(元素已按score從大到小排序)中的index從start到end的所有元素
  • zrangebyscore(key, min, max):返回名稱為key的zset中score >= min且score <= max的所有元素 zcard(key):返回名稱為key的zset的基數 zscore(key, element):返回名稱為key的zset中元素element的score zremrangebyrank(key, min, max):刪除名稱為key的zset中rank >= min且rank <= max的所有元素 zremrangebyscore(key, min, max) :刪除名稱為key的zset中score >= min且score <= max的所有元素
  • zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX):對N個zset求並集和交集,並將最後的集合儲存在dstkeyN中。對於集合中每一個元素的score,在進行AGGREGATE運算前,都要乘以對於的WEIGHT引數。如果沒有提供WEIGHT,預設為1。預設的AGGREGATE是SUM,即結果集合中元素的score是所有集合對應元素進行SUM運算的值,而MIN和MAX是指,結果集合中元素的score是所有集合對應元素中最小值和最大值。

7、對Hash操作的命令

  • hset(key, field, value):向名稱為key的hash中新增元素field<—>value
  • hget(key, field):返回名稱為key的hash中field對應的value
  • hmget(key, field1, …,field N):返回名稱為key的hash中field i對應的value
  • hmset(key, field1, value1,…,field N, value N):向名稱為key的hash中新增元素field i<—>value i
  • hincrby(key, field, integer):將名稱為key的hash中field的value增加integer
  • hexists(key, field):名稱為key的hash中是否存在鍵為field的域
  • hdel(key, field):刪除名稱為key的hash中鍵為field的域
  • hlen(key):返回名稱為key的hash中元素個數
  • hkeys(key):返回名稱為key的hash中所有鍵
  • hvals(key):返回名稱為key的hash中所有鍵對應的value
  • hgetall(key):返回名稱為key的hash中所有的鍵(field)及其對應的value

8、持久化

  • save:將資料同步儲存到磁碟
  • bgsave:將資料非同步儲存到磁碟
  • lastsave:返回上次成功將資料儲存到磁碟的Unix時戳
  • shundown:將資料同步儲存到磁碟,然後關閉服務

9、遠端服務控制

  • info:提供伺服器的資訊和統計
  • monitor:實時轉儲收到的請求
  • slaveof:改變複製策略設定
  • config:在執行時配置Redis伺服器
Redis 事務機制:

二、相關命令列表:

命令原型 時間複雜度 命令描述 返回值
MULTI   用於標記事務的開始,其後執行的命令都將被存入命令佇列,直到執行EXEC時,這些命令才會被原子的執行。 始終返回OK
EXEC   執行在一個事務內命令佇列中的所有命令,同時將當前連線的狀態恢復為正常狀態,即非事務狀態。如果在事務中執行了WATCH命令,那麼只有當WATCH所監控的Keys沒有被修改的前提下,EXEC命令才能執行事務佇列中的所有命令,否則EXEC將放棄當前事務中的所有命令。 原子性的返回事務中各條命令的返回結果。如果在事務中使用了WATCH,一旦事務被放棄,EXEC將返回NULL-multi-bulk回覆。
DISCARD   回滾事務佇列中的所有命令,同時再將當前連線的狀態恢復為正常狀態,即非事務狀態。如果WATCH命令被使用,該命令將UNWATCH所有的Keys。 始終返回OK。
WATCHkey [key ...] O(1) 在MULTI命令執行之前,可以指定待監控的Keys,然而在執行EXEC之前,如果被監控的Keys發生修改,EXEC將放棄執行該事務佇列中的所有命令。 始終返回OK。
UNWATCH O(1) 取消當前事務中指定監控的Keys,如果執行了EXEC或DISCARD命令,則無需再手工執行該命令了,因為在此之後,事務中所有被監控的Keys都將自動取消。 始終返回OK。

三、命令示例:

   1. 事務被正常執行:
    #在Shell命令列下執行Redis的客戶端工具。
    /> redis-cli
    #在當前連線上啟動一個新的事務。

    redis 127.0.0.1:6379> multi
    OK
    #執行事務中的第一條命令,從該命令的返回結果可以看出,該命令並沒有立即執行,而是存於事務的命令佇列。
    redis 127.0.0.1:6379> incr t1
    QUEUED
    #又執行一個新的命令,從結果可以看出,該命令也被存於事務的命令佇列。
    redis 127.0.0.1:6379> incr t2
    QUEUED
    #執行事務命令佇列中的所有命令,從結果可以看出,佇列中命令的結果得到返回。
    redis 127.0.0.1:6379> exec
    1) (integer) 1
    2) (integer) 1
        
   2. 事務中存在失敗的命令:
    #開啟一個新的事務。
    redis 127.0.0.1:6379> multi
    OK
    #設定鍵a的值為string型別的3。
    redis 127.0.0.1:6379> set a 3
    QUEUED
    #從鍵a所關聯的值的頭部彈出元素,由於該值是字串型別,而lpop命令僅能用於List型別,因此在執行exec命令時,該命令將會失敗。
    redis 127.0.0.1:6379> lpop a
    QUEUED
    #再次設定鍵a的值為字串4。
    redis 127.0.0.1:6379> set a 4
    QUEUED
    #獲取鍵a的值,以便確認該值是否被事務中的第二個set命令設定成功。
    redis 127.0.0.1:6379> get a
    QUEUED
    #從結果中可以看出,事務中的第二條命令lpop執行失敗,而其後的set和get命令均執行成功,這一點是Redis的事務與關係型資料庫中的事務之間最為重要的差別。
    redis 127.0.0.1:6379> exec
    1) OK
    2) (error) ERR Operation against a key holding the wrong kind of value
    3) OK
    4) "4"

   3. 回滾事務:
    #為鍵t2設定一個事務執行前的值。
    redis 127.0.0.1:6379> set t2 tt
    OK
    #開啟一個事務。
    redis 127.0.0.1:6379> multi
    OK
    #在事務內為該鍵設定一個新值。
    redis 127.0.0.1:6379> set t2 ttnew
    QUEUED
    #放棄事務。
    redis 127.0.0.1:6379> discard
    OK
    #檢視鍵t2的值,從結果中可以看出該鍵的值仍為事務開始之前的值。
    redis 127.0.0.1:6379> get t2
    "tt"

四、WATCH命令和基於CAS的樂觀鎖:

      在Redis的事務中,WATCH命令可用於提供CAS(check-and-set)功能。假設我們通過WATCH命令在事務執行之前監控了多個Keys,倘若在WATCH之後有任何Key的值發生了變化,EXEC命令執行的事務都將被放棄,同時返回Null multi-bulk應答以通知呼叫者事務執行失敗。例如,我們再次假設Redis中並未提供incr命令來完成鍵值的原子性遞增,如果要實現該功能,我們只能自行編寫相應的程式碼。其偽碼如下:
      val = GET mykey
      val = val + 1
      SET mykey $val
      以上程式碼只有在單連線的情況下才可以保證執行結果是正確的,因為如果在同一時刻有多個客戶端在同時執行該段程式碼,那麼就會出現多執行緒程式中經常出現的一種錯誤場景--競態爭用(race condition)。比如,客戶端A和B都在同一時刻讀取了mykey的原有值,假設該值為10,此後兩個客戶端又均將該值加一後set回Redis伺服器,這樣就會導致mykey的結果為11,而不是我們認為的12。為了解決類似的問題,我們需要藉助WATCH命令的幫助,見如下程式碼:
      WATCH mykey
      val = GET mykey
      val = val + 1
      MULTI
      SET mykey $val
      EXEC
      和此前程式碼不同的是,新程式碼在獲取mykey的值之前先通過WATCH命令監控了該鍵,此後又將set命令包圍在事務中,這樣就可以有效的保證每個連線在執行EXEC之前,如果當前連線獲取的mykey的值被其它連線的客戶端修改,那麼當前連線的EXEC命令將執行失敗。這樣呼叫者在判斷返回值後就可以獲悉val是否被重新設定成功。

參考文獻:
http://www.cnblogs.com/stephen-liu74/archive/2012/02/18/2357783.html
http://slj.me/2011/04/redis-cli-commands/
http://baike.baidu.com/link?url=lGUP7ZKfRvkSEVr6tDZNqhYT5YOpQkHBJ01My-RtE2xjjjvO-Ez1g0gDyUyMCofQcQWZzuA4qnZK2CyVYCZqTK#1  

相關文章