關於高性能的那點事

    對於大部分應用來說,想要高性能,主要是要做到儘可能的減少網絡請求(含db、redis、mongo、mq等)。幾乎所有的應用,性能瓶頸永遠是在帶寬那裏,硬件方面這裏就不提了,說說我們能做的事。

    找了半天沒有找到那張圖,關於各個組件到cpu的時間週期,我用文字描述一下,L1>L2>memory>disk>internet。

    有人說redis性能高,做大併發,大數據訪問必須要用,有人說mongo性能高,什麼zeromq等等一系列的,其實都是渣。



    先說網絡請求,關於tcp/ip:

    大家都知道ip是逐跳協議,也就是說我只能從一個路由器,到下一個路由器,再到下一個路由器,如果你的電腦到服務器,中途要經過很多個路由器,那時間週期就會長很多很多恨多。爲什麼要做cdn、p2p等也是這個考慮,縮短網絡的路徑(降低帶寬承載也是一方面)。

    再說redis、mongo:

    舉個簡單的例子,我有一個遊戲服務器,在線人數約4000,裏面是一個狀態機在跑,需要不斷的去檢測各種狀態,經驗,星座,任務開放,技能開放等等。一個玩家大約10個狀態的判定,4000個玩家必須在200ms之內檢測完畢,不然延遲會很嚴重,那1s就是大約執行5次,如果每一次數據都去redis去取,大約是5*10*4000 = 200k次,別說redis,怎樣的牛B的服務器都頂不住,這還是隻有1個服。

    那麼問題來了:怎麼解決呢?

    把數據放在內存裏面,直接從內存取,然後foreach。大部分的應用優化到這裏,基本上應付所謂的日pv百萬,就不是什麼問題了。



    到了這一步,那麼問題來了,對於內部應用,比如分佈式文件存儲,數據分析,任務調度。腫麼破?

    對於大數據,其實一直是一個僞命題,數據量太大屬於硬傷。所有的做大數據處理的,都是把數據分成小數據,然後分塊來處理,最後再合併。其實從mysql,oracle,mssql等一系列rmdb的分區,分庫上的處理就可以看出來。想要提高性能,必須要做到,每個模塊處理的數據量,都是細分到了一定粒度的。這個時候index, group, hash等的重要性,在這裏就體現出來了。

    舉個簡單的例子:我有一個業務系統,每天的日誌大約是10個G,一個月就大約是300g,一季度大約1T,我需要看每小時/每天/每週/每月/每季度的各種報表,每次都去數T裏面去找,肯定是不可能的。

    那麼問題來了:怎麼解決呢?

    按業務分析每分鐘的數據,10g/24/60大約7M,然後生成一個分析後的結果文件,大約幾k,1小時就是60個文件,需要查看每小時的數據,則將60個文件的結果合併。具體粒度可按具體業務定製,這個是比較簡單的分組的例子。

    那我需要查看某一個用戶,最近10天來的所有操作/訂單,那原分組方式,已經無法滿足,這個時候怎麼辦呢?

    在插入用戶數據的時候,可以按照一定規則,比如用戶編號的後兩位取摸,去存儲在某一個文件裏面,10g的數據,則可以相對平均的分配到100個文件裏面去,需要查看某用戶時,則可以針對用戶編號取摸,直接定位到那個文件,然後再去裏面查詢數據。這個是比較簡單的gourp+index。這一塊想明白以後,你就可以在這個基礎上面,寫個定製化的簡單的fs了(當然了,實際情況需要考慮的會更多,包括內存換入換出等,不在本文列舉)。



    經常聽到有人說,多線程的程序還不如單線程的程序性能高。那如何編寫一個能合理利用cpu資源的多線程程序?

    大家都知道,線程切換是需要額外的開銷,所以在編寫多線程程序的時候,就需要儘可能的避免共享式資源,這樣就可以在保證數據一致性的同時,而又避開線程等待的時間。

    舉個簡單的例子:

    我有個大的字典(Dictionary/Map)存放用戶的會話數據,每個線程,去這個字典裏面去讀/寫數據的時候,都需要去上鎖,才能保證數據的一致性,如果兩個(更多)線程同時去讀/寫數據,其他的線程就需要去等待當前線程釋放資源,線程越多,則等待的機率越大,性能則越差,多線程處理變成了單線程處理,且等待完了以後,能否再切換回來這個線程繼續執行,又是另外一個開銷,這一部分屬於系統拖託管,屬於不可控的。

    那麼問題來了:怎麼解決呢?

    根據硬件和實際測試數據,合理分配線程資源,比如,我初始化了8個線程,每個用戶的請求,對於線程總數取摸,保證每個用戶的請求,入同一個線程處理,則可以在每個線程內部,存放這些用戶數據,每個線程在自己內部進行存取,避開了lock,也避開了線程等待/切換帶來的資源開銷。不取模,隨機分配線程,然後用一個hash表來存放,也可。讓每個線程,專注於做自己的事情,任務調度作業,也大是基於這個處理。把線程處理機制,放大到虛擬機/物理機之間的消息分發,也大是如此。

    還有很多很多,不一一列舉,具體業務,視具體情況而定。

    總體來說,避開網絡開銷,避開海量數據,避開資源爭奪 是所有高性能的幾個基本要素。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章