2013-12-16 60 views
1

我目前正在開發用於將用戶的當前位置歷史存儲到HBase表中的解決方案原型。 (假設有數以億計的用戶)。 每個用戶對位置的試用都存儲在HBase表中。 然後,將這種位置的蹤跡用作少數離線數據分析作業的一部分。用於存儲時間序列用戶數據的HBase架構

以下是2種主數據訪問模式:

  1. 我應該能夠通過所有或位置的一個子集來掃描(根據時間範圍)從所存儲的位置試驗的特定用戶的。

  2. 對於離線數據分析,我應該能夠通過所有用戶的 的時間範圍內的所有位置進行掃描。

鑑於上述要求,我想出了以下行按鍵設計:

<uid>_<timestamp> 

其中「UID」代表用戶ID和「時間戳」表示時間在該位置被檢測並保存。

通過這種行鍵設計,實現訪問模式#1是直接的 - 掃描請求可以有一個開始鍵和結束鍵,給定的時間戳附加到特定的uid。

但是,棘手的部分是訪問模式#2,我正在尋求來自HBase專家的幫助。 因爲,我需要掃描過去6個月的所有用戶說,我最終不會使用任何鍵與掃描操作。這對掃描整個HBase表格有影響。我覺得效率低下。而且,我的數據容量預計會隨着2K /秒的寫入負載而提前增長。

我看了OpenTSDB,這是許多人在公開論壇中指出的。但我無法將該解決方案與我的數據訪問模式聯繫起來。

我正在尋找優化此架構的幫助,這將導致避免全表掃描。

+0

你有時間戳的限制嗎?也就是說,你將只保留過去6個月的最後時間戳? – Udy

+0

是的。我可能會保留最近一年的數據。我將以這種方式配置TTL。數據訪問模式#2的 –

+0

- 時間範圍應該是靈活的還是固定的? – Udy

回答

0

你可以做的一件簡單的事情是促進關鍵的一些時間 - 例如,在這種情況下添加一個月份前綴,常規查詢可能需要查看多個掃描(假設在通常情況下,您只需要最新的記錄,而不是大多數情況下不會有問題),但更長的運行時間將受到月份的限制。

順便說一句,如果經常使用你想你可能需要從最新的日期存儲到最舊的最新記錄(MAXLONG - 時間戳),以便查詢的時間範圍會更快

+0

對不起,我無法按照你的回答。當你說爲鑰匙添加月份前綴時,你是什麼意思?當我需要在一個時間範圍內獲取所有用戶記錄時,這將如何避免全表掃描? –

+0

Yearmonth_user_timestamp例如201312_01_123456788 ..所以你只是掃描你需要的月份,並跳過大掃描不需要的月份 –

+1

我擔心這個行鍵「201312_ [user] _ [timestamp]」可能會導致寫入熱點的寫入命中相同的區域服務器。 –

0

就個人而言,我將避免在行鍵中使用基於時間的前綴。

讓我指出另一個方向,你能負擔得起數據重複嗎?

如果答案爲YES,只需創建另一張表,併爲您的作業創建最小的必需數據,並將TTL設置爲6個月(如果需要,還可以使用另一個3個月的TTL),並且一次寫入所有表(您可以儘可能多地將寫入操作緩衝到該表)。另外,你的餐桌上有幾個家庭,你可以將短壽的家庭添加到同一張桌子上,但我更喜歡爲此而設置不同的(個人偏好)。

如果答案爲否,您仍然可以執行基於時間戳的範圍掃描,以避免讀取儘可能多的數據。如果(如你所說)表格將有1年的TTL,你可以負擔得起,它不需要對30年的數據進行全表掃描,只需要幾天的檢索。

順便說一句,我建議你至少包括一個基於數字uuid(modulo,crc32,md5 ...)的2-3字節前綴,以便在區域之間獲得均勻的分佈並更好地處理不活動(或非常活躍的)用戶。你無法預測用戶的活躍程度。

+0

謝謝@ rmruano,保持重複的數據絕對是一種選擇,我可以考慮到。但是,我仍然覺得這是黑客,因爲我需要管理重複項。 –

+0

不客氣。在HBase或任何其他NoSQL數據庫中複製數據是非常常見的,而不是根本就沒有hacky,因爲我們不是在討論RDBM。你只需要包裝常見的CRUD操作來寫入兩個表。作爲一個簡單的用戶位置日誌,你可能會添加另一個put(緩衝),並且像你所說的那樣,性能增益對​​於數億用戶來說將是巨大的。無論如何,這是你的選擇,有更多的桌子,你可以簡單地添加一些短壽命的家庭(1周,1個月,3個月...),並做一個基於家庭的掃描。 –

0

不是將每個位置點存儲在一行中,而是可以將每個位置存儲在自己的列中,並使用一年的TTL。這與OpenTSDB如何計算指標是類似的,對於某個時間窗口,每次讀取指標都存儲在單獨的列中。

該模式允許您掃描您的所有用戶和掃描作業中的內容,手動篩選出您不關心的日期。這仍然是全表掃描,但僅限於您的用戶組,而不是您所有位置的集合。

該模式還具有允許用戶訪問其整個位置歷史記錄的簡單掃描的優勢,如下所示。

此架構的缺點是圍繞每個用戶行的大小。如果每個用戶都有幾百或幾千個數據點,則應該沒問題。但是,如果每個用戶擁有數百萬個地理位置,則您的行大小可能會與您所在地區的大小相同。由於HBase不會將行分割到不同的區域,因此您最終會得到由單行組成的區域,這不是最優的。

要解決這個問題,您需要爲OpenTSDB這樣的每個用戶實施自己的簽入數據分段。說每個桶是uid + weekOfTheYear + year。存儲桶粒度在很大程度上取決於用戶添加位置數據的頻率。這會爲每個用戶創建多行,因此需要對給定用戶的每個存儲桶進行掃描。要訪問特定日期範圍的數據,只需使用內置的時間戳過濾器即可掃描。

相關問題