前言在大資料時代,軟體系統需要具備處理海量資料的能力,同時也更加依賴於系統強大的儲存能力與資料響應能力。各種大資料的工具如雨後春筍般孕育而生,這對於系統來說是極大的利好。但在後端採用分布式、雲儲存和虛擬化等技術大刀闊斧地解決大部分儲存問題後,仍然不足以滿足所有的業務需求。對於以使用者為終點的軟體系統來說,無論後台多麼強大都難以避免有一部分資料流向終端,面向使用者。為了應對這最後一公里的通勤問題,我們得在終端快取部分資料來提高系統的響應效率。另外一方面,受限於使用者終端的機器效能,快取大量的資料反而會降低系統響應速度,甚至讓系統崩潰。為此,我們需要乙個根據系統當前狀態動態調整最急需的資料的快取器,滑窗快取是乙個很不錯的選擇。最終,我們找到了slidingwindowcache,乙個基於 .net standard 實現的滑窗快取。
slidingwindowcache 簡介slidingwindowcache 基於鍵值對快取,可以快取以特定序列序列組織的資料,比如時間序列資料。其本身帶有預先快取的能力,當系統狀態滿足預設條件後將自動快取資料。每次自動快取的量可自行配置。當快取超出視窗後即被視為無用資料,會被自動釋放。同樣的,快取視窗大小可進行配置。
作為 key/value 快取,該快取的 value 可以是任意型別的資料。但為了滿足有序組織,目前的 key 只支援 int、long、float 和 double 四種型別。對於時間序列資料來說,可以將時間轉化為 long 作為 key 使用。後面將以 datatime 轉為 ticks 為例進行演示(事實上轉為時間戳更具有通用性),直接展示使用例程更加容易說明問題。
slidingwindowcache 使用slidingwindowcache 的絕大部分配置都在
islidingwindowconfig
介面中定義,目前具有以下重要的配置:
我們可以用形象的比喻來做進一步的解釋。startpoint
和endpoint
限定了窗體能滑動的邊界。totalcachesize
限定了窗體的大小,在某種意義上來說,該窗體是殘破不堪的,因其並未隨時擁有所有的資料。它等待著修補匠進行破窗修補(資料來源載入)。totalloadsize
限定了每個狀態生命週期中修補破窗的總大小,也就是自動請求資料量的大小。perloadsize
則為每次修補的大小,即每次向資料來源請求的資料量。loadparallellimit
可以理解為可以同時工作的修補匠的最多人數。loadtriggerfrequency
則可以理解為當狀態變更時,修補匠的出勤率。
slidingwindowcache 當前只提供少數重要的功能,全在islidingwindowcache
介面中進行定義。
// 當前點,用來標記快取狀態
tkey currentpoint
// 當前快取的key的個數
int count
// 從快取中獲取資料
task> getcachedata(tkey start, tkey end, funckeyoftdata);
// 載入源資料的委託(必須進行賦值)
func>> datasourcedelegate
// 自動載入任務狀態報告事件
event eventhandlerondataautoloaderstatuschanged;
下面以快取時間序列資料為例做一具體使用介紹
// 自定義資料模擬類
public class datamodel
// 模擬大量資料,占用記憶體
public long data = new long[1000];
// 模擬伺服器資料請求
public task> loaddatafromsource(long s, long e,
cancellationtoken cancellationtoken)
).orderby(t => t.point)
.tolist();
return (ienumerable)result;
}, cancellationtoken);
}}// 滑窗配置
var config = new slidingwindowconfig;
// 例項化快取器
var cache = new slidingwindowcache(config)
;// 獲取2019-1-1 0:1:39至2019-1-1 0:2:0之間的資料
// lamda表示式t => t.point提供快取型別datamodel中的tkey的獲取方法,用於資料過濾
var data = await cache.getcachedata(
new datetime(2019, 1, 1, 0, 1, 39).ticks,
new datetime(2019, 1, 1, 0, 2, 0).ticks,
t => t.point);
上述例子中,我們可能檢視的資料總範圍為:2019-1-1 至 2019-2-1,總共為乙個月的資料量。而終端機器允許快取的資料量最多只能有 7 個小時。為了減少伺服器壓力,每次請求兩分鐘的資料量,預先自動快取為半小時的資料量。在某一次資料獲取中(2019-1-1 0:1:39 至 2019-1-1 0:2:0),獲取 21 秒的資料,lamda 將提供自動篩選的憑據。隨著cache.currentpoint
逐漸增加(這裡模擬時間增加),可以看到記憶體的大致變化趨勢:
隨著時間增加,記憶體使用量首先會持續增加,當達到設定閾值後便自動下降。此後,便在某一視窗之間重複**。符合滑動視窗快取的預期。
後記slidingwindowcache 已經投入實際使用環境中,每次請求的量達到千級甚至萬級,總共快取的量達到百萬級別(後端使用 hbase 作為最終的儲存方案,前端以 slidingwindowcache 作為最前的快取方案)。
slidingwindowcache 專案剛剛起步,歡迎提出改進意見。
c語言 滑窗法 滑窗演算法
滑窗演算法 與跳窗演算法 類似,滑窗 moving window 演算法也是通過限制各個時間視窗內所能接 收的最大信元數對業務量進行控制。區別是,在滑窗演算法中,時間視窗不是向前跳,而 是每過乙個信元時間向前滑動一次,滑動的長度是乙個信元的時間。以下是幾種 upc演算法。信元一旦被 upc判定是違約...
滑窗問題總結
對於大多數子字串問題,我們獲得乙個字串和需要尋找乙個符合條件的子字串。乙個通常的解法是使用hashmap來關聯兩個指標,接下來是模板 思路 使用count作為匹配數 對於單個字串匹配問題,直接用乙個視窗滑動,右窗滑動並更改count值,使count值符合完全匹配條件 左窗滑動令count值不符合完全...
c語言 滑窗法 滑動視窗濾波演算法
滑動視窗協議 在tcp通訊中的一種流量控制協議。先握手確定每次發2條記錄,在網路擁堵時,接收方反饋調整接收的大小,傳送方按照這個新調整的大小來發資料。滑動 遞推 平均演算法 維護一定長佇列,每在隊尾插入乙個元素就在佇列頭部刪除乙個元素,然後對其求出均值。滑動視窗濾波演算法 方法一 前提先要獲得一組資...