性能測試瓶頸定位——磁盤IO和線程切換過多

近期在一個性能測試項目中遇到了一個調優的過程。分享一下給大家。

  1、 第一次打壓時,發現A請求壓力80tps後,cpu佔用就非常高了(24核的機器,每個cpu佔用率全面飆到80%以上),且設置的檢查點沒有任何報錯。

  2、 瞭解了一下後臺實現邏輯:大體是這樣的:服務器接到請求後,會再到另一臺kv服務器請求數據,拿回來數據後,根據用戶的機器碼做個性化運算,最後將結果返回給客戶端,期間會輸出一些調試log。

  查了下,kv服務器正常,說明是本機服務服務器的問題。具體用vmstat命令看一下異常的地方。

  3、 從圖中可以直觀的看出,bi、bo、in、cs這四項的值都很高,根據經驗,bi和bo代表磁盤io相關、in和cs代表系統進程相關。一個一個解決吧,先看io。

  4、 用iostat –x命令看了下磁盤讀寫,果然,磁盤慢慢給堵死了。

  5、 看了下過程,只有寫log操作才能導致頻繁讀寫磁盤。果斷關閉log。重新打壓試下。

  6、 Bi和bo降到正常值了,說明磁盤的問題解決了。但是上下文切換數竟然達到了每秒40萬次!好可怕~

  7、 只知道上下文切換數很大,怎麼知道是在哪些進程間切換呢?

  到網上搜了一個腳本,這個腳本用來統計特定時間內進程切換的top20並打印出來。

  #! /usr/bin/env stap

  #

  #

  global csw_count

  global idle_count

  probe scheduler.cpu_off {

  csw_count[task_prev, task_next]++

  idle_count+=idle

  }

  function fmt_task(task_prev, task_next)

  {

  return sprintf("%s(%d)->%s(%d)",

  task_execname(task_prev),

  task_pid(task_prev),

  task_execname(task_next),

  task_pid(task_next))

  }

  function print_cswtop () {

  printf ("%45s %10s\n", "Context switch", "COUNT")

  foreach ([task_prev, task_next] in csw_count- limit 20) {

  printf("%45s %10d\n", fmt_task(task_prev, task_next), csw_count[task_prev, task_next])

  }

  printf("%45s %10d\n", "idle", idle_count)

  delete csw_count

  delete idle_count

  }

  probe timer.s($1) {

  print_cswtop ()

  printf("--------------------------------------------------------------\n")

  }

  保存成cs.stp後,用stap cswmon.stp 5命令執行下。

  8、發現是discover進程在反覆和系統進程進行切換。從此消耗了大量資源。

  9、從網上查了下減少切換進程的一些方法:

  開發隨後改了下:將線程數開大了一倍,控制在一個進程中。

  重新打壓了一下。發現上下文切換數降低到25萬次左右。

  此時的性能數據可以達到每秒260次左右,遠遠高於之前的80次。已經達到可以上線的需求

  但是由於頁面中斷書和上下文切換數還是很高,後續還是需要優化~

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