2008-12-01 156 views
6

我在寫一個相當複雜的Web應用程序。 Python後端運行一種算法,其狀態取決於存儲在不經常改變的多個相關數據庫表中的數據,以及經常改變的用戶特定數據。當用戶使用應用程序時,算法的每個用戶狀態會經歷許多小的更改。該算法經常在每個用戶的工作中用於做出某些重要的決定。如何讓一個web對象中的Python對象持久化?

由於性能原因,對來自(半規範化)數據庫數據的每個請求重新初始化狀態很快變得不可行。例如,以某種方式緩存狀態的Python對象,以便在需要時可以簡單地使用和/或更新,這將是非常可取的。但是,由於這是一個Web應用程序,因此有幾個進程爲請求提供服務,因此使用全局變量是不可能的。我試着序列化相關對象(通過pickle)並將序列化數據保存到數據庫,現在我正在試驗通過memcached緩存序列化數據。但是,這仍然會經常導致序列化和反序列化的大量開銷。

我看過共享內存解決方案,但我發現的唯一相關事項是POSH。然而,POSH似乎沒有被廣泛使用,我不覺得將這樣的實驗組件集成到我的應用程序中很容易。

我需要一些建議!這是我開發Web應用程序的第一步,所以我希望這是一個常見的問題,以至於有這樣的問題的衆所周知的解決方案。在這一點上的解決方案,假設Python的後端是一臺服務器上運行就足夠了,但加分解決方案,規模到多臺服務器以及:)

注:

  • 我有這個應用程序正在工作,目前正在使用並且處於活動狀態我開始時沒有做任何過早的優化,然後根據需要進行優化。我已經完成了測量和測試,以確保上述問題是實際的瓶頸。我敢肯定,我可以從目前的設置中擠出更多的性能,但我想問問是否有更好的方法。
  • 設置本身仍然是一項工作;假定系統的架構可以是任何套件的解決方案。
+0

哪個框架? CherryPy的? Django的? – 2008-12-01 11:20:26

+0

你有沒有做過任何測量證明狀態訪問是瓶頸?醃菜有多大,取出多少時間,整個請求的時間等等? – 2008-12-01 12:28:35

+0

@Martin:鹹菜大約2MB(協議2),反序列化和序列化佔用請求處理時間的90%。 – taleinat 2008-12-01 21:51:05

回答

3

我認爲multiprocessing框架有什麼可能適用於此 - 即共享ctypes模塊。

多處理對於Python來說是相當新的,所以它可能有一些奇怪的地方。我不太確定該解決方案是否適用於不通過multiprocessing產生的進程。

2

我想你可以給ZODB一槍。 「

」ZODB的一個主要特性是透明性,不需要編寫任何代碼來顯式讀寫數據庫中的對象,只需將持久對象放入一個像Python字典一樣工作的容器中,這個字典中的所有東西都保存在數據庫中,這個字典被認爲是數據庫的「根」,它就像一個魔術包;任何你放進它裏面的Python對象都會變成持久的。

Initailly它是Zope的一個組成部分,但最近還有一個獨立的軟件包。

它具有以下限制:

「。其實有什麼你可以在ZODB存儲有一些限制,您可以存儲可以在任何物體‘醃’到一個標準的,跨平臺的串行格式像列表,字典和數字這樣的對象可能被醃漬,像文件,套接字和Python代碼對象這樣的對象不能被存儲在數據庫中,因爲它們不能被醃製。「

我看了,但沒有給它一個鏡頭,自己雖然

其他可能的事情可能是在內存中的SQLite數據庫,這可能有點加速過程 - 是一個內存分貝,但你仍然必須做的序列化的東西,所有 注:在內存數據庫是對資源的價格

這裏是一個鏈接:。http://www.zope.org/Documentation/Articles/ZODB1

+1

這或多或少是我正在做的 - 用pickle序列化對象並將序列化數據保存到數據庫。由於我試圖消除序列化和反序列化過程的開銷,所以ZODB將無濟於事。 – taleinat 2008-12-01 11:38:35

+1

@taleinat,它只在對象退出緩存並且再次請求時才反序列化和序列化。 – Unknown 2009-05-17 02:37:32

8

要謹慎過早優化的

此外:「Python後端運行一種算法,其狀態......」是Web框架中的會話。而已。讓Django框架在緩存中維護會話狀態。期。

「算法的每個用戶狀態在用戶使用該應用程序時會經歷許多小的更改。」大多數Web框架都提供了一個緩存會話對象。通常它是非常高的性能。請參閱Django的session documentation

建議。 [修訂]

看來你有一些工作。利用學習你的框架,學習工具,並學習你可以轉動什麼旋鈕,而不會冒汗。具體來說,使用會話狀態。其次,緩存緩存,會話管理以及易於調整的內容,並查看是否有足夠的速度。通過試用MySQL套接字或命名管道是否更快。這些是無編程優化。

第三,測量性能以找到您的實際瓶頸。準備好提供(並捍衛)這些測量的細粒度足夠有用和穩定,足以提供備選方案的有意義的比較。

例如,顯示持久會話和高速緩存會話之間的性能差異。

1

另一種選擇是審查狀態的要求,聽起來好像序列化是瓶頸然後對象非常大。你真的需要一個大的物體嗎?

我知道在Stackoverflow播客27 reddit球員討論他們用於狀態,所以也許有用的傾聽。

2

首先您的方法不是一種常見的Web開發實踐。即使使用多線程技術,Web應用程序也可以運行多處理環境,以實現可擴展性和更輕鬆的部署。

如果您只需要初始化一個大對象,並且以後不需要更改,那麼可以通過使用在創建WSGI應用程序時初始化的全局變量,或者該模塊包含對象被加載等,多處理將爲你做的罰款。

如果您需要更改對象並從每個線程訪問它,您需要確保您的對象是線程安全的,請使用鎖來確保。並使用單個服務器上下文,一個進程。任何多線程python服務器都能很好地爲您服務,FCGI也是這種設計的不錯選擇。但是,如果多個線程正在訪問和更改您的對象,那麼這些鎖可能會對您的性能增益產生非常不利的影響,這可能會使所有好處消失。

2

這是Durus,一個用Python編程語言編寫的應用程序的持久對象系統。 Durus提供了一種簡單的方法來使用和維護一個或多個進程使用的對象實例的一致集合。通過包含 commit()和abort()方法的緩存的Connection實例來管理持久實例的訪問和更改,以便更改是事務性的。

我之前已經用它在一些研究代碼,在這裏我想堅持某些計算的結果http://www.mems-exchange.org/software/durus/

。我最終轉向pytables,因爲它更好地滿足了我的需求。