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 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章