2010-08-06 33 views
4

我開始設計一個新的應用程序,將由大約50000個設備使用。每臺設備每天產生大約1440個註冊表,這意味着每天將存儲超過7200萬個註冊表。這些註冊表每分鐘都會出現,我必須能夠通過Java應用程序(J2EE)查詢這些數據。所以它需要快速寫入,快速閱讀和編制索引以生成報告。 設備僅插入數據,J2EE應用程序需要偶爾讀取。 現在我正在尋找軟件替代品來支持這種操作。一個巨大的數據存儲問題

  • 把單個表上的這些數據將導致災難性的狀況,因爲我將無法使用這些數據,因爲它存儲了一年的數據量。

  • 我使用Postgres,數據庫分區似乎不是答案,因爲我需要按月分區表,或者可能是更細化的方法,例如幾天。

我在考慮使用SQLite的解決方案。每個設備都有它自己的SQLite數據庫,而不是足夠精細的信息,以便進行良好的維護和快速插入和查詢。

您認爲如何?

+1

太通用的問題。完全取決於數據/查詢的類型等。 – 2010-08-06 17:40:45

+0

因此,更具體地說,數據是插入數據庫的GPS座標。這些查詢將會是這樣的報告:「顯示設備1234在2010年7月的位置」。 – gmuller 2010-08-06 18:34:40

+0

您是否已經在您的數據庫中安裝PostGIS? – 2010-08-06 22:34:53

回答

4
  1. 只記錄設備的位置的變化 - 大部分時間任何設備將不動 - 汽車將停,一個人會坐下或睡覺,一個電話將是一動不動的人或充電等等 - 這會使你存儲的數據少一個數量級。

  2. 您每年最多會產生大約1TB的數據(即使不執行第1點),這不是一個非常大的數據量。這意味着每個SATA驅動器可以處理大約30MB/s的數據。

  3. 即使一個簡單的未分區的Postgres數據庫在不太大的硬件上應該設法處理這個問題。唯一的問題可能是當你需要查詢或備份 - 這可以通過使用鏡像使用Streaming Replication來解決 - 這是即將發佈的PostgreSQL 9.0中的一項新功能。只需查詢/備份鏡像 - 如果它正忙,它會暫時自動排隊更改,並在稍後追上。

  4. 當你真的需要分區時,例如在device_id模256上而不是時間。這樣你就可以將寫入分散到每個分區上。如果按時進行分區,只有一個分區在任何時候都非常繁忙,而其他分區將閒置。 Postgres supports partitioning這種方式非常好。然後,您也可以使用tablespaces將負載分散到多個存儲設備,這在Postgres中也得到很好的支持。

+0

+1 for device_id modulo paritioning – 2010-08-06 21:54:52

+0

好建議通過device_ids進行分區。但是隨着時間的推移,分區會過大,你不覺得嗎? – gmuller 2010-08-06 22:04:30

+0

一致性散列比device_id modulo 256更好。請參見http://michaelnielsen.org/blog/consistent-hashing/ – TTT 2010-08-07 03:24:52

0

這是一個你問的模糊問題。我認爲你並不面臨數據庫軟件的選擇,而是一個架構問題。

一些注意事項:

  • 如何可靠的是設備,以及如何 以及被它們連接到 查詢軟件?
  • 如何安全運行 您需要的存儲是?
  • 設備 需要多少額外的處理能力才能處理您的查詢?

基本上,你的空間分區的想法是一個好主意。如果有必要,這並不排除時間分區。無論你在postgres還是sqlite中都這樣做,取決於其他因素,如處理能力和可用的庫。

另一個考慮因素是您的設備是否可靠並且功能足以處理您的查詢。否則,您可能需要使用集中的數據庫集羣,而您仍然可以並行查詢。

+0

設備和J2EE是分離的實體。設備只能寫入,J2EE應用程序偶爾讀取。 - 設備將通過數據庫連接到查詢軟件。 - 數據必須是故障安全的,所以丟失數據不好。 - 設備不會查詢數據,它們只會生成數據。 – gmuller 2010-08-06 17:58:16

2

時間間隔分區是一個非常好的解決方案,即使你必須自己推出。與單個Postgres數據庫相比,維護與50,000個SQLite數據庫的單獨連接遠不如實際,即使對於每天數百萬個插入數據庫也是如此。

根據您需要針對數據集運行的查詢類型,可以考慮將遠程設備分區到多個服務器,然後查詢這些服務器以將聚合數據寫入後端服務器。

高容量表的關鍵是:最小化您寫入的數據量和必須更新的索引數;不要執行UPDATE或DELETE,而只執行INSERT(並且對將來要刪除的數據使用分區--DROP TABLE比DELETE FROM TABLE快得多!)。

當您開始挑戰數據庫引擎時,表設計和查詢優化變得非常特定於數據庫。考慮僱用一名Postgres專家,至少諮詢一下你的設計。

2

也許現在是時候讓你可以在許多機器上分割數據庫了?卡桑德拉? Redis的?不要限制自己到SQL數據庫的。

1

數據庫分區管理可以自動化;對數據進行基於時間的分區是處理這類問題的標準方式,and I'm not sure that I can see any reason爲什麼PostgreSQL無法做到這一點。

你每天大約有72m行 - 假設一個設備ID,datestamp和兩個浮點座標,你將擁有(比如說)每行16-20個字節加上一些minor page metadata overhead. fag-packet容量計劃背後的建議每天1-1.5GB數據,或者每年400-500GB,如果需要的話加上索引。

如果您可以定期刷新數據(即不完全更新),您可以構建一個單獨的報告表並定期使用ETL過程進行更新。如果此表存儲在單獨的物理磁盤捲上,則可以查詢它,而不會顯着影響事務數據的性能。

歷史數據的單獨報告數據庫還允許您通過刪除較舊的分區來修剪操作表,這可能有助於提高應用程序的性能。您還可以爲報表創建索引並創建彙總表以優化報表性能。

如果您需要低延遲數據(即報告最新數據),還可以構建一個視圖,在該視圖中將主分區從操作系統報告出來,並從數據報告歷史數據市場。這將允許在針對此優化的報表上進行批量查詢,而可以從操作系統直接讀取相對較小量的當前數據。

大多數低延遲報告系統使用這種方法的一些變化 - 一個領先的分區可以通過實時進程(可能是觸發器)進行更新,並且包含的​​數據相對較少,因此可以快速查詢,但不包含行李這會降低更新速度。其餘的歷史數據可以大量編制報告。按日期分區意味着系統將自動開始填充下一個分區,並且定期過程可以移動,重新編制索引或爲歷史數據執行任何需要的操作以優化報告。

備註:如果您的預算運行於PostgreSQL而不是Oracle,您可能會發現直連式存儲比SAN快得多,除非您想在SAN硬件上花費大量資金。