成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

后端緩存的23個關鍵關注點

存儲 存儲軟件
建議將使用緩存的業務進行分離,核心業務和非核心業務使用不同的緩存實例,從物理上進行隔離,如果有條件,則請對每個業務使用單獨的實例或者集群,以減小應用之間互相影響的可能性。

[[253797]]

 ▌1:極簡緩存架構

通過JSR107規范,我們將框架定義為客戶端層、緩存提供層、緩存管理層、緩存存儲層。其中緩存存儲層又分為基本存儲層、LRU存儲層和Weak存儲層,如下圖所示。

 

緩存分層圖

其中:

客戶端層:使用者直接通過該層與數據進行交互。

緩存提供層:主要對緩存管理層的生命周期進行維護,負責緩存管理層的創建,保存、獲取以及銷毀。

緩存管理層:主要對緩存客戶端的生命周期進行維護,負責緩存客戶端的創建,保存、獲取以及銷毀

緩存存儲層:負責數據以什么樣的形式進行存儲。

基本存儲層:是以普通的ConcurrentHashMap為存儲核心,數據不淘汰。

LRU存儲層:是以最近最少用為原則進行的數據存儲和緩存淘汰機制。

Weak存儲層:是以弱引用為原則的數據存儲和緩存淘汰機制。

▌2:容量評估

緩存系統主要消耗的是服務器的內存,因此,在使用緩存時必須先對應用需要緩存的數據大小進行評估,包括緩存的數據結構、緩存大小、緩存數量、緩存的失效時間,然后根據業務情況自行推算在未來一定時間內的容量的使用情況,根據容量評估的結果來申請和分配緩存資源,否則會造成資源浪費或者緩存空間不夠。

▌3:業務分離

建議將使用緩存的業務進行分離,核心業務和非核心業務使用不同的緩存實例,從物理上進行隔離,如果有條件,則請對每個業務使用單獨的實例或者集群,以減小應用之間互相影響的可能性。筆者就經常聽說有的公司應用了共享緩存,造成緩存數據被覆蓋以及緩存數據錯亂的線上事故。

▌4:監控為王

所有的緩存實例都需要添加監控,這是非常重要的,我們需要對慢查詢、大對象、內存使用情況做可靠的監控。

▌5:失效時間

任何緩存的key都必須設定緩存失效時間,且失效時間不能集中在某一點,否則會導致緩存占滿內存或者緩存雪崩。

▌6:大量key同時失效時間的危害

在使用緩存時需要進行緩存設計,要充分考慮如何避免常見的緩存穿透、緩存雪崩、緩存并發等問題,尤其是對于高并發的緩存使用,需要對key的過期時間進行隨機設置,例如,將過期時間設置為10秒+random(2),也就是將過期時間隨機設置成10~12秒。

筆者曾經見過一個case:在應用程序中對使用的大量緩存key設置了同一個固定的失效時間,當緩存失效時,會造成在一段時間內同時訪問數據庫,造成數據庫的壓力較大。

▌7:先更新數據庫后更新緩存有啥問題?

想象一下,如果兩個線程同時執行更新操作,線程1更新數據庫后,線程2也更新了數據庫,然后開始寫緩存,但線程2先執行了更新緩存的操作,而線程1在執行更新緩存的時候就把線程2更新的數據給覆蓋掉了,這樣就會出現數據不一致。

▌8:先刪緩存, 行不行?

“先刪緩存,然后執行數據庫事務”也有人討論這種方案,不過這種操作對于如商品這種查詢非常頻繁的業務不適用,因為在你刪緩存的同時,已經有另一個系統來讀緩存了,此時事務還沒有提交。當然對于如用戶維度的業務是可以考慮的。

▌9:數據庫和緩存數據一致性

京東采用了通過canal更新緩存原子性的方法,如下圖所示。

 

最終一致性方案

幾個關注點:

更新數據時使用更新時間戳或者版本對比。

使用如canal訂閱數據庫binlog;此處把mysql看成發布者,binlog是發布的內容,canal(canal 是阿里巴巴mysql數據庫binlog的增量訂閱&消費組件)看成消費者,canal訂閱binlog然后更新到Redis。

將更新請求按照相應的規則分散到多個隊列,然后每個隊列的進行單線程更新,更新時拉取***的數據保存;更新之前獲取相關的鎖再進行更新。

▌10.先更新數據庫,再刪除緩存的一種實踐

流程如下圖所示:

 

過程不贅述,只強調一個,數據庫update變更會同步發到消息,通過消息去刪除緩存。如果刪除失敗,消息有重試機制保障。另外除了極端情況,緩存更新是比較及時的。

▌11:本地緩存的挑戰

如果對性能的要求不是非常高,則盡量使用分布式緩存,而不要使用本地緩存,因為本地緩存在服務的各個節點之間復制,在某一時刻副本之間是不一致的,如果這個緩存代表的是開關,而且分布式系統中的請求有可能會重復,就會導致重復的請求走到兩個節點,一個節點的開關是開,一個節點的開關是關,如果請求處理沒有做到冪等,就會造成處理重復,在嚴重情況下會造成資金損失。

▌12:緩存熱點與多級緩存

對于分布式緩存,我們需要在Nginx+Lua應用中進行應用緩存來減少Redis集群的訪問沖擊;即首先查詢應用本地緩存,如果***則直接緩存,如果沒有***則接著查詢Redis集群、回源到Tomcat;然后將數據緩存到應用本地。如同14-8所示。

此處到應用Nginx的負載機制采用:正常情況采用一致性哈希,如果某個請求類型訪問量突破了一定的閥值,則自動降級為輪詢機制。另外對于一些秒殺活動之類的熱點我們是可以提前知道的,可以把相關數據預先推送到應用Nginx并將負載均衡機制降級為輪詢。

 

分布式緩存方案

另外可以考慮建立實時熱點發現系統來發現熱點,如下圖所示:

 

實時熱點發現方案

1)接入Nginx將請求轉發給應用Nginx;

2)應用Nginx首先讀取本地緩存;如果***直接返回,不***會讀取分布式緩存、回源到Tomcat進行處理;

3)應用Nginx會將請求上報給實時熱點發現系統,如使用UDP直接上報請求、或者將請求寫到本地kafka、或者使用flume訂閱本地nginx日志;上報給實時熱點發現系統后,它將進行統計熱點(可以考慮storm實時計算);

4)根據設置的閥值將熱點數據推送到應用Nginx本地緩存。

因為做了本地緩存,因此對于數據一致性需要我們去考慮,即何時失效或更新緩存:

1)如果可以訂閱數據變更消息,那么可以訂閱變更消息進行緩存更新;

2)如果無法訂閱消息或者訂閱消息成本比較高,并且對短暫的數據一致性要求不嚴格(比如在商品詳情頁看到的庫存,可以短暫的不一致,只要保證下單時一致即可),那么可以設置合理的過期時間,過期后再查詢新的數據;

3)如果是秒殺之類的,可以訂閱活動開啟消息,將相關數據提前推送到前端應用,并將負載均衡機制降級為輪詢;

4)建立實時熱點發現系統來對熱點進行統一推送和更新。

應對緩存大熱點:數據復制模式

 

在Facebook有一招,就是通過多個key_index(key:xxx#N) 來解決數據的熱點讀問題。解決方案是所有熱點key發布到所有web服務器;每個服務器的key有對應別名,可以通過client端的算法路由到某臺服務器;做刪除動作時,刪除所有的別名key。可簡單總結為一個通用的group內一致模型。把緩存集群劃分為若干分組(group),在同組內,所有的緩存服務器,都發布熱點key的數據。

對于大量讀操作而言,通過client端路由策略,隨意返回一臺機器即可;而寫操作,有一種解法是通過定時任務來寫入;Facebook采取的是刪除所有別名key的策略。如何保障這一個批量操作都成功?

(1)容忍部分失敗導致的數據版本問題

(2)只要有寫操作,則通過定時任務刷新緩存;如果涉及3臺服務器,則都操作成功代表該任務表的這條記錄成功完成使命,否則會重試。

▌13:緩存失效的連接風暴

引起這個問題的主要原因還是高并發的時候,平時我們設定一個緩存的過期時間時,可能有一些會設置1分鐘,5分鐘,并發很高可能會出在某一個時間同時生成了很多的緩存,并且過期時間都一樣,這個時候就可能引發過期時間到后,這些緩存同時失效,請求全部轉發到DB,DB可能會壓力過重。那如何解決這些問題呢?

其中的一個簡單方案就是將緩存失效時間分散開,比如我們可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復率就會降低,就很難引發集體失效的事件。

如果緩存集中在一段時間內失效,DB的壓力凸顯。這個沒有***解決辦法,但可以分析用戶行為,盡量讓失效時間點均勻分布。

上述是緩存使用過程中經常遇到的并發穿透、并發失效問題。一般情況下,我們解決這些問題的方法是,引入空值、鎖和隨機緩存過期時間的機制。

▌14:緩存預熱

提前把數據讀入到緩存的做法就是數據預熱處理。數據預熱處理要注意一些細節問題:

(1)是否有監控機制確保預熱數據都寫成功了!筆者曾經遇到部分數據成功而影響高峰期業務的案例;

(2)數據預熱配備回滾方案,遇到緊急回滾時便于操作。對于新建cache server集群,也可以通過數據預熱模式來做一番手腳。如下圖所示,先從冷集群中獲取key,如果獲取不到,則從熱集群中獲取。同時把獲取到的key put到冷集群。如下圖

 

數據預熱

(3)預熱數據量的考量,要做好容量評估。在容量允許的范圍內預熱全量,否則預熱訪問量高的。

(4)預熱過程中需要注意是否會因為批量數據庫操作或慢sql等引發數據庫性能問題。

▌15:超時時間設計

在使用遠程緩存(如Redis、Memcached)時,一定要對操作超時時間進行設置,這是非常關鍵的,一般我們設計緩存作為加速數據庫讀取的手段,也會對緩存操作做降級處理,因此推薦使用更短的緩存超時時間,如果一定要給出一個數字,則希望是100毫秒以內。

筆者曾經遇到過一個案例:某個正常運行的應用突然報警線程數過高,之后很快就出現了內存溢出。

分析原因為:由于緩存連接數達到***限制,應用無法連接緩存,并且超時時間設置得較大,導致訪問緩存的服務都在等待緩存操作返回,由于緩存負載較高,處理不完所有的請求,但是這些服務都在等待緩存操作返回,服務這時在等待,并沒有超時,就不能降級并繼續訪問數據庫。這在BIO模式下線程池就會撐滿,使用方的線程池也都撐滿;在NIO模式下一樣會使服務的負載增加,服務響應變慢,甚至使服務被壓垮。

▌16:不要把緩存到存儲

大家都知道一個顛撲不破的真理:在分布式架構下,一切系統都可能fail,無論是緩存、存儲包括數據庫還是應用服務器,而且部分緩存本身就未提供持久化機制比如memcached。即使使用持久化機制的cache,也要慎用,如果作為唯一存儲的話。

▌17:緩存崩潰解決之道

當我們使用分布式緩存時,應該考慮如何應對其中一部分緩存實例宕機的情況。接下來部分將介紹分布式緩存時的常用算法。而當緩存數據是可丟失的情況時,我們可以選擇一致性哈希算法。

取模

對于取模機制如果其中一個實例壞了,如果摘除此實例將導致大量緩存不***,瞬間大流量可能導致后端DB/服務出現問題。對于這種情況可以采用主從機制來避免實例壞了的問題,即其中一個實例壞了可以那從/主頂上來。但是取模機制下如果增加一個節點將導致大量緩存不***,一般是建立另一個集群,然后把數據遷移到新集群,然后把流量遷移過去。

一致性哈希

對于一致性哈希機制如果其中一個實例壞了,如果摘除此實例將只影響一致性哈希環上的部分緩存不***,不會導致瞬間大量回源到后端DB/服務,但是也會產生一些影響。

▌18. 緩存崩潰后的快速恢復

如果出現之前說到的一些問題,可以考慮如下方案:

1)主從機制,做好冗余,即其中一部分不可用,將對等的部分補上去;

2)如果因為緩存導致應用可用性已經下降可以考慮:

部分用戶降級,然后慢慢減少降級量;

后臺通過Worker預熱緩存數據。

也就是如果整個緩存集群壞了,而且沒有備份,那么只能去慢慢將緩存重建;為了讓部分用戶還是可用的,可以根據系統承受能力,通過降級方案讓一部分用戶先用起來,將這些用戶相關的緩存重建;另外通過后臺Worker進行緩存數據的預熱。

▌19. 開啟Nginx Proxy Cache性能不升反降

開啟Nginx Proxy Cache后,性能下降,而且過一段內存使用率到達98%;解決方案:

1)對于內存占用率高的問題是內核問題,內核使用LRU機制,本身不是問題,不過可以通過修改內核參數:

sysctl -wvm.extra_free_kbytes=6436787

sysctl -wvm.vfs_cache_pressure=10000

2)使用Proxy Cache在機械盤上性能差可以通過tmpfs緩存或nginx共享字典緩存元數據,或者使用SSD,我們目前使用內存文件系統。

▌20:“網絡抖動時,返回502錯誤”緣于timeout

Twemproxy配置的timeout時間太長,之前設置為5s,而且沒有分別針對連接、讀、寫設置超時。后來我們減少超時時間,內網設置在150ms以內,當超時時訪問動態服務。

▌21:應對惡意刷的經驗

商品詳情頁庫存接口2014年被惡意刷,每分鐘超過600w訪問量,tomcat機器只能定時重啟;因為是詳情頁展示的數據,緩存幾秒鐘是可以接受的,因此開啟nginxproxy cache來解決該問題,開啟后降到正常水平;后來我們使用Nginx+Lua架構改造服務,數據過濾、URL重寫等在Nginx層完成,通過URL重寫+一致性哈希負載均衡,不怕隨機URL,一些服務提升了10%+的緩存***率。

▌22:網卡打滿了咋辦?

用Redis都有個很頭疼的問題,就是Redis的網卡打滿問題,由于Redis的性能很高,在大并發請求下,很容易將網卡打滿.通常情況下,1臺服務器上都會跑幾十個Redis實例 ,一旦網卡打滿,很容易干擾到應用層可用性.所以我們基于開源的Contiv netplugin項目,限制了網卡的使用, 主要功能是提供基于Policy的網絡和存儲管理。Contiv比較“誘人”的一點就是,它的網絡管理能力,既有L2(VLAN)、L3(BGP),又有 Overlay(VxLAN),有了它就可以無視底層的網絡基礎架構,向上層容器提供一致的虛擬網絡了。最主要的一點是,既滿足了業務場景,又兼容了以往的網絡架構。在轉發性能上,它能接近物理網卡的性能,特別在沒有萬兆網絡的老機房也能很好的使用。在網絡流量監控方面,我們通過使用ovs的sflow來抓取宿主機上所有的網絡流量,然后自開發了一個簡單的sflow Collecter, 服務器收到sflow的數據包進行解析,篩選出關鍵數據,然后進行匯總分析,得到所需要的監控數據。通過這個定制的網絡插件,我們可以隨意的控制某個Redis的流量,流量過大,也不會影響其他的項目,而如果某個服務器上的Redis流量很低,我們也可以縮小它的配額,提供給本機其他需要大流量的程序使用,這些,通過后臺的監控程序,可以實現完全自動化。

▌23:緩存組件的選擇

緩存的種類很多,我們實際使用時,需要根據緩存位置(系統前后端)、待存數據類型、訪問方式、內存效率等情況來選擇最適合的緩存組件。本小節接下來將主要探討在應用層后端如何選擇分布式緩存組件。

一般業務系統中,大部分數據都是簡單KV數據類型,如前述微博Feed系統中的feed content、feed列表、用戶信息等。這些簡單類型數據只需要進行set、get、delete操作,不需要在緩存端做計算操作,最適合以memcached作為緩存組件。

其次對于需要部分獲取、事物型變更、緩存端計算的集合類數據,擁有豐富數據結構和訪問接口的Redis 也許會更適合。Redis還支持以主從(master-slave)方式進行數據備份,支持數據的持久化,可以將內存中的數據保持在磁盤,重啟時再次加載使用。因磁盤緩存(diskstore)方式的性能問題,Redis數據基本只適合保存在內存中,由此帶來的問題是:在某些業務場景,如果待緩存的數據量特別大,而數據的訪問量不太大或者有冷熱區分,也必須將所有數據全部放在內存中,緩存成本(特別是機器成本)會特別高。如果業務遇到這種場景,可以考慮用pika、ssdb等其他緩存組件。pika、ssdb都兼容Redis協議,同時采用多線程方案,支持持久化和復制,單個緩存實例可以緩存數百G的數據,其中少部分的熱數據存放內存,大部分溫熱數據或冷數據都可以放在磁盤,從而很好的降低緩存成本。

對前面講到的這些后端常用的緩存組件,可以參考下表進行選擇。

***,對于對存儲效率、訪問性能等有更高要求的業務場景,結合業務特性進行緩存組件的定制化設計與開發,也是一個很好的選擇。

總之,緩存組件的選型要考慮數據模型、訪問方式、緩存成本甚至開發人員的知識結構,從而進行因地制宜的取舍,不要盲目引入不熟悉、不活躍、不成熟的緩存組件,否則中途頻繁調整緩存方案,會給開發進度、運維成本帶來較大的挑戰。

責任編輯:武曉燕 來源: 技術瑣話
相關推薦

2017-12-12 14:38:44

數據中心液體冷卻

2012-05-17 16:00:22

數據中心數據中心布線布線

2019-01-14 08:39:01

2023-11-10 16:18:59

2016-12-09 09:13:06

大數據隱私安全

2022-07-17 16:01:25

信息安全數據安全工具

2013-08-05 09:35:23

100G組網技術100G技術100G

2013-09-17 16:54:01

技術

2018-11-22 11:09:39

AR自動駕駛技術

2022-12-27 08:10:07

PG數據庫運維

2019-11-07 09:00:00

人工智能AI

2012-01-06 08:48:09

云計算安全

2015-10-22 09:54:49

觸屏數據分析優化

2023-06-08 14:36:49

2009-12-03 17:37:10

商務智能BI數據挖掘

2011-03-08 22:44:38

寬帶光網光網城市

2015-08-27 15:54:49

NFV互操作性

2015-07-31 10:06:38

2009-12-30 14:14:39

PPPoA體系

2023-08-17 09:00:00

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜成人免费电影 | 97伊人| 精品视频在线播放 | 久久久精品一区 | 亚洲一二三区精品 | 亚洲精品久久久一区二区三区 | 巨大荫蒂视频欧美另类大 | 国产片网站 | 熟女毛片| 一级欧美一级日韩片免费观看 | 国产高清一区二区三区 | 国产高清精品一区二区三区 | 国产高清在线 | 亚洲欧美成人 | 成人三区四区 | 日韩a视频 | 日日天天 | 午夜午夜精品一区二区三区文 | 天天曰天天曰 | 国产精品一区二区在线 | 免费观看一级特黄欧美大片 | 青青草久久 | 日韩在线免费播放 | 久久一区二区三区电影 | 国产在线视频一区 | av在线一区二区 | 99精品视频在线 | 国产我和子的乱视频网站 | 黄色操视频 | 欧美综合久久 | 一区二区三区小视频 | 干干干操操操 | 五月综合激情网 | 超碰精品在线观看 | 日韩久久久一区二区 | 久久久久久国产精品免费 | 日韩精品 电影一区 亚洲 | 中文字幕综合 | 日韩高清一区 | 国产精品伦一区二区三级视频 | 91亚洲精品国偷拍自产在线观看 |