5

我正在設計一個系統,該系統應該分析大量用戶事務併產生聚合度量(如趨勢等)。該系統應該工作快速,健壯和可擴展。 系統是基於Java的(在Linux上)。實時分析處理系統設計

數據從生成用戶事務的日誌文件(基於CSV)的系統到達。 系統每分鐘生成一個文件,每個文件包含不同用戶的交易(按時間排序),每個文件可能包含數千用戶。

用於CSV文件的採樣數據結構:

10:30:01,用戶1,...
10:30:01,用戶1,...
10時30分02秒,用戶78,...
10:30:02,用戶2,...
10:30:03,用戶1,...
10:30:04,用戶2,...
。 。 。

我計劃的系統應該實時處理文件並執行一些分析。 它必須收集輸入,將其發送到多個算法和其他系統,並將計算結果存儲在數據庫中。該數據庫不包含實際的輸入記錄,而僅包含關於交易的高層彙總分析。例如趨勢等。

我打算使用的第一個算法要求最佳操作至少10條用戶記錄,如果在5分鐘後找不到10條記錄,則應該使用所有可用數據。

我想用Storm來實現,但我寧願儘可能在設計層面上討論這個問題。

系統組件列表:

  1. 監視每分鐘輸入的文件的任務。

  2. 一個讀取文件的任務,解析它並使其可用於其他系統組件和算法。

  3. 一個組件爲用戶緩衝10條記錄(不超過5分鐘),當收集10條記錄或5分鐘過去時,是時候將數據發送給算法進行進一步處理。 由於要求爲該算法提供至少10條記錄,因此我想到了使用Storm Field Grouping(這意味着爲同一用戶調用相同的任務)並跟蹤任務內的10個用戶記錄的集合,當然我計劃有幾個這些任務,每個處理一部分用戶。

  4. 還有其他的組件可以在單個事務上工作,對於他們我計劃創建其他任務,以便在解析每個事務(與其他任務並行)時接收每個事務。

我需要你的幫助#3。

設計此類組件的最佳做法是什麼? 很明顯,它需要維護每個用戶10條記錄的數據。 鍵值映射可能會有所幫助,在任務本身中管理映射還是使用分佈式緩存更好? 例如Redis是一個關鍵的價值存儲(我以前從未使用過)。

感謝您的幫助

回答

5

我曾經使用redis相當多。所以,我會在你使用Redis的

#3的思想評論有3所要求

每個用戶
  1. 緩衝

  2. 緩衝器,用於10個任務

  3. 本應到期時,每5分鐘

1. Buffer P er用戶: Redis只是一個關鍵的價值商店。雖然它支持各種各樣的datatypes,但它們始終是映射到STRING鍵的值。所以,你應該決定如何識別一個用戶是否需要每個用戶緩衝區。因爲在Redis中,當你覆蓋一個關鍵的新值時,你永遠不會得到錯誤。一種解決方案可能是在寫入之前檢查存在性。

2. 10個任務的緩衝區:你很明顯可以在redis中實現一個queue。但限制它的大小是留給你的。例如:使用LPUSHLTRIM或使用LLEN來檢查長度並決定是否觸發您的過程。與此隊列關聯的密鑰應該是您在第1部分中決定的密鑰。

3. Buffer在5分鐘內過期:這是一項最艱鉅的任務。在redis中,每個關鍵字都可以有一個expiry,而不管它具有哪個數據類型。但到期過程是沉默的。任何密鑰到期時都不會收到通知。所以,如果你使用這個屬性,你會默默地失去你的緩衝區。一個解決這個問題的方法是,有一個索引。意思是,索引將映射時間戳到所有需要在該時間戳值過期的密鑰。然後在後臺,您可以每隔一分鐘閱讀一次索引,然後手動刪除[在讀完]之後的密鑰,並使用緩衝區數據調用所需的進程。要獲得這樣的索引,您可以查看Sorted Sets。其中時間戳將是您的score並且集member將是您希望在該時間戳刪除的密鑰[每個用戶決定的第1部分中映射到隊列的唯一密鑰]。你可以做zrangebyscore讀取所有組成員指定的時間戳

總評:

使用Redis的列表來實現隊列。

使用LLEN來確保你沒有超過你的10個限制。

每當您創建一個新列表時,請以Score爲Current Timestamp + 5 min並將Value作爲列表的關鍵字輸入索引[Sorted Set]。

當LLEN達到10時,請記住閱讀然後從索引[有序集]和從db [刪除鍵 - >列表]中刪除鍵。然後用數據觸發你的過程。

對於每一分鐘,生成當前時間戳,讀取索引和每個鍵,讀取數據,然後從數據庫中刪除鍵,並觸發您的過程。

這可能是我實現它的方法。可能有一些其他更好的方式來在Redis的

0

您的數據模型,您的要求1 & 2:Apache的水槽或卡夫卡]

您的需求#3:艾斯波博爾特內線強攻。在Redis中,爲了完成此操作,您將不得不重寫Esper Logic。]