Postgresql

如何將實時數據儲存到數據庫

  • April 2, 2020

這是我的情況:

  • 我有一個實時向我提供數據的 WebSocket 連接
  • 我有一個非同步回調函式,它獲取數據並插入隊列
  • 我有另一個執行緒從隊列中讀取並將其儲存到 Postgres 數據庫中,一次一行(使用 python 的 psycopg2 庫)

問題是實時數據的輸入速度比插入數據庫的時間要快,並且在幾個小時內,伺服器就會耗盡記憶體。(這是因為 psycopg2 庫很慢嗎?)

一個簡單的解決方案是創建更多插入數據庫的執行緒;但是,這會導致數據亂序。是否有對數據進行排序的數據庫?其他建議將不勝感激。

一般來說,對於關係數據庫,1000 次單行插入會比單次 1000 行插入慢。在記憶體中批量處理數據並載入到數據庫可能會更快。

當您將數據接收到記憶體中時,您會建構一個隊列。然後,您從隊列中彈出頂部項目並將其插入數據庫。相反,彈出頂部N項目並將它們全部插入單個INSERT語句中。的理想值N並不普遍,因此您必須進行試驗。嘗試從 1000、10000 開始,然後根據吞吐量結果從那裡開始。

我還看到(並支持)大量數據流式傳輸到文件,然後非同步載入到數據庫的架構。這有助於確保您的接收服務永遠不會耗盡記憶體和崩潰(從而失去記憶體中的數據),但它確實增加了一些複雜性,並且不能保證您載入數據的速度總是比輸入數據快。相反,它只是把它分成一個單獨的問題來解決。在此配置中,您的接收服務會將數據寫入文件,直到它們的N大小為 MB/行。然後,您轉入下一個文件。(就個人而言,我喜歡文件名上的日期時間戳以保留文件順序。)非同步地,一個單獨的服務會選擇最近的文件並將它們載入到數據庫中,(使用COPY或任何你找到的 Python 庫) .

這個問題更適合 Stack Overflow。我想你的架構幾乎就在那裡了。您希望網路套接字盡可能快,並將數據保存到一些非持久性儲存中,如果您不擔心在伺服器崩潰時失去數據,那麼記憶體中就足夠了。然後,您經常需要一個程序將該隊列中的數據保存到 Postgres 中。確保在一次往返數據庫中批量插入許多行。使用準備好的語句並僅將需要插入的數據數組傳遞給它。——科林特哈特

引用自:https://dba.stackexchange.com/questions/260351