資料庫調研:memcached

pengcheng發表於2018-01-18

複製程式碼

介紹

memcached是高效能多執行緒的分散式快取k-v資料庫。Memcached是記憶體中的鍵值資料庫,用於快取從資料庫呼叫,API呼叫的任意小塊資料(字串,物件)。可以通過快取減輕資料庫或IO的負載,從而增加應用的效能。

核心特徵和原理

  • 分散式

使用一致性hash來進行分散式節點選擇,進行資料均衡和負載均衡。

  • 快取

不持久化。採用LRU(最近最少使用)回收空間。

  • k-v資料庫

功能單一的k-v資料庫。

分散式架構

支援。

使用環形hash空間,對server節點和key都進行hash(32位元的迴圈冗餘校驗(CRC-32)計算鍵值),並且選擇雙方hash值最靠近的server節點。解決普通取模造成大量遷移的情況。

通過對物理節點虛擬更多節點,比如‘10.0.0.0-1~10.0.0.1-n’,解決server過少導致不均衡的問題。如下(擴容前)

資料庫調研:memcached

如下(擴容後)

資料庫調研:memcached

memcached需要在客戶端維護節點列表,並進行業務分發。

快取策略

  • 使用LRU(最近最少使用)回收空間。

LRU(least recently used)最近最少使用。假設 序列為 4 3 4 2 3 1 4 2物理塊有3個 則首輪 4調入記憶體 4次輪 3調入記憶體 3 4之後 4調入記憶體 4 3之後 2調入記憶體 2 4 3之後 3調入記憶體 3 2 4之後 1調入記憶體 1 3 2(因為最少使用的是4,所以丟棄4)之後 4調入記憶體 4 1 3(原理同上)最後 2調入記憶體 2 4 1複製程式碼
  • 支援每個kv對的有效時限。

Kv的儲存有效時限可以在客戶端設定並作為引數傳遞給服務端

  • 偷懶替代法。

服務端採用分類chunk定長記錄,因此刪除記錄可以只做個標記,可以通過覆蓋來回收並複用空間。

  • 比較優秀的記憶體管理

相比redis等,應該有更高的記憶體利用率。

k-v資料庫

功能單一的k-v資料庫。

基本操作

Add
功能:往記憶體增加一條新的快取記錄
Delete
功能:從記憶體刪除一條快取記錄
Get
功能:從記憶體中提取一條快取記錄
Replace
功能:替換記憶體中的快取記錄
Set
功能:設定或者替換記憶體中的快取記錄,相當於add + replace的功能。
複製程式碼

原子操作和事務性策略

支援incr,decr,cas等操作

持久化策略---現狀

不支援。當機會丟失資料

需要配合mysql,mariaDb等進行資料持久化設計。或者memcachedb?效能可能會大大降低。

雖然不能持久化,但是目標單純,功能單一也有優點,可以避免額外設計帶來的問題。比如持久化涉及到io的訪問,有時候系統io的阻塞,可能會導致快取效能受影響。

持久化策略---快取資料一致性策略

  • 查詢策略

先查詢cache,miss時查詢db,並寫入cache。

  • 寫入策略

採用writethrough策略。寫db成功後,失效cache(寫只寫db;更新資料先更新db,再失效cache)

1,writethrough。如果配合高效能儲存。可以先同步到db,如果成功則讓快取失效。(假設刪除快取不會失敗,或極小可能性失敗)。如果刪除快取失敗(cache miss也算成功,其他不可預期失敗算失敗),則回退db操作(此間,快取命中優先從快取讀取資料)。

2,writeback。先寫入(刪除)快取,再寫入db。在高併發的情況,容易出現資料不一致的場景。比如刪除快取後,寫入db成功前,使用者發起讀請求,會導致讀取到舊資料,從而引起資料不一致。

3,readonly。不適用。

  • 其他需要考慮的併發性問題

1,執行緒1查詢cache;執行緒2寫db,並失效cache(非原子,非同步寫db),寫cache

2,事務性問題:一個事務包含多個db操作,db1操作成功,寫cache1成功,寫db2操作失敗,事務回滾,db2資料回滾,cache1無法回滾,導致髒資料。

3,併發性問題:兩個更新操作併發,如更新名字,並且cache中key以名字為關鍵字,更新一寫db成功,寫快取XXXX_name1成功。更新二寫db成功,寫快取XXXX_name2成功。導致cache髒資料。(多讀少寫情況下,考慮樂觀鎖加version解決-類似CAS,如下圖)

資料庫調研:memcached

效能

待測試。

據稱在高速網路下,memcached可以輕鬆處理每秒200,000個以上的請求。並且消耗更少的記憶體。

貌似不支援組合請求,或合併批量處理。

從其他找到的一個測試如下:memcached貌似不如redis。另外20k以上的大資料會導致請求數顯著下降。

資料庫調研:memcached

其他

  • 高可用和冗餘設計

不支援。當機後資料會丟失,需要配合其他設計。

  • 併發策略

多執行緒充分利用多核處理器的優勢。

資料通過一致性hash分片儲存到不同節點。

  • 其他功能

功能較單一。比如只支援單一的資料結構

  • 可維護性

一般

  • 擴充套件設計

一致性hash可以保證擴容或故障時,影響較小的資料。

  • 商業成熟度

比較成熟。很流行,被廣泛使用。

通過memcached的客戶端實現分散式,支援多種語言的客戶端,包括c,java等等。

  • 程式碼量

1.47大概只有1萬行左右。程式碼可讀性不如redis。

  • 開源協議

BSD開源協議

  • 依賴

依賴libevent

擴充套件

原作者開發go的替代版groupcache

https://www.csdn.net/article/2013-07-30/2816399-groupcache-readme-go

優化

記憶體要足夠避免使用swap減低效能,並儘量節點間記憶體一致。

總結

  • key長度有限制。

儲存的key不超過250位元組,資料不能超過1M,最好小於10K。因為資料太大容易導致LRU淘汰比較嚴重,而且Memcached是CPU密集型的程式,容易降低QPS。

  • 支援的資料型別單一

如果需要序列化和反序列化,需要考慮額外開銷

  • 不使用場景

寫頻繁的資料不適合使用快取。

沒有持久化和副本。任意節點掉電(非多臺整系統掉電)都會導致資料丟失。對一致性,實時性,安全性要求極高的業務,可能不適合快取。

  • 多執行緒開銷

在memcached多執行緒環境下使用CAS,在高併發上高QPS的情況下可能效能會顯著降低。

參考資料

http://www.quweiji.com/memcachedb-tokyo-tyrant-redis-performance-test/

http://www.cnblogs.com/hjwublog/p/5625275.html

http://ruturaj.net/redis-memcached-tokyo-tyrant-and-mysql-comparision/

https://stackoverflow.com/questions/2873249/is-memcached-a-dinosaur-in-comparison-to-redis/8494397#8494397


作者:luciham@gmail.com
出處:https://juejin.im/user/5a4e11d96fb9a01c9f5b3367
本文歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線。複製程式碼


相關文章