官术网_书友最值得收藏!

第1章 簡介

Redis 是一個開源的、高性能的、基于鍵值對的緩存與存儲系統(tǒng),通過提供多種鍵值數(shù)據(jù)類型來適應(yīng)不同場景下的緩存與存儲需求。同時Redis的諸多高層級功能使其可以勝任消息隊(duì)列、任務(wù)隊(duì)列等不同的角色。除此之外,Redis還支持外部模塊擴(kuò)展,使其在某些場景下可以作為主數(shù)據(jù)庫使用。

本章將分別介紹Redis的歷史和特性,以使讀者能夠快速地對Redis有一個全面的了解。

1.1 歷史與發(fā)展

2008年,意大利的一家創(chuàng)業(yè)公司Merzia推出了一款基于MySQL的網(wǎng)站實(shí)時統(tǒng)計系統(tǒng)LLOOGG,然而沒過多久,該公司的創(chuàng)始人Salvatore Sanfilippo便開始對MySQL的性能感到失望,于是他決定親自為LLOOGG量身定制一個數(shù)據(jù)庫,并于2009年開發(fā)完成,這個數(shù)據(jù)庫就是Redis。不過Salvatore Sanfilippo并不滿足將Redis只用于LLOOGG這一款產(chǎn)品,而是希望讓更多的人使用它,于是在同一年Salvatore Sanfilippo將Redis開源發(fā)布,并開始和Redis的另一名主要的代碼貢獻(xiàn)者Pieter Noordhuis一起繼續(xù)著Redis的開發(fā)。

Salvatore Sanfilippo自己也沒有想到,短短的幾年時間,Redis就擁有了龐大的用戶群體。截至2021年,在Stack Overflow發(fā)布的全球開發(fā)者調(diào)查報告中,Redis連續(xù)4年蟬聯(lián)“最受開發(fā)者喜愛的數(shù)據(jù)庫”以及“亞馬遜云使用最廣泛的數(shù)據(jù)庫”兩項(xiàng)殊榮。Redis的國內(nèi)用戶包括新浪微博、街旁網(wǎng)和知乎等,國外用戶包括GitHub、Stack Overflow、Flickr、暴雪和Instagram等。

VMware公司從2010年開始贊助Redis的開發(fā),Salvatore Sanfilippo和Pieter Noordhuis也分別于同年的3月和5月加入VMware,全職開發(fā)Redis。

隨后在2015年7月15日,Salvatore Sanfilippo加入一家位于美國加利福尼亞州的公司Redis Labs。這家公司專門提供圍繞Redis的數(shù)據(jù)庫云服務(wù)。從此,Redis Labs正式成為Redis的官方贊助商。

2020年6月30日,Salvatore Sanfilippo決定退居二線,即不再參與Redis的日常維護(hù),而是作為Redis Labs的技術(shù)顧問去探索如何讓Redis更進(jìn)一步等更多未知的事情。自此,Redis Labs的首席架構(gòu)師Yossi Gottlieb和高級軟件架構(gòu)師Oran Arga接替Salvatore Sanfilippo的工作讓Redis繼續(xù)前進(jìn)。

Redis的代碼托管在GitHub上,開發(fā)十分活躍。截至本書出版,Redis的最新穩(wěn)定版本為發(fā)布于2020年的Redis 6。本書的內(nèi)容也是基于此版本編寫的。



小背景 

2009年2月25日,有人在Hacker News上發(fā)布了一個帖子(如圖1-1所示),內(nèi)容就是“Redis”這五個字母,還有到當(dāng)時Redis的托管商Google Code的鏈接。Redis的作者在這個貼子下面發(fā)表回復(fù):“Redis(與其他競品相比)的一個重要目標(biāo)就是讓鍵值能夠支持更多高級復(fù)雜的數(shù)據(jù)類型?!睂?shí)際上一直到十幾年后的今天,Redis仍然在朝著這個方向努力。

圖1-1 Redis官網(wǎng)提供了詳細(xì)的命令文檔



1.2 特性

作為一款最初由個人開發(fā)的系統(tǒng),Redis究竟有什么魅力經(jīng)久不衰,吸引了如此多的用戶呢?

1.2.1 存儲結(jié)構(gòu)

有腳本語言編程經(jīng)驗(yàn)的讀者對字典(或稱映射、關(guān)聯(lián)數(shù)組)數(shù)據(jù)結(jié)構(gòu)一定很熟悉,如代碼dict["key"] = "value"中dict是一個字典變量,字符串"key"是鍵名,而"value"是鍵值,在字典中我們可以獲取或設(shè)置鍵名對應(yīng)的鍵值,也可以刪除一個鍵。

Redis是REmote DIctionary Server(遠(yuǎn)程字典服務(wù)器)的縮寫,它以字典存儲數(shù)據(jù),并允許其他應(yīng)用通過TCP讀寫字典中的內(nèi)容。同大多數(shù)腳本語言中的字典一樣,Redis字典中的鍵值除了可以是字符串,還可以是其他數(shù)據(jù)類型。到目前為止,Redis支持的鍵值數(shù)據(jù)類型如下:

● 字符串類型(其擴(kuò)展類型還包括HyperLogLog類型);

● 哈希類型;

● 列表類型;

● 集合類型;

● 有序集合類型;

● 流類型。

這種字典形式的存儲結(jié)構(gòu)與常見的MySQL等關(guān)系數(shù)據(jù)庫的二維表形式的存儲結(jié)構(gòu)有很大的差異。舉個例子,如下所示,我們在程序中使用post變量存儲了一篇文章的數(shù)據(jù)(包括標(biāo)題、正文、閱讀量和標(biāo)簽):

post["title"]  =  "Hello World!"
post["content"] = "Blablabla..."
post["views"] = 0
post["tags"] = ["PHP", "Ruby", "Node.js"]

現(xiàn)在我們希望將這篇文章的數(shù)據(jù)存儲在數(shù)據(jù)庫中,并且要求可以通過標(biāo)簽檢索出文章。如果使用關(guān)系數(shù)據(jù)庫存儲,一般會將其中的標(biāo)題、正文和閱讀量存儲在一個表中,而將標(biāo)簽存儲在另一個表中,然后使用第三個表連接文章和標(biāo)簽表[1]。需要查詢時還得將3個表進(jìn)行連接,不是很直觀。而Redis字典結(jié)構(gòu)的存儲方式和對多種鍵值數(shù)據(jù)類型的支持使得開發(fā)者可以將程序中的數(shù)據(jù)直接映射到Redis中,數(shù)據(jù)在Redis中的存儲形式和其在程序中的存儲方式非常相近。使用Redis的另一個優(yōu)勢是其對不同的數(shù)據(jù)類型提供了非常方便的操作方式,如使用集合類型存儲文章標(biāo)簽,對標(biāo)簽進(jìn)行如交、并這樣的集合運(yùn)算操作。3.5節(jié)會專門介紹如何借助集合運(yùn)算輕松地實(shí)現(xiàn)“找出所有同時屬于A標(biāo)簽和B標(biāo)簽且不屬于C標(biāo)簽的元素”這樣用關(guān)系數(shù)據(jù)庫實(shí)現(xiàn)起來性能不高且較為煩瑣的操作。

1.2.2 內(nèi)存存儲與持久化

Redis數(shù)據(jù)庫中的所有數(shù)據(jù)都存儲在內(nèi)存中。由于內(nèi)存的讀寫速度遠(yuǎn)快于硬盤,因此Redis在性能上對比其他基于硬盤存儲的數(shù)據(jù)庫有非常明顯的優(yōu)勢,在一臺普通的筆記本計算機(jī)上,Redis可以在一秒內(nèi)讀寫超過10萬個鍵值。

將數(shù)據(jù)存儲在內(nèi)存中也有問題,例如程序退出后內(nèi)存中的數(shù)據(jù)會丟失。不過Redis提供了對持久化的支持,即可以將內(nèi)存中的數(shù)據(jù)異步寫入硬盤中,同時不影響繼續(xù)提供服務(wù)。

1.2.3 功能豐富

Redis雖然是作為數(shù)據(jù)庫開發(fā)的,但由于其提供了豐富的功能,越來越多的人將其用作緩存、隊(duì)列系統(tǒng)等。Redis可謂是名副其實(shí)的多面手。

Redis可以為每個鍵設(shè)置生存時間(Time To Live,TTL),生存時間到期后鍵會自動被刪除。這一功能配合出色的性能讓Redis可以作為緩存系統(tǒng)來使用,而且Redis支持持久化和豐富的數(shù)據(jù)類型的特性使其成為另一個非常流行的緩存系統(tǒng)Memcached的有力競爭者。



討論 

關(guān)于Redis和Memcached優(yōu)劣的討論一直是一個熱門的話題。在性能上Redis是單線程模型,而Memcached支持多線程,所以在多核服務(wù)器上后者的性能理論上相對更高一些。然而,前面已經(jīng)介紹過,Redis的性能已經(jīng)足夠優(yōu)異,在絕大部分場景中其性能不會成為瓶頸,所以在使用時更應(yīng)該關(guān)心的是二者在功能上的區(qū)別。Redis 3.0的推出標(biāo)志著Memcached的幾乎所有功能已成為Redis的子集。同時,Redis對集群的支持使得Memcached原有的第三方集群工具不再成為優(yōu)勢。因此,在新項(xiàng)目中使用Redis而不是Memcached將會是更好的選擇。



作為緩存系統(tǒng),Redis還可以限定數(shù)據(jù)占用的最大內(nèi)存空間,在數(shù)據(jù)達(dá)到空間限制后可以按照一定的規(guī)則自動淘汰不需要的鍵。

除此之外,Redis的列表類型鍵可以用來實(shí)現(xiàn)隊(duì)列系統(tǒng),并且支持阻塞式讀取,可以很容易地實(shí)現(xiàn)一個高性能的優(yōu)先級隊(duì)列。同時在更高層面上,Redis還支持“發(fā)布/訂閱”的消息模式,可以基于此構(gòu)建聊天室[2]等系統(tǒng)。

更有趣的是,Redis從4.0版本開始提供對模塊(module)的支持。借助模塊,用戶可以高性能地基于Redis本身的核心能力擴(kuò)展出更廣泛的用途。以下是一些常見的模塊:

(1)RediSearch模塊提供了全文搜索功能;

(2)RedisGraph模塊可以把Redis變成一個圖數(shù)據(jù)庫;

(3)RedisJSON為Redis增加了JSON數(shù)據(jù)類型;

(4)rediSQL可以讓Redis運(yùn)行SQL語句。

1.2.4 簡單穩(wěn)定

即使功能再豐富,如果使用起來太復(fù)雜也很難吸引人。Redis直觀的存儲結(jié)構(gòu)使得通過程序與Redis交互十分簡單。在Redis中使用命令來讀寫數(shù)據(jù),命令之于Redis就相當(dāng)于SQL語言之于關(guān)系數(shù)據(jù)庫。例如在關(guān)系數(shù)據(jù)庫中要獲取posts表內(nèi)id為1的記錄的title字段的值,可以使用如下SQL語句實(shí)現(xiàn):

SELECT title FROM posts WHERE id = 1 LIMIT 1

相應(yīng)地,在Redis中要讀取鍵名為post:1的哈希類型鍵的title字段的值,可以使用如下命令實(shí)現(xiàn):

HGET post:1 title

其中,HGET就是一條命令。Redis提供了200多條命令(如圖1-2所示),聽起來很多,但是由于使用場景不同,每個使用場景中需要用到的命令不會很多,而且每條命令都很容易記憶。讀完第3章你就會發(fā)現(xiàn)Redis的命令比SQL語言要簡單很多。

圖1-2 Redis官網(wǎng)提供了詳細(xì)的命令文檔

Redis提供了幾十種不同編程語言的客戶端庫,這些庫都很好地封裝了Redis的命令,使得在程序中與Redis進(jìn)行交互變得更容易。有些庫還提供了可以將編程語言中的數(shù)據(jù)類型直接以相應(yīng)的形式存儲到Redis中(如將數(shù)組以列表類型直接存入Redis)的簡單方法,使用起來非常方便。

Redis使用C語言開發(fā),代碼量只有幾萬行。這降低了用戶通過修改Redis源代碼來使之更適合自己的項(xiàng)目所需要的門檻。對于希望“榨干”數(shù)據(jù)庫性能的開發(fā)者,這無疑具有強(qiáng)大的吸引力。

Redis是開源的,所以事實(shí)上Redis的開發(fā)者并非只有Salvatore Sanfilippo。截至目前,有數(shù)百名開發(fā)者為Redis貢獻(xiàn)了代碼。良好的開發(fā)氛圍和嚴(yán)謹(jǐn)?shù)陌姹景l(fā)布機(jī)制使得Redis的穩(wěn)定版本非??煽?,如此多的公司在項(xiàng)目中使用Redis也可以印證這一點(diǎn)。


[1] 這是一種符合第三范式的設(shè)計。事實(shí)上,還可以使用其他方式來實(shí)現(xiàn)標(biāo)簽系統(tǒng)。

[2] Redis的貢獻(xiàn)者之一Pieter Noordhuis提供了一個使用該模式開發(fā)的聊天室的例子。

主站蜘蛛池模板: 拉孜县| 十堰市| 交口县| 林口县| 赤城县| 城步| 三明市| 盐边县| 电白县| 富源县| 襄垣县| 葫芦岛市| 万年县| 义马市| 竹溪县| 扬州市| 平原县| 获嘉县| 曲麻莱县| 郑州市| 会东县| 定安县| 勐海县| 镇原县| 井冈山市| 武冈市| 高清| 新安县| 肥乡县| 柳江县| 观塘区| 涡阳县| 马尔康县| 台中县| 昌平区| 呼和浩特市| 灵宝市| 长武县| 方正县| 富平县| 洛南县|