日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis:22---客户端API:client、monitor)

發布時間:2023/12/13 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis:22---客户端API:client、monitor) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

一、client list

  • client list命令能列出與Redis服務端相連的所有客戶端連接信息。例如下面代碼是在一個Redis實例上執行client list的結果,其中每一行代表一個客戶端信息:

  • ?

  • 下面將選擇幾個重要的屬性進行說明,其余通過表格的形式進行展示

①標識:id、addr、fd、name

  • 這四個屬性屬于客戶端的標識:

    • id:客戶端連接的唯一標識,這個id是隨著Redis的連接自增的,重啟 Redis后會重置為0

    • addr:客戶端連接的ip和端口

    • fd:socket的文件描述符,與lsof命令結果中的fd是同一個,如果fd=-1代表當前客戶端不是外部客戶端,而是Redis內部的偽裝客戶端

    • name:客戶端的名字,后面的client setName和client getName兩個命令會對其進行說明

②輸入緩沖區:qbuf、qbuf-free

  • Redis為每個客戶端分配了輸入緩沖區,它的作用是:將客戶端發送的命令臨時保存,同時Redis從會輸入緩沖區拉取命令并執行,輸入緩沖區為客 戶端發送命令到Redis執行命令提供了緩沖功能,如下圖所示

  • client list中qbuf和qbuf-free:

    • 這兩個屬性分別代表這個緩沖區的總容量和剩余容量

    • Redis沒有提供相應的配置來規定每個緩沖區的大小,輸入緩沖區會根據輸入內容大小的不同動態調整,只是要求每個客戶端緩沖區的大小不能超過1G,超過后客戶端將被關閉

    • 下面是Redis源碼中對于輸入緩沖區的硬編碼:

/* Protocol and I/O related defines */ #define REDIS_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */
  • 輸入緩沖使用不當會產生兩個問題:

    • 一旦某個客戶端的輸入緩沖區超過1G,客戶端將會被關閉

    • 輸入緩沖區不受maxmemory控制,假設一個Redis實例設置了maxmemory為4G,已經存儲了2G數據,但是如果此時輸入緩沖區使用了3G,已經超過maxmemory限制,可能會產生數據丟失、鍵值淘汰、OOM等情況(如下圖所示)

  • 上圖的執行效果如下:

  • 上面已經看到,輸入緩沖區使用不當造成的危害非常大,那么造成輸入緩沖區過大的原因有哪些?

    • 輸入緩沖區過大主要是因為Redis的處理速度跟不上輸入緩沖區的輸入速度,并且每次進入輸入緩沖區的命令包含了大量 bigkey,從而造成了輸入緩沖區過大的情況

    • 還有一種情況就是Redis發生了阻塞,短期內不能處理命令,造成客戶端輸入的命令積壓在了輸入緩沖區, 造成了輸入緩沖區過大

  • 那么如何快速發現和監控呢?監控輸入緩沖區異常的方法有兩種:

    • 通過定期執行client list命令,收集qbuf和qbuf-free找到異常的連接記錄 并分析,最終找到可能出問題的客戶端。

    • 通過info命令的info clients模塊,找到最大的輸入緩沖區,例如下面命令中的其中client_recent_max_input_buffer代表最大的輸入緩沖區,例如可以設置超過10M就進行報警

  • 上面兩種方法各有自己的優劣勢,下圖對兩種方法進行了對比:

  • 運維提示:輸入緩沖區問題出現概率比較低,但是也要做好防范,在開發中要減少bigkey、減少Redis阻塞、合理的監控報警

③輸出緩沖區:obl、oll、omem

  • Redis為每個客戶端分配了輸出緩沖區,它的作用是:保存命令執行的結 果返回給客戶端,為Redis和客戶端交互返回結果提供緩沖

  • 與輸入緩沖區不同的是:

    • 輸出緩沖區的容量可以通過參數client-outputbuffer-limit來進行設置

    • 并且輸出緩沖區做得更加細致,按照客戶端的不同分為三種:普通客戶端、發布訂閱客戶端、slave客戶端。如下圖所示

  • client-output-buffer-limit格式如下。參數意義為:

    • <class>:客戶端類型,分為三種。a)normal:普通客戶端;b) slave:slave客戶端,用于復制;c)pubsub:發布訂閱客戶端

    • <hard limit>:如果客戶端使用的輸出緩沖區大于該值,客戶端會被立即關閉

    • <soft limit>和<soft seconds>:如果客戶端使用的輸出緩沖區超過了并且持續了秒,客戶端會被立即關閉

  • 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
  • 和輸入緩沖區相同的是,輸出緩沖區也不會受到maxmemory的限制,如果使用不當同樣會造成maxmemory用滿產生的數據丟失、鍵值淘汰、OOM等情況

  • 實際上輸出緩沖區由兩部分組成:

    • 固定緩沖區(16KB):返回比較小的執行結果

    • 動態緩沖區:返回比較大的結果。例如大的字符串、hgetall、smembers命令的結果等,通過Redis源碼中redis.h的redisClient結構體(Redis3.2版本變為Client)可以看到兩個緩沖區的實現細節:

typedef struct redisClient { // 動態緩沖區列表 list *reply; // 動態緩沖區列表的長度(對象個數) unsigned long reply_bytes; // 固定緩沖區已經使用的字節數 int bufpos; // 字節數組作為固定緩沖區 char buf[REDIS_REPLY_CHUNK_BYTES]; } redisClient;
  • 固定緩沖區使用的是字節數組,動態緩沖區使用的是列表。當固定緩沖區存滿后會將Redis新的返回結果存放在動態緩沖區的隊列中,隊列中的每個對象就是每個返回結果,如下圖所示:

  • obl、oll、omem:

    • client list中的obl代表固定緩沖區的長度,oll代表動態緩沖區列表的長度,omem代表使用的字節數

    • 例如下面代表當前客戶端的固定緩沖區的長度為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 list命令,收集obl、oll、omem找到異常的連接記錄 并分析,最終找到可能出問題的客戶端

    • ②通過info命令的info clients模塊,找到輸出緩沖區列表最大對象數,例如(其中,client_longest_output_list代表輸出緩沖區列表最大對象數):

    • 這兩種統計方法的優劣勢和輸入緩沖區是一樣的,這里就不再贅述了

  • 相比于輸入緩沖區,輸出緩沖區出現異常的概率相對會比較大,那么如何預防呢?方法如下:

    • 進行上述監控,設置閥值,超過閥值及時處理

    • 適當增大slave的輸出緩沖區的,如果master節點寫入較大,slave客戶 端的輸出緩沖區可能會比較大,一旦slave客戶端連接因為輸出緩沖區溢出 被kill,會造成復制重連

    • 限制容易讓輸出緩沖區增大的命令,例如,高并發下的monitor命令就 是一個危險的命令

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

    • 限制普通客戶端輸出緩沖區的,把錯誤扼殺在搖籃中,例如可以進行如下設置:

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

④客戶端的存活狀態(age、idle)

  • client list中的age和idle分別代表:當前客戶端已經連接的時間、最近一次的空閑時間:

  • 例如下面這條記錄代表當期客戶端連接Redis的時間為304秒,其中空閑了0秒:

  • 例如下面這條記錄代表當期客戶端連接Redis的時間為8888581秒,其中空閑了8888581秒。實際上這種就屬于不太正常的情況,當age等于idle時, 說明連接一直處于空閑狀態

演示案例

  • 為了更加直觀地描述age和idle,下面用一個例子進行說明:

String key = "hello"; // 1) 生成jedis,并執行get操作 Jedis jedis = new Jedis("127.0.0.1", 6379); System.out.println(jedis.get(key)); // 2) 休息10秒 TimeUnit.SECONDS.sleep(10); // 3) 執行新的操作ping System.out.println(jedis.ping()); // 4) 休息5秒 TimeUnit.SECONDS.sleep(5); // 5) 關閉jedis連接 jedis.close();
  • 下面對代碼中的每一步進行分析,用client list命令來觀察age和idle參數的相應變化(備注:為了與redis-cli的客戶端區分,本次測試客戶端IP地址:10.7.40.98)

  • 1)在執行代碼之前,client list只有一個客戶端,也就是當前的rediscli,下面為了節省篇幅忽略掉這個客戶端。

  • 2)使用Jedis生成了一個新的連接,并執行get操作,可以看到IP地址為 10.7.40.98的客戶端,最后執行的命令是get,age和idle分別是1秒和0秒

  • 3)休息10秒,此時Jedis客戶端并沒有關閉,所以age和idle一直在遞 增:

  • 4)執行新的操作ping,發現執行后age依然在增加,而idle從0計算,也 就是不再閑置

  • 5)休息5秒,觀察age和idle增加:

  • 6)關閉Jedis,Jedis連接已經消失:

⑤客戶端類型(flag)

  • client list中的flag是用于標識當前客戶端的類型

  • 例如flag=S代表當前客 戶端是slave客戶端、flag=N代表當前是普通客戶端,flag=O代表當前客戶端 正在執行monitor命令。下圖列出了11種客戶端類型:

  • 序號客戶端類型說明
    lN普通客戶端
    2M當前客戶端是master節點
    3s當前客戶端是slave節點
    4o當前客戶端正在執行monitor命令
    5x當前客戶端正在執行事務
    6b當前客戶端正在等得阻塞事件
    7i當前客戶端正在等待VM IO,但是此狀態目前已經廢棄不用
    8d一個受監視的鍵已被修改,EXEC命令將失敷
    9u客戶端未被阻察
    10c回復完整輸出后,關閉連接
    11A盡可能快地關閉連接?

二、client setName和client getName

client setName xx

client setName

  • client setName用于給客戶端設置名字,這樣比較容易標識出客戶端的來源。例如將當前客戶端命名為test_client,可以執行如下操作:

  • 此時再執行client list命令,就可以看到當前客戶端的name屬性為test_client:

client getName

client getName
  • 如果想直接查看當前客戶端的name,可以使用client getName命令

  • 第一次進入客戶端時,客戶端是沒有名字的,因此名字為空

  • 更改名字之后,就可以看到更改后的名字了。例如:

  • client getName和setName命令可以做為標識客戶端來源的一種方式,但是通常來講,在Redis只有一個應用方使用的情況下,IP和端口作為標識會更加清晰。當多個應用方共同使用一個Redis,那么此時client setName可以作為標識客戶端的一個依據

三、client kill

client kill ip:port
  • 此命令用于殺掉指定IP地址和端口的客戶端

  • 由于一些原因(例如設置timeout=0時產生的長時間idle的客戶端),需要手動殺掉客戶端連接時,可以使用client kill命令

演示案例

  • 例如左側為一個客戶端(127.0.0.1:34658),右側為一個客戶端(127.0.0.1:34660)

  • 如果想殺掉127.0.0.1:34656的客戶端,可以執行:

  • 執行命令后,client list結果只剩下了127.0.0.1:34658自己這個客戶端:

四、client pause

client pause timeout(毫秒)
  • client pause命令用于阻塞客戶端timeout毫秒數,在此期間客戶端連接將被阻塞。如下圖所示:

演示案例

  • 例如在一個客戶端執行下面的命令,在之后的10000毫秒內的其他客戶端連接都會被阻塞

  • 過一會后在另一個客戶端執行ping命令,發現整個ping命令執行了2.40秒(手動執行redis-cli,只為了演示,不代表真實執行時間):

  • 該命令可以在如下場景起到作用:

    • client pause只對普通和發布訂閱客戶端有效,對于主從復制(從節點內部偽裝了一個客戶端)是無效的,也就是此期間主從復制是正常進行的, 所以此命令可以用來讓主從復制保持一致

    • client pause可以用一種可控的方式將客戶端連接從一個Redis節點切換到另一個Redis節點

  • 需要注意的是在生產環境中,暫停客戶端成本非常高

五、monitor

  • monitor命令用于監控Redis正在執行的命令?

演示案例

  • 如下圖所示:

    • 我們打開了兩個redis-cli,右側先執行monitor命令,左側再執行其他命令

    • 可以看到monitor命令能夠監聽其他客戶端正在執行的命令,并記錄了詳細的時間戳

  • 注意事項:monitor的作用很明顯,如果開發和運維人員想監聽Redis正在執行的命令,就可以用monitor命令,但事實并非如此美好,每個客戶端都有自己的輸出緩沖區,既然monitor能監聽到所有的命令,一旦Redis的并發量過大, monitor客戶端的輸出緩沖會暴漲,可能瞬間會占用大量內存。

總結

以上是生活随笔為你收集整理的Redis:22---客户端API:client、monitor)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。