Redis高級命令操作大全--推薦
阿新 • • 發佈:2018-07-05
例如 ati sort list 安裝 命令執行 大數 結合 字符串長度 鏈表
redis安裝和使用
redis安裝
wget http://download.redis.io/redis-stable.tar.gz tar zxvf redis-stable.tar.gz cd redis-stable.tar.gz make make install
redis啟動
redis-serverredis關閉
redis-cli shutdown
配置
方法一
redis-server /path/to/redis.conf redis-server /path/to/redis.conf --loglevel warning //設置日誌級別
方法二
redis-cli redis > CONFIG SET loglevel warning
多數據庫的選擇
默認情況下,客戶端自動選擇0號數據庫。 可以使用select命令來選擇其他數據庫。> select 1redis不可以設置數據庫的名稱,數據庫是通過編號來使用的。 redis只有一個全局的密碼,不存在訪問某個數據庫的密碼。
數據庫基本操作
(1)添加數據和查找數據,通過set/get命令添加和獲取數據
127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> set bar 1 OK 127.0.0.1:6379[1]> get bar "1" 127.0.0.1:6379[1]> get aaa (nil)
(2)判斷一個鍵是否存在,exists命令可以判斷key是否存在,存在返回1,不存在返回0
127.0.0.1:6379[1]> exists bar (integer) 1 127.0.0.1:6379[1]> exists aaa (integer) 0
(3)刪除數據,del命令刪除key,返回值為成功刪除key的個數
127.0.0.1:6379[1]> del aaa (integer) 0 127.0.0.1:6379[1]> del bar (integer) 1
(4)獲取value的類型
127.0.0.1:6379[1]> set bar 1 OK 127.0.0.1:6379[1]> type bar string
(5)自增和自減,incr 、decr以及incrby和decrby實現整數的加減
127.0.0.1:6379[1]> INCR ab (integer) 1 127.0.0.1:6379[1]> INCR ab (integer) 2 127.0.0.1:6379[1]> INCRBY ab 2 (integer) 4 127.0.0.1:6379[1]> DECR ab (integer) 3 127.0.0.1:6379[1]> DECRBY ab 2 (integer) 1
(6)增加指定浮點數,incrbyfloat可以指定自增的浮點數
127.0.0.1:6379[1]> INCRBYFLOAT ab 1.1 "2.1"
(7)向尾部追加,append命令可以向字符尾部追加內容
127.0.0.1:6379[1]> set key hello OK 127.0.0.1:6379[1]> append key world (integer) 10 127.0.0.1:6379[1]> get key "helloworld"
(8)獲取字符串長度,strlen獲取value的長度
127.0.0.1:6379[1]> STRLEN key (integer) 10
(9)批量設置和獲取,通過mset和mget命令可以批量執行設置和獲取
127.0.0.1:6379[1]> mset key1 va1 key2 va2 OK 127.0.0.1:6379[1]> mget key1 key2 1) "va1" 2) "va2"
(10)位操作
getbit key offset setbit key offset bitcount key [start] [end] bitop operation destkey key [key ...]
散列類型
其實這裏的散列類型就是類似於非結構化數據,json數據一樣。{ "id":1, "name":"test" }
基本操作
(1)存儲方法,可以通過hset和hget來設置和獲取數據
127.0.0.1:6379[1]> hset user id 1 (integer) 1 127.0.0.1:6379[1]> hset user name test (integer) 1 127.0.0.1:6379[1]> hget user id "1" 127.0.0.1:6379[1]> hget user name "test"
(2)判斷字段是否存在,hexists命令,返回1存在,返回0不存在
127.0.0.1:6379[1]> hexists user id (integer) 1 127.0.0.1:6379[1]> hexists user age (integer) 0
(3)使用hsetnx(hset if not exists)如果不存在賦值
127.0.0.1:6379[1]> hsetnx user age 111 (integer) 1 127.0.0.1:6379[1]> hget user age "111"
(4)增加數字
127.0.0.1:6379[1]> hincrby user score 60 (integer) 60 127.0.0.1:6379[1]> hget user score "60"
(5)刪除字段
127.0.0.1:6379[1]> hdel user score (integer) 1 127.0.0.1:6379[1]> hget user score (nil)
如何存儲數據?
(1)使用散列類型存儲數據,散列數據包括三部分(鍵、字段、字段值)鍵 字段 字段值 post:id field value
127.0.0.1:6379[1]> incr userid (integer) 1 127.0.0.1:6379[1]> hset user:1 name test (integer) 1 127.0.0.1:6379[1]> hset user:1 score 90 (integer) 1 127.0.0.1:6379[1]> incr userid (integer) 2 127.0.0.1:6379[1]> hset user:2 name test2 (integer) 1 127.0.0.1:6379[1]> hset user:2 score 99 (integer) 1
添加了兩條數據,id為1的名字為test分數為90,而id為2的名字為test2分數為90.
(2)獲取多個字段的數據,需要使用hmget命令,並制定字段名稱127.0.0.1:6379[1]> hmget user:1 name score 1) "test" 2) "90"(3)獲取一行數據,不需要指定字段名稱,只需要指出鍵名
127.0.0.1:6379[1]> hgetall user:2 1) "name" 2) "test2" 3) "score" 4) "99"(4)只獲取字段名或字段值
127.0.0.1:6379[1]> hkeys user:1 1) "name" 2) "score" 127.0.0.1:6379[1]> hvals user:1 1) "test" 2) "90"(5)獲取字段數量
127.0.0.1:6379[1]> hlen user:1 (integer) 2
需要註意的是,散列類型無法獲取所有存在的鍵值,也就是id,如果刪除了中間某個id的話,只可以使用exist命令來判斷key是否存在。
列表類型
類表類型解決了上述的問題。 類表類型是有序的,值是可以重復的。 列表類型是通過雙向鏈表實現的,向列表兩端添加元素的時間復雜度為O(1),獲取兩端元素的速度也是最快。基本操作
列表的基本操作命令都是以l開頭的。
(1)添加和彈出元素使用lpush和rpush以及lpop和rpop分別從列表的左側和右側添加和刪除元素。127.0.0.1:6379> lpush user test (integer) 1 127.0.0.1:6379> rpush user test1 (integer) 2 127.0.0.1:6379> lpop user "test" 127.0.0.1:6379> rpop user "test1" 127.0.0.1:6379>(2)llen查看元素個數
127.0.0.1:6379> llen user (integer) 0 127.0.0.1:6379> lpush user test (integer) 1 127.0.0.1:6379> llen user (integer) 1(3)獲取列表片段
127.0.0.1:6379> lrange user 0 3 1) "test" 2) "test1" 3) "test2" 4) "test3" 127.0.0.1:6379> lrange user 0 2 1) "test" 2) "test1" 3) "test2"(4)從列表中刪除元素
lrem key count value @count 為刪除個數,大於0的話從左邊開始,小於0的話從右邊開始 @value 要刪除的值
(5)獲取和設置索引元素值 (6)向列表中插入元素我們可以把數據的id存儲在列表中,當某一行數據被刪除時候,只需要刪除為該value為key即可,而查詢數據的時候,需要先從列表中讀取所有的id,再從散列表中讀取數據。
127.0.0.1:6379> lrange user 0 -1 1) "test" 2) "test1" 3) "test2" 4) "test3" 127.0.0.1:6379> linsert user before test1 test0 (integer) 5 127.0.0.1:6379> linsert user after test1 test1.5 (integer) 6 127.0.0.1:6379> lrange user 0 -1 1) "test" 2) "test0" 3) "test1" 4) "test1.5" 5) "test2" 6) "test3"(7)將元素從一個列表轉移到另外一個列表
rdroplpush source destination 從source列表的右側彈出一個數據,添加到destination列表的左側
集合類型
集合中不允許重復數據的出現,數據是唯一的,無序的。 空的散列表的HASH TABLE實現,因此操作時間復雜度為O(1)。 (1)增加sadd和刪除srem、獲取所有元素smembers,返回值標識成功添加元素的數量:127.0.0.1:6379> sadd key 1 (integer) 1 127.0.0.1:6379> sadd key 2 (integer) 1 127.0.0.1:6379> sadd key 2 (integer) 0 127.0.0.1:6379> smembers key 1) "1" 2) "2" 127.0.0.1:6379> srem key 2 (integer) 1 127.0.0.1:6379> smembers key 1) "1"(2)判斷元素是否在集合中可以使用sismember命令。
127.0.0.1:6379> sismember key 1 (integer) 1 127.0.0.1:6379> sismember key 3 (integer) 0(3)集合運算
sdiff key [key...] sinter key [key...] sunion key [key...](4)獲取元素個數
127.0.0.1:6379> scard key (integer) 1(5)集合運算並保存結果
sdiffstore destination key [key...] sinterstore destination key[key...] sunionstore destination key[key...](6)隨機獲取集合的元素
srandmember key [count] 127.0.0.1:6379> srandmember key 3 1) "4" 2) "2" 3) "3"需要註意,srandmember取到的隨機元素在集合比較小的情況下並不是完全隨機的,由於redis的存儲方法是利用哈希桶+數據鏈的存儲方式,當桶和每個桶內元素的個數都非常小時就會造成取到相同數據的情況。
有序集合類型 sorted set
與普通的集合類型相比,有序集合為集合中的每一個元素都關聯了一個分數,這使得我們不僅可以完成插入、刪除和判斷元素是否存在等集合的基本操作,還能夠得到分數最高(或最低)的前n個元素、獲得指定分數範圍內的元素等與分有關的操作,雖然集合中的元素必須是不同的,但是其分數是可以相同的。 有序結合和列表的使用區別: (1)列表類型是通過鏈來實現的,獲取靠近兩端數據的速度極快,而當元素增多後,訪問中間元素的數據就會變慢,所以她更適合實現如“新鮮事”或“日誌”這樣少訪問中間元素的應用。 (2)有序集合類型是使用散列和跳躍表實現的,所以即使讀取位於中間部分數據的速度也很快(時間復雜度為O(log(n)))。 (3)列表中不能簡單地調整某個元素的位置,但有序集合可以通過調整分數來實現位置的調整。 (4)有序集合更加消耗內存。基本操作
(1)zadd添加元素,並設置分數score
127.0.0.1:6379> zadd students 60 xiaoming (integer) 1 127.0.0.1:6379> zadd students 80 daxiong (integer) 1(2)zscore獲取元素分數
127.0.0.1:6379> zscore students xiaoming "60"(3)獲取排名在某個範圍的列表,元素是從0開始的
127.0.0.1:6379> zrange students 0 1 1) "xiaoming" 2) "daxiong"(4)獲取指定分數範圍的元素,用於篩選數據
127.0.0.1:6379> zrangebyscore students 0 70 1) "xiaoming" 127.0.0.1:6379> zrangebyscore students 0 100 1) "xiaoming" 2) "daxiong"limit命令可以實現sql語句中的Limit效果
獲取從0開始的前2個數據 127.0.0.1:6379> zrangebyscore students 0 100 limit 0 2 1) "xiaoming" 2) "daxiong" 獲取從1開始的前2個數據 127.0.0.1:6379> zrangebyscore students 0 100 limit 1 2 1) "daxiong"(5)增加和減少某個元素的分數
127.0.0.1:6379> zincrby students 5 xiaoming "65" 127.0.0.1:6379> zincrby students -5 xiaoming "60"(6)獲取集合中元素個數
127.0.0.1:6379> zcard students (integer) 2(7)獲取指定分數範圍內的元素個數
zcount key min max 127.0.0.1:6379> zcount students 0 70 (integer) 1 127.0.0.1:6379> zcount students 0 90 (integer) 2(8)刪除一個或多個元素
zrem key [key...](9)按照排名範圍來刪除元素
zremrangebyrank key start stop(10)按照分數範圍來刪除元素
zremrangebyscore key min max(11)獲取元素的排名,註意元素從0開始排序
127.0.0.1:6379> zrank students xiaoming
(integer) 0
事務
redis的事務是一組命令的集合。事務同命令一樣都是redis的最小執行單元,一個事務中的命令要麽執行要麽都不執行。
首先需要multi命令來開始事務,用exec命令來執行事務。
127.0.0.1:6379> multi OK 127.0.0.1:6379> hset user:1 name xiaoming QUEUED 127.0.0.1:6379> hset user:1 name daxiong QUEUED 127.0.0.1:6379> exec 1) (integer) 0 2) (integer) 0 127.0.0.1:6379> hgetall user:1 1) "name" 2) "daxiong" 3) "score" 4) "61"multi代表事務的開始,返回ok表示成功; exec代表事務的執行,返回各個命令的執行結果; 在multi和exec中間添加需要執行的命令。 在multi開始後,所有命令都不會執行,而是全部暫時保存起來,在執行exec命令後會按照命令保存的順序依次執行各個命令。 如果事務執行過程中存在失敗的情況下(某一個命令執行失敗後其他命令會繼續執行),需要開發人員自行處理後果。 註意:redis不支持回滾操作,導致redis的錯誤異常需要開發人員處理。
watch
watch命令可以監控一個或多個鍵值的變化,一旦其中一個鍵被改變,之後的事務就不會執行,而且監控會一直持續到exec命令。127.0.0.1:6379> set key 1 OK 127.0.0.1:6379> watch key OK 127.0.0.1:6379> set key 2 OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> set key 3 QUEUED 127.0.0.1:6379> exec (nil) 127.0.0.1:6379> get key "2"
生存時間
(1)設置key的超時時間,超時後redis會自動刪除給key值,類似於memcache中的超時時間。expire key seconds //設置成功返回1,失敗返回0
127.0.0.1:6379> set session:aabb uid1122 OK 127.0.0.1:6379> expire session:aabb 300 (integer) 1 127.0.0.1:6379> del session:aabb (integer) 1 127.0.0.1:6379> expire session:aabb 300 (integer) 0 127.0.0.1:6379> expire session:aabb 300 (integer) 1 127.0.0.1:6379> ttl session:aabb (integer) 290(2)查詢剩余超時時間
ttl key
127.0.0.1:6379> expire session:aabb 300 (integer) 1 127.0.0.1:6379> ttl session:aabb (integer) 290(3)取消超時時間 127.0.0.1:6379> get session:aabb
"300" 127.0.0.1:6379> ttl session:aabb (integer) 280 127.0.0.1:6379> persist session:aabb (integer) 1 127.0.0.1:6379> ttl session:aabb (integer) -1(4)如果使用設置相關的命令,會取消該鍵的超時間
緩存數據
在某些情況下,需要緩存一部分網站數據,而網站數據由需要持續的更新(假如需要兩個小時更新一次),那麽可以采用redis進行緩存這部分數據,設置數據的超時時間為2小時,每當有請求訪問的時候首先到redis中查找該數據是否存在,如果存在直接讀取,如果不存在的話重新從數據庫中讀取該數據加載到redis中。 在緩存數據的時候需要考慮到被緩存數據的大小,如果緩存數據較大,會占用過多的內存資源,有必要在配置文件中限制內存的使用大小(maxmemory)。 當超過maxmemory的限制後,redis會根據maxmemory-policy參數指定的策略(包括LRU等算法)來刪除不需要的鍵。排序
sort命令支持對集合類型、類表類型、有序集合類型進行排序。127.0.0.1:6379> lpush list 1 2 6 3 4 9 8 (integer) 7 127.0.0.1:6379> sort list 1) "1" 2) "2" 3) "3" 4) "4" 5) "6" 6) "8" 7) "9"可以對有序集合的值進行排序:
127.0.0.1:6379> zadd set 50 2 40 3 20 1 60 5 (integer) 4 127.0.0.1:6379> sort set 1) "1" 2) "2" 3) "3" 4) "5"sort命令可以添加desc來實現倒序排序
127.0.0.1:6379> sort set desc 1) "5" 2) "3" 3) "2" 4) "1"
BY參數
很多時候我們需要根據ID對應的對象的某一個屬性進行排序,那麽如何才能把多個不同的數據進行關聯查詢呢? (1)首先,向userids中添加三個用戶id127.0.0.1:6379> lpush userids 1 2 3 (integer) 3(2)其次,分別對三個用戶添加分數
127.0.0.1:6379> set user_score_1 50 OK 127.0.0.1:6379> set user_score_2 30 OK 127.0.0.1:6379> set user_score_3 70 OK(3)最後,使用sort、by命令來對對用戶按照默認情況以及分數的遞增和遞減進行排序。
127.0.0.1:6379> sort userids 1) "1" 2) "2" 3) "3" 127.0.0.1:6379> sort userids by user_score_* 1) "2" 2) "1" 3) "3" 127.0.0.1:6379> sort userids by user_score_* desc 1) "3" 2) "1" 3) "2"
GET參數
get參數並不影響排序,它的作用是使sort命令返回的結果不再是元素自身的值,而是get參數中指定的鍵值,同by參數一樣,支持字符串類型和散列類型的鍵。127.0.0.1:6379> sort userids by user_score_* get user_name_* 1) "xiaoming" 2) "daxiong" 3) "xiaohong" 127.0.0.1:6379> sort userids by user_score_* desc get user_name_* 1) "xiaohong" 2) "daxiong" 3) "xiaoming"
STORE參數
store參數用於結果保存。 sort命令是redis的復雜命令之一,使用不好會造成性能的瓶頸。 sort命令的時間復雜度是O(n+mlog(m)),其中n是排序列表(集合和有序集合)中元素的個數,m是返回元素的個數。Redis在排序前會建立一個長度為n的的容器來存儲待排序元素,雖然是一個臨時的過程,但是多個較大數據的排序操作則會嚴重影響系統的性能。 因此,在開發中需要註意: (1)盡可能減少排序鍵中的元素個數,降低n (2)使用Limit參數只獲取需要的數據,降低n (3)如果要排序的數據量較大,盡可能使用store名來緩存結果。任務隊列
任務隊列一般適用於生產者和消費者之間通信的,那麽在redis中很容易想到使用列表類型來實現任務隊列,具體方法是創建一個任務隊列,生產者主動lpush數據,而消費者去rpop數據,保持一個先進先出的循序。 但是這樣存在一個問題,消費者需要主動去請求數據,周期性的請求會造成資源的浪費,因此,redis提供了一個brpop的命令來解決這個問題。BRPOP key timeoutbrpop命令接收兩個參數,第一個參數key為鍵值,第二個參數timeout為超時時間。BRPOP命令取數據時候,如果暫時不存在數據,該命令會一直阻塞直到達到超時時間。如果timeout設置為0,那麽就會無限等待下去。
優先級隊列
基於任務隊列,如何實現優先級隊列呢? 那麽可以選擇多個任務隊列,而每個任務隊列的任務優先級是不同的。 redis提供了下面的命令,會從左邊第一個key開始讀下去知道返回一個數據。brpop key [key...] timetout
發布/訂閱模式
redis提供了rabitmq類似的發布訂閱模式,通過生產者使用下面的命令來發布消息,PUBLISH CHANNEL MESSAGE消費者通過下面的消息來訂閱消息,
SUBSCRIBE CHANNEL MESSAGE生產者:
#向channel.test發布消息 127.0.0.1:6379> publish channel.test hello (integer) 0 #返回0表明訂閱者為0,沒有發布消息 127.0.0.1:6379> publish channel.test hello (integer) 1 #返回n表明訂閱者為n,成功發布給1個消費者消費者:
#訂閱channel.test消息 127.0.0.1:6379> subscribe channel.test Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "channel.test" 3) (integer) 1
#接收到來自channel.test的消息 1) "message" 2) "channel.test" 3) "hello"
管道
redis的底層通信協議對管道提供了支持。通過管道可以一次性發送多條命令並在執行完後一次性將結果返回,當一組命令中每條命令都不依賴之前命令的執行結果時就可以將這組命令一起通過管道發出。管道通過減少客戶端與redis的通信次數來實現降低往返實驗累計值的目的。節省空間
(1)精簡鍵名和鍵值 (2)redis為每種數據類型提供了兩種內部編碼。例如散列類型的存儲是通過散列表來實現的,redis會根據數據的多少來選擇編碼類型,當數據較少的時候會采用緊湊但性能稍差的內部編碼方式,而數據變多時會把編碼方式改為散列表。 轉載自:cococo點點 http://www.cnblogs.com/coder2012Redis高級命令操作大全--推薦