1. 程式人生 > >k8s環境下由predis初始化連線緩慢引起的一次問題排查

k8s環境下由predis初始化連線緩慢引起的一次問題排查

背景

最近業務上在做同城雙中心。原本的機房使用的是swarm叢集,新機房使用的是k8s叢集。業務遷移到新機房的主要工作集中在:

  1. 庫、redis、es等底層服務的遷移;
  2. redis由原來的vip單點模式,切換為redis-cluster,由於phpredis1官方版本暫時不支援帶auth的cluster模式,所以選擇了predis連結redis;
  3. 將之前的swarm叢集,遷移到k8s叢集;

現象

部署完成之後發現,首頁載入很慢,開啟network,發現ajax請求普遍比老機房慢2-3秒。業務已經上了redis快取,仍是如此。

排查思路

瀏覽器併發數

首先考慮瀏覽器同域下請求併發數問題,由於瀏覽器對於同域的併發數有限制,當同域的請求過多是,後續的請求會出現stock情況。通過network中的waterfall基本排除了該種可能:

服務端profiling

基本排除了客戶端問題之後,開始服務端profiling(效能剖析)。專案使用的是php的CodeIgniter框架,之前自己動手寫過一個profiling的框架。所以引入框架後開始分析,以下是首頁眾多ajax請求中的一個:
在這裡插入圖片描述

然而單獨除錯這個介面的時候,結果卻是這樣:
在這裡插入圖片描述

對比兩個結果,可以看出幾點:

  • 多處耗時較長,包括初始化框架、sql查詢和redis初始化;
  • 單獨請求介面時,比在首頁眾多請求中請求介面,效能有很大提升;

此時,我進入了一個誤區。我嘗試針對各個耗時的操作逐一排查。於是就開始從初始化redis(因為我覺得這裡最蹊蹺)開始,開始除錯predis原始碼,各種優化連線引數。然而折騰了很久,只是發現除錯的過程中一切執行都正常,但是就隨著程式碼執行,耗時出奇的高。

直到,我意識到一個問題:是不是併發越高,相應越慢?

併發情況下資源等待

我依次在本機使用ab,測試了100次請求下,不同併發下介面的響應情況:

  1. 併發1的情況:
    在這裡插入圖片描述

  2. 併發10的情況:
    在這裡插入圖片描述

緊接著,我又測試了在有無壓測的情況下,在瀏覽器上profiling單個介面,結果果然如我所料,在壓測情況下,介面耗時慢很多。

其實到這裡,原因基本可以猜到了,就是k8s中container的資源限制。由於資源limit配置不當(cpu設定limit:200m),導致隨著併發請求的處理,很多操作在等待cpu資源,所以最終表現的情況就是,併發越大,請求越慢。
在我移除cpu限制之後,請求基本正常。

結論

這個問題的排查過程,給了一類介面請求慢問題的排查思路:當發現程式執行基本正常,而大部分整體耗時較長的情況下,可以考慮是否是機器/作業系統的資源限制造成的。


  1. 就是php的redis擴充套件,以前的名字叫phpredis,最近好像更名為redis了,估計是為了防止歧義吧,連結在:http://pecl.php.net/package/redis ↩︎