天天看點

帶你讀《Redis 5設計與源碼分析》之一:引言第1章

資料庫技術叢書 點選這裡檢視第二章:簡單動态字元串 點選這裡檢視第三章:跳躍表

Redis 5設計與源碼分析

陳雷 等編著

帶你讀《Redis 5設計與源碼分析》之一:引言第1章

第1章

引  言

Redis是目前最流行的鍵值對(key-value)資料庫,以出色的性能著稱,官方提供的資料是可以支援100 000以上的+QPS。Redis具有高性能的主要原因如下。

1)Redis是基于記憶體的存儲資料庫,絕大部分的指令處理隻是純粹的記憶體操作,記憶體的讀寫速度非常快。

2)Redis是單程序線程的服務(實際上一個正在運作的Redis Server肯定不止一個線程,但隻有一個線程來處理網絡請求),避免了不必要的上下文切換,同時不存在加鎖/釋放鎖等同步操作。

3)Redis使用多路I/O複用模型(select、poll、epoll),可以高效處理大量并發連接配接。

4)Redis中的資料結構是專門設計的,增、删、改、查等操作相對簡單。

本章主要介紹Redis簡介、Redis 5.0的新特性、Redis源代碼概念、Redis安裝與調試,希望對讀者閱讀和研究Redis源碼有一定的幫助。

1.1 Redis簡介

Redis(REmote DIctionary Server)是一個使用ANSI C編寫的、開源的、支援網絡的、基于記憶體的、可選持久化的鍵值對存儲系統。在2013年5月之前,Redis的開發由VMware贊助;2013年5月至2015年6月,由Pivotal贊助;從2015年6月起,Redis的開發由Redis Labs贊助。根據資料庫使用排行網站db-engines.com上的排名,Redis是目前最流行的鍵值對存儲系統。

Redis由Salvatore Sanfilippo在2009年釋出初始版本,開源後不斷發展壯大,目前的最新版為Redis 5.0。Redis的主要版本如下。

1)2009年5月釋出Redis初始版本。

2)2012年釋出Redis 2.6.0。

3)2013年11月釋出Redis 2.8.0。

4)2015年4月釋出Redis 3.0.0,該版本引入了叢集。

5)2017年7月釋出Redis 4.0.0,該版本引入了子產品系統。

6)2018年10月釋出Redis 5.0.0,該版本引入了Streams結構。

Redis在網際網路資料存儲方面應用廣泛,主要具有以下優點。

1)Redis是記憶體型的資料庫,也就是說Redis中的key-value對是存儲在記憶體中的,因而效率比磁盤型的快。

2)Redis的工作模式為單線程,不需要線程間的同步操作。Redis采用單線程主要因為其瓶頸在記憶體和帶寬上,而不是CPU。

3)Redis中key-value的value不僅可以是字元串,也可以是複雜的資料類型,如連結清單、集合、散清單等。

4)Redis支援資料持久化,可以采用RDB、AOF、RDB&AOF三種方案。計算機重新開機後可以在磁盤中進行資料恢複。

5)Redis支援主從結構,可以利用從執行個體進行資料備份。

1.2 Redis 5.0的新特性

相較于Redis 4.0,Redis 5.0增加了很多新的特性,限于篇幅,本節主要介紹幾個較重要的特性,具體内容可以參考官方文檔。

1)新增Streams資料類型,這是Redis 5.0最重要的改進之一。可以把Streams當作消息隊列,詳細内容參見後續章節。

2)新的子產品API、定時器、叢集及字典。

3)RDB中持久化存儲LFU和LRU的資訊。

4)将叢集管理功能完全用C語言內建到redis-cli中,Redis 3.x和Redis 4.x的叢集管理是通過Ruby腳本實作的。

5)有序集合新增指令ZPOPMIN/ZPOPMAX。

6)改進HyperLogLog的實作。

7)新增Client Unblock和Client ID。

8)新增LOLWUT指令。

9)Redis主從複制中的從不再稱為Slave,改稱Replicas。

10)Redis 5.0引入動态哈希,以平衡CPU的使用率和相應性能,可以通過配置檔案進行配置。Redis 5.0預設使用動态哈希。

11)Redis核心代碼進行了部分重構和優化。

1.3 Redis源碼概述

Redis源代碼主要存放在src檔案夾中,作者沒有整理這些檔案,統一存放到了一個檔案夾中,如圖1-1所示。其中server.c為服務端程式,redis-cli.c為用戶端程式。

帶你讀《Redis 5設計與源碼分析》之一:引言第1章

Redis源代碼的核心部分主要如下。

(1)基本的資料結構

□動态字元串sds.c

□整數集合intset.c

□壓縮清單ziplist.c

□快速連結清單quicklist.c

□字典dict.c

□Streams的底層實作結構listpack.c和rax.c

(2)Redis資料類型的底層實作

□Redis對象object.c

□字元串t_string.c

□清單t_list.c

□字典t_hash.c

□集合及有序集合t_set.c和t_zset.c

□資料流t_stream.c

(3)Redis資料庫的實作

□資料庫的底層實作db.c

□持久化rdb.c和aof.c

(4)Redis服務端和用戶端實作

□事件驅動ae.c和ae_epoll.c

□網絡連接配接anet.c和networking.c

□服務端程式server.c

□用戶端程式redis-cli.c

(5)其他

□主從複制replication.c

□哨兵sentinel.c

□叢集cluster.c

□其他資料結構,如hyperloglog.c、geo.c等

□其他功能,如pub/sub、Lua腳本

以上為Redis核心代碼的簡單劃分,本書重點介紹Redis用戶端使用指令的底層實作,在閱讀後續章節時,建議按照本書編排順序進行閱讀。首先學習Redis底層的資料存儲結構;然後學習Redis每個指令的具體實作;最後可以根據需要學習Redis其他方面的内容,如主從複制、哨兵、叢集、持久化等。

1.4 Redis安裝與調試

我們以 Linux 環境為例來進行安裝。

通過網址

http://download.redis.io/releases/

可以獲得各個版本的Redis源碼,本書以Redis 5.0為例,下載下傳源碼包并編譯安裝(源碼包URL為

http://download.redis.io/releases/redis-5.0.0.tar.gz

)。

$ wget

$ tar -zxvf redis-5.0.0.tar.gz

$ cd redis-5.0.0

$ make

$ cd src

$make install

到此,我們完成了Redis 5.0的編譯安裝,生成的可執行檔案在/usr/local/bin目錄中:

redis-benchmark redis-check-aof redis-check-rdb redis-cli

redis-sentinel redis-server

其中redis-benchmark是官方自帶的Redis性能測試工具;當AOF檔案或者RDB檔案出現文法錯誤時,可以使用redis-check-aof或者redis-check-rdb修複;redis-cli是用戶端指令行工具,可以通過指令redis-cli -h {host} -p {port}連接配接到指定Redis伺服器;redis-sentinel是Redis哨兵啟動程式;redis-server是Redis服務端啟動程式。

例如,使用redis-server啟動服務端程式(預設監聽端口是6379):

$ /usr/local/bin/redis-server

使用redis-cli連接配接Redis伺服器并添加鍵值對:

$ redis-cli -h 127.0.0.1 -p 6379

127.0.0.1:6379> set name zhangsan

OK

127.0.0.1:6379> get name

"zhangsan"

GDB是一個由GNU開源組織釋出的、UNIX/Linux作業系統下的、基于指令行的、功能強大的程式調試工具。下面我們示範如何通過GDB來調試Redis。

用GDB啟動redis-server服務端程式:

$ gdb /usr/local/bin/redis-server

(gdb)

使用b指令在main函數入口增加斷點:

(gdb) b main

Breakpoint 1 at 0x427770: file server.c, line 4000.

使用r指令運作:

(gdb) r

Starting program: /usr/local/bin/redis-server

[Thread debugging using libthread_db enabled]

Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0x7fffffffe528) at server.c:4000

4000 int main(int argc, char **argv)

從上面的輸出中可以看到,代碼執行到main函數停止。接下來,使用n指令執行下一步:

(gdb) n

4034 spt_init(argc, argv);

使用p指令檢視某個變量的資訊:

(gdb) p argc

$1 = 1

這裡隻是簡要介紹使用GDB調試Redis程式的方法,更多GDB的使用技巧有待讀者去研究。

當然,還可使用很多友善的源碼閱讀工具閱讀代碼。例如,Windows環境下有一款功能強大的IDE(內建開發環境)—Source Insight,内置C++代碼分析功能;同時能自動維護項目内的符号資料庫,非常友善。另外,Mac 平台下功能強大的 IDE(內建開發環境)—Understand具備代碼依賴、圖形化等實用功能。Linux環境下可以使用 Vim + Ctags 來閱讀代碼,其中Ctags 是Vim下閱讀代碼的一個輔助工具,可以生成函數、類、結構體、宏等文法結構的索引檔案,使用方法也非常簡單。讀者可以自行學習這些源碼閱讀工具的具體安裝教程,這裡不再贅述。

1.5 本章小結

本章首先介紹了Redis的發展曆程及Redis 5.0的新特性。然後重點講解了如何閱讀Redis源代碼,并簡單介紹了Redis源碼的安裝與調試方法,為讀者學習後續章節奠定基礎。