国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring Data Redis 讓 NoSQL 快如閃電 (1)

JerryC / 2925人閱讀

摘要:以遠(yuǎn)程緩存服務(wù)器見長,對易揮發(fā)數(shù)據(jù)來說是極快型數(shù)據(jù)庫。即使成功寫入數(shù)據(jù)庫,最后也可能會因為網(wǎng)絡(luò)故障而使得緩存服務(wù)器以失敗告終。

【編者按】本文作者為 Xinyu Liu,詳細(xì)介紹了 Redis 的特性,并輔之以豐富的用例。在本文的第一部分,將重點(diǎn)概述 Redis 的方方面面。文章系國內(nèi) ITOM 管理平臺 OneAPM 編譯呈現(xiàn)。

建立在 Java 企業(yè)版之上的多層體系結(jié)構(gòu)是強(qiáng)大的服務(wù)器端編程解決方案。作為一名從業(yè)多年的 Java 企業(yè)版開發(fā)人員,我最滿意的就是三層企業(yè)開發(fā)法:最下方是 JPA/Hibernate 持久層,中間是 Spring 或 EJB 應(yīng)用層,最上方則是 web 層。對于較為復(fù)雜的用例,我用 BPM(業(yè)務(wù)流程管理)、一個類似于 Drools 的規(guī)則引擎和一個集成框架(例如 Camel)集成了一個工作流驅(qū)動的解決方案。

但是,筆者最近接到一個任務(wù),要設(shè)計一個擁有亞秒級響應(yīng)延遲并能支持成千上萬名并發(fā)用戶的系統(tǒng)。我立即發(fā)現(xiàn)了自己常用的 Java 企業(yè)版棧區(qū)的局限性。基于關(guān)系數(shù)據(jù)庫管理系統(tǒng)的傳統(tǒng)型 web 應(yīng)用程序,包括在 Hibernate/JPA 之上構(gòu)建的應(yīng)用程序,都有二階延遲,擴(kuò)展效果不佳。傳統(tǒng)的 Java 企業(yè)版持久性體系結(jié)構(gòu)無法滿足我當(dāng)時設(shè)計的系統(tǒng)的性能和處理能力要求。然后我轉(zhuǎn)而嘗試 NoSQL,最后發(fā)現(xiàn)了 Redis。

作為一種內(nèi)存鍵值數(shù)據(jù)庫,Redis 打破了數(shù)據(jù)庫的傳統(tǒng)定義(將數(shù)據(jù)保存在硬盤上)。反之,使用 Redis 時可結(jié)合持久性的 NoSQL 數(shù)據(jù)庫,比如 MongoDB、HBase、Cassandra 或 DynamoDB。Redis 以遠(yuǎn)程緩存服務(wù)器見長,對易揮發(fā)數(shù)據(jù)來說是極快型數(shù)據(jù)庫。

在本文中,筆者會介紹一些有關(guān) Redis 的簡單用例和進(jìn)階用例以及性能調(diào)優(yōu)情況。當(dāng)然,我還會做個簡單概述,但我相信各位基本都了解 NoSQL 及其各種解決方案。

Spring Data Redis

Redis 幾乎擁有針對所有編程語言的各種客戶端庫,其中就包括 Java。Jedis 可能是最受歡迎的 Java 客戶端庫了。本文中的示例都基于 Spring Data Redis,我把它作為一個較高層次的包裝程序 API。Spring Data Redis 不僅配置方便,而且擁有各種友好的 API 和實用插件。

Redis 概述

和大多數(shù) NoSQL 數(shù)據(jù)庫一樣,Redis 舍棄了表格、行列的關(guān)系概念。而事實上,Redis 是一種鍵值數(shù)據(jù)庫,利用獨(dú)特的字符串鍵值來存儲和檢索每條記錄。Redis 支持把以下內(nèi)置數(shù)據(jù)結(jié)構(gòu)作為所有記錄的值:

STRING 保有單個字符串值。

LISTSETHASH 從語義上來說與 Java 中的相同數(shù)據(jù)結(jié)構(gòu)相一致。

ZSET 是由浮點(diǎn)分?jǐn)?shù)安排的字符串列表,類似于 Java 中的 PriorityQueue

不同于關(guān)系數(shù)據(jù)庫管理系統(tǒng)中的表,Redis 數(shù)據(jù)結(jié)構(gòu)是即時實例化的。如果用戶查詢的內(nèi)容不存在于 Redis 中,系統(tǒng)只會返回空值。雖然 Redis 不允許嵌套結(jié)構(gòu),但用戶可以執(zhí)行自定義的 Java 或 JSON 串行器/解串器,從而將 POJO 映射到字符串。通過這種方式,就可以把任意 Java bean 保存為 STRING,或者將其放置在 LISTSET 中,等等。

性能和可擴(kuò)展性

對于 Redis,人們注意到的第一個特點(diǎn)可能就是它的速度極快。根據(jù)記錄的大小和連接的數(shù)量,性能基準(zhǔn)會有所不同,但延遲通常為單數(shù)位毫秒。在大多數(shù)用例中,Redis 每秒最多可支持 50000 次請求。如果用戶使用較高端的硬件,處理能力更可高達(dá)每秒 700000 次請求(但這一數(shù)值可能會被網(wǎng)卡帶寬扼制)。

作為一種內(nèi)存數(shù)據(jù)庫,Redis 的存儲容量有限; AWS EC2 中的最大實例為 r3.8xlarge,內(nèi)存 244 GB。由于數(shù)據(jù)結(jié)構(gòu)的索引和性能都經(jīng)過優(yōu)化,Redis 消耗的內(nèi)存比所存儲的數(shù)據(jù)量大得多。切分 Redis 有助于克服這一局限性。要把內(nèi)存數(shù)據(jù)備份到硬盤上,可以在預(yù)定作業(yè)中進(jìn)行時間點(diǎn)轉(zhuǎn)儲,也可以根據(jù)需要運(yùn)行 dump 命令。

用 Spring 進(jìn)行遠(yuǎn)程數(shù)據(jù)緩存

要想提升應(yīng)用程序服務(wù)器的性能,數(shù)據(jù)緩存可能是性價比最高的辦法了。利用 Spring 的緩存抽象注釋(@Cacheable@CachePut@CacheEvict@Caching@CacheConfig)可以毫不費(fèi)力地啟用數(shù)據(jù)緩存。在 Spring 配置下,用戶還可以把 Ehcache、Memcached 或 Redis 當(dāng)作基本緩存服務(wù)器。

Encache 通常被配置成本地緩存層,具有嵌套結(jié)構(gòu),在應(yīng)用的 JVM 上運(yùn)行。 Memcached 和 Redis 都能作為獨(dú)立的緩存服務(wù)器運(yùn)行。要想把 Redis 緩存集成到基于 Spring 的應(yīng)用中,需要使用 Spring Data Redis 的 RedisTemplate 和 RedisCacheManager。

在 Redis 中訪問已緩存的對象,耗時通常不到數(shù)毫秒,和關(guān)系數(shù)據(jù)庫查詢相比,這大幅提升了應(yīng)用程序的性能。

延遲和收益

亞馬遜公司在很大程度上依賴緩存服務(wù)器來最大程度地減少其零售網(wǎng)站的延遲,該公司甚至曾經(jīng)發(fā)布過一份案例分析,其中記錄了延遲和收益之間的關(guān)系。

本地緩存與遠(yuǎn)程緩存

在沒有網(wǎng)絡(luò)開銷的系統(tǒng)中,本地緩存快于遠(yuǎn)程緩存。本地緩存的缺點(diǎn)是,同一個對象的多個拷貝在服務(wù)器集群中的各個不同節(jié)點(diǎn)之中會同步得更快。正因如此,本地緩存僅適用于靜態(tài)數(shù)據(jù),例如可容忍短期滯后和不一致現(xiàn)象的系統(tǒng)級設(shè)置。如果為易揮發(fā)的業(yè)務(wù)數(shù)據(jù)(例如用戶數(shù)據(jù)和交易數(shù)據(jù))使用本地緩存,很有可能會以運(yùn)行應(yīng)用程序服務(wù)器的單個實例而告終。

遠(yuǎn)程緩存服務(wù)器就沒有這一局限性。在同一個鍵的情況下,可保證緩存服務(wù)器上的對象只有一個拷貝。只要用戶讓緩存中的對象及其數(shù)據(jù)庫值彼此保持同步,就無需處理過期數(shù)據(jù)。

列表 1 給出了一個 Spring 數(shù)據(jù)緩存的示例。

列表 1:在基于 Spring 的應(yīng)用中啟用緩存

@Cacheable(value="User_CACHE_REPOSITORY", key = "#id")
   public User get(Long id) {  
      return em.find(User.class, id);
}
@Caching(put = {@CachePut(value="USER_CACHE_REPOSITORY", key = "#user.getId()")})  
public User update(User user) {
    em.merge(user);    
    return user;  
}
@Caching(evict = {@CacheEvict(value="USER_CACHE_REPOSITORY", key = "#user.getId()")})  public void delete(User user) {
    em.remove(user);
}
@Caching(evict = {@CacheEvict(value="USER_CACHE_REPOSITORY", key = "#user.getId()")})  public void evictCache(User user) {
}

這里的讀取操作被 Spring 的 @Cacheable 注釋圍繞,作為 AOP 幕僚而執(zhí)行。Spring 中的存活時間設(shè)置也規(guī)定了這些對象可在緩存中停留的時間。調(diào)用 get() 方法后,Spring 就會試著先從遠(yuǎn)程緩存讀取和返回對象。如果未找到對象,Spring 會執(zhí)行方法主體,然后將數(shù)據(jù)庫結(jié)果放在遠(yuǎn)程緩存中,之后再返回結(jié)果。

但如果另一個過程(例如另一個服務(wù)器節(jié)點(diǎn))甚至同一個 JVM 中的另一個線程在數(shù)據(jù)庫中更新了同一個對象,又會怎樣呢?如果只運(yùn)用 @Cacheable 注釋,你可能會從遠(yuǎn)程緩存服務(wù)器收到過期拷貝。

為了防止發(fā)生這種情況,可以給所有數(shù)據(jù)庫更新操作添加一個 @CachePut 注釋。每次調(diào)用這些方法時,返回值就會替換掉遠(yuǎn)程緩存中原先的對象。在數(shù)據(jù)庫讀取和寫入上都更新緩存,可以讓緩存服務(wù)器和后臺數(shù)據(jù)之間的記錄保持同步。

容錯

聽起來簡直完美,對吧?事實當(dāng)然不是這樣。利用列表 1 中的配置,負(fù)載較低時可能不會遇到任何問題,但隨著服務(wù)器集群上的負(fù)載逐漸增加,遠(yuǎn)程緩存上就會出現(xiàn)過期數(shù)據(jù)。要做好準(zhǔn)備應(yīng)對服務(wù)器節(jié)點(diǎn)爭用甚至更糟的情況。即使成功寫入數(shù)據(jù)庫,最后也可能會因為網(wǎng)絡(luò)故障而使得緩存服務(wù)器 PUT 以失敗告終。另外,NoSQL 通常不支持在關(guān)系數(shù)據(jù)庫中存在完整事務(wù)語義,因為這會導(dǎo)致部分提交。為了讓代碼容錯,可以考慮給數(shù)據(jù)模型增加版本號,實現(xiàn)樂觀鎖。

在收到 OptimisticLockingFailureExceptionCurrentModificationException(具體取決于持久性解決方案)時,可以調(diào)用帶有 @CacheEvict 注釋的方法,從緩存中清除過期拷貝,然后重試同一個操作:

列表 2:解決緩存中的過期對象

try{
    User user = userDao.get(id);    // user fetched in cache server
    userDao.update(user, oldname, newname);      
}catch(ConcurrentModificationException ex) {   // cached user object may be stale
    userDao.evictCache(user);
    user =  userDao.get(id);     // refresh user object
    userDao.update(user, oldname, newname);    // retry the same operation. Note it may still throw legitimate ConcurrentModificationException.}

結(jié)合 Elasticache 使用 Redis

Amazon Elasticache 是一款內(nèi)存緩存服務(wù),可結(jié)合 Memcached 或 Redis 作為緩存服務(wù)器使用。雖然 Elasticache 不在本文介紹范圍內(nèi),但筆者還是想給各位開發(fā)人員介紹一個結(jié)合 Redis 使用 Elasticache 的技巧。對于大多數(shù) Redis 參數(shù),使用其默認(rèn)值并無大礙,但 tcp-keepalivetimeout 的默認(rèn) Redis 設(shè)置并不會移除已無效的客戶連接,最后還會耗盡緩存服務(wù)器上的套接口。結(jié)合 Elasticache 使用 Redis 時,務(wù)必每次都明確設(shè)置這兩個值。

在本文的第二部分,將介紹 Redis 的6大用例,敬請期待。

本文系 OneAPM 工程師編譯整理。OneAPM 能為您提供端到端的 Java 應(yīng)用性能解決方案,我們支持所有常見的 Java 框架及應(yīng)用服務(wù)器,助您快速發(fā)現(xiàn)系統(tǒng)瓶頸,定位異常根本原因。分鐘級部署,即刻體驗,Java 監(jiān)控從來沒有如此簡單。想閱讀更多技術(shù)文章,請訪問 OneAPM 官方技術(shù)博客。

本文轉(zhuǎn)自 OneAPM 官方博客

原文地址:http://www.javaworld.com/article/3062899/big-data/lightning-fast-nosql-with-spring-data-redis.html?page=1

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64857.html

相關(guān)文章

  • Spring Data Redis NoSQL 快如閃電(2)

    摘要:布隆過濾器布隆過濾器是一種空間利用率較高的概率數(shù)據(jù)結(jié)構(gòu),用來測試某元素是否某個集的一員。則利用布隆過濾器過濾掉不包含特殊行或列的塊磁盤讀取,使讀取速度得到明顯提升。搜索,就能發(fā)現(xiàn)很多布隆過濾器項目,其中一些還支持可調(diào)諧精度。 【編者按】本文作者為 Xinyu Liu,文章的第一部分重點(diǎn)概述了 Redis 方方面面的特性。在第二部分,將介紹詳細(xì)的用例。文章系國內(nèi) ITOM 管理平臺 On...

    lewif 評論0 收藏0
  • 快如閃電,觸控優(yōu)先。新一代的純前端控件集 WijmoJS發(fā)布新版本了

    摘要:全球最大的控件提供商葡萄城宣布,新一代純前端控件發(fā)布版本,進(jìn)一步增強(qiáng)產(chǎn)品功能,并支持在上的安裝和發(fā)布,極大的提升了產(chǎn)品的易用性。葡萄城的控件和軟件產(chǎn)品在國內(nèi)外屢獲殊榮,在全球被數(shù)十萬家企業(yè)學(xué)校和政府機(jī)構(gòu)廣泛應(yīng)用。 全球最大的控件提供商葡萄城宣布,新一代純前端控件 WijmoJS 發(fā)布2018 v1 版本,進(jìn)一步增強(qiáng)產(chǎn)品功能,并支持在 Npm 上的安裝和發(fā)布,極大的提升了產(chǎn)品的易用性。 ...

    aikin 評論0 收藏0
  • 快如閃電,觸控優(yōu)先。新一代的純前端控件集 WijmoJS發(fā)布新版本了

    摘要:全球最大的控件提供商葡萄城宣布,新一代純前端控件發(fā)布版本,進(jìn)一步增強(qiáng)產(chǎn)品功能,并支持在上的安裝和發(fā)布,極大的提升了產(chǎn)品的易用性。葡萄城的控件和軟件產(chǎn)品在國內(nèi)外屢獲殊榮,在全球被數(shù)十萬家企業(yè)學(xué)校和政府機(jī)構(gòu)廣泛應(yīng)用。 全球最大的控件提供商葡萄城宣布,新一代純前端控件 WijmoJS 發(fā)布2018 v1 版本,進(jìn)一步增強(qiáng)產(chǎn)品功能,并支持在 Npm 上的安裝和發(fā)布,極大的提升了產(chǎn)品的易用性。 ...

    陳江龍 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<