2012-08-25 15 views
2

我遇到了特定的問題並想到了解決方案。但是由於解決方案非常複雜,我想知道其他人是否遇到類似的問題,並且可以對最佳實踐發表評論或者提出其他建議。與併發用戶和重度數據處理的交互式web應用程序的體系結構

問題如下: 我有一個用Django編寫的webapp,它有一些屏幕,其中來自多個表的數據按時間間隔被收集,分組和聚合。 它基本上是一個很棒的矩陣,我們在一個座標軸上按時間間隔聚合數據,在另一個座標軸上按照間隔聚合數據。 它涉及許多內部和左連接來收集所有數據,並且由於呈現數據的字符「報告」,我使用原始的sql查詢所有內容。

問題是多個用戶可以同時在這些間隔中查看編輯數據。與其他使用相同數據的用戶相比,他們還可以編輯更細或更粗粒度的數據,但是以子/重疊間隔進行編輯。目前,當用戶編輯一些數據時,會激發一個django請求,更改數據,將受影響的時間間隔聚合在一起並重新顯示。但由於這些數據的不穩定性,其他用戶可能已經改變了一些東西。每次對錶格進行分組/彙總和重新渲染都是非常繁重的操作(取決於數據量和間隔範圍)。這與併發用戶編輯變得更糟..

我建議的解決方案: 很明顯,http請求/響應機制並不是真正理想的這種事情;分組/聚合相當重量級,並不理想爲每個請求執行此操作,併發將理想地在用戶之間引導,並且反饋應該像googledocs一樣實時,而不是整個頁面刷新。

我在考慮做一個守護進程,它讀取平板 dbms中的所有感興趣的數據,並將它緩存在內存中。對數據的所有更改都會在內存中發生,並寫入dbms。該守護進程通過鎖訪問數據,因此守護進程可以處理哪些用戶可以覆蓋其他更改。

使用python代碼對平面數據進行聚合和分組,並且僅返回用戶所需的切片;用戶/守護進程通信將通過websockets運行。守護進程將提供訂閱者/發佈者頻道,其中對特定切片數據感興趣的用戶在發生改變時被通知。這個守護進程可以使用像扭曲的框架來實現。但我不確定一個事件驅動的方法會在這裏工作,因爲我們想要「引導」所有未知的請求......也許這些應該放在一個隊列中,並在一個單獨的線程中運行?如果在我的調度程序旁邊的線程中進行扭曲運行會更好嗎,還是扭曲的主循環會在該隊列上運行的線程停止運行?我的理解是,線程最適合IO,而python重碼基本上阻塞了其他線程。我有兩個(websockets/dbms和處理數據),這會工作嗎?

有沒有人做過類似的事情?

在此先感謝!

Karl

回答

2

我試了類似的東西,你可能會對解決方案感興趣。這裏是我的問題:

python Socket.IO client for sending broadcast messages to TornadIO2 server

這就是答案:

https://stackoverflow.com/a/10950702/675065

他還寫了一篇博客文章的解決方案:

http://blog.y3xz.com/blog/2012/06/08/a-modern-python-stack-for-a-real-time-web-application/

軟件堆棧包括:

我這個實現自己和它的工作原理就像一個魅力。

+0

謝謝!我會看看這些庫.Tornado似乎比這種情況更適合扭曲,這將涵蓋我的問題的溝通部分。 – Martijnh

+0

順便說一句,另外我使用[uwsgi](http://projects.unbit.it/uwsgi/)爲django應用程序和[nginx](http://nginx.org/)提供反向代理服務所有靜態文件並將請求重定向到uwsgi。 – Alp

+0

最後一條評論已過時。 uwsgi或gunicorn是不需要的。 Tornado能夠爲wsgi應用程序提供服務,因此您的軟件堆棧中不需要其他工具。 – Alp

3

Google爲現在放棄的Wave產品的併發編輯功能實施的方案記錄在案文http://www.waveprotocol.org/whitepapers/operational-transform。儘管Wave本身很快就被拋棄了,但Wave的這一方面看起來仍然很成功。

至於問題,你問到實現你提出的方案:

  1. 事件驅動系統是完全能夠實現這個想法。事件驅動是一種組織代碼的方式。它並不妨礙你實現任何特定的功能。
  2. 線程不能很好地工作,特別是在Python中。
    1. 由於CPython一次只運行一個Python線程(不管可用的硬件資源如何),因此它對CPU綁定的工作有明顯的缺點。這意味着一個多線程CPU綁定的Python程序通常不會比單線程等價物更快,甚至更慢。
    2. 對於IO來說,這個缺點不是一個限制,因爲IO不涉及在CPython上運行Python代碼(IO API全部用C實現)。這意味着你可以同時在多個線程中執行IO,所以線程化可能是一個好處。但是,在單個線程中同時執行IO正是Twisted所要做的。只要你以非阻塞方式(或者可能是異步)進行IO操作,線程技術對於在單線程中執行IO沒有任何好處。
  3. Hello world。
+0

感謝您與OT的聯繫!除了有趣的閱讀,我不確定它是否真的適用於我的情況...這些轉換適用於文本編輯器之類的東西,但是當協作數據有點複雜時,衝突情況似乎變得非常適合應用領域。 至於nr 2,如果您有大量的處理*和*異步IO(處理輸入/輸出連接),該怎麼辦?再次分成獨立的進程? – Martijnh

相關問題