2010-12-23 23 views
1

我們有一個系統,我們每秒都會在多個網站上收集用戶活動的數據。我們將這些數據轉儲到數據庫X(比如MS SQL Server)中。我們現在需要從daatbase X中的單個表中獲取數據並插入數據庫Y(比如說mySql)。從多個線程的單個數據庫表中獲取數據的最佳方法?

我們希望通過多線程從數據庫X中獲取基於時間的數據,以便儘可能快地獲取數據。一旦提取並存儲在數據庫Y中,我們將從數據庫X中刪除數據。

這種設計是否有任何最佳實踐?任何具體的事情要照顧桌子設計,如分享或什麼?是否還有其他任何事情需要注意,以確保我們可以從運行在多臺機器上的線程中儘可能快地獲取它?

提前致謝! Ravi

+1

爲什麼不從第一個數據庫導出數據並將其導入到第二個數據庫? – 2010-12-23 12:30:14

回答

0

我會測試(通過測量)你的假設,多個slurper線程將加快速度。沒有更具體的問題,它看起來像你想用你的數據庫做一個ETL(提取轉換加載)過程,當你讓數據庫特定的技術處理它時,這些是非常有效的,特別是如果你有興趣在聚合等

+0

感謝您的回覆。讓我試着讓這個更清楚,我會設置多臺機器,每臺機器運行4個「fetcher」線程。所有這些多線程將從一個數據庫表中獲取數據,並將其轉儲到這個新的數據庫中以備將來處理。我們的目標是儘可能快地從原始數據庫獲取數據,然後清除它。其他一些軟件將繼續生成這些數據並繼續在原始數據庫中發佈。 – 2010-12-23 13:57:16

+0

我以前使用ETL的東西,但更多的是作爲一夜之間/計劃的工作。我想這取決於第一個數據庫的填充速度有多快,並且存在任何約束,以及您想將它移動到其他位置?有聚合嗎?你爲什麼要保留原來的「清晰」? – Toby 2010-12-23 17:21:09

1

如果您將數據從一個數據庫移動到另一個數據庫,您將不會因多個線程執行工作而獲得任何優勢。它只會增加爭用。

如果兩個數據庫的類型相同,則應該查看供應商特定的複製工具。這基本上總是勝過本土解決方案。

如果數據庫是不同的(供應商),你必須在一個有效的機制來決定

  1. 確定新的/更新/刪除的行(觸發器,基於範圍查詢,完全轉儲)
  2. 運輸數據(卸載到文件& FTP,拉從程序/推)
  3. 加載其他數據庫上的數據(進口,批量插入)

沒有更多細節,這是不可能的比這更具體。 哦,而影響您選擇的兩個最重要的考慮因素是:

  1. 預期的數據量是多少?在目標DB源DB行創建和可用性之間
  2. 最長可接受的延遲
0

有您的問題的關注的兩個層次:

  1. 這兩個數據庫之間的交易:

    這很重要,因爲您會從源數據庫中刪除數據庫。必須確保只有在數據庫已成功存儲到Y時才從X中刪除數據。另一方面,您必須確保從X中刪除數據必須成功,以防止將相同的數據重新插入Y.

  2. 傳輸數據的表現:

    如果X數據庫有每當傳入的數據,這是一個在線數據庫,它是不是一個好的做法,只是收集數據,商店Y,並刪除它們。計劃批量的大小時,程序會啓動該批次的事務;重複運行程序,直到X中的數據數量小於批量大小。

在這兩個數據庫中,您都應該添加一個表來記錄批處理。 處理中有三種狀態。

INIT - The start of batch, this value should be synchronized between two databases 
COPIED - In database Y, the insertion of data and the update of this status should be in one transaction. 
FINISH - In database X, the deletion of data and the update of this status should be in on transaction. 

當編程運行時,它首先檢查「INIT」或「COPIED」狀態的批次,並重新啓動以處理該會話。

  • 如果X有一個「INIT」記錄和Y不這樣做,只是插入相同INIT記錄到Y,然後執行插入到Y
  • 如果Y中的記錄被「複製」和X是「INIT」,只需將X的狀態更新爲「COPIED」,然後執行X的刪除即可。
  • 如果X中的記錄是「FINISH」且Y中的相應記錄是「COPIED」,只需更新Y的狀態爲「完成」。

總之,批量處理數據會讓您有機會優化兩個數據庫之間的這種傳輸。批量大小的數量決定了轉換的效率,並取決於兩個因素:其他操作同時使用的數據庫以及數據庫的調整參數。在一般情況下,Y的寫吞吐量可能是處理的瓶頸。

0

線程是不是要走的路。數據庫是這裏的瓶頸。多線程將只有增加爭用。即使有10個進程將數據干擾到SQL Server,單個線程(而不是多個進程)可以更快地將其拉出。這絕對沒有疑問。

SELECT本身可能會導致主表中的鎖定,從而降低INSERT的吞吐量,因此我會盡可能快地「進出」。如果是我,我會:

  1. 根據範圍查詢(date,recno,whatever)選擇行,將它們轉儲到文件中並關閉結果集(遊標)。
  2. 根據相同的範圍查詢刪除行。
  3. 然後處理轉儲。如果可能的話,轉儲格式應該可以批量加載到MySQL中。

我不想毆打你的架構,但總的來說設計聽起來有問題。選擇和刪除表中的行高INSERTion率會導致巨大的鎖定問題。我將在SQL Server中查看「雙緩衝」數據。

例如,每分鐘插入在兩個表格之間切換。例如,在第一分鐘INSERT進入TABLE_1,但是當分鐘翻轉時,他們開始INSERT到TABLE_2,下一分鐘回到TABLE_1等等。當INSERT進入TABLE_2時,選擇TABLE_1中的所有內容並將其轉儲到MySQL(儘可能高效),然後對錶進行TRUNCATE(刪除所有行,並且零懲罰)。這樣,讀者和作者之間就不會存在爭執。

協調TABLE_1和TABLE_2之間的翻轉點是棘手的部分。但它可以通過巧妙使用SQL Server分區視圖自動完成。

相關問題