2016-06-01 60 views
-2

運行一個C#.net應用程序,每隔30秒從100個客戶端接收數據,然後將數據存儲在數據庫中。數據是針對每個客戶端的兩個參數。我需要爲每個客戶每小時確定每個參數的總和,並根據結果做出決定。決策算法將以滑動窗口的方式爲最後一小時的數據做出決定。我最初的想法是保留100個客戶端的字典,其中關鍵是客戶端IP,價值是一個總計。但是1)如果我的應用程序在半小時或59分鐘的時候重新開始,我就失去了所有這些溫暖的運行總數。 2)如果更多的客戶端開始發送數據,字典將消耗更多的內存,3)如果將來2個參數變爲100,字典增長更大4)使運行總值總是反映一小時的最近數據值不是直截了當。從傳入流計算隨時間變化的值的最佳方法

我應該考慮哪些不同的方法?最佳實踐?設計模式?

+2

這是非常廣闊的,但這裏有我的兩分錢:1店在數據庫中的數據,2 *鍵值爲客戶端IP *非常糟糕的主意,兩個不同的客戶端可以具有相同的外部IP(流量通過代理, nat,其他)。 2,在客戶端生成GUID並將其存儲在客戶端上,然後當客戶端連接發送ID,這樣你會毫不含糊地identfy每個客戶端,甚至可以有多個用戶在同一臺​​機器上。 – Gusman

+0

謝謝。 IP是一個壞主意,我同意。我將使用GUID。對於數據庫存儲,我將在傳入數據到達時進行存儲。決策邏輯在存儲之前在數據上運行。還是你的意思是,存儲它,然後決定邏輯定期工作的數據庫?我試圖避免這種情況,因爲它可能無法在數據庫讀取和常量寫入方面表現良好。 – sOltan

+0

是的,我打算在存儲的數據上間隔運行它。關於性能,你說你將有100個客戶端,你希望每個客戶端創建多少個寄存器?任何實際的數據庫都將工作得足夠快,以支持每秒數千次寫入,因此根據事務量可能足夠快或不足。 – Gusman

回答

0

很廣,但我會嘗試定義結構:

  1. 確定每個客戶端連續8個字節的整數,UID。不是GUID,甚至沒有順序的GUID。 4字節的整數是一個選項,但我會堅持8字節。種子從十萬。

  2. 用連續的8字節整數CID識別來自用戶的每個呼叫。不是GUID,甚至沒有順序的GUID。 4字節的整數是一個選項,但我會堅持8字節。我將從1970-01-01T00:00:00開始以CID爲單位進行微秒數。

  3. 將所有數據存儲在存檔數據庫表REPORT_ARCHIVE中,UID + CID是複雜的PK。 CID散列上的簇表使其變得矮胖(每年/每次錄製1個文件)。

  4. 在操作數據庫表REPORT_OPER中存儲最後N條記錄(N取決於您的時間窗口,應該是您的配置值),UID + CID是複雜的PK。 UID散列上的羣集(8-16個文件)。

  5. 將所有傳入的調用像隊列一樣管理到內存結構中。異步處理代理應該抓取隊列中的記錄。通過大塊抓取,使用數據塊分塊(SQL Server和Oracle支持)保存到DB中。保存到REPORT_OPER表中,在INSERT上設置觸發器以將數據從REPORT_OPER推送到REPORT_ARCHIVE。

  6. 運行所有的工作對REPORT_OPER查詢(總結等),您的分析可以運行在REPORT_ARCHIVE。

  7. 對於類似於最新的X報告的SUM,我會在使用UID作爲關鍵字的ConcurrentDictionary的內存中緩存SUM。重要提示:緩存請求呼叫(管理員要求總計),而不是插入呼叫(用戶在30秒間隔內呼入)。爲此,您需要就SLA達成一致 - 報告總計可接受的延遲是多少。如果客戶希望接近實時 - 協商調用頻率來計算緩存命中/未命中。

祝你好運。