用Go實現Redis之一準備工做

緣起

最近公司的第一個PHP轉GO項目已經在生產環境穩定運行數週,又逢需求小年兒,最近能夠得空分享下去年學GO過程當中的練手項目Godis——用Golang實現的Redis.程序員

Redis3.0版本,代碼簡明精煉,再加上是Web後端程序員使用最多組件之一,熟悉Redis原理並閱讀多源碼的開發者人數頗多,這個系列小文便再也不對Redis細節作過多介紹。不過,有必要系統性說明的地方仍然會以較大篇幅嘗試解讀。redis

進入正題

基本流程

Godis初版的目標是「最基本的kv緩存」,feature list以下:數據庫

  1. 客戶端/服務端交互
  2. set/get 命令實現
  3. AOF持久化實現

已經作到,再精簡就等於沒寫的境界。遵循實際工做中的編碼流程,先設計基本架構再填充實現的方式,Godis的架構圖一步到位、毫無點綴:segmentfault

圖片描述

原理分析

1. 客戶端/服務端交互

客戶端與服務端經過創建網絡鏈接,發送、處理、返回數據給對方,完成通訊。Redis的單機應用中,一個服務端redis-server進程能夠處理多個客戶端的請求。後端

客戶端須要一個數據結構來保存信息,接收命令,維持和服務端的鏈接,與服務端進行一對一的交互。
客戶端具體須要哪些信息,暫且不表。緩存

服務端爲了響應多個客戶端的請求,對數據進行查詢、存儲、更新、刪除操做,也須要一個結構來保存基本信息,包括數據自己、正在鏈接中的客戶端等。
客戶端和服務端經過這兩個基本數據結構,即可以在創建鏈接(能夠簡化爲socket demo)以後,保存自身和對方的必要信息,維持以後的交互。服務器

從原理分析入手,使用下圖所示的結構體,能夠知足存儲客戶端、服務端的數據存儲要求:
圖片描述網絡

client並不是是咱們用來和redis-server交互的client,而是與redis-server創建鏈接後,服務端在服務器建立的、用來存儲當前鏈接的結構。與redis-server創建鏈接的客戶端什麼樣,redis-server不關心,畢竟與之交互的都是協議而已。數據結構

由圖,client和server結構體均有Db字段,不一樣的是,server.Db指向的是0號db(Redis支持多db,能夠自行查閱瞭解);client.Db指向的是正在鏈接的db。若是有select切換操做,該指向也會隨之變化。架構

2. set/get 命令實現

set、get 命令是redis最經常使用的命令之一,也是最能反映緩存發展歷史的操做。對最簡單命令代碼的閱讀,能夠看到Redis最核心的原理。
set命令將數據以k-v鍵值對,保存到數據庫,也就是redis-server佔用的內存中,而且任何鏈接到此Redis服務器的客戶端,均可以經過get命令查詢到。
上一小節提到,保存服務器相關的信息須要一個結構體,這裏set命令保存的數據,也存在這個結構體中。不過,存儲的是數據的指針。
因此,set/get的實現原理能夠簡化爲,在服務器數據結構中保存set命令的數據,get命令執行時,也從這個數據結構中查找。
set、get命令在客戶端接收以後,經由協議轉換傳遞給服務端執行。服務端執行命令前先查詢是否支持該命令,以決定是否執行。因此server結構體還須要有個commands字段,記錄支持的命令列表。

3. AOF持久化實現

set命令保存的數據不能一直在內存中,萬一宕機或者硬件故障,數據豈不是煙消雲散?
這就須要持久化技術,這也是存儲領域的一大關鍵技術。AOF,是Append Only File的簡稱,表明的是「只存增量」的持久化方式。在Godis v1.0版本中,將以最簡單的方式實現AOF持久化,作到下次開機能夠查到上次set的數據 :)
持久化不該該對全部命令一視同仁,減小不必的執行開銷。在server中增長dirty字段,標記數據是否已經被污染,再決定是否持久化。

數據結構關聯

通過如上說明,這裏還有一幅Godis v1.0版數據結構圖:
圖片描述

下集預告

完成服務端/客戶端交互

相關文章
相關標籤/搜索