記一次效能調優

Fish發表於2019-01-19

引子

最近負責的一個訊息推送系統要上線了,效能方便要滿足兩個要求
1、對外提供的介面能達到5w條/s的tps。
2、查詢功能和統計報表在資料量大的情況下要保證速度。

專案環境:
linux+tomcat8+mysql8+redis+rocketmq

優化思路

1、介面優化

介面狀況:http介面,接收到簡訊資料庫後,先進行使用者身份、使用者餘額、黑名單、敏感詞等校驗,校驗完成後,插入到mysql資料庫。然後通過計劃任務從資料庫中查詢出待傳送的簡訊資料,推送到mq,傳送子系統負責從mq中消費簡訊資料傳送到運營商閘道器。
壓測的時候發現,只能達到15條/s的tps,離5w這個目標差十萬八千里。

問題分析:
校驗的時候都是從redis裡面取的資料,問題應該不大,那就剩下一個插入資料的操作了,剛好測試那邊也反饋了資料庫cpu佔用100%,那麼基本確定效能瓶頸就在插入資料庫這裡。

<<優化思路>>
當時想到兩個解決辦法:
a、介面接收到資料後,校驗通過,直接傳送mq,訊息推送系統和傳送子系統同時去消費,一邊入庫一邊發到運營商閘道器。
b、介面接收到資料後,校驗通過,先儲存到redis中,再用一個計劃任務輪詢redis去批量入庫。
批量入庫參考:https://www.cnblogs.com/caica…

a計劃,優點是簡訊資料很快的就傳送到運營商閘道器,使用者能夠很快的收到。缺點就是,第一如果傳送子系統已傳送完畢,狀態報告返回時,簡訊資料還沒入庫,這時候就比較蛋疼了。第二資料入庫還是單條,資料庫壓力仍然很大,影響其他功能的使用。

b計劃,優點是使用redis做快取層,再通過計劃任務從redis中取資料進行批量入庫,介面只操作redis,效能沒問題,批量入庫大大減輕了資料庫壓力。缺點是資料入庫到傳送到運營商閘道器會有幾秒的延遲,還有就是批量入庫失敗,資料有丟失風險。

2、查詢優化

簡訊查詢功能,需要根據一些查詢條件去查詢簡訊的資料(分頁查詢),需要根據傳送時間降序排列,還需要根據使用者許可權過濾,關聯表有4張左右。600萬條資料,需要幾十秒的查詢時間,崩潰。

<<優化思路>>
在查詢條件欄位和排序欄位加上索引,減少幾張關聯表(資料量很少幾十條的樣子,如果關聯進去是用來做查詢條件,可以用exists來替代,如果是用來查詢某個欄位的,可以在取到結果集後,再去單獨查一下這個欄位),優化後,0.004秒搞定。然後又發現翻頁的時候,查詢總數速度慢、還有查詢頁數越大越慢的問題。

  • 總數慢的問題解決:count(1),count(*),count(欄位)這幾種方式都試了,沒用啊,後面發現單表count快,多表就慢,於是只count一張表,其他表主要是做查詢條件的,使用exists的方式改寫,問題解決。
  • 翻頁慢的問題解決:越往後面翻頁就越慢,最後一頁要80多秒,使用的limit m,n來分頁的,幸好有大神詳細分析了這個問題,部落格地址:https://www.cnblogs.com/genin…

後記

1、單機壓測最終能達到5000條/s的tps,離目標5w/s的距離仍有一定距離,但是可以通過叢集部署的方式來彌補。後續優化方向,增加nginx配置長連線、使用undertow伺服器替換tomcat伺服器,使用netty重新開發簡訊傳送介面等。

2、查詢慢的問題基本解決,後續再根據實際情況看是否需要繼續優化,優化方向:表分割槽、分庫分表。

相關文章