命中率:命中數/(命中數+沒有命中數)java
1、影響因素算法
2、緩存分類和應用場景spring
3、經常使用組件數據庫
Guava Cacheapache
public class GuavaCacheExample1 { public static void main(String[] args) { LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() .maximumSize(10) // 最多存放10個數據 .expireAfterWrite(10, TimeUnit.SECONDS) // 緩存10秒 .recordStats() // 開啓記錄狀態數據功能 .build(new CacheLoader<String, Integer>() { @Override public Integer load(String key) throws Exception { return -1; } }); log.info("{}", cache.getIfPresent("key1")); // null cache.put("key1", 1); log.info("{}", cache.getIfPresent("key1")); // 1 cache.invalidate("key1"); log.info("{}", cache.getIfPresent("key1")); // null try { log.info("{}", cache.get("key2")); // -1 cache.put("key2", 2); log.info("{}", cache.get("key2")); // 2 log.info("{}", cache.size()); // 1 for (int i = 3; i < 13; i++) { cache.put("key" + i, i); } log.info("{}", cache.size()); // 10 log.info("{}", cache.getIfPresent("key2")); // null Thread.sleep(11000); log.info("{}", cache.get("key5")); // -1 log.info("{},{}", cache.stats().hitCount(), cache.stats().missCount()); log.info("{},{}", cache.stats().hitRate(), cache.stats().missRate()); } catch (Exception e) { log.error("cache exception", e); } } }
Memcache編程
Redis緩存
最大元素(空間):緩存大小 服務器
清空策略:FIFO、LFO、LRU、過時時間,隨機等網絡
FIFO: 先進先出策略mybatis
LFO:最少使用策略
LRU:最近最少使用策略
緩存一致性
形成這種問題的場景:
緩存併發問題
同時大量請求訪問緩存未命中,而後大量請求同時訪問數據庫形成數據庫壓力增大,解決辦法是加鎖,避免同時執行
緩存穿透問題
某個查詢結果爲空,致使緩存爲存儲,所以大量請求會去查詢數據庫,形成對數據庫的壓力大增
解決辦法:
一、緩存空對象,緩存時間要短,適合命中率不高,可是須要頻繁修改的數據
二、進行單獨過濾處理,對全部可能結果爲空的請求進行統一存放,而且對請求進行攔截,避免請求到數據庫對數據庫形成大量壓力
緩存雪崩現象
致使緣由:緩存併發,緩存穿透等
解決辦法:過時時間設置隨機數,避免同時失效10
特性
爲何須要消息隊列
消息隊列的好處
舉例
拆分原則
須要考慮的問題
通訊工具
經常使用限流算法
計數器法
滑動窗口法
漏桶算法
令牌桶算法(Guava RateLimit)
@Slf4j public class RateLimiterExample1 { private static RateLimiter rateLimiter = RateLimiter.create(5); public static void main(String[] args) throws Exception { for (int index = 0; index < 100; index++) { if (rateLimiter.tryAcquire(190, TimeUnit.MILLISECONDS)) { handle(index); } } } private static void handle(int i) { log.info("{}", i); } }
@Slf4j public class RateLimiterExample2 { private static RateLimiter rateLimiter = RateLimiter.create(5); public static void main(String[] args) throws Exception { for (int index = 0; index < 100; index++) { rateLimiter.acquire(); handle(index); } } private static void handle(int i) { log.info("{}", i); } }
Guava RateLimiter是單機版的限流
若是是分佈式能夠採用 分佈式限流:
能夠採用Redis做爲中間組件,使用Redis的incrby key num 方法
服務降級
服務熔斷
總結
共性:目的、最終表現、粒度、自治
區別:
服務降級要考慮的問題
Hystrix
數據庫瓶頸
數據庫切庫
自定義註解完成數據庫切庫-代碼實現
數據庫支持多個數據源-代碼實現
數據庫分表