獲取服務器支持的最大文件描述符數(該 值會限制你的最大文件打開數,對我們而言,關心的是可供打開的socket的數量)
linux機器可以使用 ulimit 命令獲取你關心的一些指數
可以看到支持的最大文件描述符數是4000
也可以直接通過 ulimit -n 獲取文件描述符數
還可以通過該命令修改最大文件描述符數
在我們線上機器系統配置文件對應位置為:/etc/sysctl.conf,目前我們線上機器配置的最大文件描述符數為655350
關於redis配置文件一些參數的理解:
daemonize no/yes Redis默認不是以守護進程的方式運行,可以通過該配置項修改,使用yes啟用守護進程(我個人是理解就是設置為yes可以支持后台運行redis)
port 6379 指定Redis監聽端口,默認端口為6379
bind 127.0.0.1 綁定的主機地址
timeout 300 當 客戶端閑置多長時間后關閉連接,如果指定為0,表示關閉該功能
databases 16 設置數據庫的數量,默認數據庫為0,可以使用SELECT <dbid>命令在連接上指定數據庫id
maxclients 128 設置同一時間最大客戶端連接數,默認無限制,Redis可以同時打開的客戶端連接數為Redis進程可以打開的最大文件描述符數,如果設置 maxclients 0,表示不作限制。當客戶端連接數到達限制時,Redis會關閉新的連接並向客戶端返回max number of clients reached錯誤信息(所以想要讓redis支持更多的連接數,需要將文件描述符數和maxclients同時設置的大一些,而最終的最大連接數取決於二者較小的那個值)
通過以上兩種設置,貌似redis已經可以支持大量的客戶端連接了,但是采用 redis-benchmark 進行壓力測試,會出現如下錯誤:
-- Could not connect to Redis at IP:PORT,Cannot assign requested address.
這是因為redis-benchmark的壓力測試時頻繁的連服務器,數據量較大的時候,由於每次連接都在很短的時間內結束,導致很多的TIME_WAIT,以至於用光了可用的端口號,所以新的連接沒辦法綁定端口,即“Cannot assign requestedaddress”。
可以通過 netstat -ant|grep TIME_WAIT 過濾出來大量的未關閉連接,效果大概是下邊這個樣子
這時,你需要讓系統知道對於這種TIME_WAIT的TCP連接應該快速回收,以釋放端口,供更多的客戶端可以請求分配到端口並訪問我們的redis
命令如下:
sysctl -w net.ipv4.tcp_timestamps=1 #開啟對於TCP時間戳的支持,若該項設置為0,則下面一項設置不起作用
sysctl -w net.ipv4.tcp_tw_recycle=1 #表示開啟TCP連接中TIME-WAIT sockets的快速回收
執行后,利用 redis-benchmark 做壓力測試,不會再出現 Cannot assign requested address 這個錯誤
redis-benchmark 壓力測試命令:
redis-benchmark -h 127.0.0.1 -p 6379 -c 20000 -n 20000 (h對應參數為ip,p對應參數為端口,c對應參數為並發連接數,n對應參數為請求數量)
這時,你可以看到高並發時 redis 對於不同操作的平均響應時長(只截取部分結果)
在xadtest這台機器上測試20000並發連接數,20000個請求的效果數據如圖(可以看到最長響應時長已經達到577ms,目前我們線上服務器的平均響應時長為110ms左右;PS:可能線上的服務器響應效果會好一些,但是有業務在跑,就沒做測試):
需要額外提一點:上邊提到要讓服務器快速關閉TIME_WAIT的TCP連接,會對系統設置做兩個修改
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1
但是目前我們線上服務器配置文件里的內容為:
#時間戳可以避免序列號的卷繞。一個1Gbps的鏈路肯定會遇到以前用過的序列號。時間戳能夠讓內核接受這種“異常”的數據包。這里需要將其關掉
net.ipv4.tcp_timestamps = 0 (與上述修改是有沖突存在的)
#開啟TCP連接復用功能,允許將time_wait sockets重新用於新的TCP連接(主要針對time_wait連接)
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
貿然更改系統配置,是會影響我們的線上服務的,測試操作請上測試機!!!
本文內容在類linux環境使用,不適用mac/windows
后續如果涉及到redis集群,會再做補充