本方案實現了客戶端對服務端緩存數據任意查找,和使用本地緩存效果一樣
先看看常用緩存的形式
本地緩存
緩存在當前應用程序內存中,通常以靜態變量存儲,它可以是任何對象,一個值,一個集合都行
因為是在當前程序中,能很好得到控制,創建,訪問都很好辦,特別是集合,通過集合查詢語法或自已寫的算法很好過濾,取出想要的結果
然而這些數據需要多程序共用,那么需要把它集中放在一個地方,供多應用程序調用
分布式緩存
分布式緩存就是為了解決二級緩存不能解決的問題,把數據放在獨立的服務器上,提供訪問接口,供不同客戶端程序調用
一般分為兩部份,服務端,客戶端接口,通過統一的客戶端接口,從服務端獲取數據
因為達成了統一訪問,沒有業務關聯,因此,緩存獲取方式為KEY值的形式,通過KEY值讀寫數據,很像一個字典,KEY為唯一,值為object
在獲取到這個object后,轉換為指定的本地業務對象
然而帶來的問題,所有值都為object,在獲取到后才能轉換為本地業務對象,如果存入的是一個對象集合,要獲取其中某個條件的一項
那得每次把整個集合object獲取到本地再換為集合再進行查找,這樣意味着多了不必要的數據傳輸,因此一般不會這么做
問題來了,從分布式緩存服務器中,沒法按業務要求對這樣的數據進行查詢,通常這樣的需要,替代做法是搜索引擎形式,隨之帶來的一系列問題...
或還有更簡單的方法,對指定業務數據查詢寫個查詢接口,這樣也能滿足需求,但是每種查詢需求都需要寫個接口,很是麻煩
能不能直接把查詢條件傳給緩存服務端,讓服務端用條件過濾數據?
理論是可以的,只需要服務端能識別解析就能,要達成這樣的條件,服務端必須能識別業務對象
這樣意味着,服務端的緩存對象是由業務創建的,需要對服務端進行開發
要實現這樣的系統,關鍵點是在查詢條件傳輸,在本地對集合查詢,一般使用Linq擴展方法,使用lambda生成篩選委托
如果能把lambda表達式傳過去,服務端再解析成篩選委托就能實現目的了
實現命令解析
由於lambda表達式很復雜,不能直接序列化,是沒法直接傳輸的,需要解析成能傳輸的對象,那么,要做的過程表示為
客戶端:lambda查詢=>解析lambda=>轉換為命令對象=>序列化發送命令
服務端:接收命令反序列化=>轉換為lambda=>創建查詢
lambda解析參考 解析lambda實現完整查詢
lambda動態創建參考 http://www.cnblogs.com/libbybyron/articles/4134494.html
服務端按業務數據緩存
服務端使用同樣的業務模型創建二級緩存,在接收到命令轉換為lambda查詢后,很輕松就能實現內存查詢了
於是整體結構設計為
數據傳輸層
為了增加查詢效率,傳輸層用長TCP連接,使用連接池的概念,啟動后保持指定的連接數,有請求時找其中一個連接與服務器通訊,如果都滿了,再創建新的連接
同時自動釋放長時間不用的連接,通過這樣處理,比HTTP接口,SERVICE/WCF連接效率高很多
分布式方案
因為緩存是服務器主動創建的,做成分布式,需要客戶端知道服務端有哪些緩存,因此需要做一個緩存類型和服務器映射
查詢緩存時,根據映射去指定的服務器查詢
通過這樣設計的緩存系統,大大增加了開發效率和使用便捷性,並與業務銜接緊密
整體涉及到的東西比較多也比較復雜,就不在這里寫代碼實現了,需要框架支持,這里只放上開發完成的測試DEMO
測試DEMO下載:點擊下載
調用示例:http://119.10.29.11:8080/page/Cache2.aspx