7天用Go動手寫/從零實現分佈式緩存GeeCache

geecache.jpg

目錄

談談分佈式緩存

第一次請求時將一些耗時操做的結果暫存,之後遇到相同的請求,直接返回暫存的數據。我想這是大部分童鞋對於緩存的理解。在計算機系統中,緩存無處不在,好比咱們訪問一個網頁,網頁和引用的 JS/CSS 等靜態文件,根據不一樣的策略,會緩存在瀏覽器本地或是 CDN 服務器,那在第二次訪問的時候,就會以爲網頁加載的速度快了很多;好比微博的點讚的數量,不可能每一個人每次訪問,都從數據庫中查找全部點讚的記錄再統計,數據庫的操做是很耗時的,很難支持那麼大的流量,因此通常點贊這類數據是緩存在 Redis 服務集羣中的。html

商業世界裏,現金爲王;架構世界裏,緩存爲王。

緩存中最簡單的莫過於存儲在內存中的鍵值對緩存了。說到鍵值對,很容易想到的是字典(dict)類型,Go 語言中稱之爲 map。那直接建立一個 map,每次有新數據就往 map 中插入不就行了,這不就是鍵值對緩存麼?這樣作有什麼問題呢?node

1)內存不夠了怎麼辦?git

那就隨機刪掉幾條數據好了。隨機刪掉好呢?仍是按照時間順序好呢?或者是有沒有其餘更好的淘汰策略呢?不一樣數據的訪問頻率是不同的,優先刪除訪問頻率低的數據是否是更好呢?數據的訪問頻率可能隨着時間變化,那優先刪除最近最少訪問的數據多是一個更好的選擇。咱們須要實現一個合理的淘汰策略。github

2)併發寫入衝突了怎麼辦?golang

對緩存的訪問,通常不多是串行的。map 是沒有併發保護的,應對併發的場景,修改操做(包括新增,更新和刪除)須要加鎖。數據庫

3)單機性能不夠怎麼辦?瀏覽器

單臺計算機的資源是有限的,計算、存儲等都是有限的。隨着業務量和訪問量的增長,單臺機器很容易遇到瓶頸。若是利用多臺計算機的資源,並行處理提升性能就要緩存應用可以支持分佈式,這稱爲水平擴展(scale horizontally)。與水平擴展相對應的是垂直擴展(scale vertically),即經過增長單個節點的計算、存儲、帶寬等,來提升系統的性能,硬件的成本和性能並不是呈線性關係,大部分狀況下,分佈式系統是一個更優的選擇。緩存

4)...服務器

關於 GeeCache

設計一個分佈式緩存系統,須要考慮資源控制、淘汰策略、併發、分佈式節點通訊等各個方面的問題。並且,針對不一樣的應用場景,還須要在不一樣的特性之間權衡,例如,是否須要支持緩存更新?仍是假定緩存在淘汰以前是不容許改變的。不一樣的權衡對應着不一樣的實現。架構

groupcache 是 Go 語言版的 memcached,目的是在某些特定場合替代 memcached。groupcache 的做者也是 memcached 的做者。不管是瞭解單機緩存仍是分佈式緩存,深刻學習這個庫的實現都是很是有意義的。

GeeCache 基本上模仿了 groupcache 的實現,爲了將代碼量限制在 500 行左右(groupcache 約 3000 行),裁剪了部分功能。但整體實現上,仍是與 groupcache 很是接近的。支持特性有:

  • 單機緩存和基於 HTTP 的分佈式緩存
  • 最近最少訪問(Least Recently Used, LRU) 緩存策略
  • 使用 Go 鎖機制防止緩存擊穿
  • 使用一致性哈希選擇節點,實現負載均衡
  • 使用 protobuf 優化節點間二進制通訊
  • ...

GeeCache 分7天實現,天天完成的部分都是能夠獨立運行和測試的,就像搭積木同樣,天天實現的特性組合在一塊兒就是最終的分佈式緩存系統。天天的代碼在 100 行左右。

附 推薦閱讀

原文地址: 7天用Go從零實現分佈式緩存GeeCache - 極客兔兔

相關文章
相關標籤/搜索