中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

你去湖北省住房城鄉(xiāng)建設廳網(wǎng)站查seo專員很難嗎

你去湖北省住房城鄉(xiāng)建設廳網(wǎng)站查,seo專員很難嗎,備案期間關網(wǎng)站嗎,萬盛網(wǎng)站建設文章目錄一、相關名詞1.mcrouter層2.GUTTER SERVER3.mcsqueal4.remote mark二、當流量增長了如何SCALE 你的網(wǎng)站?三、背景及業(yè)務特點1.讀多寫少2.FB需求:3.之前情況四、簡介五、FaceBook的架構五、Cache Policy六、In a Cluster : Latency and Load(一&a…

文章目錄

  • 一、相關名詞
    • 1.mcrouter層
    • 2.GUTTER SERVER
    • 3.mcsqueal
    • 4.remote mark
  • 二、當流量增長了如何SCALE 你的網(wǎng)站?
  • 三、背景及業(yè)務特點
    • 1.讀多寫少
    • 2.FB需求:
    • 3.之前情況
  • 四、簡介
  • 五、FaceBook的架構
  • 五、Cache Policy
  • 六、In a Cluster : Latency and Load
    • (一)Reducing Latency
    • (二) Reducing Load
      • 1.Lease
        • (1)stale set 過期寫入
        • (2) Thundering herds 驚群
      • 2. MemcachePools
    • (三)Handling Failures
  • 七、In a Region: Replication
    • (一)Regional Invalidations
    • (二) Regional Pools
    • (三)Cold Cluster Warmup
  • 八、Across Regions: Consistency
  • 九、memcache的一致性
  • 十、總結

一、相關名詞

1.mcrouter層

FACEBOOK提供了一個mcrouter層,CLIENT對所有請求構建一個DAG,找到可以合并發(fā)送的請求發(fā)送給mcrouter,讓他來分發(fā)出去。
降低數(shù)據(jù)包率:如果直接將失效緩存消息發(fā)送會浪費網(wǎng)絡資源,因此需要將緩存失效消息批量發(fā)送給每個前端集群中的mcrouter,再由mcrouter轉發(fā)給集群內的服務器。
是memcache 客戶端(sdk 與 proxy)的一部分,代理proxy被稱為 mcrouter。

2.GUTTER SERVER

他們是一組IDLE的SERVER,用戶使用他們只當MC SERVER掛了的時候。
系統(tǒng)設置了少量稱為Gutter的機器來暫時管理不可用機器的鍵范圍,Gutter中的數(shù)據(jù)有效期很短,這樣避免了需要使緩存失效的操作。

3.mcsqueal

存儲集群保存著最新數(shù)據(jù),用戶請求將數(shù)據(jù)副本寫入到前端服務器。存儲集群負責發(fā)送緩存失效命令,來保持數(shù)據(jù)的一致性。對數(shù)據(jù)產(chǎn)生修改的SQL會附上需要失效的mamcache鍵,應用更改之后由mcsqueal將緩存失效消息發(fā)送給各個前端集群中的服務器。
利用 DB 數(shù)據(jù)的更新日志來保證數(shù)據(jù)在不同集群間的最終一致性。

squeal/skwi?l/告密,尖叫聲

4.remote mark

FB解決REGION間的主從不一致,通過"remote mark"
C1 DELETE()的時候,如果是主, 使用mcsqueal傳輸失效消息可以避免失效信息先于數(shù)據(jù)更新到達。(因為mcsqueal 這個daemon是監(jiān)聽DB的COMMIT消息)
如果是非主,當Web務器更新鍵值k時:
在從region , delete()時,這個K上寫一個"remote mark"
如果C1 get()的時候,發(fā)現(xiàn)了這個標記,就去master那讀,而不是自己的LOCAL DB。
隨后去主region進行UPDATE,然后復制數(shù)據(jù)到從DB,這個時候這個標記會被清除。

二、當流量增長了如何SCALE 你的網(wǎng)站?

1.在最開始的時候我們搭建一個站點,可能就一臺機器里面包含了WEB SERVER,Application和DB(如MySQL)。 DB就把數(shù)據(jù)存在硬盤里。application 去查詢 db隨后渲染HTML。當流量開始增長,你的PHP Application要消耗更多CPU,單機無法承受,這通常這就是他們所遇到的第一個性能瓶頸。所以,你所需要做的就是為你的PHP腳本提供更多的服務器資源。
在這里插入圖片描述
2.我們轉向了第二種網(wǎng)站架構—— 多個WEB SERVER, 一個共享的數(shù)據(jù)庫。
用戶大量增多,需要更多的CPU處理能力來執(zhí)行PHP腳本。所以運行了一堆前端服務器(下圖中的FE),它們只負責運行和用戶瀏覽器進行通信的web服務器。這上面運行著Apacheweb服務器以及PHP腳本,所有這些前端服務器都需要看到相同的后端數(shù)據(jù)。為了做到這點,這里你可以放一個數(shù)據(jù)庫服務器(下圖最右側的MySQL)。流量增長,我們只需要加更多WEB SERVER直到DB成為瓶頸。
當使用一個服務器來運行MySQL時,它用來處理所有來自前端服務器對數(shù)據(jù)庫的查詢,更新,讀取以及寫入請求。如果使用兩個數(shù)據(jù)庫服務器,并將你的數(shù)據(jù)以某種方式分散到多個數(shù)據(jù)庫服務器中時,情況就會變得更為復雜。你就需要關心是否要使用分布式事務,或者該PHP腳本應該通過哪種方式來確定它要和哪個數(shù)據(jù)庫服務器進行通信。
在這里插入圖片描述
3.大型網(wǎng)站的一種標準演變,下面要轉向web架構3——水平擴容
數(shù)據(jù)根據(jù)SHARD KEY散落在不同的DB上。 APP 根據(jù)SHARD KEY去查詢對應的DB(如下圖第一個數(shù)據(jù)庫服務器上保存的是key從a到g的相關數(shù)據(jù),第二個數(shù)據(jù)庫服務器上保存的是key從g到q的相關數(shù)據(jù),以此類推)。 只要沒有單個KEY是超級火爆的,負載就會被均勻的分散。
在這里插入圖片描述
但是數(shù)據(jù)分片帶來了額外開銷:①需要對前端服務器上的軟件進行修改讓PHP代碼知道數(shù)據(jù)分片相關的信息。②對于事務會需要用到兩階段提交或者一些其他分布式事務方案,速度很慢。
這種方案,成本高,速度慢,還會有熱點問題。所以我們無須花大量的錢來添加另一臺運行著MySQL的數(shù)據(jù)庫服務器,可以在同一臺服務器上面運行緩存memcached。在相同的硬件上,使用緩存每秒讀取的數(shù)據(jù)量要比使用數(shù)據(jù)庫多得多。
總結:為了更好的解決流量增長時的網(wǎng)絡架構面對的db訪問瓶頸,出現(xiàn)了memcached.
4.Facebook的架構
現(xiàn)在我們的架構變成很多WEB SERVER, 很多CACHE SERVER提供讀服務,還有很多DB支持寫。
在前端服務器和數(shù)據(jù)庫服務器之間有一個緩存層memcached。當前端服務器需要去讀取一些數(shù)據(jù),它會往其中一個memcache服務器發(fā)送一個攜帶某個key的get請求。memcache服務器會去檢查它內存中的一張表(大型hash table)中是否有這個key,如果有的話,它就會將對應的數(shù)據(jù)返回給前端服務器。
如果并未命中memcache服務器中的緩存,那么前端服務器就得將請求重新發(fā)送給相關的數(shù)據(jù)庫服務器。為了之后的請求,前端服務器會發(fā)送一個put請求并攜帶它從數(shù)據(jù)庫中所拿到的數(shù)據(jù)給memcache服務器。
(注:讀——memcache, 寫——數(shù)據(jù)庫)
在這里插入圖片描述
(1)問題:當讀memcache miss時,為什么是前端服務器發(fā)送put請求寫入memcache,而不是memcache在miss時,轉發(fā)給db,并將db的響應緩存起來?
不能這樣做的原因是,memcache就像是一個完全獨立的軟件,它對數(shù)據(jù)庫一無所知。雖然我們經(jīng)常將它和數(shù)據(jù)庫放在一起使用,但我們無法將數(shù)據(jù)庫的知識應用到memcache中。
更深層次的理由是,前端服務器會對從db得到的結果進行某種處理(它可能需要花幾步來將結果轉換為html,或者,它會從數(shù)據(jù)庫的多行數(shù)據(jù)中獲取結果,并將部分處理過的信息緩存到memcache中,以此來節(jié)省下一個要執(zhí)行相同操作的reader所要花的時間)。所以,memcache并不理解前端服務器想看到哪些緩存數(shù)據(jù),以及你是如何從數(shù)據(jù)庫中衍生數(shù)據(jù)的。這些邏輯都是放在前端服務器中的php代碼里的。
所以,從架構上來說,這是一個很不錯的想法,但我們不能做這種整合,即讓memcache和數(shù)據(jù)庫之間直接進行通信,雖然這會讓緩存一致性變得更為簡單。
(總結:web服務器可能需要的并不是數(shù)據(jù)庫中的原始數(shù)據(jù),而是經(jīng)過處理的html或整合后的結果,會向memcache中存儲處理后的數(shù)據(jù),所以不能直接由memcache與數(shù)據(jù)庫交互來保存數(shù)據(jù))

(2)問題:look-aside cache和look-through cache間的區(qū)別是什么?
look-aside cache的作用是,前端服務器會先查看數(shù)據(jù)是否存在于緩存中,它會從數(shù)據(jù)庫中獲取未緩存的數(shù)據(jù)。如果使用的是look-through cache,那么就會通過memcache將我的請求轉發(fā)給數(shù)據(jù)庫,讓數(shù)據(jù)庫來處理響應(即memcache與數(shù)據(jù)庫有交互)。
(總結:數(shù)據(jù)同步時,look-aside cache是以前端服務器為中心,look-through cache是以memcache為中心)
memcache流行的部分原因是,它使用的是look-aside cache,讓web服務器作為中間方來對memcache中的數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)進行操作,即memcache不直接與數(shù)據(jù)庫進行交互,通過web服務器來和數(shù)據(jù)庫進行交互。

三、背景及業(yè)務特點

1.讀多寫少

與大部分互聯(lián)網(wǎng)公司的讀寫流量特點類似,FB 的整體業(yè)務呈現(xiàn)出明顯讀多寫少的特點,其讀請求量比寫請求量高出 2 個數(shù)量級 (數(shù)據(jù)來自于https://www.usenix.org/sites/default/files/conference/protected-files/nishtala_nsdi13_slides.pdf、 slides),因此增加緩存層可以顯著提高業(yè)務穩(wěn)定性,保護 DB。

2.FB需求:

Facebook作為社交網(wǎng)絡服務基礎設施,需要滿足:

  • 近似實時通信;
  • 實時聚合多個來源的內容;
  • 讀取/更新熱點的共享內容;
  • 可伸縮以處理billion級用戶并發(fā)。

為滿足以上需求,Facebook從單機(memcached)、集群(cluster)、區(qū)域(region)、跨區(qū)域(cross-region)這4個方面以bottom up的方式講述他們是如何scale的。

3.之前情況

在使用緩存層之前,FB 的 Web Server 直接訪問數(shù)據(jù)庫,通過 數(shù)據(jù)分片 和 一主多從 的方式來扛住讀寫流量:
在這里插入圖片描述
但隨著用戶數(shù)數(shù)量飆升,單純靠數(shù)據(jù)庫來抗壓成本高,效率低。

四、簡介

1.Scaling Memcache at Facebook是Facebook團隊2013年的一篇論文,講述Facebook如何使用開源的memcached構建分布式內存KV集群,使用memcache來處理海量的工作量(這里指的memcache和下文的memcacheD,說的都是運行著memcacheD的服務器)。

這篇paper中存在著很多可以借鑒的經(jīng)驗,它里面并沒有任何新的概念或者想法或者技術之類的東西,當那些公司試著去構建具備高負載能力的基礎架構時,他們就會去使用這篇paper中提到的這些方法。

2.Memcached是一個簡單的內存cache組件,支持低延遲低成本的內存訪問。

3.Memcached提供的是一個純內存的哈希表訪存服務,支持鍵值對的存儲模式,提供的基本接口為put, get, delete。

五、FaceBook的架構

1.在進入正文之前,需要厘清以下概念(見Figure 2):

  • memcached:開源memcached技術,在文中指運行時的單臺實例;
  • cluster:指多臺memcached組成的最小單位的集群,memcached之間相互不通信,由client端使用consistent hash將數(shù)據(jù)分布到多臺memcached;
  • region:多web server集群和多cluster集群組成frontend clusters,共享一個storage cluster組成一個region;
  • cross-region:多個region,每個region分布在不同地理位置。只有一個region的storage
    cluster是master角色,其他的是slave角色,從master同步數(shù)據(jù)。
    在這里插入圖片描述
    2.如上圖所示,一個region對應一個數(shù)據(jù)中心,單個region內有多個cluster的replica。
    在部署規(guī)模上,單cluster是對應了10^3量級的memcached server,數(shù)據(jù)使用一致性哈希分布于各個memcached中(通過對key進行hash來將我們的數(shù)據(jù)拆分到可用的memcache服務器上)。
    一個用戶與單個web server通信請求服務,每個前端服務器只和一個memcache服務器進行通信。

3.他們是通過并行執(zhí)行來做到高性能的。對于存儲系統(tǒng)來說,從高級層面來講,可以通過兩種途徑來獲得不錯的性能,其中一種是通過分區(qū)(partition),即對數(shù)據(jù)分片,并分散到10臺服務器上,我們希望這10臺服務器可以獨立運行。另一種方式就是replication(復制),使用額外的硬件來獲取更高的性能。
實際上對于memcache,Facebook將分區(qū)和復制這兩種技術結合起來使用,分區(qū)的優(yōu)點是內存效率(Ram efficient),因為你只保存每個item的一份副本。然而,使用復制技術的話,你會在每臺服務器上都保存該數(shù)據(jù)的一個副本。分區(qū)的缺點在于熱點問題(not good for hot keys)。分區(qū)的另外一個缺點是,每個前端服務器可能要和大量的分區(qū)進行通信(clients talk to every partion),因為取的內容可能在不同的分片。
復制優(yōu)點是有利于熱門key(good if hot keys)。每個前端服務器可能只和一個memcache服務器進行通信(few TCP connections)。但缺點是,每個服務器上都留有一份數(shù)據(jù)副本,通過復制服務器要保存的總數(shù)據(jù)量就會變得更少**(less total data)。
這就是通過這兩種途徑使用額外的硬件來獲得更高性能時的一些利弊。
注:復制在有一些KEY特別火爆的時候工作的很好。因為他可以把流量均攤出去。
在這里插入圖片描述
3.從最高層的LEVEL開始說,首先是REGION,REGION是
主從結構**。也就是說主負責讀寫,從只負責讀,從通過日志來復制主的寫。寫請求都要通過主的,隨后用復制日志去同步給從REGION(MySQL提供了一種異步日志復制的機制)。
講完了最上層,我們再看進去。
一個REGION里 有多個front-end 集群,和一個存儲集群。 注意集群和集群間的數(shù)據(jù)是完全等價的。當然REGION 和 REGION間的數(shù)據(jù)也是完全一致的。這里都是用的復制策略,而不是SHARD策略。而在一個集群里多個WEB SERVER和多個MEMCACHE是SHARD的。 然后多個前端集群共享一個存儲集群,存儲集群里,多個DB是水平擴容,也就是SHARD的。
(總結:region間完全復制,cluster之間完全復制,web server和memcache是shard,存儲集群之內多個DB是shard)

4.為什么有些是復制,有些是SHARD的呢?
從最高層面來看,他們是在不同區(qū)域間使用復制和數(shù)據(jù)分片這兩項技術。
(1)regin之間——復制
每個區(qū)域中都有一份關于所有數(shù)據(jù)的完整副本。每個區(qū)域中,他們都有一組完整的數(shù)據(jù)庫服務器,是為了讓不同位置的用戶能夠訪問距離最近的數(shù)據(jù)庫副本。另外一個原因是,讓前端服務器始終能盡可能靠近它們所需要的數(shù)據(jù)。
例子:假如我們在這兩個區(qū)域間數(shù)據(jù)進行拆分(下圖中的WEST和EAST數(shù)據(jù)中心),接著,如果我去查看我的好友列表,其中一部分好友是在東海岸,另一部分是在西海岸,這就可能會需要讓前端去發(fā)起多個請求(向另一個數(shù)據(jù)中心發(fā)送請求并得到響應需要花50毫秒),用戶會注意到這種延遲。
這使得寫操作的成本變得更高。如果這個前端服務器是位于第二數(shù)據(jù)中心,它需要去執(zhí)行寫操作時,它就得通過網(wǎng)絡將數(shù)據(jù)發(fā)送給第一數(shù)據(jù)中心。但是執(zhí)行讀操作的頻率要遠遠高于寫操作。所以從設計上來講,這是一種很好的取舍。
雖然paper并沒有提到這一點,對兩個數(shù)據(jù)中心的數(shù)據(jù)進行完全復制的另一個原因是為了容災。
(總結:paper中,FB在不同區(qū)域之間采取的是復制策略。1.獲取不同的key減少時延。2.前端服務器靠近數(shù)據(jù)。3.容災)
在這里插入圖片描述
注:MASTER REGION 會把自己的數(shù)據(jù)復制到非MASTER REGION,這僅僅涉及到存儲集群的交互,對上層的前端集群無感知。
(2)region內部
在每個數(shù)據(jù)中心中,他們都放了一組數(shù)據(jù)庫服務器(下圖最下端DB1、DB2。。。)。從數(shù)據(jù)庫層面來講,數(shù)據(jù)被分片,并且,在每個region中,我們并沒有對它們進行復制。
但是,從memcache的層面來講,實際上,它們既使用了復制,也使用了數(shù)據(jù)分片。他們有一個關于集群cluster的概念,在一個給定的區(qū)域,它實際上是支持擁有多個(前端服務器和memcache服務器的)集群。下圖有2個集群,這兩個集群幾乎是完全獨立的。集群1中的某個前端服務器將它所有的讀操作發(fā)送給本地(該集群內)的memcache服務器,此時,并沒有命中緩存,它就得需要去其中一個數(shù)據(jù)庫服務器組中獲取數(shù)據(jù)。類似地,該集群中的每個前端服務器只會和該集群下的memcache服務器進行通信。
(總結:數(shù)據(jù)庫在每個region中是分片的。memcache和前端服務器FE在cluster之間是復制,在cluster內部是分片)
在這里插入圖片描述
問題:為什么使用多集群而不是單集群?
每個集群下有一組前端服務器以及所有前端服務器所共享的一組memcache服務器。如果是單集群要提高處理能力,往同一個集群中添加更多的其他memcache服務器以及前端服務器(很多的memcache和前端處理器都在同一個集群中)。性能上熱門key所對應的數(shù)據(jù)沒有提升,而多集群可以通過復制并行提供熱門key對應的數(shù)據(jù)。
另外一個不想讓單個集群變得太大的原因是,該集群內所有的數(shù)據(jù)都會被拆分到所有的memcache服務器上。通常任意前端服務器可能會從每個memcache服務器上獲取它們所需要的數(shù)據(jù)。這意味著在前端服務器和memcache服務器間,你會擁有N^2個通信連接,他們使用TCP來進行通信,這會產(chǎn)生大量的性能開銷以及要去維護所有不同TCP連接的大量狀態(tài)。他們想對此進行限制,的解決方法就是不讓任何集群的體積變得過大。另外,業(yè)務繁忙時,前端收到的memcache服務器返回的響應太多,會導致數(shù)據(jù)包丟失。
paper提到的最后一個原因是,如果一個region是單集群,網(wǎng)絡維持太難。
(總結:不用單集群原因:1.會有很多memcache和前端處理器都在同一個集群中。2.對hot key性能沒有提升。3.集群內memcache是分片策略,每個FE需要與所有memcache通信,限制通信量。)

5.memcache使用look-aside cache的一些細節(jié)
look-aside cache:對于讀操作,前端服務器調用庫中所提供的get傳入要讀取的key生成一個RPC請求,并將該請求發(fā)送給相關的memcache服務器。它們會對傳入的這個key進行hash,以此來選擇要進行通信的memcache服務器,memcache服務器會回復Yes和要讀取的數(shù)據(jù),或者memcache服務器返回No。如果v是nil的話(下圖READ中第二行),那么前端服務器就會向數(shù)據(jù)庫發(fā)送用來獲取該數(shù)據(jù)的SQL查詢。接著,它會將另一個RPC請求(put)發(fā)送給相關的memcache服務器,并將獲取到的數(shù)據(jù)放入這個memcache服務器。
對于寫操作來說,我們要往write中傳入一個key和一個value,讓前端服務器將新數(shù)據(jù)發(fā)送給數(shù)據(jù)庫,數(shù)據(jù)庫中所保存的數(shù)據(jù)的形式可能和memcache中所保存的形式有所不同。但現(xiàn)在,我們假設數(shù)據(jù)庫和memcache服務器中保存的數(shù)據(jù)形式是一樣的。一旦數(shù)據(jù)庫拿到了新的數(shù)據(jù),接著,通過調用write操作來發(fā)送一個RPC請求給memcacheD,并告訴它請刪除這個key所對應的數(shù)據(jù),writer會讓memcacheD中與這個key所對應的數(shù)據(jù)失效。下一個試著從memcacheD中讀取該key的前端服務器所拿到的是nil,它會從數(shù)據(jù)庫中獲取更新后的值,并將它放入memcacheD中。So,這就是失效策略(invalidation scheme)。
實際上,在Facebook所使用的策略中,我們需要這個delete操作的真正原因是,前端服務器會看到它們發(fā)出的寫請求所更新的結果。事實上,在他們的策略中,數(shù)據(jù)庫服務器也會給memcache服務器發(fā)送delete操作,當任意前端服務器往數(shù)據(jù)庫中寫入數(shù)據(jù)時。正如paper中提到的,(具備mcsqueal機制)數(shù)據(jù)庫會將相關的delete操作發(fā)送給持有該key數(shù)據(jù)的memcache服務器。所以,數(shù)據(jù)庫服務器會讓memcache中保存的數(shù)據(jù)失效。前端服務器也會刪除這些key相關的數(shù)據(jù),前端服務器在它剛剛更新過這個數(shù)據(jù)后,它不會看到該數(shù)據(jù)以前的值。這就是大家平時使用memcacheD的方式。
在這里插入圖片描述
6.問題:當我們把對主MySQL數(shù)據(jù)庫所做的更新操作復制到副數(shù)據(jù)庫時,副數(shù)據(jù)庫是否也要向memcache服務器發(fā)送delete操作?
是的。當一個前端服務器發(fā)送了一個write操作給數(shù)據(jù)庫服務器,數(shù)據(jù)庫服務器會更新它保存在磁盤上的數(shù)據(jù),它會向本地數(shù)據(jù)中心里保存著剛剛更新過的這個key所對應數(shù)據(jù)的memcache服務器發(fā)送一個用于數(shù)據(jù)失效的delete操作。數(shù)據(jù)庫服務器也會向其他數(shù)據(jù)中心中與它相對應的那個數(shù)據(jù)庫服務器發(fā)送這個更新操作,它會對磁盤上的數(shù)據(jù)執(zhí)行這個寫操作。它會去使用mcsqueal機制來讀取日志,以此弄清楚哪個memcache服務器可能持有著剛剛更新過的這個key所對應的舊數(shù)據(jù),并將這個delete操作發(fā)送給這個memcache服務器。所以,如果這個key被緩存在memcache服務器中,那么通過這個delete操作,這兩個數(shù)據(jù)中心中的memcache服務器中這個數(shù)據(jù)就會失效。

7.問題:在我們執(zhí)行write操作時,如果我們先執(zhí)行delete,再將數(shù)據(jù)發(fā)送給數(shù)據(jù)庫時,這會發(fā)生什么?
我們來看下圖WRITE(k,v)部分的代碼,假設你先進行delete操作,然后再將要寫入的數(shù)據(jù)發(fā)送給數(shù)據(jù)庫。此處(下圖筆尖處),如果有另一個client讀取了同一個key所對應的數(shù)據(jù),此時就會發(fā)生緩存未命中的情況,它們會從數(shù)據(jù)庫中接收到舊數(shù)據(jù),接著,它們會將該數(shù)據(jù)插入memcache。當你去更新這個數(shù)據(jù)時,memcache中的過時數(shù)據(jù)還會被保留一段時間,接著,如果這個進行寫操作的client再次讀取了這個數(shù)據(jù),它可能會看到過時的數(shù)據(jù),即使它剛剛更新了數(shù)據(jù)。
實際上的write操作我們是在第二步的時候執(zhí)行了delete操作(下圖WRITE左側的代碼)。有人可能會在這段時間內讀取數(shù)據(jù),他們所看到的數(shù)據(jù)都是過時的。但它們并不擔心看到的是過時數(shù)據(jù),在這個情況下,他們最關心的是client讀取它們自己所做的寫操作的值。雖然這里存在著一致性問題,我這里第二步所做的delete操作是為了確保client能讀取到它們自己寫操作所更新后的值。不管在哪種情況下,數(shù)據(jù)庫服務器最終會將一個與寫入key相關的delete操作發(fā)送給memcache。
總結:為什么需要delete?主要是client更新后能馬上讀到它自己修改后的最新數(shù)據(jù)
在這里插入圖片描述
8.問題:既然client已經(jīng)知道了新數(shù)據(jù),為什么我們不讓它直接發(fā)一個setRPC給memcache呢,而是使用一個delete操作呢?(下圖左下處的set方法)
這里我們使用了一個失效策略(invalidate scheme),這通常也被叫做更新策略(update scheme)。
在這里插入圖片描述
例子:假設Client1向數(shù)據(jù)庫發(fā)送命令,把x值從0變成1(下圖第一行C1處)。之后,Client1會調用set命令(下圖左下C1處)傳入x和它的值1,并將結果寫入memcacheD。
此時Client2也想增加x的值,它會從數(shù)據(jù)庫中讀取最新的值。為保證正確性,client就會將一個用于增加x值的事務發(fā)送給數(shù)據(jù)庫,因為數(shù)據(jù)庫支持事務。假設Client2將數(shù)據(jù)庫中的x的值設置到2,之后Client2也會去執(zhí)行這個set操作(下圖右側C2處),它會將x設置為2。但現(xiàn)在memcacheD中x的值是1,雖然數(shù)據(jù)庫中正確的值是2。
如果我們使用這個set操作來更新memcache的數(shù)據(jù)(如下圖左側C1),雖然它確實能避免以后有人請求這個數(shù)據(jù)時緩存未命中的情況。但我們會冒著這種風險,即數(shù)據(jù)庫中熱門數(shù)據(jù)的值是過時的(因為網(wǎng)絡的因素,set(x,1)可能比set(x,2)要后執(zhí)行,所以會產(chǎn)生過時垃圾數(shù)據(jù))。這就是他們使用失效策略而不是去使用更新策略的原因了。
在這里插入圖片描述

五、Cache Policy

1.memcache 的 cache policy 可以用 2 個詞概括:
demand-filled look-aside (read) 按需后備
write-invalidate (write)
在這里插入圖片描述
讀請求:首先從memcache查詢數(shù)據(jù)。如果cache里沒有數(shù)據(jù),就從后臺的database獲取數(shù)據(jù),并把key-value pair更新到cache中。
寫請求:首先對database進行修改,然后向cache發(fā)送請求,invalidate之前的舊數(shù)據(jù)。
采用 write-invalide 的主要原因有兩個:

  • 刪除操作冪等,當任何異常發(fā)生時可以重試
  • write-invalidate 與 demand-filled 在語義上是天作之合

2.首先緩存是加速讀取,同時保護DB過載。MEMCACHE是一個look aside的CACHE,也就是說CACHE對DB無感知,不知道DB存了什么,他存的東西和DB什么關系,這一切都通過應用層CLIENT來控制。還有一種CACHE是LOOK THROUGH,就是DB負責來維護這個CACHE。

六、In a Cluster : Latency and Load

本節(jié)探討在一個集群內部部署上千個 memcached 服務遇到的挑戰(zhàn)和相應的解決方案。在這個規(guī)模上,系統(tǒng)優(yōu)化的主要精力集中在如何減少獲取緩存數(shù)據(jù)的時延 (latency),抵抗 cache miss 時造成的負載壓力 (load)。

(一)Reducing Latency

1、緩存層擴容,FB 采用的是一種常見的擴容方案:部署多個 memcached 服務,形成單個緩存集群,并通過 consistent hashing 將緩存數(shù)據(jù)散列在不同的 memcached 實例上。
(總結:memcache的分片)
2.扇出 Fanout
在 FB 的服務中,載入一個熱門的網(wǎng)頁平均需要從 memcache 中獲取 521 條不同的數(shù)據(jù),如果出現(xiàn) cache miss 則需要從持久化存儲中獲取數(shù)據(jù),這些數(shù)據(jù)讀取請求的時延都將影響到服務的質量。通常不同數(shù)據(jù)的讀取之間存在一定的先后依賴關系,可以表示成一個有向無環(huán)圖 (DAG),如下圖所示:
在這里插入圖片描述
我們稱這種放射狀的數(shù)據(jù)讀取模式為 fanout。

3.面對 high fanout,memcache 集群首先要面對的問題就是 all-to-all communication。由于緩存數(shù)據(jù)被散列到不同的 memcached 實例上,每個 web server 都可能需要與所有 memcached 服務通信:

  • 由于 fanout 的存在,處理每個請求需要各個 web server 從多個 memcached 實例上獲取數(shù)據(jù),如果這些數(shù)據(jù)在短時間內忽然到來,可能造成網(wǎng)絡擁堵,即 incast congestion 由于每個 memcached。
  • 實例都持有一部分數(shù)據(jù),這使得每個實例在高負載下都有可能成為服務瓶頸。

4.客戶端的優(yōu)化手段包括:

  • 請求優(yōu)化(Parallel requests and batching)
  • 通信連接優(yōu)化(Client-server communication)
    • client-server通信
    • 傳輸層連接

5.請求本身的優(yōu)化主要是parallel并行化以及batching合并
Parallel requests and batching
簡而言之就是要減少網(wǎng)絡上的round trips次數(shù)
要實現(xiàn)這一目的可以把數(shù)據(jù)間的依賴調整為一個DAG圖,由于并不存在環(huán),因此可以并行發(fā)出請求——parallel并行化
同時在必要時合并多個請求,按照經(jīng)驗可以合并24個key——batching合并
(并行、打包請求memcache)

6.Client-server communication
(1)在通信層面上,memcached server間互不通信,facebook希望把所有復雜實現(xiàn)下放到無狀態(tài)的客戶端
client通過一個mcrouter的代理與server通信,即web server連接client(proxy)即可,proxy接口仍然保持和memcached server一致,這樣避免了單個web server直連多個memcached server。
在緩存層上,FB 的主要思路就是將控制邏輯集中到 memcache client 上。memcache client 分成兩部分:sdk 與 proxy,后者被稱為 mcrouter。mcrouter 向外暴露與 memcached 相同的接口,在 web server 與 memcached server 之間增加一層抽象。

(2)在傳輸層上,連接嘗試盡可能通過使用UDP來減少overhead。
考慮到對數(shù)據(jù)錯誤容忍度高,memcached client的get請求使用UDP與memcached服務器通信,減少了創(chuàng)建和維護連接帶來的開銷。一旦出現(xiàn)丟包或者亂序包,client會將其作為異常處理,即視作cache miss,get請求會被重傳到數(shù)據(jù)庫,論文中提到系統(tǒng)在高峰期也只有0.25%的請求會被丟棄。為了可靠性,對于set和delete,則是通過可靠的TCP通信
圖3 web server與memcached的通信示意圖

  • web server client使用UDP(見圖3)繞過mcrouter直接向memcached實例get數(shù)據(jù),以實現(xiàn)低通信延遲。
  • mcrouter負責set和delete請求(見圖3),和web server結對部署,使用TCP和需要通信的memcached建立長連接。這樣設計是因為set和delete請求需要TCP的可靠重試,以及不需要每個web server thread都和memcached直接建立長連接,由mcrouter統(tǒng)一接管減少長連接數(shù)量可節(jié)省CPU、內存、帶寬。

7.Incast congestion
對于Incast congestion問題,memcached的client實現(xiàn)了類似TCP的擁塞控制邏輯,根據(jù)網(wǎng)絡情況控制滑動窗口。
相比TCP不同在于來自同一個web server的請求會放入到同一個窗口(而不是維護單連接的窗口):當超出窗口范圍時,主動拒絕響應,避免級聯(lián)壓垮server.

(二) Reducing Load

為了減輕負載,論文提到了三種技術:Leases、Memcache Pools、Replication with int Pools

1.Lease

FB 在 memcache 中通過引入 leases 來解決兩個問題:stale set過期寫入、thundering herds驚群。

(1)stale set 過期寫入

look-aside cache policy 下可能發(fā)生數(shù)據(jù)不一致:
假設兩個前端服務器x 和 y,需要讀取同一條數(shù)據(jù) d,其執(zhí)行順序如下:
a.x 從 memcache 中讀取數(shù)據(jù) d,發(fā)生 cache miss,從數(shù)據(jù)庫讀出 d = A
b.另一個 memcache client 將 DB 中的 d 更新為 B
c.y 從 memcache 中讀取數(shù)據(jù) d,發(fā)生 cache miss,從數(shù)據(jù)庫讀出 d = B
d.y 將 d = B 寫入 memcache 中
e.x 將 d = A 寫入 memcache 中
此時,在 d 過期或者被刪除之前,數(shù)據(jù)庫與緩存內的數(shù)據(jù)將保持不一致的狀態(tài)。引入 leases 可以解決這個問題:
每次出現(xiàn) cache miss 時返回一個 lease id,每個 lease id 都只針對單條數(shù)據(jù)
當數(shù)據(jù)被刪除 (write-invalidate) 時,之前發(fā)出的 lease id 失效
寫入數(shù)據(jù)時,sdk 會將上次收到的 lease id 帶上,memcached server 如果發(fā)現(xiàn) lease id 失效,則拒絕執(zhí)行
注:lease解決過期寫入的問題例子見本文第九部分

(2) Thundering herds 驚群

前端服務器對熱門key執(zhí)行write操作時,在刪除memcache中熱門key和再次寫回的空隙時間內,多個訪問該熱門key的前端服務器對DB的請求可能導致成千上萬個請求同時發(fā)生 cache miss,從而重擊 DB,這就是驚群效應(Thundering herd)。通過擴展 lease 機制可以解決這個問題。每個 memcached server 都會控制每個 key 的 lease 發(fā)放速率。默認配置下,每個 key 在 10 秒內只會發(fā)放一個 lease,余下訪問同一個 key 的請求都會被告知要么等待一小段時間后重試或者拿過期數(shù)據(jù)走人。通常在數(shù)毫秒內,獲得 lease 的 web server 就會將數(shù)據(jù)寫入memcache,這時其它 client 重試時就會成功,整個過程只有一個請求會穿透到 DB。
(總結:當cache miss時,同一個key只有第一個拿到lease的請求可以到數(shù)據(jù)庫)
在這里插入圖片描述
在這里插入圖片描述
如果拿到lease的前端服務器發(fā)生了故障,它并沒有向數(shù)據(jù)庫請求數(shù)據(jù),或者并沒有將數(shù)據(jù)插入memcached緩存,那么memcached最終會刪除這個lease,因為它超時了。接著,下一個訪問memcache的前端服務器會拿到一個新的lease,它會和數(shù)據(jù)庫進行通信,并往memcache中插入新的數(shù)據(jù)。

2. MemcachePools

所謂的池,指的其實是資源的分區(qū),對于數(shù)據(jù)中的不同的訪問模式,根據(jù)模式進行資源分區(qū)。例如緩存未命中的代價小,但是訪問頻次高的鍵放入一個小池,緩存未命中代價高,但訪問頻次低的鍵放入一個大池。

(三)Handling Failures

如果整個數(shù)據(jù)中心出現(xiàn)大面積問題,FB 會將用戶請求直接轉移到另一個數(shù)據(jù)中心;
如果只是少數(shù)幾個memcache server 因為網(wǎng)絡原因失聯(lián),則依賴于一種自動恢復機制,通?;謴托枰獛追昼姇r間,但幾分鐘就有可能將 DB 和后臺服務擊垮。為此, FB 團隊專門用少量的機器配置一個小的 memcache 集群,稱為 Gutter。當集群內部少量的 server 發(fā)生故障時,memcached client 會將請求先轉發(fā)到 Gutter 中。除了在memcache服務器出現(xiàn)故障的情況下,這些GutterServer都處于閑置狀態(tài)。

Gutter 與普通的 rehash 不同,后者將失聯(lián)機器的負載轉嫁到了剩余的 server 上,可能造成雪崩效應/鏈式反應。

當前端服務器收到一個錯誤,說它們無法和memcache服務器進行通信,它會將相同請求再發(fā)給其中一個GutterServer。前端服務器會對key進行hash以此來選擇它要和哪個Gutter Server進行通信(論文中未說明)。如果這個GutterServer上保存著對應的數(shù)據(jù),前端服務器就會和數(shù)據(jù)庫服務器進行通信來讀取數(shù)據(jù),并將該數(shù)據(jù)放入memcache服務器(GutterServer),萬一其他人也去獲取相同的數(shù)據(jù),那就可以直接從memcache服務器處獲取了。所以,當memcache服務器發(fā)生了宕機,簡單來講,這些GutterServer就會去處理原本由這個memcache服務器所處理的請求。這里會發(fā)生緩存未命中的情況(因為剛開始時GutterServer是空的),可能出現(xiàn)的驚群問題會由lease機制來解決。
有一個問題,前端服務器應該不會將delete操作發(fā)送給這些GutterServer。因為GutterServer可以去接手一個或多個已經(jīng)掛掉的memcache服務所處理的請求,實際上,它可以去緩存任何key所對應的數(shù)據(jù)。這意味著當一個前端服務器需要從memcache中刪除一個key所對應的數(shù)據(jù)時,或者數(shù)據(jù)庫中的mcsqueal發(fā)送了一個delete操作給保存著某個key相關數(shù)據(jù)的memcache服務器,它也會將這個delete操作的副本發(fā)送給每一個GutterServer。即它們會將數(shù)據(jù)從memcache服務器中刪除,它們也得從GutterServer中刪除這些數(shù)據(jù),這會使必須要發(fā)送的delete操作的數(shù)量增加一倍。實際上,他們對GutterServer進行了一些處理,這樣他們就能快速刪除這些key的相關數(shù)據(jù),而不是等到顯式刪除它們的時候才去刪除。這就是這個問題的答案。
(Gutter中的數(shù)據(jù)有效期很短,這樣避免了需要使緩存失效的操作。)
在這里插入圖片描述

七、In a Region: Replication

隨著用戶的訪問量繼續(xù)增大,你可能會想要購買更多的機器來部署 web server 和 memcached server,實現(xiàn)橫向擴容。然而簡單地橫向擴容不能解決所有問題。越來越多的用戶會將原本不嚴重的問題暴露出來:

  • 用戶增多會導致熱點數(shù)量增多、單個熱點熱度增大
  • 由于 memcached client 需要與所有 memcached server 通信,incast congestion 問題會更嚴重

因此有必要將 memcached servers 分成多個集群,將熱點問題和網(wǎng)絡問題分而治之。多個集群將繼續(xù)共享同一個 DB 集群:
在這里插入圖片描述

(一)Regional Invalidations

部署多個 memcached server 集群,同一條數(shù)據(jù)的不同版本可能會出現(xiàn)在不同集群上。一種簡單的解決方案是讓 web server 每次發(fā)生 cache miss 時,將所有集群中的對應數(shù)據(jù)刪除。顯然這會造成大量的跨集群通信,又重新引發(fā)了網(wǎng)絡問題。
既然數(shù)據(jù)在 DB 中只有一份,何不利用 DB 數(shù)據(jù)的更新日志來保證數(shù)據(jù)在不同集群間的最終一致性?
在這里插入圖片描述
FB 在持久化層中使用 MySQL 集群,于是它們順著思路開發(fā)了 mcsqueal 中間件,并將其部署到每個 MySQL 集群上。mcsqueal 負責讀取 MySQL 的 commit log,解析其中的 SQL 語句,捕獲數(shù)據(jù)更新信息,并將其廣播給所有 memcached 集群。
在這里插入圖片描述
從架構圖中,不難看出 fanout 問題再次出現(xiàn),大量的跨集群通信數(shù)據(jù)同樣可能將網(wǎng)絡打垮。解決方案也不難想到,即分而治之
在這里插入圖片描述
一個區(qū)域內部部署多個 memcache 集群能夠給我們帶來諸多好處,除了緩解熱點問題、網(wǎng)絡擁堵問題,還能讓運維人員方便地下線單個節(jié)點、集群,而不至于使得 cash miss rate 忽然增大。

(二) Regional Pools

在同一個region中的不同集群之間,數(shù)據(jù)進行了復制。但是一些不太熱門的數(shù)據(jù),其多副本放在內存中是一種浪費。所以每個集群內除了memcache服務器池以外,還會有一個放著memcache服務器的regional pool,它會被該區(qū)域中所有集群所共享。前端軟件進行修改,當前端服務器上所運行的軟件知道這個key所對應的數(shù)據(jù)的使用頻率不高,就不會將這些數(shù)據(jù)保存在本集群中的memcache服務器里,而是放在這個regional pool(下圖REG. POOL)中合適的memcache服務器上。
在這里插入圖片描述
(總結:regional pool所有集群共享一份的memcache,放一些不熱門的數(shù)據(jù),不必提供多塊復制)

(三)Cold Cluster Warmup

上線新的 memcache 集群時,如果不預熱可能會出現(xiàn)大量 cache miss(因為一開始緩存是空的)。FB使用了一種cold start的思想,當新集群處于cold start狀態(tài)時,我們會給它做一個標記。在這種情況下,當新集群中的前端服務器遇到緩存未命中的情況,首先,前端服務器會去訪問該集群本地的memcache服務器,如果該memcache服務器表示它上面沒有前端服務器所要的這個數(shù)據(jù),那么前端服務器就會跑去另一個集群中對應的memcache服務器(warm cluster)那里獲取數(shù)據(jù),如果有前端服務器就會拿到數(shù)據(jù)并將該數(shù)據(jù)放入它所在集群中的本地memcache服務器中。只有當本地memcache服務器,以及warm memcache服務器中沒有它所要的數(shù)據(jù)時,新集群中的這個前端服務器才會從數(shù)據(jù)庫服務器中讀取數(shù)據(jù)。集群會在這種cold mode下運行一段時間直到新集群中的memcache服務器中緩存了所有熱門數(shù)據(jù)為止。然后就可以關閉這種cold mode,直接獨立使用該集群本地的memcache服務器即可。
(總結:新集群上線時,memcache中為空,使用cold start思想,標記新集群,memcache未命中時,去另外集群的memcache獲取,再找不到再去DB)

八、Across Regions: Consistency

1.memcache 服務也需要能夠被部署到多個區(qū)域。利用 MySQL 的復制機制,FB 將一個區(qū)域設置為 master 區(qū)域,而其它區(qū)域為只讀區(qū)域,負責從 master 中同步數(shù)據(jù)。web servers 處理讀請求時只需要訪問本地的 DB 或緩存服務即可。
在這里插入圖片描述
2.但這里將產(chǎn)生一個新的問題:只讀區(qū)域的數(shù)據(jù)庫有同步延遲,可能導致競爭條件出現(xiàn)。想象以下這個場景:
在這里插入圖片描述
①復制集群中的 web server A 寫入數(shù)據(jù)到 master DB
②A 將本地 memcache 中的數(shù)據(jù)刪除
③復制集群中的 web server B 從 memcache 中讀取數(shù)據(jù)發(fā)生 cache miss,從本地 DB 中獲取數(shù)據(jù)
④A 寫入的數(shù)據(jù)從 master DB 中同步到 replica DB,并通過 mcsqueal 將本地 memcache 中的數(shù)據(jù)刪除 ?
⑤web server B 將其讀到的數(shù)據(jù)寫入 memcache 中

3.此時,DB 與 memcache 中的數(shù)據(jù)將再次出現(xiàn)不一致,且必須等待數(shù)據(jù)過期之后才能恢復。如何解決這個問題?FB 在 memcache 上引入 remote marker 機制:
在這里插入圖片描述
當 replica 區(qū)域的 web server 需要寫入某數(shù)據(jù) d 時:
①在本地 memcache 上打上 remote marker
②將 d 寫入到 master DB 中
③將 d 從 memcache 中刪除 (remote marker 不刪除)
④等待 master DB 將數(shù)據(jù)同步到本地 replica DB 中,并且在 SQL 語句中埋入remote marker的信息
⑤本地 replica DB 通過 mcsqueal 解析 SQL 語句中,刪除 remote marker

4.當 replica 區(qū)域的 web server 想要讀取數(shù)據(jù) d 發(fā)生 cache miss 時:
如果 memcache 中數(shù)據(jù) d 帶了 remote marker,則從 master DB 中讀取數(shù)據(jù)
如果 memcache 中數(shù)據(jù) d 沒有remote marker,則直接從本地的 replica DB 中讀取數(shù)據(jù)

5.remote marker 機制實際上就是標記了 數(shù)據(jù)寫入 master DB 但尚未同步到 replica DB 的中間狀態(tài)。

九、memcache的一致性

1.一致性問題在于DB中的數(shù)據(jù)存在著很多個副本(主數(shù)據(jù)庫、副數(shù)據(jù)中心數(shù)據(jù)庫、每個集群的memcache服務器、Gutter Server)。
當有一個寫操作傳入的時候,這個寫操作要應用到相關數(shù)據(jù)的所有這些副本上。此外,這些寫操作可能來源于多個地方,在同一時間,可能會有多個前端服務器對同一個key所對應的數(shù)據(jù)進行寫入。這些寫操作可能來自于不同區(qū)域的前端服務器。由于并發(fā)、多副本以及來自多個前端服務器所做的寫操作等原因,這就會導致讓過時的數(shù)據(jù)停留在系統(tǒng)中很長一段時間。

2.之前的問題:為什么前端服務器使用的是delete操作而不是update,這是因為多個數(shù)據(jù)源所導致的。我們在執(zhí)行正確操作順序的時候遇上了問題。這里我們來看個關于update race的案例(即并發(fā)更新操作所產(chǎn)生的問題)如果它們沒有做任何處理,那么memcache中的數(shù)據(jù)肯定是過時的數(shù)據(jù)。
假設有個Client1想去讀取某個key所對應的數(shù)據(jù),但memcache表示它里面并沒有這些數(shù)據(jù)。C1就會從數(shù)據(jù)庫中讀取數(shù)據(jù),假設它取回的值是v1。與此同時,C2想對該數(shù)據(jù)進行更新,C2會將要修改的數(shù)據(jù)(V2)傳入這個write操作,并發(fā)送給數(shù)據(jù)庫。C2要做的另一件事情就是將原來的數(shù)據(jù)從memcache中刪除,數(shù)據(jù)庫也會將key所對應的數(shù)據(jù)從memcache中刪除,paper中說過delete操作是冪等的,所以delete始終是安全的。
如果你遇上緩存未命中的情況,那你就會從數(shù)據(jù)庫中讀取數(shù)據(jù),接著,你會將讀取到的數(shù)據(jù)插入memcache中。假設C1的速度比較慢,它會發(fā)送一個setRPC給memcache服務器,它之前所讀取到的是版本1時的值(過時)并將這個值放入了memcache中。這里所發(fā)生的另一件事情就是,當你要往數(shù)據(jù)庫中寫入數(shù)據(jù)時,數(shù)據(jù)庫會往memcache中發(fā)送delete操作。此時,數(shù)據(jù)庫會發(fā)送一個delete(k)操作給memcache(下圖右側DB的delete(k))?,F(xiàn)在我們有兩個delete操作(一次DB一次C2),但這并沒有關系。當C1去更新該key所對應的數(shù)據(jù)時,這些delete操作可能就已經(jīng)執(zhí)行完了。所以,此時,memcache緩存的一直是該數(shù)據(jù)的過時版本。如果系統(tǒng)是以這種方式工作的,那么沒有任何機制能讓memcache拿到的是正確的值,它所保存并向前端服務器提供的(與k相關的)數(shù)據(jù)始終是過時的。
(總結:C1執(zhí)行的慢,向memcache執(zhí)行set操作在C2的delete之后,導致過期數(shù)據(jù)一直在mamcache中,直到下次修改)
在這里插入圖片描述
3. 他們實際上通過lease機制解決了這個問題,即之前在驚群問題時所討論過的lease機制。當memcache告訴我們,緩存中沒有我們要的數(shù)據(jù)時(緩存未命中),它就會頒發(fā)lease。client就會拿到這個miss指示,以及這個lease(這個lease是一個很大的數(shù)字,并且它是唯一的)。memcache服務器會去記住這個lease和這個key之間的關系,它知道拿著這個lease的人,才有資格去更新這個key所對應的內容。
這里的新規(guī)則是這樣的,當memcache服務器從另一個Client或者數(shù)據(jù)庫那里收到一個delete操作時,它除了會刪除這個數(shù)據(jù)以外,它還會使之前頒發(fā)的lease失效。所以,不管是哪個delete先到達memcache那里,memcache服務器會將這個lease從它的表中刪除。這個set操作會攜帶前端服務器所拿到的lease,當這個set操作到達memcache服務器時,memcache會去查看這個lease,如果這個lease對于這個key來說是失效的,memcache會將這個set操作忽略。如果其中一個delete操作在這個set操作之前到達memcache,它就會看到這個lease是失效的,memcache服務器就會將這個set操作給忽略。這就意味著,這個key所對應的數(shù)據(jù)并沒有放在memcache中,下一個試著讀取這個key的client就會遇上緩存未命中的情況,它就會從數(shù)據(jù)庫中讀取到最新的數(shù)據(jù),并將該數(shù)據(jù)放入memcache中,第二個reader所拿著的lease就會是有效的。
如果發(fā)生的順序改變,那么會發(fā)生什么呢?假設這些delete操作是在set操作之后才發(fā)生的,這種方案依然有效。此時,memcache服務器并不會將這個lease從lease表中刪除,當這個set操作到達memcache的時候,這個lease依然是有效的。那么它會接受這個set操作,即我們會將該key的值設置為一個過時的數(shù)據(jù)(V1)。但我們所做的假設是,此時的delete操作是在set之后發(fā)生的,當
這些delete操作到達memcache
時,那么這個過時的數(shù)據(jù)就會從緩存中清除出去。這些過時數(shù)據(jù)呆在緩存中的時間會有點長,但我們不希望遇上這種情況:即過時的數(shù)據(jù)一直呆在緩存中,從來沒有被刪除。
在這里插入圖片描述

十、總結

該系統(tǒng)存在著大量的復雜性,因為它是由彼此并不了解的部分所拼接起來的。memcache承擔了某些數(shù)據(jù)庫方面的事情,所以需要一種一致性方案來讓它們一起協(xié)調工作。我們從這篇paper中所學到的其中一點是,對于那些大型操作來說,緩存是至關重要的,它能讓我們的系統(tǒng)從高負載的情況下存活下來。對于降低延遲這方面來說,緩存并不是那么有幫助,它更多還是關于將那些高負載工作盡量對那些速度相對較慢的存儲服務器屏蔽。Facebook通過緩存來避免讓數(shù)據(jù)庫直面這些負載。
我們從中學到的另一個東西是,在大型系統(tǒng)中,你一直得去思考緩存、分區(qū)以及replication的問題。你得需要某種方式來決定在分區(qū)這塊你要投入多少資源,replication這塊你又要投入多少資源。最后,在這篇paper中,你能夠學會以更好的方式來整合不同的存儲層,以此獲取良好的一致性。(怎么選擇復制、分區(qū),以及他們的整合和資源分配)

http://m.risenshineclean.com/news/60974.html

相關文章:

  • 動態(tài)ip上做網(wǎng)站網(wǎng)絡軟文是什么意思
  • 做網(wǎng)站 做好把我踢開長沙百度網(wǎng)站排名優(yōu)化
  • 建設網(wǎng)站需要哪些人獨立站seo推廣
  • 珠海市城市建設檔案館網(wǎng)站seo優(yōu)化標題 關鍵詞
  • 我國現(xiàn)在疫情防控現(xiàn)狀搜索引擎優(yōu)化公司排行
  • 網(wǎng)站建設常見問題及解決辦法廈門網(wǎng)站建設
  • 攝影網(wǎng)頁設計方案win7優(yōu)化設置
  • 怎么創(chuàng)辦自己的網(wǎng)站云搜索網(wǎng)頁版入口
  • 設計好看的美食網(wǎng)站有哪些百度廣告投放收費標準
  • 寧國市有做網(wǎng)站推廣賺傭金項目
  • 戈韋思網(wǎng)站建設優(yōu)化網(wǎng)站推廣教程排名
  • 上海網(wǎng)站建設公司四葉互聯(lián)網(wǎng)站運營工作的基本內容
  • 張家界網(wǎng)站建設多少錢大連網(wǎng)站排名推廣
  • 手機網(wǎng)站解析天津百度網(wǎng)站排名優(yōu)化
  • 我愛做媽媽網(wǎng)站磁力天堂
  • 黃山旅游攻略一日游最佳路線排名seo怎么樣
  • 網(wǎng)站難做嗎推動高質量發(fā)展
  • 南聯(lián)網(wǎng)站建設哪家好seo是什么意思新手怎么做seo
  • 高端網(wǎng)站建設深圳寧德市屬于哪個省份
  • 網(wǎng)站方案策劃怎么寫免費網(wǎng)站推廣軟件下載
  • 怎么樣提高網(wǎng)站點擊率高明公司搜索seo
  • 上海城鄉(xiāng)建設網(wǎng)站如何制作一個屬于自己的網(wǎng)站
  • 接單做效果圖網(wǎng)站域名查詢訪問
  • 企業(yè)營銷型網(wǎng)站做的好小程序推廣方案
  • 小企業(yè)網(wǎng)站建設的措施群站優(yōu)化之鏈輪模式
  • 網(wǎng)站開發(fā)流程詳細介紹日本櫻花免m38vcom費vps
  • 網(wǎng)站后臺功能開發(fā)seo網(wǎng)站分析工具
  • 聯(lián)合實驗室 網(wǎng)站建設方案seo網(wǎng)站地圖
  • 什么企業(yè)做網(wǎng)站網(wǎng)站點擊快速排名
  • wordpress上傳圖片x整站優(yōu)化關鍵詞推廣