如果設置Redis客戶端的超時時長?


 

客戶端的超時時長分連接超時和讀寫超時,如果是基於hiredis的實現,則讀寫超時是合在一起的,同一參數控制。

hiredis中,讀寫超時調用函數redisSetTimeout設置,可以看到沒有區分讀和寫:

int redisSetTimeout(redisContext *c, const struct timeval tv);

 

而連接超時,則是在建立連接時指定:

redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);

 

超時值設置偏小,容易導致訪問redis失敗。如果是寫操作(setlpushhsetincrby等操作),則結果還有不確定性,即可能在redis端成功了,但客戶端得到的是超時,象incrbysetnx等操作還不方便簡單重試。

如果超時值設置過大,則在redis異常時不容易及時做切換,比如master卡住(可能因為在重寫AOF而繁忙)時,調用者也將被卡住,不能及時解脫,一些情況下可能造成雪崩,這種情況下超時值越小越有利。

 

如何確定一個合理超時值了?原則是保證大多數超時都能成功,因此需要確定什么值可以滿足大多數情況。這需考慮兩個方面:

1) 網絡延遲,通過ping掌握網絡延遲

$ ping -c 3 192.168.1.22

PING 192.168.1.22 (192.168.1.22) 56(84) bytes of data.

64 bytes from 192.168.1.22: icmp_seq=1 ttl=53 time=31.7 ms

64 bytes from 192.168.1.22: icmp_seq=2 ttl=53 time=31.7 ms

64 bytes from 192.168.1.22: icmp_seq=3 ttl=53 time=31.7 ms

 

--- 192.168.1.22 ping statistics ---

3 packets transmitted, 3 received, 0% packet loss, time 2000ms

rtt min/avg/max/mdev = 31.720/31.725/31.728/0.145 ms

 

2) 查看redis慢日志

$ redis-cli slowlog get

 1) 1) (integer) 10526

    2) (integer) 1566357322

    3) (integer) 10926

    4) 1) "ZCOUNT"

       2) "test1"

       3) "-9223372036854775808"

       4) "9223372036854775807"

 2) 1) (integer) 10525

    2) (integer) 1566343237

    3) (integer) 17572

    4) 1) "HGET"

       2) "test2"

       3) "tq"

 3) 1) (integer) 10524

    2) (integer) 1566343212

    3) (integer) 101400

    4) 1) "HGET"

       2) "test3"

       3) "tq"

 

slowlog get”命令輸出的第“3”條數值,比如上面的“10926”、“17572”和“101400”,分別表示對應命令執行的時長,單位為微秒。顯然以上述為例,超時時長不能小於“102+32”毫秒,即讀寫超時至少得設置134毫秒。

 

顯然實際中,超值時不可能很小,如果都是同步調用,調用相互耦合,一個redis節點異常即會影響全局,為此業務側的架構應考慮到這一點。原則是一次業務操作只涉及單個redis節點,業務側采用分機器、分進程或分線程方式解耦,這樣即使某redis節點異常,也只會影響這部分數據,其它部分仍然可正常操作(這里建議redis的配置項cluster-require-full-coverage值為no)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM