Redis 服務器管理相關命令

客戶端相關

查看客戶端列表

CLIENT LIST

自2.4.0可用。git

時間複雜度:O(N) N是客戶端鏈接數量。redis

語法:CLIENT LIST
說明:

Redis CLIENT LIST 命令用於返回全部鏈接到服務器的客戶端信息和統計數據。shell

返回值:

一個獨特的字符串,格式以下:數據庫

  • 每一個已鏈接客戶端對應一行(以 LF 分割)express

  • 每行字符串由一系列 屬性=值(property=value) 形式的域組成,每一個域之間以空格分開。segmentfault

下面是各字段的含義:windows

  1. 客戶端標識api

CLIENT LIST 命令中相關字段:數組

    • id: 惟一的64位的客戶端1ID(Redis 2.8.12加入)。緩存

    • addr: 客戶端的地址和端口

    • fd: 套接字所使用的文件描述符

    • name:客戶端的名字,後面的 CLIENT SETNAMECLIENT GETNAME 兩個命令會對其進行說明。

    1. 輸入緩衝區

    Redis 爲每一個客戶端分配有輸入緩存區,用於將客戶端發送的命令臨時保存。Redis 會從緩存區中拉取命令並執行。輸入緩衝區會根據輸入內容大小的不一樣動態調整,只是要求每一個客戶端緩衝區的大小不能超過 1G ,超事後客戶端將被關閉。

    輸入緩衝區不受 maxmemory 控制,假設一個 Redis 實例設置了 maxmemory 爲4G,已經存儲了2G數據,可是若是此時輸入緩衝區使用了 3G,已經超過 maxmemory 限制,可能會產生數據丟失、鍵值淘汰、Out Of Memory 等狀況。這種狀況在正常使用過程當中出現較少,可是須要注意防範 Redis 使用不規範致使出現這種狀況

    形成緩衝區過大的緣由是 輸入命令過多,Redis 沒法及時處理,可能的狀況:

    ​ a) 客戶端過多,命令輸入過多。

    ​ b) 因爲命令使用的不恰當(key過大,或運行時間複雜度較高的命令)等緣由形成 Redis 阻塞沒法處理新的命令,從而致使客戶端輸入的命令積壓在輸入緩衝區,形成了輸入緩衝區過大。

    監控輸入緩衝區異常的方法有兩種:

    a) 經過按期執行 `CLIENT LIST` 命令,收集 `qbuf` 和 `qbuf-free` 找到異常的鏈接記錄並分析,最終找到可能出問題的客戶端。該方法能夠精準的監控每一個客戶端,但執行較慢,在鏈接數較多時可能會阻塞 Redis。
     b) 經過 `INFO CLIENTS` 命令,找到最大的輸入緩衝區(`client_biggest_input_buf`),該命令相較於 `CLIENT LIST`  執行較快,結果一目瞭然,但沒法精準到具體客戶端,沒法查看緩存區大小等信息。

    CLIENT LIST 命令中相關字段:

    • qbuf: 查詢緩衝區的總容量(字節爲單位, 0 表示沒有分配查詢緩衝區)

    • qbuf-free: 查詢緩衝區剩餘容量(字節爲單位, 0 表示沒有剩餘空間)

    1. 輸出緩衝區

    Redis爲每一個客戶端分配了輸出緩衝區,它的做用是保存命令執行的結果返回給客戶端,爲Redis和客戶端交互返回結果提供緩衝。與輸入緩衝區不一樣的是,輸出緩衝區的容量能夠經過參數 client-outputbuffer-limit 來進行設置,而且輸出緩衝區作得更加細緻,按照客戶端的不一樣分爲三種:普通客戶端、發佈訂閱客戶端、slave客戶端,不一樣類型的客戶端的輸出緩衝區不一樣能夠分別進行設置。

    在 Redis 配置文件中能夠配置:

    client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

    其中:

    • <class> :客戶端類型,分爲三種。

      a)normal:普通客戶端;

      b)slave:slave客戶端,用於複製;

      c)pubsub:發佈訂閱客戶端。

    • <hard limit>:若是客戶端使用的輸出緩衝區大於<hard limit>,客戶端會被當即關閉。

    • <soft limit><soft seconds> :若是客戶端使用的輸出緩衝區超過了 <soft limit> 而且持續了 <soft limit> 秒,客戶端會被當即關閉。

    Redis 中對應的默認配置:

    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit slave 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60

    輸出緩衝區一樣存在內存溢出的問題。(見 輸入緩衝區相關內容)

    輸出緩衝區由兩部分組成:響應緩衝區(16KB)和回覆列表,其中響應緩衝區返回比較小的執行結果,而回覆列表返回比較大的結果,例如大的字符串、HGEtALLSMEMBERS 命令的結果等。

    響應緩衝區使用的是字節數組,回覆列表使用的是列表。當響應緩衝區存滿後會將 Redis 新的返回結果存放在回覆列表的隊列中,隊列中的每一個對象就是每一個返回結果。

    監控輸出緩衝區異常的方法有兩種:

    a) 經過按期執行 `CLIENT LIST` 命令,收集 `obl`、`oll` 和 `omem` 找到異常的鏈接記錄並分析,最終找到可能出問題的客戶端。該方法能夠精準的監控每一個客戶端,但執行較慢,在鏈接數較多時可能會阻塞 Redis。
      b) 經過 `INFO CLIENTS` 命令,找到最大的回覆列表(`client_longest_output_list`),該命令相較於 `CLIENT LIST`  執行較快,結果一目瞭然,但沒法精準到具體客戶端,沒法查看緩存區大小等信息。

    相比於輸入緩衝區,輸出緩衝區出現異常的機率相對會比較大,預防出現問題的方法:

    1. 經過上面兩中方法進行監控,設置閾值,超閾值後及時處理。

    2. 顯示普通客戶端的輸出緩存區:

      client-output-buffer-limit normal 20mb 10mb 120

    3. 適當增大 slave 的輸出緩衝區的,若是 master 節點寫入較大,slave 客戶端的輸出緩衝區可能會比較大,一旦 slave 客戶端鏈接由於輸出緩衝區溢出被 kill ,會形成複製重連。

    4. 限制容易讓輸出緩衝區增大的命令,例如,高併發下的 MONITOR 命令就是一個危險的命令。

    5. 及時監控內存,一旦發現內存抖動頻繁,可能就是輸出緩衝區過大。

    CLIENT LIST 命令中相關字段:

    • obl: 輸出緩衝區的長度(字節爲單位, 0 表示沒有分配輸出緩衝區)

    • oll: 輸出列表包含的對象數量(當輸出緩衝區沒有剩餘空間時,命令回覆會以字符串對象的形式被入隊到這個隊列裏)

    • omem: 輸出緩衝區和輸出列表佔用的內存總量

    1. 客戶端的存活狀態

      • age: 以秒計算的已鏈接時長

      • idle: 最近一次(100ms 或者更長時間)以秒計算的空閒時長

    2. 客戶端類型

      • flags: 客戶端 flag

      客戶端 flag 能夠由如下部分組成:

      • O: 客戶端是 MONITOR 模式下的附屬節點(slave)

      • S: 客戶端是通常模式下(normal)的附屬節點

      • M: 客戶端是主節點(master)

      • x: 客戶端正在執行事務

      • b: 客戶端正在等待阻塞事件

      • i: 客戶端正在等待 VM I/O 操做(已廢棄)

      • d: 一個受監視(watched)的鍵已被修改, EXEC 命令將失敗

      • c: 在將回復完整地寫出以後,關閉連接

      • u: 客戶端未被阻塞(unblocked)

      • U: 經過Unix套接字鏈接的客戶端

      • r: 客戶端是隻讀模式的集羣節點

      • A: 儘量快地關閉鏈接

      • N: 未設置任何 flag,普通客戶端

    • db: 該客戶端正在使用的數據庫 ID

    • sub: 已訂閱頻道的數量

    • psub: 已訂閱模式的數量

    • multi: 在事務中被執行的命令數量

    • events: 文件描述符事件

    • cmd: 最近一次執行的命令

    文件描述符事件能夠是:

    • r: 客戶端套接字(在事件 loop 中)是可讀的(readable)

    • w: 客戶端套接字(在事件 loop 中)是可寫的(writeable)

    爲了 debug 的須要,常常會對域進行添加和刪除。一個版本安全的 Redis 客戶端使用這個命令時應該根據字段解析相應內容。(好比:處理未知的字段,應跳過該字段)。

    示例:
    coderknock> CLIENT LIST
    # 鏈接時間 87 秒 空閒 87 秒 說明該鏈接一直處於空閒狀態
    id=3 addr=127.0.0.1:55773 fd=8 name= age=87 idle=87 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=18446744073709537584 events=r cmd=command
    id=4 addr=127.0.0.1:55795 fd=7 name= age=58 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client
    #響應緩衝區的長度爲0,回覆列表有4869個對象,兩個部分共使用了133081288字節=126M
    id=7 addr=127.0.0.1:56358 fd=6 name= age=91 idle=0 flags=O db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=4869 omem=133081288 events=rw cmd=monitor

    獲取/設置名稱

    CLIENT GETNAME

    自2.6.9可用。

    時間複雜度:O(1)。

    語法:CLIENT GETNAME
    說明:

    CLIENT GETNAME 返回當前鏈接由CLIENT SETNAME設置的名字。若是沒有用CLIENT SETNAME設置名字,將返回一個空的回覆。

    返回值:

    返回鏈接名字或者空(沒有設置名字時)

    示例:
    coderknock> CLIENT GETNAME
    (nil)
    # 只針對當前客戶端
    coderknock> CLIENT SETNAME coderknock
    OK
    coderknock> CLIENT GETNAME
    "coderknock"

    CLIENT SETNAME

    自2.6.9可用。

    時間複雜度:O(1)。

    語法:CLIENT SETNAME connection-name
    說明:

    爲當前鏈接分配一個名字。

    這個名字會顯示在 CLIENT LIST 命令的結果中, 用於識別當前正在與服務器進行鏈接的客戶端。

    舉個例子, 在使用 Redis 構建隊列(queue)時, 能夠根據鏈接負責的任務(role), 爲信息生產者(producer)和信息消費者(consumer)分別設置不一樣的名字。

    名字使用 Redis 的字符串類型來保存, 最大能夠佔用 512 MB 。 另外, 爲了不和 CLIENT LIST 命令的輸出格式發生衝突, 名字裏不容許使用空格。

    要移除一個鏈接的名字, 能夠將鏈接的名字設爲空字符串 ""

    使用 CLIENT GETNAME 命令能夠取出鏈接的名字。

    新建立的鏈接默認是沒有名字的。

    在 Redis 應用程序發生鏈接泄漏時,爲鏈接設置名字是一種很好的 debug 手段。

    返回值:

    設置成功時返回 OK

    示例:
    # 新鏈接默認沒有名字
    
    coderknock> CLIENT GETNAME
    (nil)
    
    # 設置名字
    coderknock> CLIENT SETNAME coderknock
    OK
    
    # 返回名字
    coderknock> CLIENT GETNAME
    "coderknock"
    
    # 在客戶端列表中查看
    coderknock> CLIENT LIST
    id=5 addr=127.0.0.1:49298 fd=8 name=coderknock age=173 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client
    
    # 清除名字
    coderknock> CLIENT SETNAME        # 只用空格是不行的!
    (error) ERR Syntax error, try CLIENT (LIST | KILL ip:port)
    coderknock> CLIENT SETNAME ""     # 必須雙引號顯示包圍
    OK
    coderknock> CLIENT GETNAME
    (nil)
    coderknock> CLIENT LIST
    id=5 addr=127.0.0.1:49298 fd=8 name= age=203 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client
    
    #別的客戶端一樣能夠取名爲 coderknock
    coderknock> CLIENT LIST
    id=6 addr=127.0.0.1:49438 fd=7 name=coderknock age=67 idle=32 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client
    id=7 addr=127.0.0.1:49454 fd=9 name=coderknock age=25 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client

    在 Redis 只有一個應用方使用的狀況下,IP和端口做爲標識會更加清晰。當多個應用方共同使用一個Redis,那麼此時 CLIENT SETNAME 能夠做爲標識客戶端的一個依據。

    客戶端限制

    maxclients timeout

    在以前的 《Redis 配置》一文中咱們講過 CONFIG GET CONFIG_SETTING_NAMECONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE,命令,其中CONFIG GET/SET maxclients 用於獲取/設置客戶端最大鏈接數,一旦鏈接數超過 maxclients 新的鏈接將被拒絕,maxclients 默認值是10000,能夠經過 INFO clients來查詢當前Redis的鏈接數:

    # 查詢最大鏈接數
    coderknock> CONFIG GET maxclients
    1) "maxclients"
    2) "10000"
    coderknock> INFO clients
    # Clients
    connected_clients:1 #當前鏈接客戶端數
    client_longest_output_list:0
    client_biggest_input_buf:0
    blocked_clients:0

    能夠經過 CONFIG SET maxclients 對最大客戶端鏈接數進行動態設置:

    # 咱們將 maxclients 設置小些
    coderknock> CONFIG SET maxclients 2
    OK
    coderknock> CONFIG GET maxclients
    1) "maxclients"
    2) "2"
    # 咱們啓動再啓動兩個客戶端此時在第一個或第二個客戶端上執行
    coderknock> CLIENT LIST
    id=2 addr=127.0.0.1:51010 fd=7 name= age=386 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=18446744073709537584 events=r cmd=client
    id=3 addr=127.0.0.1:51091 fd=8 name= age=154 idle=126 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=18446744073709537584 events=r cmd=keys
    # 在第三個啓動的客戶端上進行操做(命令窗口並無關閉因此仍是能夠執行的)
    coderknock> keys *
    Error: 遠程主機強迫關閉了一個現有的鏈接。
    # 能夠看到這個客戶端不能正常使用

    通常狀況下 maxclients 默認的 10000 大小已經作夠使用了,可是有時因爲使用不當可能致使存在大量空閒鏈接(idle 較大的鏈接),不管是從網絡鏈接的成本仍是超過maxclients的後果來講都不是什麼好事,所以 Redis 提供了 timeout (單位爲秒)參數限制鏈接的最大空閒時間,一旦客戶端空閒時間超過了 timeout 設置,鏈接將會被關閉。使用 CONFIG GET/SET timeout 能夠獲取設置 timeout:

    # #Redis默認的 timeout 是0,也就是沒有超時時間
    coderknock> CONFIG GET timeout
    1) "timeout"
    2) "0"

    Redis的默認配置給出的 timeout=0 ,在這種狀況下客戶端基本不會出現上面的異常,這是基於對客戶端開發的一種保護。若是客戶端設置了超時,可能就會出現鏈接超時的異常,對應用業務形成必定影響,可是若是 Redis 的客戶端使用不當或者客戶端自己的一些問題,形成沒有及時釋放客戶端鏈接,可能會形成大量的空閒鏈接佔據着不少鏈接資源,一旦超過 maxclients;後果也是不堪設想。所在在實際開發和運維中,須要將 timeout 設置成大於0 且較大的數字,例如能夠設置爲300秒,同時在客戶端使用上添加空閒檢測和驗證等等措施。

    關閉客戶端

    CLINET KILL

    自2.4.0可用。

    時間複雜度:O(N) N是客戶端鏈接數量。

    語法:CLIENT KILL [ip:port][ID client-id] [normal|slave|pubsub][ADDR ip:port][SKIPME yes/no]
    說明:

    CLIENT KILL關閉一個指定的鏈接。在 Redis2.8.11 時能夠根據客戶端地址關閉指定鏈接,關閉方式以下:

    CLIENT KILL addr:port addr:port 應該是 CLIENT LIST 命令裏面列出的客戶端鏈接之一。

    然而,從Redis 2.8.12開始,這個命令改成以下格式:

    CLIENT KILL <filter> <value> ... ... <filter> <value>

    新的格式能夠根據不一樣屬性殺死客戶端而不是隻按地址殺死。他們有如下一些格式:

    • CLIENT KILL ADDR ip:port : 和舊版的三個參數時的行爲徹底同樣。

    • CLIENT KILL ID client-id : 能夠經過惟一 ID 字段殺死一個客戶端,惟一 ID 能夠經過 Redis 2.8.12 開始的 CLIENT LIST 命令查詢(以前版本可能沒有 ID 字段)。

    • CLIENT KILL TYPE type : 這裏的 type 能夠是 normal , slave , pubsub (Redis 3.2 版本以後增長了 master 類型的支持)。 這將關閉全部特殊類的客戶端。 請注意被認爲是屬於正常類的客戶端將會被MONITOR 命令監視到。

    • CLIENT KILL SKIPME yes/no:默認狀況下,該選項設置爲yes ,即調用過該命令的客戶端將不會被殺死,將該選項設置爲 no 即也會殺死調用過該命令的客戶端。

    該命令支持同時使用多個過濾器,或殺死多個過濾器的合集。

    因爲Redis的單線程特性,在執行命令時沒法終止客戶端鏈接。從客戶端的角度來看,在執行命令的過程當中,鏈接永遠不會被關閉。可是,只有當下一個命令發送(並致使網絡錯誤)時,客戶端纔會注意到鏈接已關閉。

    返回值:

    當用三個參數格式調用時:

    若是鏈接存在並已關閉返回OK

    當使用過濾器/值格式調用時:

    客戶端數量被殺。

    示例:
    # 列出全部已鏈接客戶端
    
    coderknock> CLIENT LIST
    addr=127.0.0.1:43501 fd=5 age=10 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
    
    # 殺死當前客戶端的鏈接
    
    coderknock> CLIENT KILL 127.0.0.1:43501
    OK
    
    # 以前的鏈接已經被關閉,CLI 客戶端又從新創建了鏈接
    # 以前的端口是 43501 ,如今是 43504
    
    coderknock> CLIENT LIST
    addr=127.0.0.1:43504 fd=5 age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

    因爲一些緣由(例如設置 timeout=0 時產生的長時間空閒的客戶端),須要手動殺掉客戶端鏈接時,可使用 CLIENT KILL 命令。

    阻塞客戶端

    CLIENT PAUSE

    自2.9.5可用。

    時間複雜度:O(1)。

    語法:CLIENT PAUSE timeout
    說明:

    CLIENT PAUSE 是一個鏈接控制命令,能夠在指定的時間(以毫秒爲單位)中掛起全部Redis客戶端。

    該命令執行如下操做:

    • 只對普通和發佈訂閱客戶端有效,對於主從複製(從節點內部假裝了一個客戶端)是無效的,也就是此期間主從複製是正常進行的,因此此命令能夠用來讓主從複製保持一致。

    • 可是它儘量地返回給調用者,所以 CLIENT PAUSE 命令的執行不會自動暫停(返回以後仍是會暫停自身的客戶端)。

    • 當指定的時間量過去時,全部客戶端都被解除阻塞:這將在暫停期間觸發對每一個客戶端的查詢緩衝區中累積的全部命令的處理。

    此命令很是有用,由於它能夠用一種可控的方式將客戶端鏈接從一個Redis節點切換到另外一個Redis節點。例如,在實例升級期間,系統管理員能夠執行如下操做:

    • 使用 CLIENT PAUSE 暫停客戶

    • 等待幾秒鐘以確保從站從主設備處理最新的複製流。

    • 把一個從節點變成一個主節點。

    • 從新配置客戶端以鏈接新的主節點。

    能夠將命令 暫停 發送到 MULTI / EXEC 塊 INFO replication 中,以便在客戶端被阻止時獲取當前的主節點偏移量。這樣,能夠在從屬端等待特定的偏移量,以確保處理全部的複製流。

    Redis 3.2.10 / 4.0.0 中此命令還能夠防止在客戶端暫停期間鍵被釋放或過時。這樣,數據集就被保證是靜態的,而不只僅是從客戶端沒法寫入的角度來看,並且從內部操做的角度來講也是如此。

    返回值:

    若是超時無效,則該命令返回OK或錯誤。

    示例:
    coderknock> CLIENT PAUSE 10000
    OK
    coderknock> GET hello
    "world"
    (10.06s) # 這裏能夠看到查詢花費 10s 的時間

    該命令在生產環境如要使用應挑選操做較少時,否則可能會引起不可預知的狀況。

    客戶端回覆設定

    CLIENT REPLY

    自3.2.0可用。

    時間複雜度:O(1)。

    語法:CLIENT REPLY ON|OFF|SKIP
    說明:

    有時客戶端能夠徹底禁用Redis服務器的回覆

    CLIENT REPLY 命令控制服務器是否會回覆客戶端的命令。提供如下模式:

    • ON。這是默認模式服務器返回每一個命令的回覆。

    • OFF。在此模式下,服務器將不會回覆客戶端命令。

    • SKIP。此模式會當即跳過命令的回覆。

    返回值:

    當用 OFFSKIP 命令調用時,不做任何回覆。調用時ON:返回OK

    該命令是新命令目前兼容客戶端較少

    監控

    MONITOR

    自1.0.0可用。

    時間複雜度:不明確。

    語法:MONITOR
    說明:

    MONITOR 是一個調試命令,返回服務器處理的每個命令,它能幫助咱們瞭解在數據庫上發生了什麼操做,能夠經過redis-cli和telnet命令使用.

    $ redis-cli monitor
    1339518083.107412 [0 127.0.0.1:60866] "keys" "*"
    1339518087.877697 [0 127.0.0.1:60866] "dbsize"
    1339518090.420270 [0 127.0.0.1:60866] "set" "x" "6"
    1339518096.506257 [0 127.0.0.1:60866] "get" "x"
    1339518099.363765 [0 127.0.0.1:60866] "del" "x"
    1339518100.544926 [0 127.0.0.1:60866] "get" "x"

    使用SIGINT (Ctrl-C)來中止 經過redis-cli使用 MONITOR 命令返回的輸出.

    $ telnet localhost 6379
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    MONITOR
    +OK
    +1339518083.107412 [0 127.0.0.1:60866] "keys" "*"
    +1339518087.877697 [0 127.0.0.1:60866] "dbsize"
    +1339518090.420270 [0 127.0.0.1:60866] "set" "x" "6"
    +1339518096.506257 [0 127.0.0.1:60866] "get" "x"
    +1339518099.363765 [0 127.0.0.1:60866] "del" "x"
    +1339518100.544926 [0 127.0.0.1:60866] "get" "x"
    QUIT
    +OK
    Connection closed by foreign host.

    使用 QUIT 命令來中止經過telnet使用 MONITOR 返回的輸出.

    MONITOR 性能消耗

    因爲 MONITOR 命令返回 服務器處理的全部的 命令, 因此在性能上會有一些消耗.

    在不運行 MONITOR 命令的狀況下,benchmark的測試結果:

    $ src/redis-benchmark -c 10 -n 100000 -q
    PING_INLINE: 101936.80 requests per second
    PING_BULK: 102880.66 requests per second
    SET: 95419.85 requests per second
    GET: 104275.29 requests per second
    INCR: 93283.58 requests per second

    在運行 MONITOR 命令的狀況下,benchmark的測試結果: (redis-cli monitor > /dev/null):

    $ src/redis-benchmark -c 10 -n 100000 -q
    PING_INLINE: 58479.53 requests per second
    PING_BULK: 59136.61 requests per second
    SET: 41823.50 requests per second
    GET: 45330.91 requests per second
    INCR: 41771.09 requests per second

    在這種特定的狀況下,運行一個 MONITOR 命令可以下降50%的吞吐量,運行多個 MONITOR 命令 下降的吞吐量更多。

    每一個客戶端都有本身的輸出緩衝區,既然 MONITOR 能監聽到全部的命令,一旦 Redis 的併發量過大 MONITOR 客戶端的輸出緩衝會暴漲,可能瞬間會佔用大量內存。

    返回值:

    沒有統一標準的返回值, 無限的返回服務器端處理的命令流.或 key 不存在,返回 0

    示例:
    # 方式一
    C:\Users\zylia>redis-cli -a admin123 monitor
    OK
    1498547986.670236 [0 127.0.0.1:63859] "AUTH" "admin123"
    1498547986.670366 [0 127.0.0.1:63859] "GET" "hello"
    1498548024.414979 [0 127.0.0.1:63869] "AUTH" "admin123"
    1498548024.415185 [0 127.0.0.1:63869] "COMMAND"
    1498548046.317448 [0 127.0.0.1:63872] "AUTH" "admin123"
    1498548046.317742 [0 127.0.0.1:63872] "COMMAND"
    #方式二 登陸後在進行
    coderknock> MONITOR
    OK
    1498548046.317448 [0 127.0.0.1:63872] "AUTH" "admin123"
    1498548046.317742 [0 127.0.0.1:63872] "COMMAND"
    #方式三 Telnet
    C:\Users\zylia>telnet 127.0.0.1 6379
    auth admin123
    +OK
    MONITOR
    +OK
    +1498548296.621530 [0 127.0.0.1:64068] "AUTH" "admin123"
    +1498548296.621658 [0 127.0.0.1:64068] "GET" "hello"
    # 支持同時開啓多個 MONITOR

    其餘配置

    • tcp-keepalive:檢測TCP鏈接活性的週期,默認值爲0,也就是不進行檢測,若是須要設置,建議爲60,那麼Redis會每隔60秒對它建立的TCP鏈接進行活性檢測,防止大量死鏈接佔用系統資源。

    • tcp-backlog:TCP 三次握手後,會將接受的鏈接放入隊列中,tcpbacklog就是隊列的大小,它在 Redis 中的默認值是 511。一般來說這個參數不須要調整,可是這個參數會受到操做系統的影響,例如在Linux操做系統中,若是/proc/sys/net/core/somaxconn小於tcp-backlog,那麼在Redis啓動時會看到以下日誌,並建議將/proc/sys/net/core/somaxconn設置更大。

      WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/
      sys/net/core/somaxconn is set to the lower value of 128.

    修改方法也很是簡單,只須要執行以下命令:

    echo 511 > /proc/sys/net/core/somaxconn

    源碼查看

    咱們來看下 Redis 源碼中客戶端部分的內容:

    typedef struct client {
        uint64_t id;            /* Client incremental unique ID.客戶端增量唯一的ID */
        int fd;                 /* Client socket. 客戶端套接字*/
        redisDb *db;            /* Pointer to currently SELECTed DB. 指向當前選擇的DB的指針*/
        robj *name;             /* As set by CLIENT SETNAME. 由客戶端 SETNAME命令設置*/
        sds querybuf;           /* Buffer we use to accumulate client queries. 用來累積客戶端查詢的緩衝區*/
        sds pending_querybuf;   /* If this is a master, this buffer represents the
                                   yet not applied replication stream that we
                                   are receiving from the master.若是這是一個主服務器 ,這個緩衝區表示咱們從主服務器接收到的未應用的複製流 */
        size_t querybuf_peak;   /* Recent (100ms or more) peak of querybuf size.最近(100ms 或者更長時間)querybuf 的峯值大小 */
        int argc;               /* Num of arguments of current command. 當前命令的參數個數*/
        robj **argv;            /* Arguments of current command. 當前命令的參數*/
        struct redisCommand *cmd, *lastcmd;  /* Last command executed. 最後一個被執行的命令*/
        int reqtype;            /* Request protocol type: PROTO_REQ_* 請求協議類型:PROTO_REQ_**/
        int multibulklen;       /* Number of multi bulk arguments left to read. 讀取的多批量參數的數量*/
        long bulklen;           /* Length of bulk argument in multi bulk request. 多批量請求的批量參數的長度*/
        list *reply;            /* List of reply objects to send to the client.發送給客戶端的應答對象列表(回覆列表 有的翻譯也叫動態緩衝區) */
        unsigned long long reply_bytes; /* Tot bytes of objects in reply list. 對象個數(列表長度)*/
        size_t sentlen;         /* Amount of bytes already sent in the current
                                   buffer or object being sent. 在當前的緩衝區或對象已經發送的字節數*/
        time_t ctime;           /* Client creation time. 客戶端建立時間*/
        time_t lastinteraction; /* Time of the last interaction, used for timeout 最後一次交互的時間,用於超時 */
        time_t obuf_soft_limit_reached_time;
        int flags;              /* Client flags: CLIENT_* macros. 客戶端標誌使用的是 CLIENT_* 宏指令(下面會列出)*/
        int authenticated;      /* When requirepass is non-NULL. 當 requirepass 不是 null 時會爲變量賦值*/
        int replstate;          /* Replication state if this is a slave. 複製狀態若是這是一個從機*/
        int repl_put_online_on_ack; /* Install slave write handler on ACK. */
        int repldbfd;           /* Replication DB file descriptor. */
        off_t repldboff;        /* Replication DB file offset. */
        off_t repldbsize;       /* Replication DB file size. */
        sds replpreamble;       /* Replication DB preamble. */
        long long read_reploff; /* Read replication offset if this is a master. */
        long long reploff;      /* Applied replication offset if this is a master. */
        long long repl_ack_off; /* Replication ack offset, if this is a slave. */
        long long repl_ack_time;/* Replication ack time, if this is a slave. */
        long long psync_initial_offset; /* FULLRESYNC reply offset other slaves
                                           copying this slave output buffer
                                           should use. */
        char replid[CONFIG_RUN_ID_SIZE+1]; /* Master replication ID (if master). */
        int slave_listening_port; /* As configured with: SLAVECONF listening-port */
        char slave_ip[NET_IP_STR_LEN]; /* Optionally given by REPLCONF ip-address */
        int slave_capa;         /* Slave capabilities: SLAVE_CAPA_* bitwise OR. */
        multiState mstate;      /* MULTI/EXEC state */
        int btype;              /* Type of blocking op if CLIENT_BLOCKED. */
        blockingState bpop;     /* blocking state */
        long long woff;         /* Last write global replication offset. */
        list *watched_keys;     /* Keys WATCHED for MULTI/EXEC CAS */
        dict *pubsub_channels;  /* channels a client is interested in (SUBSCRIBE) */
        list *pubsub_patterns;  /* patterns a client is interested in (SUBSCRIBE) */
        sds peerid;             /* Cached peer ID. */
    
        /* Response buffer 響應緩衝區(固定緩衝區)*/
        int bufpos;
        // 字節數組做爲響應緩衝區 16K  */
        char buf[PROTO_REPLY_CHUNK_BYTES];//#define PROTO_REPLY_CHUNK_BYTES (16*1024) /* 16k output buffer
    } client;

    Client flags

    /* Client flags */
    #define CLIENT_SLAVE (1<<0)   /* This client is a slave server */
    #define CLIENT_MASTER (1<<1)  /* This client is a master server */
    #define CLIENT_MONITOR (1<<2) /* This client is a slave monitor, see MONITOR */
    #define CLIENT_MULTI (1<<3)   /* This client is in a MULTI context */
    #define CLIENT_BLOCKED (1<<4) /* The client is waiting in a blocking operation */
    #define CLIENT_DIRTY_CAS (1<<5) /* Watched keys modified. EXEC will fail. */
    #define CLIENT_CLOSE_AFTER_REPLY (1<<6) /* Close after writing entire reply. */
    #define CLIENT_UNBLOCKED (1<<7) /* This client was unblocked and is stored in
                                      server.unblocked_clients */
    #define CLIENT_LUA (1<<8) /* This is a non connected client used by Lua */
    #define CLIENT_ASKING (1<<9)     /* Client issued the ASKING command */
    #define CLIENT_CLOSE_ASAP (1<<10)/* Close this client ASAP */
    #define CLIENT_UNIX_SOCKET (1<<11) /* Client connected via Unix domain socket */
    #define CLIENT_DIRTY_EXEC (1<<12)  /* EXEC will fail for errors while queueing */
    #define CLIENT_MASTER_FORCE_REPLY (1<<13)  /* Queue replies even if is master */
    #define CLIENT_FORCE_AOF (1<<14)   /* Force AOF propagation of current cmd. */
    #define CLIENT_FORCE_REPL (1<<15)  /* Force replication of current cmd. */
    #define CLIENT_PRE_PSYNC (1<<16)   /* Instance don't understand PSYNC. */
    #define CLIENT_READONLY (1<<17)    /* Cluster client is in read-only state. */
    #define CLIENT_PUBSUB (1<<18)      /* Client is in Pub/Sub mode. */
    #define CLIENT_PREVENT_AOF_PROP (1<<19)  /* Don't propagate to AOF. */
    #define CLIENT_PREVENT_REPL_PROP (1<<20)  /* Don't propagate to slaves. */
    #define CLIENT_PREVENT_PROP (CLIENT_PREVENT_AOF_PROP|CLIENT_PREVENT_REPL_PROP)
    #define CLIENT_PENDING_WRITE (1<<21) /* Client has output to send but a write
                                            handler is yet not installed. */
    #define CLIENT_REPLY_OFF (1<<22)   /* Don't send replies to client. */
    #define CLIENT_REPLY_SKIP_NEXT (1<<23)  /* Set CLIENT_REPLY_SKIP for next cmd */
    #define CLIENT_REPLY_SKIP (1<<24)  /* Don't send just this reply. */
    #define CLIENT_LUA_DEBUG (1<<25)  /* Run EVAL in debug mode. */
    #define CLIENT_LUA_DEBUG_SYNC (1<<26)  /* EVAL debugging without fork() */
    #define CLIENT_MODULE (1<<27) /* Non connected client used by some module. */

    INFO

    INFO

    自1.0.0可用。

    時間複雜度:O(1)。

    語法:INFO [section]
    說明:

    INFO命令以一種易於理解和閱讀的格式,返回關於Redis服務器的各類信息和統計數值。

    經過給定可選的參數 section ,可讓命令只返回某一部分的信息:

    • server: Redis服務器的通常信息

    • clients: 客戶端的鏈接部分

    • memory: 內存消耗相關信息

    • persistence: RDB和AOF相關信息

    • stats: 通常統計

    • replication: 主/從複製信息

    • cpu: 統計CPU的消耗

    • commandstats: Redis命令統計

    • cluster: Redis集羣信息

    • keyspace: 數據庫的相關統計

    它也能夠採起如下值:

    • all: 返回全部信息

    • default: 值返回默認設置的信息

    若是沒有使用任何參數時,默認爲default

    請注意不一樣Redis版本會添加或者刪除一些字段。一個健壯的客戶端應用解析該命令的結果時,應該跳過未知的字段,而且優雅的處理缺乏的字段。

    已下描述要求 Redis >= 2.4

    下面是全部 server (記錄了 Redis 服務器的信息)相關的信息:

    • redis_version: Redis 服務器版本

    • redis_git_sha1: Git SHA1

    • redis_git_dirty: Git dirty flag

    • os: Redis 服務器的宿主操做系統

    • arch_bits: 架構(32 或 64 位)

    • multiplexing_api: Redis 所使用的事件處理機制

    • gcc_version: 編譯 Redis 時所使用的 GCC 版本

    • process_id: 服務器進程的 PID

    • run_id: Redis 服務器的隨機標識符(用於 Sentinel 和集羣)

    • tcp_port: TCP/IP 監聽端口

    • uptime_in_seconds: 自 Redis 服務器啓動以來,通過的秒數

    • uptime_in_days: 自 Redis 服務器啓動以來,通過的天數

    • lru_clock: 以分鐘爲單位進行自增的時鐘,用於 LRU 管理

    下面是全部 clients(記錄了已鏈接客戶端的信息) 相關的信息:

    • connected_clients: 已鏈接客戶端的數量(不包括經過從屬服務器鏈接的客戶端)

    • client_longest_output_list: 當前鏈接的客戶端當中,最長的輸出列表

    • client_biggest_input_buf: 當前鏈接的客戶端當中,最大輸入緩存

    • blocked_clients: 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客戶端的數量

    下面是全部 memory (記錄了服務器的內存信息)相關的信息:

    • used_memory: 由 Redis 分配器分配的內存總量,以字節(byte)爲單位

    • used_memory_human: 以人類可讀的格式返回 Redis 分配的內存總量

    • used_memory_rss: 從操做系統的角度,返回 Redis 已分配的內存總量(俗稱常駐集大小)。這個值和 top 、 ps 等命令的輸出一致。

    • used_memory_peak: Redis 的內存消耗峯值(以字節爲單位)

    • used_memory_peak_human: 以人類可讀的格式返回 Redis 的內存消耗峯值

    • used_memory_lua: Lua 引擎所使用的內存大小(以字節爲單位)

    • mem_fragmentation_ratio: used_memory_rssused_memory 之間的比率

    • mem_allocator: 在編譯時指定的, Redis 所使用的內存分配器。能夠是 libc 、 jemalloc 或者 tcmalloc 。 在理想狀況下, used_memory_rss 的值應該只比 used_memory 稍微高一點兒。

    當 rss > used ,且二者的值相差較大時,表示存在(內部或外部的)內存碎片。

    內存碎片的比率能夠經過 mem_fragmentation_ratio 的值看出。

    當 used > rss 時,表示 Redis 的部份內存被操做系統換出到交換空間了,在這種狀況下,操做可能會產生明顯的延遲。

    因爲Redis沒法控制其分配如何被映射到內存頁面,所以較高的 usedmemoryrss 一般是內存使用量激增的結果。

    當 Redis 釋放內存時,分配器可能會,也可能不會,將內存返還給操做系統。

    若是 Redis 釋放了內存,卻沒有將內存返還給操做系統,那麼 used_memory 的值可能和操做系統顯示的 Redis 內存佔用並不一致。

    查看 used_memory_peak 的值能夠驗證這種狀況是否發生。

    下面是全部 persistence (記錄了跟 RDB 持久化和 AOF 持久化有關的信息)相關的信息:

    • loading : 一個標誌值,記錄了服務器是否正在載入持久化文件。

    • rdb_changes_since_last_save : 距離最近一次成功建立持久化文件以後,通過了多少秒。

    • rdb_bgsave_in_progress : 一個標誌值,記錄了服務器是否正在建立 RDB 文件。

    • rdb_last_save_time : 最近一次成功建立 RDB 文件的 UNIX 時間戳。

    • rdb_last_bgsave_status : 一個標誌值,記錄了最近一次建立 RDB 文件的結果是成功仍是失敗。

    • rdb_last_bgsave_time_sec : 記錄了最近一次建立 RDB 文件耗費的秒數。

    • rdb_current_bgsave_time_sec : 若是服務器正在建立 RDB 文件,那麼這個域記錄的就是當前的建立操做已經耗費的秒數。

    • aof_enabled : 一個標誌值,記錄了 AOF 是否處於打開狀態。

    • aof_rewrite_in_progress : 一個標誌值,記錄了服務器是否正在建立 AOF 文件。

    • aof_rewrite_scheduled : 一個標誌值,記錄了在 RDB 文件建立完畢以後,是否須要執行預定的 AOF 重寫操做。

    • aof_last_rewrite_time_sec : 最近一次建立 AOF 文件耗費的時長。

    • aof_current_rewrite_time_sec : 若是服務器正在建立 AOF 文件,那麼這個域記錄的就是當前的建立操做已經耗費的秒數。

    • aof_last_bgrewrite_status : 一個標誌值,記錄了最近一次建立 AOF 文件的結果是成功仍是失敗。

    若是 AOF 持久化功能處於開啓狀態,那麼這個部分還會加上如下字段:

    • aof_current_size : AOF 文件目前的大小。

    • aof_base_size : 服務器啓動時或者 AOF 重寫最近一次執行以後,AOF 文件的大小。

    • aof_pending_rewrite : 一個標誌值,記錄了是否有 AOF 重寫操做在等待 RDB 文件建立完畢以後執行。

    • aof_buffer_length : AOF 緩衝區的大小。

    • aof_rewrite_buffer_length : AOF 重寫緩衝區的大小。

    • aof_pending_bio_fsync : 後臺 I/O 隊列裏面,等待執行的 fsync 調用數量。

    • aof_delayed_fsync : 被延遲的 fsync 調用數量。

    If a load operation is on-going, these additional fields will be added:

    • loading_start_time: Epoch-based timestamp of the start of the load operation

    • loading_total_bytes: Total file size

    • loading_loaded_bytes: Number of bytes already loaded

    • loading_loaded_perc: Same value expressed as a percentage

    • loading_eta_seconds: ETA in seconds for the load to be complete

    下面是全部 stats(記錄了通常統計信息)相關的信息:

    • total_connections_received : 服務器已接受的鏈接請求數量。

    • total_commands_processed : 服務器已執行的命令數量。

    • instantaneous_ops_per_sec : 服務器每秒鐘執行的命令數量。

    • rejected_connections : 由於最大客戶端數量限制而被拒絕的鏈接請求數量。

    • expired_keys : 由於過時而被自動刪除的數據庫鍵數量。

    • evicted_keys : 由於最大內存容量限制而被驅逐(evict)的鍵數量。

    • keyspace_hits : 查找數據庫鍵成功的次數。

    • keyspace_misses : 查找數據庫鍵失敗的次數。

    • pubsub_channels : 目前被訂閱的頻道數量。

    • pubsub_patterns : 目前被訂閱的模式數量。

    • latest_fork_usec : 最近一次 fork() 操做耗費的毫秒數。

    下面是全部 replication(主/從複製信息) 相關的信息:

    • role : 若是當前服務器沒有在複製任何其餘服務器,那麼這個域的值就是 master ;不然的話,這個域的值就是 slave。注意,在建立複製鏈的時候,一個從服務器也多是另外一個服務器的主服務器。

    若是當前服務器是一個從服務器的話,那麼這個部分還會加上如下字段:

    • master_host : 主服務器的 IP 地址。

    • master_port : 主服務器的 TCP 監聽端口號。

    • master_link_status : 複製鏈接當前的狀態, up 表示鏈接正常, down 表示鏈接斷開。

    • master_last_io_seconds_ago : 距離最近一次與主服務器進行通訊已通過去了多少秒鐘。

    • master_sync_in_progress : 一個標誌值,記錄了主服務器是否正在與這個從服務器進行同步。

    若是同步操做正在進行,那麼這個部分還會加上如下字段:

    • master_sync_left_bytes : 距離同步完成還缺乏多少字節數據。

    • master_sync_last_io_seconds_ago : 距離最近一次由於 SYNC 操做而進行 I/O 已通過去了多少秒。

    若是主從服務器之間的鏈接處於斷線狀態,那麼這個部分還會加上如下字段:

    • master_link_down_since_seconds : 主從服務器鏈接斷開了多少秒。

    如下是一些總會出現的字段:

    • connected_slaves : 已鏈接的從服務器數量。

    對於每一個從服務器,都會添加如下一行信息:

    • slaveXXX : ID、IP 地址、端口號、鏈接狀態

    下面是全部 cpu 相關的信息:

    • used_cpu_sys : Redis 服務器耗費的系統 CPU 。

    • used_cpu_user : Redis 服務器耗費的用戶 CPU 。

    • used_cpu_sys_children : 後臺進程耗費的系統 CPU 。

    • used_cpu_user_children : 後臺進程耗費的用戶 CPU 。

    • commandstats 部分記錄了各類不一樣類型的命令的執行統計信息,好比命令執行的次數、命令耗費的 CPU 時間、執行每一個命令耗費的平均 CPU 時間等等。對於每種類型的命令,這個部分都會添加一行如下格式的信息:

      • cmdstat_XXX:calls=XXX,usec=XXX,usecpercall=XXX

    • cluster 部分記錄了和集羣有關的信息,它包含如下域:

      • cluster_enabled : 一個標誌值,記錄集羣功能是否已經開啓。

    • keyspace 部分記錄了數據庫相關的統計信息,好比數據庫的鍵數量、數據庫已經被刪除的過時鍵數量等。對於每一個數據庫,這個部分都會添加一行如下格式的信息:

      • dbXXX:keys=XXX,expires=XXX

    除上面給出的這些值之外, section 參數的值還能夠是下面這兩個:

    • all : 返回全部信息

    • default : 返回默認選擇的信息

    返回值:

    具體請參見下面的測試代碼。

    示例:
    coderknock> INFO
    # Server
    redis_version:3.2.100
    redis_git_sha1:00000000
    redis_git_dirty:0
    redis_build_id:dd26f1f93c5130ee
    redis_mode:standalone
    os:Windows
    arch_bits:64
    multiplexing_api:WinSock_IOCP
    process_id:19944
    run_id:472a23ff45a04eb3081b48078a0c619c26376ddf
    tcp_port:6379
    uptime_in_seconds:268
    uptime_in_days:0
    hz:10
    lru_clock:5378046
    executable:D:\redis\redis-server.exe
    config_file:D:\redis\redis.windows.conf
    
    # Clients
    connected_clients:1
    client_longest_output_list:0
    client_biggest_input_buf:0
    blocked_clients:0
    
    # Memory
    used_memory:711792
    used_memory_human:695.11K
    used_memory_rss:674008
    used_memory_rss_human:658.21K
    used_memory_peak:787952
    used_memory_peak_human:769.48K
    total_system_memory:0
    total_system_memory_human:0B
    used_memory_lua:37888
    used_memory_lua_human:37.00K
    maxmemory:0
    maxmemory_human:0B
    maxmemory_policy:noeviction
    mem_fragmentation_ratio:0.95
    mem_allocator:jemalloc-3.6.0
    
    # Persistence
    loading:0
    rdb_changes_since_last_save:0
    rdb_bgsave_in_progress:0
    rdb_last_save_time:1498550002
    rdb_last_bgsave_status:ok
    rdb_last_bgsave_time_sec:-1
    rdb_current_bgsave_time_sec:-1
    aof_enabled:0
    aof_rewrite_in_progress:0
    aof_rewrite_scheduled:0
    aof_last_rewrite_time_sec:-1
    aof_current_rewrite_time_sec:-1
    aof_last_bgrewrite_status:ok
    aof_last_write_status:ok
    
    # Stats
    total_connections_received:2
    total_commands_processed:6
    instantaneous_ops_per_sec:0
    total_net_input_bytes:165
    total_net_output_bytes:11895644
    instantaneous_input_kbps:0.02
    instantaneous_output_kbps:2286.67
    rejected_connections:0
    sync_full:0
    sync_partial_ok:0
    sync_partial_err:0
    expired_keys:0
    evicted_keys:0
    keyspace_hits:1
    keyspace_misses:0
    pubsub_channels:0
    pubsub_patterns:0
    latest_fork_usec:0
    migrate_cached_sockets:0
    
    # Replication
    role:master
    connected_slaves:0
    master_repl_offset:0
    repl_backlog_active:0
    repl_backlog_size:1048576
    repl_backlog_first_byte_offset:0
    repl_backlog_histlen:0
    
    # CPU
    used_cpu_sys:0.20
    used_cpu_user:0.11
    used_cpu_sys_children:0.00
    used_cpu_user_children:0.00
    
    # Cluster
    cluster_enabled:0
    
    # Keyspace
    db0:keys=43,expires=0,avg_ttl=0
    db1:keys=3,expires=0,avg_ttl=0

    我是廣告

    本人的直播課程在 7 月份就要開始了,但願小夥伴們支持一下,如今報名有優惠噢

    https://segmentfault.com/l/15...

    https://segmentfault.com/l/15...

    相關文章
    相關標籤/搜索