c 滑窗快取

2022-07-04 11:33:13 字數 3152 閱讀 8511

前言

在大資料時代,軟體系統需要具備處理海量資料的能力,同時也更加依賴於系統強大的儲存能力與資料響應能力。各種大資料的工具如雨後春筍般孕育而生,這對於系統來說是極大的利好。但在後端採用分布式、雲儲存和虛擬化等技術大刀闊斧地解決大部分儲存問題後,仍然不足以滿足所有的業務需求。對於以使用者為終點的軟體系統來說,無論後台多麼強大都難以避免有一部分資料流向終端,面向使用者。為了應對這最後一公里的通勤問題,我們得在終端快取部分資料來提高系統的響應效率。另外一方面,受限於使用者終端的機器效能,快取大量的資料反而會降低系統響應速度,甚至讓系統崩潰。為此,我們需要乙個根據系統當前狀態動態調整最急需的資料的快取器,滑窗快取是乙個很不錯的選擇。最終,我們找到了slidingwindowcache,乙個基於 .net standard 實現的滑窗快取。

slidingwindowcache 簡介

slidingwindowcache 基於鍵值對快取,可以快取以特定序列序列組織的資料,比如時間序列資料。其本身帶有預先快取的能力,當系統狀態滿足預設條件後將自動快取資料。每次自動快取的量可自行配置。當快取超出視窗後即被視為無用資料,會被自動釋放。同樣的,快取視窗大小可進行配置。

作為 key/value 快取,該快取的 value 可以是任意型別的資料。但為了滿足有序組織,目前的 key 只支援 int、long、float 和 double 四種型別。對於時間序列資料來說,可以將時間轉化為 long 作為 key 使用。後面將以 datatime 轉為 ticks 為例進行演示(事實上轉為時間戳更具有通用性),直接展示使用例程更加容易說明問題。

slidingwindowcache 使用

slidingwindowcache 的絕大部分配置都在islidingwindowconfig介面中定義,目前具有以下重要的配置:

我們可以用形象的比喻來做進一步的解釋。startpointendpoint限定了窗體能滑動的邊界。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條記錄,在網路擁堵時,接收方反饋調整接收的大小,傳送方按照這個新調整的大小來發資料。滑動 遞推 平均演算法 維護一定長佇列,每在隊尾插入乙個元素就在佇列頭部刪除乙個元素,然後對其求出均值。滑動視窗濾波演算法 方法一 前提先要獲得一組資...