摘要:命令實(shí)現(xiàn)命令是最常用的命令之一,也是最能反映緩存發(fā)展歷史的操作。命令在客戶端接收之后,經(jīng)由協(xié)議轉(zhuǎn)換傳遞給服務(wù)端執(zhí)行。服務(wù)端執(zhí)行命令前先查詢是否支持該命令,以決定是否執(zhí)行。,是的簡(jiǎn)稱(chēng),代表的是只存增量的持久化方式。
緣起
最近公司的第一個(gè)PHP轉(zhuǎn)GO項(xiàng)目已經(jīng)在生產(chǎn)環(huán)境穩(wěn)定運(yùn)行數(shù)周,又逢需求小年兒,最近可以得空分享下去年學(xué)GO過(guò)程中的練手項(xiàng)目Godis——用Golang實(shí)現(xiàn)的Redis.
Redis3.0版本,代碼簡(jiǎn)明精煉,再加上是Web后端程序員使用最多組件之一,熟悉Redis原理并閱讀多源碼的開(kāi)發(fā)者人數(shù)頗多,這個(gè)系列小文便不再對(duì)Redis細(xì)節(jié)做過(guò)多介紹。不過(guò),有必要系統(tǒng)性說(shuō)明的地方仍然會(huì)以較大篇幅嘗試解讀。
進(jìn)入正題 基本流程Godis第一版的目標(biāo)是“最基本的kv緩存”,feature list如下:
客戶端/服務(wù)端交互
set/get 命令實(shí)現(xiàn)
AOF持久化實(shí)現(xiàn)
已經(jīng)做到,再精簡(jiǎn)就等于沒(méi)寫(xiě)的境界。遵循實(shí)際工作中的編碼流程,先設(shè)計(jì)基本架構(gòu)再填充實(shí)現(xiàn)的方式,Godis的架構(gòu)圖一步到位、毫無(wú)點(diǎn)綴:
原理分析 1. 客戶端/服務(wù)端交互客戶端與服務(wù)端通過(guò)建立網(wǎng)絡(luò)連接,發(fā)送、處理、返回?cái)?shù)據(jù)給對(duì)方,完成通信。Redis的單機(jī)應(yīng)用中,一個(gè)服務(wù)端redis-server進(jìn)程可以處理多個(gè)客戶端的請(qǐng)求。
客戶端需要一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)保存信息,接收命令,維持和服務(wù)端的連接,與服務(wù)端進(jìn)行一對(duì)一的交互。
客戶端具體需要哪些信息,暫且不表。
服務(wù)端為了響應(yīng)多個(gè)客戶端的請(qǐng)求,對(duì)數(shù)據(jù)進(jìn)行查詢、存儲(chǔ)、更新、刪除操作,也需要一個(gè)結(jié)構(gòu)來(lái)保存基本信息,包括數(shù)據(jù)本身、正在連接中的客戶端等。
客戶端和服務(wù)端通過(guò)這兩個(gè)基本數(shù)據(jù)結(jié)構(gòu),便可以在建立連接(可以簡(jiǎn)化為socket demo)之后,保存自身和對(duì)方的必要信息,維持之后的交互。
從原理分析入手,使用下圖所示的結(jié)構(gòu)體,可以滿足存儲(chǔ)客戶端、服務(wù)端的數(shù)據(jù)存儲(chǔ)要求:
client并非是我們用來(lái)和redis-server交互的client,而是與redis-server建立連接后,服務(wù)端在服務(wù)器創(chuàng)建的、用來(lái)存儲(chǔ)當(dāng)前連接的結(jié)構(gòu)。與redis-server建立連接的客戶端什么樣,redis-server不關(guān)心,畢竟與之交互的都是協(xié)議而已。
由圖,client和server結(jié)構(gòu)體均有Db字段,不同的是,server.Db指向的是0號(hào)db(Redis支持多db,可以自行查閱了解);client.Db指向的是正在連接的db。如果有select切換操作,該指向也會(huì)隨之變化。
2. set/get 命令實(shí)現(xiàn)set、get 命令是redis最常用的命令之一,也是最能反映緩存發(fā)展歷史的操作。對(duì)最簡(jiǎn)單命令代碼的閱讀,可以看到Redis最核心的原理。
set命令將數(shù)據(jù)以k-v鍵值對(duì),保存到數(shù)據(jù)庫(kù),也就是redis-server占用的內(nèi)存中,并且任何連接到此Redis服務(wù)器的客戶端,都可以通過(guò)get命令查詢到。
上一小節(jié)提到,保存服務(wù)器相關(guān)的信息需要一個(gè)結(jié)構(gòu)體,這里set命令保存的數(shù)據(jù),也存在這個(gè)結(jié)構(gòu)體中。不過(guò),存儲(chǔ)的是數(shù)據(jù)的指針。
所以,set/get的實(shí)現(xiàn)原理可以簡(jiǎn)化為,在服務(wù)器數(shù)據(jù)結(jié)構(gòu)中保存set命令的數(shù)據(jù),get命令執(zhí)行時(shí),也從這個(gè)數(shù)據(jù)結(jié)構(gòu)中查找。
set、get命令在客戶端接收之后,經(jīng)由協(xié)議轉(zhuǎn)換傳遞給服務(wù)端執(zhí)行。服務(wù)端執(zhí)行命令前先查詢是否支持該命令,以決定是否執(zhí)行。所以server結(jié)構(gòu)體還需要有個(gè)commands字段,記錄支持的命令列表。
set命令保存的數(shù)據(jù)不能一直在內(nèi)存中,萬(wàn)一宕機(jī)或者硬件故障,數(shù)據(jù)豈不是煙消云散?
這就需要持久化技術(shù),這也是存儲(chǔ)領(lǐng)域的一大關(guān)鍵技術(shù)。AOF,是Append Only File的簡(jiǎn)稱(chēng),代表的是“只存增量”的持久化方式。在Godis v1.0版本中,將以最簡(jiǎn)單的方式實(shí)現(xiàn)AOF持久化,做到下次開(kāi)機(jī)可以查到上次set的數(shù)據(jù) :)
持久化不應(yīng)該對(duì)所有命令一視同仁,減少?zèng)]必要的執(zhí)行開(kāi)銷(xiāo)。在server中增加dirty字段,標(biāo)記數(shù)據(jù)是否已經(jīng)被污染,再?zèng)Q定是否持久化。
經(jīng)過(guò)如上說(shuō)明,這里還有一幅Godis v1.0版數(shù)據(jù)結(jié)構(gòu)圖:
完成服務(wù)端/客戶端交互
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/28767.html
摘要:寫(xiě)在前面在前一篇梳理了版本的基本功能,這一篇要做的是實(shí)現(xiàn)客戶端服務(wù)端的交互。進(jìn)入正題事件處理器既要實(shí)現(xiàn)交互,網(wǎng)絡(luò)編程必不可少。 寫(xiě)在前面 在前一篇梳理了Godis v1.0版本的基本功能,這一篇要做的是實(shí)現(xiàn)客戶端/服務(wù)端的交互。先讓代碼跑起來(lái),才算有了生命力。本篇Godis版本號(hào):v0.0.1 在這個(gè)系列文章里,盡量減少介紹Golang語(yǔ)法、C語(yǔ)言語(yǔ)法和redis原理,聚焦在用Gol...
摘要:在讀者閱讀實(shí)現(xiàn)代碼時(shí),也可以看到最新版本,與有一處是在文件清除掉回車(chē)換行符該行被暫時(shí)注釋掉,也就是在版本,使用作為文本協(xié)議分隔符,確定命令的結(jié)尾。 寫(xiě)在前面 本篇Godis版本號(hào):v0.0.2 前一篇文章實(shí)現(xiàn)了客戶端/服務(wù)端的交互。這一篇,主要介紹get/set命令的實(shí)現(xiàn)。命令本身比較簡(jiǎn)單,支撐命令的整個(gè)系統(tǒng)基礎(chǔ)比較麻煩。本文會(huì)介紹get/set操作涉及的組件和模塊,并適當(dāng)簡(jiǎn)化,最后實(shí)...
閱讀 2070·2019-08-29 16:27
閱讀 1422·2019-08-29 16:14
閱讀 3436·2019-08-29 14:18
閱讀 3520·2019-08-29 13:56
閱讀 1305·2019-08-29 11:13
閱讀 2197·2019-08-28 18:19
閱讀 3505·2019-08-27 10:57
閱讀 2349·2019-08-26 11:39