精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

張開濤:京東業務數據應用級緩存示例

開發 開發工具
我們的業務數據如商品類目、店鋪、商品基本信息都可以進行適當的本地緩存,以提升性能。對于多實例的情況時不僅會使用本地緩存,還會使用分布式緩存,因此需要進行適當的API封裝以簡化緩存操作。

一、多級緩存API封裝

我們的業務數據如商品類目、店鋪、商品基本信息都可以進行適當的本地緩存,以提升性能。對于多實例的情況時不僅會使用本地緩存,還會使用分布式緩存,因此需要進行適當的API封裝以簡化緩存操作。

[[189271]]

1. 本地緩存初始化

  1. public class LocalCacheInitService extends BaseService { 
  2.    @Override 
  3.     publicvoid afterPropertiesSet() throws Exception { 
  4.         //商品類目緩存 
  5.         Cache<String, Object> categoryCache = 
  6.                CacheBuilder.newBuilder() 
  7.                         .softValues() 
  8.                         .maximumSize(1000000) 
  9.                        .expireAfterWrite(Switches.CATEGORY.getExpiresInSeconds()/ 2, TimeUnit.SECONDS) 
  10.                         .build(); 
  11.        addCache(CacheKeys.CATEGORY_KEY, categoryCache); 
  12.     } 
  13.   
  14.     privatevoid addCache(String key, Cache<??> cache) { 
  15.         localCacheService.addCache(key,cache); 
  16.     } 

本地緩存過期時間使用分布式緩存過期時間的一半,防止本地緩存數據緩存時間太長造成多實例間的數據不一致。

另外,將緩存KEY前綴與本地緩存關聯,從而匹配緩存KEY前綴就可以找到相關聯的本地緩存。

2. 寫緩存API封裝

先寫本地緩存,如果需要寫分布式緩存,則通過異步更新分布式緩存。

  1. public void set(final String key, final Object value, final intremoteCacheExpiresInSeconds) throws RuntimeException { 
  2.     if (value== null) { 
  3.         return; 
  4.     } 
  5.   
  6.     //復制值對象 
  7.     //本地緩存是引用,分布式緩存需要序列化 
  8.     //如果不復制的話,則假設之后數據改了將造成本地緩存與分布式緩存不一致 
  9.     final Object finalValue = copy(value); 
  10.     //如果配置了寫本地緩存,則根據KEY獲得相關的本地緩存,然后寫入 
  11.     if (writeLocalCache) { 
  12.        Cache localCache = getLocalCache(key); 
  13.         if(localCache != null) { 
  14.            localCache.put(key, finalValue); 
  15.         } 
  16.     } 
  17.     //如果配置了不寫分布式緩存,則直接返回 
  18.     if (!writeRemoteCache) { 
  19.         return; 
  20.     } 
  21.     //異步更新分布式緩存 
  22.     asyncTaskExecutor.execute(() -> { 
  23.         try { 
  24.             redisCache.set(key,JSONUtils.toJSON(finalValue), remoteCacheExpiresInSeconds); 
  25.         } catch(Exception e) { 
  26.             LOG.error("updateredis cache error, key : {}", key, e); 
  27.         } 
  28.     }); 

此處使用了異步更新,目的是讓用戶請求盡快返回。而因為有本地緩存,所以即使分布式緩存更新比較慢又產生了回源,也可以在本地緩存***。

3. 讀緩存API封裝

先讀本地緩存,本地緩存不***的再批量查詢分布式緩存,在查詢分布式緩存時通過分區批量查詢。

  1. private Map innerMget(List<String> keys, List<Class> types) throwsException { 
  2.    Map<String, Object> result = Maps.newHashMap(); 
  3.    List<String> missKeys = Lists.newArrayList(); 
  4.    List<Class> missTypes = Lists.newArrayList(); 
  5.     //如果配置了讀本地緩存,則先讀本地緩存 
  6.     if(readLocalCache) { 
  7.         for(int i = 0; i < keys.size(); i++) { 
  8.            String key = keys.get(i); 
  9.            Class type = types.get(i); 
  10.            Cache localCache = getLocalCache(key); 
  11.             if(localCache != null) { 
  12.                Object value = localCache.getIfPresent(key); 
  13.                result.put(key, value); 
  14.                if (value == null) { 
  15.                    missKeys.add(key); 
  16.                     missTypes.add(type); 
  17.                } 
  18.            } else { 
  19.                missKeys.add(key); 
  20.                missTypes.add(type); 
  21.            } 
  22.         } 
  23.     } 
  24.     //如果配置了不讀分布式緩存,則返回 
  25.     if(!readRemoteCache) { 
  26.         returnresult; 
  27.     } 
  28.     finalMap<String, String> missResult = Maps.newHashMap(); 
  29.   
  30.     //對KEY分區,不要一次性批量調用太大 
  31.     final List<List<String>>keysPage = Lists.partition(missKeys, 10); 
  32.    List<Future<Map<String, String>>> pageFutures = Lists.newArrayList(); 
  33.   
  34.     try { 
  35.         //批量獲取分布式緩存數據 
  36.         for(final List<String>partitionKeys : keysPage) { 
  37.            pageFutures.add(asyncTaskExecutor.submit(() -> redisCache.mget(partitionKeys))); 
  38.         } 
  39.         for(Future<Map<String,String>> future : pageFutures) { 
  40.            missResult.putAll(future.get(3000, TimeUnit.MILLISECONDS)); 
  41.         } 
  42.     } catch(Exception e) { 
  43.        pageFutures.forEach(future -> future.cancel(true)); 
  44.         throw e; 
  45.     } 
  46.     //合并result和missResult,此處實現省略 
  47.     return result; 

此處將批量讀緩存進行了分區,防止亂用批量獲取API。

二、NULL Cache

首先,定義NULL對象。

  1. private static final String NULL_STRING =new String(); 

當DB沒有數據時,寫入NULL對象到緩存

  1. //查詢DB 
  2. String value = loadDB(); 
  3. //如果DB沒有數據,則將其封裝為NULL_STRING并放入緩存 
  4. if(value == null) { 
  5.     value = NULL_STRING
  6. myCache.put(id, value); 

讀取數據時,如果發現NULL對象,則返回null,而不是回源到DB

  1. value = suitCache.getIfPresent(id); 
  2. //DB沒有數據,返回null 
  3. if(value == NULL_STRING) { 
  4.     return null; 

通過這種方式可以防止當KEY對應的數據在DB不存在時頻繁查詢DB的情況。

三、強制獲取***數據

在實際應用中,我們經常需要強制更新數據,此時就不能使用緩存數據了,可以通過配置ThreadLocal開關來決定是否強制刷新緩存(refresh方法要配合CacheLoader一起使用)。

  1. if(ForceUpdater.isForceUpdateMyInfo()) { 
  2.     myCache.refresh(skuId); 
  3. String result = myCache.get(skuId); 
  4. if(result == NULL_STRING) { 
  5.     return null; 

四、失敗統計

  1. private LoadingCache<String, AtomicInteger> failedCache = 
  2.        CacheBuilder.newBuilder() 
  3.                .softValues() 
  4.                .maximumSize(10000) 
  5.                .build(new CacheLoader<String, AtomicInteger>() { 
  6.                    @Override 
  7.                     public AtomicIntegerload(String skuId) throws Exception { 
  8.                         return new AtomicInteger(0); 
  9.                    } 
  10.                }); 

當失敗時,通過failedCache.getUnchecked(id).incrementAndGet()增加失敗次數;當成功時,使用failedCache.invalidate(id)失效緩存。通過這種方式可以控制失敗重試次數,而且又是內存敏感緩存。當內存不足時,可以清理該緩存騰出一些空間。

五、延遲報警

  1. private static LoadingCache<String, Integer> alarmCache = 
  2.        CacheBuilder.newBuilder() 
  3.                 .softValues() 
  4.                .maximumSize(10000).expireAfterAccess(1, TimeUnit.HOURS) 
  5.                .build(new CacheLoader<String, Integer>() { 
  6.                    @Override 
  7.                    public Integer load(String key) throws Exception { 
  8.                         return 0; 
  9.                    } 
  10.                }); 
  11.   
  12. //報警代碼 
  13. Integer count = 0
  14. if(redis != null) { 
  15.     StringcountStr = Objects.firstNonNull(redis.opsForValue().get(key), "0"); 
  16.     count =Integer.valueOf(countStr); 
  17. } else { 
  18.     count = alarmCache.get(key); 
  19. if(count % 5 == 0) { //5次報一次 
  20.     //報警 
  21. countcount = count + 1; 
  22. if(redis != null) { 
  23.     redis.opsForValue().set(key,String.valueOf(count), 1, TimeUnit. HOURS); 
  24. } else { 
  25.     alarmCache.put(key,count); 

如果一出問題就報警,則存在報警量非常多或者假報警,因此,可以考慮N久報警了M次,才真正報警。此時,也可以使用Cache來統計。本示例還加入了Redis分布式緩存記錄支持。

六、性能測試

筆者使用JMH 1.14進行基準性能測試,比如測試寫。

  1. @Benchmark 
  2. @Warmup(iterations = 10time = 10timeUnit =TimeUnit.SECONDS) 
  3. @Measurement(iterations = 10time = 10timeUnitTimeUnit.SECONDS) 
  4. @BenchmarkMode(Mode.Throughput) 
  5. @OutputTimeUnit(TimeUnit.SECONDS) 
  6. @Fork(1) 
  7. public void test_1_Write() { 
  8.     counterWritercounterWriter= counterWriter + 1; 
  9.     myCache.put("key"+ counterWriter, "value" + counterWriter); 

使用JMH時首先進行JVM預熱,然后進行度量,產生測試結果(本文使用吞吐量)。建議讀者按照需求進行基準性能測試來選擇適合自己的緩存框架。

【本文是51CTO專欄作者張開濤的原創文章,作者微信公眾號:開濤的博客( kaitao-1234567)】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2017-05-01 17:03:01

Java緩存分布式

2017-05-05 10:13:03

應用級緩存緩存代碼

2017-05-10 11:40:29

緩存Nginx HTTP

2017-05-18 16:07:23

回滾數據庫代碼

2017-04-18 14:49:38

應用層API代碼

2017-07-02 16:50:21

2017-06-04 16:24:27

線程線程池中斷

2017-06-16 15:16:15

2012-12-13 17:38:48

2012年度IT博客大IT博客大賽博客

2016-01-04 15:16:01

京東詳情頁實踐

2016-06-17 14:19:52

數據中心

2022-05-12 14:34:14

京東數據

2010-06-02 17:46:54

MySQL 查詢緩存

2015-07-24 12:38:00

吳靜濤

2010-10-19 08:59:40

PHP緩存技術

2016-11-10 14:38:44

京東深度學習

2024-11-01 10:37:31

2009-08-13 17:50:49

Hibernate 3

2018-01-18 19:11:36

點贊
收藏

51CTO技術棧公眾號

**精品中文字幕一区二区三区| 日本天堂在线| 欧美久久一区| 亚洲激情在线视频| 91视频免费版污| 粗大黑人巨茎大战欧美成人| bt7086福利一区国产| 国产成人小视频在线观看| 影音先锋男人看片资源| youjizz亚洲| 在线区一区二视频| 日本天堂免费a| 黄色av免费在线看| 国产69精品一区二区亚洲孕妇| 欧美在线免费视频| 欧美在线视频第一页| 日韩在线黄色| 91精品免费在线观看| 欧美日韩中文在线视频| 国产福利视频在线观看| caoporen国产精品视频| 91免费在线视频网站| 亚洲天堂一区在线观看| 91精品国产自产拍在线观看蜜 | 东京热加勒比无码少妇| 黄色网址在线免费| 欧美精彩视频一区二区三区| 成人午夜电影在线播放| 又骚又黄的视频| 99热在线精品观看| 色综合久久88色综合天天看泰| 免费人成又黄又爽又色| 精品福利网址导航| 日韩欧美综合在线| 欧美女同在线观看| 日韩在线短视频| 福利视频一区二区| 国产 日韩 欧美在线| 国产传媒在线播放| 椎名由奈av一区二区三区| 色狠狠久久av五月综合|| 污视频网站在线播放| 成人妖精视频yjsp地址| 亚洲一区二区三区视频播放| japanese国产在线观看| 久久国产精品久久久久久电车| 隔壁老王国产在线精品| 久久久久久久黄色| 欧美激情偷拍| 欧美刺激性大交免费视频| 波多野结衣喷潮| 色婷婷综合网| 日韩在线视频播放| 久久视频一区二区三区| 大色综合视频网站在线播放| 亚洲另类激情图| 精品无码人妻一区| 国产欧美日韩精品一区二区三区 | 欧美精品a∨在线观看不卡 | 欧美日韩精品一区二区三区蜜桃 | 日韩av在线一区| 男人网站在线观看| 久久97精品| 日韩精品在线免费播放| 一级片手机在线观看| 蜜桃tv一区二区三区| 亚洲欧美中文日韩在线v日本| 国产精品揄拍100视频| 国产精选一区| 日韩中文字幕国产精品| 国产老头老太做爰视频| 在线精品国产| 欧美极品xxxx| 一级黄色免费网站| 日韩成人一级大片| 成人激情视频在线观看| 国产浮力第一页| 成人久久18免费网站麻豆| 国产偷久久久精品专区| 亚洲 小说区 图片区 都市| 久久久久久一二三区| 亚洲成人蜜桃| 神马午夜伦理不卡| 欧美日韩精品在线| 老熟妇仑乱视频一区二区| 黄色成人在线视频| 日韩欧美一二三| 欧美成人三级伦在线观看| 久久99国内| 久久综合伊人77777蜜臀| 久草视频免费在线播放| 亚洲一区二区三区高清不卡| 国产欧美日韩免费| 亚洲高清视频网站| 日本一区二区三区高清不卡| 国产日韩欧美大片| 成人免费影院| 日韩一二三四区| 波多野结衣 在线| 亚洲va在线| 日韩av电影在线免费播放| 97超碰国产在线| av网站一区二区三区| 夜夜爽www精品| xxxx视频在线| 欧美麻豆精品久久久久久| 亚洲成年人在线观看| 精品国产不卡| 久久噜噜噜精品国产亚洲综合 | 欧美一区二区三区免费| 香港三日本8a三级少妇三级99| 日韩成人精品一区| 欧美亚洲国产日韩2020| av高清一区二区| 国产亚洲制服色| 日韩欧美猛交xxxxx无码| 精品视频一区二区三区四区五区| 日韩亚洲欧美成人一区| 美国黄色特级片| 久久精品一区| 国产在线精品一区二区三区| 日本不卡不卡| 色av综合在线| 国产麻豆天美果冻无码视频| 亚洲高清资源在线观看| 国产精品久久久久久久久| 日韩一卡二卡在线| 亚洲国产综合人成综合网站| www.成年人| 成人精品影视| 国产精品福利网站| 欧美精品a∨在线观看不卡| 亚洲成人av一区二区| 加勒比av中文字幕| 色爱综合网欧美| 国产精品一区二区久久国产| 日本不卡视频一区二区| 黄色成人在线播放| 中国av免费看| 国产精品久久久久久久久久妞妞 | 国产欧美日韩影院| 2019中文字幕在线| 天堂在线中文资源| 午夜影视日本亚洲欧洲精品| 无码人妻一区二区三区免费n鬼沢| 欧美成人milf| 国产日韩av高清| 日韩在线资源| 777精品伊人久久久久大香线蕉| 久久久免费看片| 久久激情综合网| 制服国产精品| 欧美日本三级| 久久91亚洲精品中文字幕奶水| 国产精品亚洲lv粉色| 国产精品国产三级国产a| 看看黄色一级片| 在线精品国产| 风间由美一区二区三区| 国产白丝在线观看| 亚洲黄页网在线观看| 日韩av大片在线观看| 久久免费看少妇高潮| 久久精品网站视频| 成人羞羞网站| 91最新国产视频| 国产盗摄在线视频网站| 亚洲精品福利免费在线观看| 亚洲第一在线播放| 国产午夜精品福利| 中文字幕第一页在线视频| 影视亚洲一区二区三区| 国产一区二区精品免费| 在线天堂新版最新版在线8| 亚洲男人天堂古典| 一级黄色短视频| 一区二区三区.www| 给我看免费高清在线观看| 日韩电影在线观看电影| 400部精品国偷自产在线观看 | 日韩一级免费观看| 日韩精品视频播放| 国产日韩欧美精品综合| 久久精品亚洲天堂| 亚洲人成久久| 亚洲国产日韩美| 欧美高清一级片| 日本成人免费在线| 中文字幕中文字幕在线十八区| 亚洲福利影片在线| 在线观看国产精品视频| 亚洲18色成人| 中日韩一级黄色片| 99久久精品免费观看| 向日葵污视频在线观看| 国产一区二区三区四区老人| 日本一区二区三区在线视频| 色妞ww精品视频7777| 国产精品第七影院| 男人添女人下部高潮视频在线观看| 日韩精品www| 国产精品久久免费| 欧美性xxxx极品高清hd直播| 国产极品国产极品| 久久久国产精品午夜一区ai换脸| 欧美体内she精高潮| 日韩精品一级二级| 日韩中文字幕在线免费| 久久一区91| 欧美乱偷一区二区三区在线| 色悠久久久久综合先锋影音下载| 国产精品免费在线免费| 日韩欧美一中文字暮专区| 久久国产精品网站| av电影在线播放高清免费观看| 亚洲国产成人精品女人久久久| 国产在成人精品线拍偷自揄拍| 欧美日韩国产限制| 国产一级在线视频| 日韩理论片中文av| 国产视频123区| 国产色爱av资源综合区| 国产精品福利导航| 国产成人在线电影| 一二三级黄色片| 蜜臀精品久久久久久蜜臀| 欧美日韩亚洲一| 亚洲国产国产亚洲一二三| 国产欧美自拍视频| 久久精品影视| 亚洲图片都市激情| japanese国产精品| 日韩欧美99| 国产精品密蕾丝视频下载 | 免费观看毛片网站| 日韩亚洲欧美高清| 国产成人a人亚洲精品无码| 欧美日韩1234| 亚洲天堂777| 欧美视频在线观看一区| 天堂网视频在线| 欧美日韩中文字幕日韩欧美| 日本亚洲色大成网站www久久| 亚洲综合在线免费观看| 欧美日韩精品亚洲精品| 亚洲精品免费看| 久久久久久久久久网站| 亚洲激情第一区| 免费中文字幕在线观看| 一区二区在线观看av| 久久久.www| 亚洲大片在线观看| 日韩av黄色片| 狠狠躁18三区二区一区| 最新中文字幕一区| 一本色道综合亚洲| 亚洲av综合一区| 欧美色图片你懂的| 91在线视频国产| 日韩手机在线导航| 天堂在线观看视频| 亚洲精品视频在线播放| 浮生影视网在线观看免费| 一区二区日韩精品| 91最新在线视频| 久久全球大尺度高清视频| 亚洲精品mv| 国产精品入口福利| 免费观看亚洲视频大全| 国产高清精品一区二区三区| 欧美一区自拍| 色涩成人影视在线播放| 色狮一区二区三区四区视频| 91网站在线观看免费| 日韩一级大片| 精品久久久久久久无码| 久久精品国产77777蜜臀| 女王人厕视频2ⅴk| 99久久精品国产导航| 久久久精品成人| 樱桃国产成人精品视频| 国产一级做a爱片久久毛片a| 日本韩国一区二区三区| 99精品视频免费看| 日韩久久免费电影| 一区二区三区视频在线观看视频| 欧美成人精品在线播放| 手机在线观看av| 国产日韩欧美视频| 加勒比视频一区| 亚洲成人网上| 亚洲每日在线| 国产美女18xxxx免费视频| 国产大陆精品国产| 免费看91的网站| 亚洲国产精品久久一线不卡| 337p粉嫩色噜噜噜大肥臀| 欧美一区二区日韩| jzzjzzjzz亚洲成熟少妇| 久久99青青精品免费观看| 色香欲www7777综合网| 丁香五月网久久综合| 色先锋久久影院av| 日本一二三区视频在线| 日韩在线观看一区二区| 美女日批在线观看| 中文字幕免费一区| 青青草免费观看视频| 欧美一区日本一区韩国一区| 美丽的姑娘在线观看免费动漫| 美女av一区二区三区| 成人国产精选| 欧美成人一区二区在线| 欧美精品自拍| mm131亚洲精品| 26uuuu精品一区二区| 免费又黄又爽又色的视频| 欧美日韩三级一区| 国产中文在线观看| 91精品国产高清自在线看超| 日韩精品亚洲专区在线观看| 亚洲精品久久区二区三区蜜桃臀| 亚洲伦理精品| 最新国产精品自拍| 综合婷婷亚洲小说| 伊人色综合久久久| 国产一区二区三区18| 麻豆视频在线看| 国产精品一区在线播放| 影音先锋日韩在线| 黄色片子免费看| 亚洲人精品午夜| 青娱乐在线免费视频| 亚洲精品资源在线| 三上悠亚国产精品一区二区三区| 精品国产一区二区三| 亚洲黄色影院| 国内精品免费视频| 亚洲一二三区在线观看| 午夜精品久久久久久久91蜜桃| 久久久av网站| 成人综合日日夜夜| 永久免费网站视频在线观看| 国产乱子伦一区二区三区国色天香| 我要看黄色一级片| 欧美一区二区三区成人| 天堂av资源在线观看| 亚洲在线www| 亚洲午夜视频| 国产chinese中国hdxxxx| 亚洲高清免费一级二级三级| 成人午夜精品福利免费| 久久久视频免费观看| 国产精品极品| 北条麻妃69av| 欧美激情综合五月色丁香小说| 亚洲黄网在线观看| 在线观看精品国产视频| 婷婷久久免费视频| 黄色网在线视频| www.色综合.com| 手机看片久久久| 在线观看国产精品淫| 香蕉久久一区| 成人毛片100部免费看| 成人福利在线看| 一级黄色大片视频| 视频在线观看99| 日韩一区二区三区高清在线观看| 国产精品免费看久久久无码| 成人精品免费看| 黄色片中文字幕| 色婷婷综合久久久久中文字幕1| 亚洲精品一区av| 亚洲 欧美 综合 另类 中字| 91视频91自| 中文字幕第315页| 欧美裸身视频免费观看| 日日天天久久| 亚洲天堂网2018| 亚洲国产aⅴ天堂久久| 噜噜噜噜噜在线视频| 成人欧美一区二区三区在线| 伊人影院久久| 夜夜春很很躁夜夜躁| 日韩精品一区二区在线| 中文字幕乱码中文乱码51精品| 亚洲精品视频一二三| 国产ts人妖一区二区| 男人的天堂av网站| 免费91在线视频| 免费av一区| 九色91porny| 日韩欧美精品中文字幕| 国产三区视频在线观看| 久久久久久久久久久久久久久久av| 久久精品国产99| 国产免费观看av| 久久av中文字幕| av永久不卡|