1. 程式人生 > >快取和資料庫重新整理的順序 及阿里OCS介紹

快取和資料庫重新整理的順序 及阿里OCS介紹

OCS概要介紹

據AlertSite網路分析公司表示,Facebook的響應時間在2010年平均為1秒鐘,到2011年中期已提高到了0.73秒。對比來看,響應時間佔第二位的LinkedIn,網路下載內容時要花費將近2倍的時間。Twitter的響應時間則整整遲了2秒鐘。響應時間優化的首要手段就是採用快取技術,減少系統間互動請求和磁碟IO。

OCS是阿里巴巴集團的分散式快取產品,支撐著淘寶、阿里巴巴、支付寶的日常運作,尤其在雙11等大型活動上,承載了絕大多數的資料請求。與OCS相比,著名的Memcached具備了分散式叢集管理的功能。2014年OCS經歷了從分散式到雲服務的進化,作為阿里雲服務的快取產品正式商業化。

OCS技術講解

OCS的核心儲存是淘寶的開源產品TAIR(發音:太愛兒)

TAIR原理

角色上分為DataServer,ConfigServer:

  1. ConfigServer負責資料的路由表管理,決定著哪些資料應該去哪裡訪問。同時也管理著DataServer節點的存活狀態,自動踢出宕機或者異常節點。
  2. DataServer是資料儲存節點,負責資料的增刪改查。通過Plugin機制支援多種儲存引擎。常用的有基於記憶體的,所有的資料儲存在記憶體之中,查詢速度快,但不持久化,網路正常的情況下,客戶端在0.2ms內得到請求響應。另外一種常用儲存引擎基於SSD介質再依靠記憶體加速,特點是容量大,成本低,效能上接近記憶體引擎,客戶端請求響應時間大概是1ms。

叢集初始化時ConfigServer會根據DataServer的數量分配BucketID到DataServer上,這層對映關係就是資料路由索引,BucketID屬於[0-1023]的範圍內。客戶端第一次啟動時會從ConfigServer上拉取對映關係,之後的讀寫請求,根據全域性約定的Hash演算法(例如MurmurHash(key)24)計算出BucketID,根據對映關係描述向指定的DataServer上傳送請求。

ConfigServer上的路由資訊會根據DataServer存活狀況動態修改更新;新結果再告知給DataServer;當DataServer處理客戶端響應時,將變更通知給客戶端。


圖1 路由路徑

從TAIR到OCS

雲服務化的過程中,首要問題是滿足使用者的相容性需求,使用者訪問介面上支援廣泛流行的Memcached介面,原生於Memcached的應用,可以無縫遷移到OCS上來。

其次是穩定性,叢集升級時,由於程序重啟會造成應用請求OCS瞬間報錯,OCS實現了一套熱升級方案,在保持TCP連結不中斷的情況下重啟程序。

雲服務還有一個重要特性就是多租戶,多租戶的情況下,為了防止某一兩個使用者的高併發訪問造成叢集負載上升,從而影響了其他租戶的穩定性。OCS內部對不同的租戶進行了資源隔離,針對請求量、頻寬、記憶體使用量做了嚴格的限制。不同規格的使用者可以購買不同規格的OCS例項,之間不會互相干擾。

與OCS相比,自建的Memcached解決了單機容量上線問題,實現擴容自動化且不需要修改客戶端配置,同時輸出了效能監控指標,網頁版Console命令等。

快取失效一致性問題

一般快取的使用方式是:先讀取快取,若不存在則從DB中讀取,並將結果寫入到快取中;下次資料讀取時便可以直接從快取中獲取資料。

資料的修改是直接失效快取資料,再修改DB內容,避免DB修改成功,但由於網路或者其他問題導致快取資料沒有清理,造成了髒資料。

但這樣仍然無法避免髒資料的產生,一種併發的場景下:假設業務對資料Key:Hello Value:World有大量的讀取和修改請求。執行緒A向OCS讀取Key:Hello,得到Not Found結果,開始向DB請求資料,得到資料Key:Hello Value:World;接下來準備向OCS寫入此條資料,但在寫入OCS前(網路,CPU都等可能導致A執行緒處理速度降低)另一B執行緒請求修改資料Key:Hello Value:OCS,首先執行失效快取動作(因為B執行緒並不知道是否有此條資料,因此直接執行失效操作),OCS成功處理了失效請求。轉回到A執行緒繼續執行寫入OCS,將Key:Hello Value:World寫入到快取中,A執行緒任務結束;B執行緒也成功修改了DB資料內容為Key:Hello Value:OCS。


圖2 併發時序

此時OCS中的資料為Key:Hello Value:World;DB中的資料為Key:Hello Value:OCS,出現快取髒資料!

為了解決這個問題,OCS擴充了Memcached協議(公有云即將支援),增加了deleteAndIncVersion介面。此介面並不會真的刪除資料,而是給資料打了標籤,表明已失效狀態,並且增加資料版本號;如果資料不存在則寫入NULL,同時也生成隨機資料版本號。OCS寫入支援原子對比版本號:假設傳入的版本號與OCS儲存的資料版本號一致或者原資料不存在,則准許寫入,否則拒絕修改。

回到剛才的場景上:執行緒A向OCS讀取Key:Hello,得到Not Found結果,開始向DB請求資料,得到資料Key:Hello Value:World;接下來準備向OCS寫入此條資料,版本號資訊預設為1;在A寫入OCS前另一個B執行緒發起了動作修改資料Key:Hello Value:OCS,首先執行刪除快取動作,OCS順利處理了deleteAndIncVersion請求,生成了隨機版本號12345(約定大於1000)。轉回到A執行緒繼續執行寫入OCS,請求將Key:Hello Value:World寫入,此時快取系統發現傳入的版本號資訊不匹配(1 != 12345),寫入失敗,A執行緒任務結束;B執行緒也成功修改了DB資料內容為Key:Hello Value:OCS。

此時OCS中的資料為Key:Hello Value:NULL Version:12345;DB中的資料為Key:Hello Value:OCS,後續讀任務時會再次嘗試將DB中的資料寫入到OCS中。

類似的併發場景還有很多,讀者可以自行推演,同時也可以思考下為何約定隨機生成的版本要大於1000?

快取資料的同步的一致性問題

隨著網站規模增長和可靠性的提升,會面臨多IDC的部署,每個IDC都有一套獨立的DB和快取系統,這時快取一致性又成了突出的問題。

首先快取系統為了保證高效率,會杜絕磁碟IO,哪怕是寫BINLOG;當然快取系統為了效能可以只同步刪除,不同步寫入,那麼快取的同步一般會優先於DB同步到達(畢竟快取系統的效率要高得多),那麼就會出現快取中無資料,DB中是舊資料的場景。此時,有業務請求資料,讀取快取Not Found,從DB讀取並載入到快取中的仍然是舊資料,DB資料同步到達時也只更新了DB,快取髒資料無法被清除。


圖3 併發時序

從上面的情況可以看出,不一致的根本原因是異構系統之間無法協同同步,不能保證DB資料先同步,快取資料後同步。所以就要考慮快取系統如何等待DB同步,或者能否做到兩者共用一套同步機制?快取同步也依賴DB BINLOG是一個可行的方案。

IDC1中的DB,通過BINLOG同步給IDC2中的DB,此事IDC2-DB資料修改也會產生自身的BINLOG,快取的資料同步就可以通過IDC2-DB BINLOG進行。快取同步模組分析BINLOG後,失效相應的快取Key,同步從並行改為序列,保證了先後順序。

這樣,IDC間的資料同步架構更加簡單清晰,系統服用率高,做好BINLOG同步和抓取即可。


圖4 異地同步

總結

不同系統之間的資料同步一直是一個世界性的問題,目前仍然沒有方法解除CAP魔咒,只能根據實際的情況在三者之間尋找理想的平衡點。本文介紹的解決方案,其一是利用了快取系統的原子操作,其二是利用了外部系統同步機制保證先後,都是在犧牲最小的效能代價時獲取最大的一致性保證,但仍然無法覆蓋全部場景下的一致性問題。

作者:楊成虎

作者簡介:花名葉翔,阿里巴巴集團技術專家,擅長通過NoSQL儲存系統、Cache系統去解決海量資料的網際網路問題。2009年加入阿里巴巴,先後開發了阿里的小檔案系統,KV儲存系統,負責阿里Tair系統的開發與架構設計。2013年至今主導研發了阿里雲分散式快取服務OCS,目前仍致力於NoSQL產品的雲服務化工作。

原文:

相關推薦

快取資料庫重新整理順序 阿里OCS介紹

OCS概要介紹 據AlertSite網路分析公司表示,Facebook的響應時間在2010年平均為1秒鐘,到2011年中期已提高到了0.73秒。對比來看,響應時間佔第二位的LinkedIn,網路下載內容時要花費將近2倍的時間。Twitter的響應時間則整整遲了2秒鐘。響應時間優化的首要手段就是採用快取技

Redis快取資料庫雙寫一致性問題:

    資料庫與快取讀寫模式策略   寫完資料庫後是否需要馬上更新快取還是直接刪除快取?   (1)、如果寫資料庫的值與更新到快取值是一樣的,不需要經過任何的計算,可以馬上更新快取,但是如果對於那種寫資料頻繁而讀資料少的場景並不合適這種解決方

Redis快取資料庫一致性問題

快取應用和資料庫在更新時經常會出現不一致的問題,採用哪種策略,值得去思考。 從理論上來說,給快取設定過期時間,是保證最終一致性的解決方案。這種方案下,我們可以對存入快取的資料設定過期時間,所有的寫操作以資料庫為準,對快取操作只是盡最大努力即可。也就是說如果資料

Redis使用總結(二、快取資料庫雙寫一致性問題)

首先,快取由於其高併發和高效能的特性,已經在專案中被廣泛使用。在讀取快取方面,大家沒啥疑問,都是按照下圖的流程來進行業務操作。但是在更新快取方面,對於更新完資料庫,是更新快取呢,還是刪除快取。又或者是先刪除快取,再更新資料庫,其實大家存在很大的爭議。目前沒有一篇全面的部落格,

高併發下快取資料庫一致性問題(更新淘汰快取不得不注意的細節)

 快取和資料庫一致性問題本文討論的背景是,cache如memcache,redia等快取來快取資料庫讀取出來的資料,以提高讀效能,如何處理快取裡的資料和資料庫資料的一致性是本文討論的內容:正常的快取步驟是:1查詢快取資料是否存在,2不存在即查詢資料庫,3將資料新增到快取同時返

Android清除快取資料庫等資料

import android.os.Environment; import java.io.File; import java.math.BigDecimal; /** * 清除應用快取 */ public class ClearData { priva

php ci框架 頁面快取資料庫快取

ci中的頁面快取和資料庫快取會以檔案的方式快取資料。 資料庫快取特點: 1.快取檔案永久存在; 2.只對頁面中的資料進行快取,不快取html部分。這意味著可以任意的修改html而不會影響頁面展示效果,相反資料表中有新記錄時該快取也不會更新; 3.可以任意設定哪條sql語句被

ionic頁面快取區域性重新整理

最近兩天在做專案時,發現ionic的快取功能非常方便好用,提高了再低端手機特別是android比較低版本上的流暢性!可是,後來發現,整體的快取整個頁面並不是一個一勞永逸的辦法,結合區域性重新整理功能,感覺就完美極了!建議有一定的ionic基礎。 面, 1.根據想實現快

簡單Java類資料庫操作javafx的結合小專案

先圖為上   秦時明月漢時關,萬里長征人未還,妙呀,甚是..   1.開始 1.專案目的:   開發工具: Idea + Mysql + JAVASE   1.其實簡單來說就是實現兩張資料表的基本操作,     1.新增     2. 刪除     3.修改

springboot中提升資料庫效能-redis快取資料監控

1.最近在看springboot ,簡單做一個記錄 一個很強大的工具 -druid   上圖自己體會吧 關於redis做快取已經很普通了,給程式碼自己體會下 感謝大神:https://github.com/chenfromsz/spring-boot-dbu

Spring Boot Cache + redis 設定有效時間自動重新整理快取,時間支援在配置檔案中配置

分享一下我老師大神的人工智慧教程吧。零基礎,通俗易懂!風趣幽默!http://www.captainbed.net/ 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

MySQL資料庫簡單操作事務索引

分享MySQL資料庫簡單操作及事務和索引的筆記,希望對大家有所幫助。 MySQL資料庫操作:[[email protected] ~]# mysql -u root -p //進入資料庫中 mysql> show databases; //檢視所有資料庫 mysql> use my

Mybatis的一級快取二級快取執行順序

1、先判斷二級快取是否開啟,如果沒開啟,再判斷一級快取是否開啟,如果沒開啟,直接查資料庫 2、如果一級快取關閉,即使二級快取開啟也沒有資料,因為二級快取的資料從一級快取獲取 3、一般不會關閉一級快取 4、二級快取預設不開啟 5、如果二級快取關閉,直接判斷一級快取是否有資料,如果沒有就

順序棧的基本操作(入棧出棧)C語言實現詳解

棧,可以理解為遵循“後入先出”原則的線性表,因此棧結構可以採用順序表或連結串列實現。 順序棧的實現採用的是順序表,也就是陣列。 順序棧的實現思想是:在陣列中設定一個隨時指向棧頂元素的變數(一般命名為 top ),當 top 的值為 -1 時,說明陣列中沒有資料,即棧中沒有資料元素,為“空棧”;只要資料元素

Redis(記憶體快取記憶體資料庫)簡介安裝

一.Redis 1.什麼是Redis Redis是REmote DIctionary Server(遠端資料服務)的縮寫,是一個開源的使用ANSI C語言編寫 它的資料模型為Key-Value資料庫 可持久化,保證資料安全; 2.為什麼可持久化 Redis一邊執行一邊就會把記憶體中的資料

Spring Cloud系列教程 | 第十篇:Spring Cloud Config ServerSpring Cloud Bus以及Kafka資料庫動態重新整理配置

推薦 Spring Cloud 視訊: Spring Cloud Config Server和Spring Cloud Bus以及Kafka和資料庫動態重新整理配置     Spring cloud config server如果不結合Spring cloud

【陌上軒客】技術領域:涉獵Java、Go、Python、Groovy 等語言,高效能、高併發、高可用、非同步與訊息中介軟體、快取資料庫、分散式與微服務、容器自動化等領域; 興趣愛好:籃球,騎行,讀書,發呆; 職業規劃:勵志成為一名出色的伺服器端系統架構師。

陌上軒客 技術領域:涉獵Java、Go、Python、Groovy 等語言,高效能、高併發、高可用、非同步與訊息中介軟體、快取與資料庫、分散式與微服務、容器和自動化等領域; 興趣愛好:籃球,騎行,讀書,發呆; 職業...

Spring Boot快取實戰 Redis 設定有效時間自動重新整理快取,時間支援在配置檔案中配置

問題描述 Spring Cache提供的@Cacheable註解不支援配置過期時間,還有快取的自動重新整理。 我們可以通過配置CacheManneg來配置預設的過期時間和針對每個快取容器(value)單獨配置過期時間,但是總是感覺不太靈活。下面是一個示例: @Bean

JAVA for迴圈執行順序 i++++i的區別

1.i與i++的區別是: ++i  是先執行   i=i+1  再使用 i 的值,而 i++ 是先使用 i 的值再執行 i=i+1。 2.但是如果不瞭解 for 迴圈的執行順序則容易出錯。  for迴圈的執行順序如下: for(sta1;sta2;sta3) {    st

資料庫sequence序列快取記憶體池——儘量減少排隊資料庫的互動

獲取資料庫序列 林小應 1.    問題描述               由於業務需要,應用程式中很多地方會用到資料庫序列sequence,如果每次都去資料庫獲取,會比較耗時。         在Java程式碼中,我們通常呼叫儲存過程或執行sql生