1)keysios
遍歷全部key。redis
可使用keys he*
遍歷全部以he開頭的鍵。數據庫
使用方式:熱備從節點,scan。編程
2)dbsize緩存
計算key的總數。安全
3)existsbash
檢查key是否存在。服務器
4)del key網絡
刪除指定的key-value。數據結構
5)expire key seconds
設置key的過時時間。
6)ttl key
查看key剩餘的過時時間。
7)persist key
去掉key的過時時間。
8)type key
查看key的類型。
1)純內存。
2)非阻塞IO。
3)避免線程切換和靜態消耗。
Redis String類型是能夠與Redis鍵關聯的最簡單的值類型。它是Memcached中惟一的數據類型,所以新手在Redis中使用它也很天然。
因爲Redis鍵是字符串,當咱們使用字符串類型做爲值時,咱們將字符串映射到另外一個字符串。字符串數據類型對於許多用例頗有用,例如緩存HTML片斷或頁面。
set
:無論key是否存在,都設置。
setnx
:key不存在,才設置。
set key value xx
:key存在,才設置。
mget key1 key2 key3,....
:批量獲取key,原子操做。
mset key1 value1 key2 value2 key3 value3
:批量設置key-value。
其實是一個map->map的結構,能夠很方便的存儲Java類。Redis哈希看起來正是人們可能指望看到一個「哈希」,使用字段值對:
> hmset user:1000 username antirez birthyear 1977 verified 1
OK
> hget user:1000 username
"antirez"
> hget user:1000 birthyear
"1977"
> hgetall user:1000
1) "username"
2) "antirez"
3) "birthyear"
4) "1977"
5) "verified"
6) "1"
複製代碼
hget、hset、hdel、hesists、hlen、hmget、hmset。
所述LPUSH命令將一個新元素到一個列表,在左側(在頭部),而RPUSH命令將一個新元素到一個列表,在右側(在尾部)。最後, LRANGE命令從列表中提取元素範圍:
> rpush mylist A
(integer) 1
> rpush mylist B
(integer) 2
> lpush mylist first
(integer) 3
> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
複製代碼
請注意,LRANGE須要兩個索引,即要返回的範圍的第一個和最後一個元素。兩個索引均可以是負數,告訴Redis從結尾開始計數:因此-1是最後一個元素,-2是列表的倒數第二個元素,依此類推。
正如您所見,RPUSH附加了列表右側的元素,而最後的LPUSH附加了左側的元素。
Redis列表中定義的一個重要操做是彈出元素的能力。彈出元素是從列表中檢索元素並同時從列表中刪除元素的操做。您能夠從左側和右側彈出元素,相似於如何在列表的兩側推送元素:
> rpush mylist a b c
(integer) 3
> rpop mylist
"c"
> rpop mylist
"b"
> rpop mylist
"a"
複製代碼
在許多用例中,咱們只想使用列表來存儲最新的項目,不管它們是什麼:社交網絡更新,日誌或其餘任何內容。
Redis容許咱們使用列表做爲上限集合,只記住最新的N項並使用LTRIM命令丟棄全部最舊的項。
的LTRIM命令相似於LRANGE,可是**,而不是顯示元件的指定範圍**它設置在該範圍做爲新的列表值。超出給定範圍以外的全部元素。
一個例子將使它更清楚:
> rpush mylist 1 2 3 4 5
(integer) 5
> ltrim mylist 0 2
OK
> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
複製代碼
上面的LTRIM命令告訴Redis只從索引0到2中獲取列表元素,其餘全部內容都將被丟棄。這容許一個很是簡單但有用的模式:一塊兒執行List推操做+ List修剪操做以添加新元素並丟棄超出限制的元素:
LPUSH mylist <some element>
LTRIM mylist 0 999
複製代碼
上面的組合添加了一個新元素,而且只將1000個最新元素放入列表中。使用LRANGE,您能夠訪問頂級項目,而無需記住很是舊的數據。
注意:雖然LRANGE在技術上是一個O(N)命令,可是訪問列表的頭部或尾部的小範圍是一個恆定時間操做。
Redis集是字符串的無序集合。該 SADD命令添加新的元素到set。對於集合執行許多其餘操做也是可能的,例如測試給定元素是否已存在,執行多個集合之間的交集,並集或差別等等。
> sadd myset 1 2 3
(integer) 3
> smembers myset
1. 3
2. 1
3. 2
複製代碼
在這裏,我已經爲個人集合添加了三個元素,並告訴Redis返回全部元素。正如您所看到的那樣,它們沒有排序 - Redis能夠在每次調用時以任意順序返回元素,由於與用戶沒有關於元素排序的合同。
Redis有命令來測試會員資格。例如,檢查元素是否存在:
> sismember myset 3
(integer) 1
> sismember myset 30
(integer) 0
複製代碼
排序集是一種數據類型,相似於Set和Hash之間的混合。與集合同樣,有序集合由惟一的,非重複的字符串元素組成,所以在某種意義上,有序集合也是一個集合。
可是,雖然內部集合中的元素沒有排序,可是有序集合中的每一個元素都與浮點值相關聯,稱爲分數 (這就是爲何類型也相似於散列,由於每一個元素都映射到一個值)。
此外,排序集合中的元素按順序排列(所以它們不是根據請求排序的,順序是用於表示排序集合的數據結構的特性)。它們按照如下規則訂購:
讓咱們從一個簡單的例子開始,添加一些選定的黑客名稱做爲有序集合元素,其出生年份爲「得分」。
> zadd hackers 1940 "Alan Kay"
(integer) 1
> zadd hackers 1957 "Sophie Wilson"
(integer) 1
> zadd hackers 1953 "Richard Stallman"
(integer) 1
> zadd hackers 1949 "Anita Borg"
(integer) 1
> zadd hackers 1965 "Yukihiro Matsumoto"
(integer) 1
> zadd hackers 1914 "Hedy Lamarr"
(integer) 1
> zadd hackers 1916 "Claude Shannon"
(integer) 1
> zadd hackers 1969 "Linus Torvalds"
(integer) 1
> zadd hackers 1912 "Alan Turing"
(integer) 1
複製代碼
正如您所看到的,ZADD與SADD相似,可是須要一個額外的參數(放在要添加的元素以前),即分數。 ZADD也是可變參數,所以您能夠自由指定多個得分 - 值對,即便在上面的示例中未使用它。
對於排序集,返回按出生年份排序的黑客列表是微不足道的,由於實際上它們已經排序了。
實現說明:排序集是經過包含跳過列表和散列表的雙端口數據結構實現的,所以每次添加元素時,Redis都會執行O(log(N))操做。這很好,可是當咱們要求排序的元素時,Redis根本不須要作任何工做,它已經所有排序了:
> zrange hackers 0 -1
1) "Alan Turing"
2) "Hedy Lamarr"
3) "Claude Shannon"
4) "Alan Kay"
5) "Anita Borg"
6) "Richard Stallman"
7) "Sophie Wilson"
8) "Yukihiro Matsumoto"
9) "Linus Torvalds"
複製代碼
若是我想以相反的方式訂購它們,最小到最老的怎麼辦?使用ZREVRANGE而不是ZRANGE:
> zrevrange hackers 0 -1
1) "Linus Torvalds"
2) "Yukihiro Matsumoto"
3) "Sophie Wilson"
4) "Richard Stallman"
5) "Anita Borg"
6) "Alan Kay"
7) "Claude Shannon"
8) "Hedy Lamarr"
9) "Alan Turing"
複製代碼
使用WITHSCORES
參數也能夠返回分數:
> zrange hackers 0 -1 withscores
1) "Alan Turing"
2) "1912"
3) "Hedy Lamarr"
4) "1914"
5) "Claude Shannon"
6) "1916"
7) "Alan Kay"
8) "1940"
9) "Anita Borg"
10) "1949"
11) "Richard Stallman"
12) "1953"
13) "Sophie Wilson"
14) "1957"
15) "Yukihiro Matsumoto"
16) "1965"
17) "Linus Torvalds"
18) "1969"
複製代碼
在切換到下一個主題以前,只須要關於排序集的最後一點。排序集的分數能夠隨時更新。僅針對已經包含在已排序集合中的元素調用ZADD將使用O(log(N))時間複雜度更新其得分(和位置)。所以,當有大量更新時,排序集合是合適的。
因爲這個特性,常見的用例是排行榜。典型的應用程序是一個Facebook遊戲,在這個遊戲中,您能夠結合使用高分進行排序的用戶以及獲取排名操做,以顯示前N個用戶以及排行榜中的用戶排名(例如,「你是這裏#4932的最佳成績「)。
理論值=命令平均執行時間*業務總QPS數。
1)maxIdle=maxTotal,減小建立新鏈接的開銷。
2)預熱minIdle,減小第一次啓動後的新鏈接的開銷。
生命週期
1)慢查詢發生在第三階段。
2)客戶端超時不必定慢查詢,但慢查詢是客戶端超時的一個可能因素。
1)slowlog-max-len
1:先進先出隊列
2:固定長度
3:保存在內存內
2)slowlog-log-slower-than
慢查詢閾值(單位:微秒)
1)slowlog get [n]:獲取慢查詢隊列。
2)slowlog len:獲取慢查詢隊列長度。
3)slowlog reset:清空慢查詢隊列。
1)slowlog-max-len不要設置太小,一般設置1000左右。
2)slowlog-log-slower-than不要設置過大,默認10ms,一般設置1ms。
3)理解生命週期。
4)按期持久化慢查詢。
Redis是使用客戶端 - 服務器模型和所謂的請求/響應協議的TCP服務器。
這意味着一般經過如下步驟完成請求:
例如,四個命令序列是這樣的:
客戶端和服務器經過網絡連接鏈接。這樣的連接能夠很是快(環回接口)或很是慢(在因特網上創建的鏈接,在兩個主機之間有許多跳)。不管網絡延遲是什麼,數據包都有時間從客戶端傳輸到服務器,而後從服務器返回到客戶端以進行回覆。
此時間稱爲RTT(Round Trip Time)。當客戶端須要連續執行許多請求時(例如,將多個元素添加到同一列表或使用多個鍵填充數據庫),很容易看出這會如何影響性能。例如,若是RTT時間是250毫秒(在因特網上的鏈路很是慢的狀況下),即便服務器可以每秒處理100k個請求,咱們也可以以每秒最多四個請求進行處理。
若是使用的接口是環回接口,則RTT要短得多(例如個人主機報告0,044毫秒,ping 127.0.0.1),但若是你須要連續執行屢次寫入,它仍然不少。
幸運的是,有一種方法能夠改進這個用例。
能夠實現請求/響應服務器,以便即便客戶端還沒有讀取舊響應,它也可以處理新請求。這樣就能夠將多個命令發送到服務器而無需等待回覆,最後只需一步便可讀取回復。
這被稱爲流水線技術,而且是幾十年來普遍使用的技術。例如,許多POP3協議實現已經支持此功能,大大加快了從服務器下載新電子郵件的過程。
Redis從很早就開始支持流水線操做,所以不管您運行什麼版本,均可以使用Redis進行流水線操做。這是使用原始netcat實用程序的示例:
$ (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG
複製代碼
重要說明:當客戶端使用流水線發送命令時,服務器將被強制使用內存對回覆進行排隊。所以,若是您須要使用流水線發送大量命令,最好將它們做爲具備合理數量的批次發送,例如10k命令,讀取回復,而後再次發送另外10k命令,依此類推。速度將幾乎相同,但使用的額外內存將最大爲此10k命令的回覆排隊所需的數量。
mset:原子操做。
pipeline:非原子操做。
1)注意每次pipeline攜帶數據量。
2)pipeline每次只能做用在一個Redis節點上。
SUBSCRIBE,UNSUBSCRIBE和PUBLISH 實現了發佈/訂閱消息傳遞範例,其中(引用維基百科)發件人(發佈者)沒有被編程爲將其消息發送給特定接收者(訂閱者)。相反,發佈的消息被表徵爲信道,而不知道可能存在什麼(若是有的話)訂戶。訂閱者表達對一個或多個頻道的興趣,而且僅接收感興趣的消息,而不知道有哪些(若是有的話)發佈者。發佈者和訂閱者的這種分離能夠容許更大的可擴展性和更動態的網絡拓撲。
例如,爲了訂閱頻道foo,bar客戶端發出提供頻道名稱的SUBSCRIBE:
SUBSCRIBE foo bar
複製代碼
其餘客戶端發送到這些頻道的消息將由Redis推送到全部訂閱的客戶端。
訂閱一個或多個頻道的客戶端不該發出命令,儘管它能夠訂閱和取消訂閱其餘頻道。對訂閱和取消訂閱操做的回覆以消息的形式發送,以便客戶端能夠只讀取連貫的消息流,其中第一個元素指示消息的類型。訂閱客戶端上下文中容許的命令是SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE,PUNSUBSCRIBE, PING和QUIT。
請注意,redis-cli在訂閱模式下不會接受任何命令,而且只能退出模式Ctrl-C。
消息是具備三個元素的Array回覆。
第一個元素是消息的類型:
subscribe
:表示咱們成功訂閱了做爲回覆中第二個元素的通道。第三個參數表示咱們當前訂閱的頻道數。unsubscribe
:表示咱們成功取消訂閱做爲回覆中第二個元素的頻道。第三個參數表示咱們當前訂閱的頻道數。當最後一個參數爲零時,咱們再也不訂閱任何通道,而且客戶端能夠發出任何類型的Redis命令,由於咱們在Pub / Sub狀態以外。message
:它是由另外一個客戶端發出的PUBLISH命令收到的消息。第二個元素是原始通道的名稱,第三個參數是實際的消息有效負載。Redis提供了不一樣的持久性選項:
最重要的是要理解RDB和AOF持久性之間的不一樣權衡。讓咱們從RDB開始:
通常的跡象是,若是您但願必定程度的數據安全性與PostgreSQL爲您提供的數據安全性至關,則應使用兩種持久性方法。
若是你很是關心你的數據,可是在發生災難的狀況下仍然會有幾分鐘的數據丟失,你能夠單獨使用RDB。
有許多用戶單獨使用AOF,但咱們不鼓勵它,由於不時有RDB快照是進行數據庫備份,更快重啓以及AOF引擎中出現錯誤的好主意。
注意:因爲全部這些緣由,咱們可能最終將AOF和RDB統一爲將來的單一持久性模型(長期計劃)。
有關詳細的服務器配置請查閱我以前的博客。
1)優先使用物理機或者高效支持fork操做的虛擬化技術。
2)控制Redis實例最大可用內存:maxmemory。
3)合理配置Linux內存分配策略:vm.overcommit_memory=1。
4)下降fork頻率:例如放寬AOF重寫自動觸發時機,沒必要要的全量複製。
開銷:RDB和AOF文件生成,屬於CPU密集型。
優化:不作CPU綁定,不和CPU密集型部署。
開銷:fork內存開銷,copy-on-write。
優化:echo never > /sys/kernel/mm/transparent_hugepage/enabled。
開銷:AOF和RDB文件寫入,能夠結合iostat,iotop分析。
優化:no-appendfsync-on-rewrite = yes
1)Redis日誌
2)info Persistence
3)硬盤使用狀況