天天看點

partysip架構優化計劃

partysip優化計劃

先說一下伺服器構成,是使用開源的partysip項目,底層協定棧用的osip。修改了裡面的注冊伺服器,在注冊伺服器上,連接配接mysql資料庫。現在初步作了一些測試,但是感覺partysip處理過程并不滿意,測試結果如下

用戶端數量

客戶并發數

持續時間(分鐘)

伺服器狀态

備注

1

100

90

運作正常

單cpu占用為40%,注冊伺服器記憶體消耗為24m

200

12

不能處理資料

注冊伺服器器無響應,mysql資料無問題

2

10

50

30

測試伺服器的配置如下

硬體:4g memory, cpu 4核1.6ghz,網卡:1000m雙網卡

作業系統:windows2003+sp1

測試環境:注冊伺服器,mysql伺服器同時運作。

總體上來說,注冊伺服器并發在200/秒時(還是用戶端),隻能同時保證5000人左右線上,這個資料太不理想了。這個過程肯定和資料庫的通路有一定的關系,因為在注冊伺服器上,每有一個注冊使用者都需要首先周遊資料庫中的表,之後根據周遊結果,決定是把使用者記錄寫入資料庫,還是修改資料庫裡面的記錄,同時,在傳回ack時,需要再次周遊資料庫,找到此使用者的contect資訊,并傳回。通路mysql資料庫的子產品為單線程的。

研究過partysip,osip朋友可能知道,partysip裡面對于每個插件,都開啟一個線程,另有一個管理線程。整個處理過程是串行處理的,是以執行效率并不是很高,我知道基于以上的測試結果提出優化方案是比較草率的,我也需要更深入的測試,我也将進行更深入的測試,但是這需要我們充分了解partysip架構,隻是現在我隻是忽略了解一下,但是發現不少問題,是以,提出此優化方案,當然随着了解的深入,測試結果的詳細,可能在很多細節上修改我的認識,但是從大的方面來說,partysip設計并不适合做一個産品伺服器(我的個人認識),因為在代碼分析中,發現了很多問題(也不能說是問題,因為partysip并沒有保證說這是一個完美的伺服器,确切的講不太适合對于大并發量的資料處理),比如沒有采用記憶體池,線程池,基于系統級别的優化(比如完成端口,epoll),是以我想從大的方面開始逐漸優化,也需要然後逐漸驗證我的設計方案是否真實有效。

1:增加buffer(cache)

       主要使用方向是:對于頻繁操作資料由檔案系統,轉移到記憶體統一管理,減少通路磁盤i/o的次數,進而是以資料通路時間。

       主要應用點是對資料庫資訊的緩存。進而減少二次通路資料庫的時間消耗。

       原理:對于資料庫中表資料進行緩存,對于注冊資訊首先從此buffer中檢索,如果沒有找到再進行資料庫查詢,并把查詢結果儲存到buffer表中。

       适用性:主要是為了優化,資料庫通路功能子產品,減少資料庫的通路。從另一方面來說,我還考慮過把通路資料庫的功能子產品做成多線程的,并采用線程池進行管理,不過現在的首要目标可能是建立一個此buffer

2:記憶體池政策

       目的:對記憶體空間的統一配置設定和管理,減少直接對記憶體的配置設定和銷毀的操作,較少記憶體碎片的産生,保障伺服器長時間高效運作,要在多線程間運作,需要采用好的信号,互斥體等機制做保障,記憶體池政策并非記憶體垃圾回收政策,對于記憶體洩露,記憶體池政策無法解決。

       記憶體池政策的概要設計

       程式首次運作時,首先擷取一定容量的記憶體,是以其他記憶體記憶體申請,都從這個記憶體中獲得,當記憶體空間不足時,再次申請一定容量的記憶體。其内部實作時,可以把記憶體空間按大小不同的結構進行劃分,并用一張空閑配置設定表(鍊)進行管理,配置設定算法可以參考作業系統記憶體配置設定算法(最佳配置設定算法),關于記憶體配置設定表的建立可以參考sccot meyer《more effective c++》上面的記憶體池政策,令網上有大量記憶體池方面的論文可以參考。

       适用性:使用partysip時,發現其所有的記憶體申請和記憶體釋放采用的函數均為osip_malloc和osip_free,而不是直接調用c中的malloc和free。osip_malloc和osip_free函數隻是對malloc和free的簡單封裝。這樣我們建立記憶體池政策時,隻需修改osip_malloc和osip_free函數即可,可以非常方面應用。

3線程池

       目的:增加伺服器的響應時間,增大伺服器的吞吐量,減少線程建立銷毀和切換的時間損失。

       線程池的概要設計

       基于線程池的設計,目前比較流行的有兩種1:生産者/消費者政策2:loader/follower政策,基于伺服器特性考慮(需要并發處理大量資料)以及參考一些成功例子,決定采用2政策:l/f政策的主要方式時,程式啟動時建立一組線程,并通過一組政策來管理,其中一個線程為loader線程,此線程處于活動狀态,當有資訊到來時有loader線程處理,如果此時有來一個資訊,線程池中一個被挂起的線程,被喚醒,來處理這個資料,處理完成後,如果還有活動線程就挂起,否則此線程講作為loader線程,等待資料的到來,更詳細的設計,參考同目錄下的lf.pdf文檔

       适用性:partysip采用為每個插件建立線程的方式,如果增加線程池,必須在資料到來的端口出,雖然有多個線程處理資料,但是由于每個插件隻有一個線程,是以在具體處理資料時也必須等待插件線程處理完畢後,再次調用,是以如果快速實作,也需要把每插件有單一線程修改為每插件線程池政策,修改這兩部分,幾乎是partysip底層流程的修改。雖然增加線程池政策是伺服器提速的最好方法,但是考慮其修改的複雜性,需要仔細partysip架構以及sip協定,分析後修改。

4基于系統的優化

說明:系統的優化,主要針對作業系統所提供的進階i/o通路功能的優化,比如windows

下的完成端口,linux下的epoll,比使用簡單的socket機制,要快很多。普通的綁定端口,監聽機制,并發總數隻有幾百個,而采用完成端口或epoll後,處理并發的數量在幾萬個左右,參考msdn上的完成端口性能測試。

       簡單實作:

由于基于系統的優化是與作業系統息息相關的,不同作業系統下,具體實作方式不同,是以,為了有更好的适用性,需要提供windows下和linux下兩種機制。

适用性:根據目前掌握的資料來看,由socket機制轉換為linux下的epoll和windows下完成端口,并不是很難,本質上講完成端口或者epoll都是在socket綁定端口的基礎增加了線程池(lp政策),可以友善異步調用。因為修改涉及到partysip底層邏輯的修改,是以需要仔細分析partysip架構以及sip協定。

我知道從整體上來說,提高系統得并發數是一項非常系統的優化工作,涉及到硬體選擇,作業系統的支援,輔助工具的優化,軟體的設計等多方面工作。是以在具體過程中,并不是簡單的通過更新硬體,更換作業系統,優化輔助工具,更改部分軟體設計就可以解決。需要系統級别的架構和設計,在具體操作過程中,隻修改一部分,并不會馬上看到優化結果,需要一個長期的測試過程。是以,基于這些考慮,伺服器端的設計必須建立一個良好的設計架構之上,以及具有足夠的優化餘地。

       在這裡希望各位做過基于partysip伺服器的朋友,多多提建議,并且談談你們伺服器在具體設計過程中碰到的問題,以及是如何解決。同時希望做過伺服器的朋友,多多給我提到的優化方案提建議,談談你們做伺服器時的一些心得,并且在不影響商業版權的情況,僅可能的多告知一些技術,非常感謝大家。同時也希望本文能夠對正在做partysip或者在項目中打算使用partysip的朋友提供借鑒的作用。

參考資料:

在即時通信軟體中,如何提高伺服器支援的最大連接配接數

(http://www.linuxforum.net/forum/gshowthreaded.php?cat=&board=program&number=529852&page=1&view=expanded&sb=5&o=all)

writing windows nt server applications in mfc using i/o completion ports

(http://msdn2.microsoft.com/en-us/library/ms810436.aspx)

win32 multithreading performance

(http://msdn2.microsoft.com/en-us/library/ms810437.aspx)

網絡的基礎架構:  ace 

www.chinaunix.net上的大量文章

《unix網絡程式設計》i卷

linux下通用線程池的建構(http://blog.csdn.net/tingya/archive/2004/12/23/226614.aspx)

微軟msn伺服器設計思想初步了解

(http://blog.csdn.net/fangzhengzhu/archive/2005/01/21/262886.aspx)

高性能伺服器軟體開發

the c10k problem

(http://www.kegel.com/c10k.html)

mmorpg遊戲伺服器端的設計

(http://blog.csdn.net/yahle/archive/2005/01/12/250034.aspx)

線程池的介紹及簡單實作

(http://blog.csdn.net/ioke/archive/2004/10/25/150874.aspx)

部分參考資料,參考同目錄下的pdf檔案

用完成端口開發大響應規模的winsock應用程式(1)(2)(3)(4)(5)

(http://dev.csdn.net/develop/article/15/15211.shtm)

write scalable winsock apps using completion ports

(http://msdn.microsoft.com/msdnmag/issues/1000/winsock/winsock.asp)

improving runtime performance with the smooth working set tool

(http://msdn.microsoft.com/msdnmag/issues/1000/bugslayer/)

udp并發伺服器設計讨論一:一台主機、一個cpu,實作機關時間内最大并發數

(http://www.linuxforum.net/forum/showflat.php?cat=&board=program&number=599334&page=4&view=expanded&sb=9&o=all&fpart=all&vc=1)