日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

Redis源码解析——前言

發(fā)布時(shí)間:2023/11/27 生活经验 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis源码解析——前言 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? ??今天開(kāi)啟Redis源碼的閱讀之旅。對(duì)于一些沒(méi)有接觸過(guò)開(kāi)源代碼分析的同學(xué)來(lái)說(shuō),可能這是一件很麻煩的事。但是我總覺(jué)得做一件事,不管有多大多難,我們首先要在戰(zhàn)略上蔑視它,但是要在戰(zhàn)術(shù)上重視它。除了一些高大上的技術(shù),我們一般人都能用比較簡(jiǎn)單的方式描述它是干什么的。比如Redis,它不就是一個(gè)可以通過(guò)網(wǎng)絡(luò)訪(fǎng)問(wèn)的KV型數(shù)據(jù)庫(kù)嘛。在沒(méi)有源碼的情況下,可以想象出它應(yīng)該是通過(guò)網(wǎng)絡(luò)服務(wù)、指令解析、特殊的內(nèi)存結(jié)構(gòu)設(shè)計(jì)(方便增刪改查)、持久化等技術(shù)構(gòu)成。然后我們?cè)趹?zhàn)術(shù)上要重視它各個(gè)技術(shù)的實(shí)現(xiàn),特別是一些我們沒(méi)想到的一些技術(shù)。(轉(zhuǎn)載請(qǐng)指明出于breaksoftware的csdn博客)

? ? ? ? 首先,我會(huì)先粗略閱讀一遍代碼。這個(gè)過(guò)程不會(huì)花費(fèi)比較多的時(shí)間,因?yàn)橹皇呛?jiǎn)單看看。很多技術(shù)細(xì)節(jié)、算法等都是一帶而過(guò)。這個(gè)過(guò)程只為了達(dá)到一個(gè)效果:大致清楚每個(gè)文件都是為了解決哪類(lèi)問(wèn)題的。其實(shí)第一遍“掃”代碼并不能完全達(dá)到這個(gè)效果,但是能預(yù)判出我們確定需要使用的技術(shù)對(duì)應(yīng)的文件就行了。剩下的一些未知文件可能就是我們?cè)陬A(yù)估這個(gè)工程構(gòu)成時(shí)沒(méi)有考慮到的,它們往往隱藏了一些特殊功能。

? ? ? ? 然后,我會(huì)選擇閱讀Makefile文件,看看它是由哪些文件編譯生成,以及它依賴(lài)的一些技術(shù)。再之后就按我們預(yù)估的技術(shù)點(diǎn)去看看它們的實(shí)現(xiàn)。在閱讀的過(guò)程中,我們可能會(huì)遇到之前我們沒(méi)有預(yù)估到的一些技術(shù)點(diǎn),這個(gè)時(shí)候我們要采用廣度優(yōu)先方法去閱讀還是深度優(yōu)先方法去閱讀就要看各自的技術(shù)能力和愛(ài)好了。

? ? ? ? 現(xiàn)在回到Redis上來(lái)。我準(zhǔn)備閱讀的源碼地址是http://download.redis.io/releases/redis-3.2.5.tar.gz。它是目前穩(wěn)定的3.2版本。解壓完之后,可以發(fā)現(xiàn)

? ? ? ??一般來(lái)說(shuō),我們可以通過(guò)文件命名猜測(cè)出它們的功能。但是閱讀過(guò)程也是要“大膽猜測(cè),小心求證”。比如上圖中,Copying文件可以猜測(cè)出它是版本信息文件,我們可以不關(guān)心。Runtest、Runtest-cluster、Runtest-sentinel分別對(duì)應(yīng)于“整體測(cè)試”、“分布式測(cè)試”和“主從切換測(cè)試”的腳本,這個(gè)時(shí)候我們就知道“分布式”和“主從切換”是Redis的重要功能,這樣就補(bǔ)齊了我們對(duì)其技術(shù)點(diǎn)構(gòu)成的認(rèn)識(shí)。Redis.conf和Seninel.conf分別對(duì)應(yīng)于Redis的配置和主從配置,此時(shí)看這些配置還沒(méi)用,前期我們可以略過(guò),等到用到時(shí)再回來(lái)看看。Deps應(yīng)該是depends的英文縮寫(xiě),即它應(yīng)該是依賴(lài)的庫(kù)

? ? ? ??一般來(lái)說(shuō),依賴(lài)庫(kù)都是開(kāi)源的第三方庫(kù)。上圖可見(jiàn)Redis需要在內(nèi)部使用到:

  • Lua腳本引擎。Redis內(nèi)嵌Lua腳本引擎,那么說(shuō)明Redis需要Lua語(yǔ)言的解析能力。那么可以進(jìn)一步猜測(cè)應(yīng)該是用戶(hù)可以定制Lua腳本讓Reids去執(zhí)行,這相當(dāng)于Redis開(kāi)放了一個(gè)非常自由的接口供外部使用。
  • Linenoise是一個(gè)命令行編輯庫(kù)。這個(gè)正是我們之前預(yù)估的Redis基礎(chǔ)功能之一。它的相關(guān)資料可見(jiàn)https://github.com/antirez/linenoise
  • Jemalloc是內(nèi)存管理庫(kù)。很多開(kāi)源項(xiàng)目不使用glibc自帶的ptmalloc,而是使用Jemalloc或者Tcmalloc這類(lèi)更高效的內(nèi)存管理庫(kù)。
  • Hiredis是Redis數(shù)據(jù)庫(kù)的C接口。這塊和Redis相關(guān)性比較大,我們之后也會(huì)重點(diǎn)關(guān)注下。
  • Geohash-int是一種地理編碼算法。它將二維經(jīng)緯度信息轉(zhuǎn)換成Int型數(shù)據(jù)。

? ? ? ? 上面這些第三方庫(kù),我們不會(huì)全部去看。比如Lua腳本引擎,這塊技術(shù)非常獨(dú)立,我們?cè)陂喿xRedis代碼時(shí)應(yīng)該是不會(huì)深入閱讀的。再比如Jemalloc庫(kù),它也是非常基礎(chǔ)的庫(kù),未來(lái)我應(yīng)該會(huì)分析ptmalloc、tcmalloc和jemalloc這三種內(nèi)存管理庫(kù),但是在分析Redis代碼時(shí)也不會(huì)去深入閱讀。Geohash-int是一套算法,除非它提供的特性對(duì)redis非常重要,否則之后應(yīng)該也不會(huì)去閱讀。Linenoise是用于命令行編輯的,它也非Redis主要功能,可以不用去看。Hiredis可能和Redis的相關(guān)性大一些,這個(gè)模塊應(yīng)該會(huì)被關(guān)注。
? ? ? ? 退到上一層,再看看Tests,它是測(cè)試相關(guān)的目錄。里面都是各種測(cè)試Redis的腳本。

? ? ? ??可見(jiàn)測(cè)試腳本是一些后綴為tcl的文件。它的內(nèi)容這是一種被廣泛使用的腳本測(cè)試語(yǔ)言——TCL語(yǔ)言。這塊我們應(yīng)該也不會(huì)過(guò)多涉及。

? ? ? ??Utils從命名看,它應(yīng)該是一些工具

? ? ? ??從上圖看,我們可以發(fā)現(xiàn)其內(nèi)容大部分是一些腳本語(yǔ)言。所以我們之后也不會(huì)太多涉及。
? ? ? ? 然后我們關(guān)注下Makefile文件

# Top level makefile, the real shit is at src/Makefiledefault: all.DEFAULT:cd src && $(MAKE) $@install:cd src && $(MAKE) $@.PHONY: install

? ? ? ??它進(jìn)入到src目錄,然后再make。于是我們也進(jìn)入最最重要的redis源碼目錄——src去一看究竟。
? ? ? ? 進(jìn)入Src后,我們?nèi)匀魂P(guān)注Makffile文件。最開(kāi)始除了一些編譯參數(shù)和依賴(lài)項(xiàng)定義外,還有就是內(nèi)存管理庫(kù)的使用問(wèn)題

# Default allocator
ifeq ($(uname_S),Linux)MALLOC=jemalloc
elseMALLOC=libc
endif# Backwards compatibility for selecting an allocator
ifeq ($(USE_TCMALLOC),yes)MALLOC=tcmalloc
endififeq ($(USE_TCMALLOC_MINIMAL),yes)MALLOC=tcmalloc_minimal
endififeq ($(USE_JEMALLOC),yes)MALLOC=jemalloc
endififeq ($(USE_JEMALLOC),no)MALLOC=libcendif

? ? ? ??linux系統(tǒng)上,Redis默認(rèn)選擇的內(nèi)存管理庫(kù)是jemalloc,其他系統(tǒng)則是選擇libc的ptmalloc。當(dāng)然還可以通過(guò)指定庫(kù)來(lái)修改內(nèi)存管理庫(kù)。如上可以見(jiàn)我們還可以選擇tcmalloc或者tcmalloc_minimal。
? ? ? ? 之后還是一些編譯對(duì)象組合

REDIS_SERVER_NAME=redis-server
REDIS_SENTINEL_NAME=redis-sentinel
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o geo.o
REDIS_GEOHASH_OBJ=../deps/geohash-int/geohash.o ../deps/geohash-int/geohash_helper.o
REDIS_CLI_NAME=redis-cli
REDIS_CLI_OBJ=anet.o adlist.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o
REDIS_BENCHMARK_NAME=redis-benchmark
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o
REDIS_CHECK_RDB_NAME=redis-check-rdb
REDIS_CHECK_AOF_NAME=redis-check-aof
REDIS_CHECK_AOF_OBJ=redis-check-aof.o
…………………………………………
# redis-server
$(REDIS_SERVER_NAME): $(REDIS_SERVER_OBJ)$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/lua/src/liblua.a $(REDIS_GEOHASH_OBJ) $(FINAL_LIBS)# redis-sentinel
$(REDIS_SENTINEL_NAME): $(REDIS_SERVER_NAME)$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME)# redis-check-rdb
$(REDIS_CHECK_RDB_NAME): $(REDIS_SERVER_NAME)$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_CHECK_RDB_NAME)# redis-cli
$(REDIS_CLI_NAME): $(REDIS_CLI_OBJ)$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o $(FINAL_LIBS)# redis-benchmark
$(REDIS_BENCHMARK_NAME): $(REDIS_BENCHMARK_OBJ)$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a $(FINAL_LIBS)# redis-check-aof
$(REDIS_CHECK_AOF_NAME): $(REDIS_CHECK_AOF_OBJ)$(REDIS_LD) -o $@ $^ $(FINAL_LIBS)

? ? ? ??上面腳本可以見(jiàn)這個(gè)Makefile可以編譯出6個(gè)不同的最終產(chǎn)物。
? ? ? ? 其中最核心的應(yīng)該是REDIS_SERVER_NAME對(duì)應(yīng)的編譯內(nèi)容。我們從其需要鏈接的文件(REDIS_SERVER_OBJ中的內(nèi)容)來(lái)看,程序的入口函數(shù)main應(yīng)該位于server.o文件中。我們繼續(xù)查看server.c文件,果然發(fā)現(xiàn)了它。
? ? ? ? 之后的代碼我采用深度優(yōu)先的方法去閱讀,但是這種方式是需要在一條主線(xiàn)的基礎(chǔ)之上進(jìn)行的。這樣就會(huì)導(dǎo)致主線(xiàn)的邏輯被打的很零散。所以我決定還是要分章節(jié),從最基礎(chǔ)的一些代碼開(kāi)始分析。如果模塊和Redis不是強(qiáng)關(guān)聯(lián)的,我將以該模塊名為分析博文的標(biāo)題,比如之前介紹的SDS字符串管理庫(kù),它的相關(guān)介紹名稱(chēng)為《Simple Dynamic Strings(SDS)源碼解析和使用說(shuō)明一》和《Simple Dynamic Strings(SDS)源碼解析和使用說(shuō)明二》。而和Redis強(qiáng)關(guān)聯(lián)的模塊,我將以《Redis源碼解析——XXXXX》形式命名。

總結(jié)

以上是生活随笔為你收集整理的Redis源码解析——前言的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。