redis在實踐中的一些常見問題以及優化思路

1、fork耗時導致高併發請求延時

RDB和AOF的時候,其實會有生成RDB快照,AOF rewrite,耗費磁盤IO的過程,主進程fork子進程。fork的時候,子進程是需要拷貝父進程的空間內存頁表的,也是會耗費一定的時間的。

一般來說,如果父進程內存有1個G的數據,那麼fork可能會耗費在20ms左右,如果是10G~30G,那麼就會耗費20 * 10,甚至20 * 30,也就是幾百毫秒的時間。info stats中的latest_fork_usec,可以看到最近一次fork的時長。redis單機QPS一般在幾萬,fork可能一下子就會拖慢幾萬條操作的請求時長,從幾毫秒變成1秒。

優化思路:

fork耗時跟redis主進程的內存有關係,一般控制每個redis實例的內存在10GB以內,採用多個實例,分而治之。

2、AOF的阻塞問題

redis將數據寫入AOF緩衝區,單獨開一個現場做fsync操作,每秒一次,但是redis主線程會檢查兩次fsync的時間,如果距離上次fsync時間超過了2秒,那麼寫請求就會阻塞。一旦fsync超過2秒的延時,整個redis就被拖慢

優化思路:

優化硬盤寫入速度,建議採用SSD,不要用普通的機械硬盤,SSD,大幅度提升磁盤讀寫的速度

3、主從複製延遲問題

主從複製可能會超時嚴重,這個時候需要良好的監控和報警機制。在info replication中,可以看到master和slave複製的offset,做一個差值就可以看到對應的延遲量。如果延遲過多,那麼就進行報警。

4、主從複製風暴問題

如果一下子讓多個slave從master去執行全量複製,一份大的rdb同時發送到多個slave,會導致網絡帶寬被嚴重佔用。如果一個master真的要掛載多個slave,那儘量用樹狀結構,不要用星型結構。

接下來是一些linux內核的參數設置的優化,啟動redis的時候,都會有一些參數設置的建議在控制檯輸出,大家可以留意一下。

5、vm.overcommit_memory

0: 檢查有沒有足夠內存,沒有的話申請內存失敗

1: 允許使用內存直到用完為止

2: 內存地址空間不能超過swap + 50%

如果是0的話,可能導致類似fork等操作執行失敗,申請不到足夠的內存空間

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內核版本

如果linux內核版本<3.5,那麼swapiness設置為0,這樣系統寧願swap也不會oom killer(殺掉進程)

如果linux內核版本>=3.5,那麼swapiness設置為1,這樣系統寧願swap也不會oom killer

保證redis不會被殺掉

echo 0 > /proc/sys/vm/swappiness

echo vm.swapiness=0 >> /etc/sysctl.conf

7、最大打開文件句柄

ulimit -n 10032 10032

自己去上網搜一下,不同的操作系統,版本,設置的方式都不太一樣

8、tcp backlog

cat /proc/sys/net/core/somaxconn

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

redis在實踐中的一些常見問題以及優化思路


分享到:


相關文章: