1、fork耗時導致高并發(fā)請求延時 RDB和AOF的時候,其實會有生成RDB快照,AOF rewrite,耗費磁盤IO的過程,主進程fork子進程。fork的時候,子進程是需要拷貝父進程的空間內(nèi)存頁表的,也是會耗費一定的時間的。 一般來說,如果父進程內(nèi)存有1個G的數(shù)據(jù),那么fork可能會耗費在20ms左右,如果是10G~30G,那么就會耗費20 * 10,甚至20 * 30,也就是幾百毫秒的時間。info stats中的latest_fork_usec,可以看到最近一次fork的時長。redis單機QPS一般在幾萬,fork可能一下子就會拖慢幾萬條操作的請求時長,從幾毫秒變成1秒。 優(yōu)化思路: fork耗時跟redis主進程的內(nèi)存有關系,一般控制每個redis實例的內(nèi)存在10GB以內(nèi),采用多個實例,分而治之。 2、AOF的阻塞問題 redis將數(shù)據(jù)寫入AOF緩沖區(qū),單獨開一個現(xiàn)場做fsync操作,每秒一次,但是redis主線程會檢查兩次fsync的時間,如果距離上次fsync時間超過了2秒,那么寫請求就會阻塞。一旦fsync超過2秒的延時,整個redis就被拖慢 優(yōu)化思路: 優(yōu)化硬盤寫入速度,建議采用SSD,不要用普通的機械硬盤,SSD,大幅度提升磁盤讀寫的速度 3、主從復制延遲問題 主從復制可能會超時嚴重,這個時候需要良好的監(jiān)控和報警機制。在info replication中,可以看到master和slave復制的offset,做一個差值就可以看到對應的延遲量。如果延遲過多,那么就進行報警。 4、主從復制風暴問題 如果一下子讓多個slave從master去執(zhí)行全量復制,一份大的rdb同時發(fā)送到多個slave,會導致網(wǎng)絡帶寬被嚴重占用。如果一個master真的要掛載多個slave,那盡量用樹狀結(jié)構(gòu),不要用星型結(jié)構(gòu)。 接下來是一些linux內(nèi)核的參數(shù)設置的優(yōu)化,啟動redis的時候,都會有一些參數(shù)設置的建議在控制臺輸出,大家可以留意一下。 5、vm.overcommit_memory 0: 檢查有沒有足夠內(nèi)存,沒有的話申請內(nèi)存失敗 1: 允許使用內(nèi)存直到用完為止 2: 內(nèi)存地址空間不能超過swap 50% 如果是0的話,可能導致類似fork等操作執(zhí)行失敗,申請不到足夠的內(nèi)存空間 cat /proc/sys/vm/overcommit_memory echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf sysctl vm.overcommit_memory=1 6、swapiness cat /proc/version,查看linux內(nèi)核版本 如果linux內(nèi)核版本<3.5,那么swapiness設置為0,這樣系統(tǒng)寧愿swap也不會oom killer(殺掉進程) 如果linux內(nèi)核版本>=3.5,那么swapiness設置為1,這樣系統(tǒng)寧愿swap也不會oom killer 保證redis不會被殺掉 echo 0 > /proc/sys/vm/swappiness echo vm.swapiness=0 >> /etc/sysctl.conf 7、最大打開文件句柄 ulimit -n 10032 10032 自己去上網(wǎng)搜一下,不同的操作系統(tǒng),版本,設置的方式都不太一樣 8、tcp backlog cat /proc/sys/net/core/somaxconn echo 511 > /proc/sys/net/core/somaxconn |
|