前言
但是高頻數據流處理系統中(zhōng),Redis 的壓力也會很大,同時 I/O 開銷才是耗時的主要關明原因,這時候為了降低 Redis 讀寫壓力我們可(kě)以用到本地緩人山存,Guava 為我們提供了優秀的本地緩存 API,包含了過期策略等等,編碼難度低,個(gè)話坐人非常推薦。
設計示例
| Redis 懶加載緩存
數據在新增到 MySQL 不進行緩存,在精确靜信查找進行緩存,做到查詢即緩存,不查詢不緩存。
// 僞代碼示例 Xx代表你(nǐ)男窗的的業(yè)務對象 如(rú)User外但 Goods等等 public class&好習nbsp;XxLazyCache { &nbs下音p; @Autowir謝票ed private&n這樹bsp;RedisTemplate redisTemplat北校e;  美熱;@Autowired &n能可bsp; private X暗黃xService xxService;//&nb音腦sp;你(nǐ)的業(yè)務service &雨校nbsp; /** &n地業bsp; * 訊吧查詢 通(tōng)過查詢緩存外南是否存在驅動(dòng)緩存加載 建議在前置業(yè)務保證id風北對應數據是絕對存在于數據庫中(zhōng)的 &睡了nbsp; */ &nbs和紙p; public Xx&nb制草sp;getXx(int id) { &通服nbsp; &n音還bsp; // 討雨1.查詢緩存裡面有沒有數據 對月 子信 Xx xxCache&n鐵飛bsp;= getXxFromCach市為e(id); &醫見nbsp; if(xxCache 畫見;!= null) { 劇少 &nbs作這p; &nbs聽來p; return校制 xxCache;// 衛語男北句使代碼更有利于閱讀 &nbs舞兵p; } &nb麗她sp; &金女nbsp; // 章技;2.查詢數據庫獲取數據 我們假定到業(yè)務這一步,傳冷要過來的id都在數據庫中(zhōng)有對應數街去據 &如見nbsp; Xx&nb相房sp;xx = xx作河Service.getXxById(id); &n動遠bsp; &報電nbsp;// 3.設置緩存、這一步相當媽道于Redis緩存懶加載,下(xià)次再查詢此id,則會走緩存 &n好也bsp;  畫白; setXxFromCache(xx);鄉城 &n嗎黃bsp; return&線媽nbsp;xx;  也遠; }家中 &nb東林sp;} /短高** 拍員 * 對xx數據進行修改或者删除操作 操作熱制數據庫成功後 删除緩存 &n請答bsp; *&n湖火bsp;删除請求 - 删除數據庫數據 工愛;删除緩存 *姐內 修改請求 -&nb影靜sp;更新數據庫數據 删除緩存 下(xi訊多à)次在查詢時候就會從數據庫拉取新的數據到緩存中(zhōng) &nb白電sp; */ &亮得nbsp; public vo高弟id deleteXxFromCac麗還he(long id) { 麗銀 &nb小個sp;String key = &書區quot;Xx:" + 科到xx.getId(); &n文鄉bsp;  慢湖; redi飛跳sTemplate.delete(key); &n鐘器bsp; }森電 計窗 private void setXxFr木現omCache(Xx xx) 志月;{ 生村 String k錯飛ey = "Xx:&quo少時t; + xx.getId(); 放他 &nb民微sp;redisTemplate.opsFor鐘好Value().set(key, xx); &n離慢bsp; } &n男服bsp; private Xx g可街etXxFromCache(int id)&nb裡影sp;{ &nbs高線p; //很雪 通(tōng)過緩存前綴拼裝唯一主鍵作為緩存Key 討但;如(rú)Xxx信息 就是Xxx:id &nb東金sp; 相離 String&術信nbsp;key = "Xx:&qu間能ot; + id; &nb工年sp; &nbs件的p; return re城她disTemplate.opsForValue大分().get(key);  鐵資; } } //&輛個nbsp;業(yè)務類 public&n是很bsp;class XxServie {  爸湖; @Autowired &看鐵nbsp; private事外 XxLazyCache xxLazy對但Cache; /線自/ 查詢數據庫 &nb理照sp;public Xx ge計市tXxById(long id) { &n司場bsp; &n房錯bsp; // 省略實現 &你工nbsp; &nbs麗睡p; return xx; &nbs看歌p; }  件紙; public void&n到了bsp;updateXx(Xx 家站;xx) { &n來在bsp; &nbs是吧p;// 更新MySQL數據 省略 飛件 &nb我間sp; // 删除緩存 &知高nbsp; &nbs家道p; xxLazyCache.del遠玩eteXxFromCache(xx.getId()); &nb大樂sp; } 做大 &n火哥bsp;public void deleteXx(麗舊long id) { &nbs船習p; //&n嗎影bsp;删除MySQL數據 省略 &間海nbsp; &nbs生什p;// 删除緩存 &北科nbsp; &現下nbsp; xxLazyCache.dele媽樂teXxFromCache(xx.getId()); &nb水會sp; } } // 實體歌書類 @Data public c黃銀lass Xx {  老技; // 業(yè)道影務主鍵 pri嗎一vate Long id;  會熱; // ...省略 }
優點如(rú)下(xià):
保證最小的緩存量滿足精确查詢業(yè)務,避免冷(lěng)現友數據占用寶貴的内存空間 對增删改查業(yè)務入侵小、删除即同步 可(kě)插拔,對于老系統升級,曆史數據無需在啟動(dòng)時初始化呢裡緩存
缺點如(rú)下(xià):
數據量需可(kě)控,在無限增長業(yè章來)務場景不适用 在微服務場景不利于全局緩存應用
總結:
空間最小化 滿足精确查詢場景 總數據量可(kě)控推薦使用 微服務場景不适用
| Redis 結合本地緩存
微服務場景下(xià),多個(gè)微服務使用一個(gè)大緩存,流數火在據業(yè)務下(xià),高頻讀取緩存對拿家 Redis 壓力很大,我們使用本地緩存結合 Redis 緩存使用,降低 Redis 壓力信跳,同時本地緩存沒有連接開銷,性能更優。
業(yè)務場景:在流處數處理過程中(zhōng),微服務對多個(gè)設備上傳的數司歌據進行處理,每個(gè)設備有一個(gè) code,流數據的頻率高,在消息靜討隊列發送過程中(zhōng)使用分區發送,我們需要為設備 c街爸ode 生成對應的自增号,用自增号對 kafka 中(zhōng) to秒紙pic 分區數進行取模。
這樣如(rú)果有 10000 台設備,自增号就是 0愛吧~9999,在取模後就進行分區發送就可(kě)以做到每個地醫(gè)分區均勻分布。
這個(gè)自增号我們使用 redis 的自增數生成,生成後鐘車放到 redis 的 hash 結構進行緩存,每次來一個(gè)設備,員服我們就去這個(gè) hash 緩存中(zhōng)取,沒雪新有取到就使用自增數生成一個(gè),然後放到 redis 的 hash 緩工笑存中(zhōng)。
這時候每個(gè)設備的自增數一經生成是不站農會再發生改變的,我們就想到使用本地緩存進行優化,避免高頻的調用 redis 制爸去獲取,降低 redis 壓力。
/** * 此緩存演遠微示如(rú)何結合redis自增數 hash 本地緩存使用劇南進行設備自增數的生成、緩存、本地緩存 * 本地村東緩存使用Guava Cache */public日土 class DeviceIncCa海近che {  愛短; /** &n分術bsp;* 本地緩存 &n銀志bsp; */ &n技用bsp; private&nb媽照sp;Cache
優點如(rú)下(xià):
redis 保證數據可(kě)持久,本地緩存保證超高的讀取性能,內南微服務共用 redis 大緩存的場景能有效降低 redis 壓力 guava 作為本地緩存,提供了豐富的 api,過期策略,最大容量分年,保證服務内存可(kě)控,冷(lěng)數據不會長服我期占據内存空間 服務重啟導緻的本地緩存清空不會影響業(yè)什錯務進行 微服務及分布式場景使用,分布式情況下(xià)每個(錢月gè)服務實例隻會緩存自己接入的那一部分設備的自增号,本地内存空間最優 在示例業(yè)務中(zhōng),自增數滿足要家了分布區發送的均勻分布需求,也可(kě)以滿足統計設備接入數目的業(yè)務林筆場景,一舉兩得
缺點如(rú)下(xià):
增加編碼複雜度,不直接 隻适用于緩存内容隻增不改的場景
總結:
本地緩存空間可(kě)控,過期策略優 适用于微服務及分布式場景 緩存内容不能發生改變 性能優
後記
redis 提供了豐富的數據類型及api,非常适合業(yè)務系統開發,統計計數(increment,dec機些rement),标記位(bitmap),松散數據(ha美作sh),先進先出、隊列式讀取(list)。訊吧
guava 緩存作為本地緩存,能夠高效的讀取的同時,提供了大量 a日很pi 方便我們控制本地緩存的數據量及冷(lěng)數據淘汰。
我們充分的學習這些特性能夠幫助我們在業(yè)務開發中(zhōng)更加輕女一松靈活,在空間與時間上找到一個(gè)平衡點。