Redis介紹與內(nèi)部實(shí)現(xiàn)機(jī)制_第1頁
Redis介紹與內(nèi)部實(shí)現(xiàn)機(jī)制_第2頁
Redis介紹與內(nèi)部實(shí)現(xiàn)機(jī)制_第3頁
Redis介紹與內(nèi)部實(shí)現(xiàn)機(jī)制_第4頁
Redis介紹與內(nèi)部實(shí)現(xiàn)機(jī)制_第5頁
已閱讀5頁,還剩22頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Redis介紹與實(shí)現(xiàn)機(jī)制第一章

Redis介紹一、Redis特性

〔一〕存儲結(jié)構(gòu) Redis是RemoteDictionaryServer的縮寫,它使用字典結(jié)構(gòu)存儲數(shù)據(jù),并允許其他應(yīng)用通過TCP協(xié)議讀寫字典中的內(nèi)容。同大多數(shù)腳本語言中的字典一樣,Redis字典中的鍵值除了可以是字符串,還可以是其他數(shù)據(jù)類型。Redis支持的數(shù)據(jù)類型有字符串、散列、列表、集合、有序集合?!捕硟?nèi)存存儲與持久化 Redis數(shù)據(jù)庫的所有數(shù)據(jù)都存儲在內(nèi)存中。在一臺普通的筆記本電腦上,Redis可以在1秒內(nèi)讀寫超過十萬個鍵值。Redis也提供了持久化的支持,即將內(nèi)存中的數(shù)據(jù)異步寫入硬盤中,同時(shí)不影響繼續(xù)提供效勞?!踩彻δ茇S富 Redis在很多場合是名副其實(shí)的多面手,越來越多的人將其用作緩存、隊(duì)列系統(tǒng)中。例如,Redis可作為緩存系統(tǒng),并且可以為每個鍵設(shè)置生存時(shí)間,生存時(shí)間到期后鍵會自動刪除;Redis還支持“發(fā)布/訂閱”的消息模式,等等〔四〕簡單穩(wěn)定 在Redis中使用命令來讀寫數(shù)據(jù),就相當(dāng)于SQL語言之關(guān)系型數(shù)據(jù)庫。并且Redis提供了幾十種不同編程語言的客戶端庫,這些庫很好地封裝了Redis命令,使得在程序中與Redis進(jìn)行交互更加容易。Redis是開源的,良好的開發(fā)氣氛和嚴(yán)謹(jǐn)?shù)陌姹景l(fā)布機(jī)制使得Redis的穩(wěn)定版本更加可靠。SQL語句:SELECTtitleFROMpostsWHEREid=1LIMIT1Redis中命令:HGETpost:1title二、Redis數(shù)據(jù)類型

1.字符串類型 字符串類型是Redis中最根本的數(shù)據(jù)類型,它能存儲任何形式的字符串,例如存儲用戶的郵箱、JSON化的對象甚至是一張圖片。一個字符串類型鍵允許存儲的數(shù)據(jù)的最大容量是512MB。2.散列類型 Redis是采用字典結(jié)構(gòu)以鍵值對的形式存儲數(shù)據(jù),而散列類型的鍵值也是一種字典結(jié)構(gòu),其存儲了字段和字段值的映射,但是字段值只能是字符串,不支持其他數(shù)據(jù)類型。散列類型適合存儲對象。

3.列表類型

列表類型可以存儲一個有序的字符串列表,常用的操作是向列表兩端添加元素,或者獲得列表的某一個字段。

5.有序集合類型 在集合類型的根底上,使得我們可以獲得最高〔最低〕的前N個元素、指定分?jǐn)?shù)范圍內(nèi)的元素等與分?jǐn)?shù)有關(guān)的操作。三、Redis常用命令

(0)啟動啟動Redisredis-server檢查Redis是否在工作redis-cli(1)字符串SETname"Tom"GETnameSETcounter1000INCRcounterDECRcounterAPPENDname"Jack"GETname(2)散列類型HMSETcarname"volvo"color"black"price20HMGETcarnameHEXISTScarnameHDELcarprice(3)列表類型LPUSHlistsredisLPUSHlistsmogodbRPUSHlistsmysqlLPOPlistsRPOPlistsLRANGElists010(4)集合類型SADDlettersaSADDlettersabcSREMletterscdSMEMBERSlettersSADDsetA123SADDsetB234SDIFFsetAsetB(5)有序集合

ZADDtutorials1redis2mongodb3mysql3mysqlZRANGEtutorials010WITHSCORES(6)事務(wù)MULTIINCRlikesINCRvisitorsEXEC(7)生存時(shí)間SETsessionuuid11EXPIREsession20TTLsession(8)排序LPUSHmylist426173SORTmylistLPUSHmylistalphaacedcaSORTmylistalphaALPHA(9)消息通知PUBLISHredisChat"Redisisagreatcachingtechnique"SUBSCRIBEredisChatPUBLISHredisChat"Learnredisbytutorialspoint"Redis的底層通信協(xié)議對管道〔pipelining〕提供了支持,通過管道可以一次性發(fā)送多條指令并在執(zhí)行完成后一次性將結(jié)果返回,當(dāng)一組命令中每條命令不依賴于之前命令的執(zhí)行結(jié)果時(shí)就可以將這組命令一起通過管道發(fā)出,管道可以減少客戶端與Redis的通信次數(shù)來實(shí)現(xiàn)降低往返時(shí)延累計(jì)值的目的。第二章Redis數(shù)據(jù)結(jié)構(gòu)與對象簡單動態(tài)字符串、鏈表、跳躍表、字典、壓縮列表、整數(shù)集合;對象一、Redis數(shù)據(jù)結(jié)構(gòu)—簡單動態(tài)字符串〔SDC〕

Redis沒有直接使用C語言傳統(tǒng)的字符串表示,而是自己構(gòu)建了名為簡單動態(tài)字符串〔simpledynamicstring,SDS〕的抽象類型,并將SDS用作Redis的默認(rèn)字符串表示。除了用來保存數(shù)據(jù)庫中的字符串值之外,SDS還被用作緩沖區(qū),例如AOF模塊中的AOF緩沖區(qū)、客戶端狀態(tài)中的輸入緩沖區(qū)等。

與C字符串的區(qū)別:〔1〕常數(shù)復(fù)雜度獲取字符串長度〔2〕杜絕緩沖區(qū)溢出〔3〕減少修改字符串時(shí)帶來的內(nèi)存重分配次數(shù)〔空間預(yù)分配、惰性空間釋放〕一、Redis數(shù)據(jù)結(jié)構(gòu)—簡單動態(tài)字符串〔SDC〕

跳躍表是一種有序數(shù)據(jù)結(jié)構(gòu),它通過在每個節(jié)點(diǎn)中維持多個指向其他節(jié)點(diǎn)的指針,從而到達(dá)快速訪問節(jié)點(diǎn)的目的。在大多數(shù)情況下,跳躍表的效率可以和平衡樹相媲美,并且因?yàn)樘S表的實(shí)現(xiàn)比平衡樹更為簡單,所以有不少程序使用跳躍表代替平衡樹。Redis只在兩個地方用到了跳躍表,一個是實(shí)現(xiàn)有序集合,另一個是集群節(jié)點(diǎn)中用作內(nèi)部數(shù)據(jù)結(jié)構(gòu)。header:指向跳躍表的表頭節(jié)點(diǎn);tail:指向跳躍表的表尾節(jié)點(diǎn);level:記錄目前跳躍表中,層數(shù)最大的那個節(jié)點(diǎn)層數(shù);前進(jìn)指針、后退指針、跨度一、Redis數(shù)據(jù)結(jié)構(gòu)—跳躍表

鏈表提供了高效的節(jié)點(diǎn)重排能力,以及順序性的節(jié)點(diǎn)訪問方式,并且可以通過增刪節(jié)點(diǎn)靈活地調(diào)整鏈表的長度。鏈表內(nèi)置在許多高級的編程語言中,因?yàn)镽edis使用的C語言并沒有內(nèi)置這種數(shù)據(jù)結(jié)構(gòu),所以Redis構(gòu)建了自己的鏈表實(shí)現(xiàn)。當(dāng)一個列表鍵包含了數(shù)量比較多的元素,又或者列表中包含的元素都是比較長的字符串時(shí),Redis就會使用鏈表作為列表鍵的底層實(shí)現(xiàn)。除了鏈表鍵之外,發(fā)布與訂閱、慢查詢、監(jiān)視器等功能也使用到了鏈表。一、Redis數(shù)據(jù)結(jié)構(gòu)—鏈表

字典,是一種用于保存鍵值對的抽象數(shù)據(jù)結(jié)構(gòu),C語言沒有內(nèi)置這種數(shù)據(jù)結(jié)構(gòu),因此Redis構(gòu)建了自己的字典實(shí)現(xiàn)。字典在Redis中的應(yīng)用相當(dāng)廣泛,比方Redis的數(shù)據(jù)庫就是使用字典作為底層實(shí)現(xiàn)的,對數(shù)據(jù)庫的增、刪、改、查等操作也是構(gòu)建在對字典的操作之上。

一、Redis數(shù)據(jù)結(jié)構(gòu)—字典

整數(shù)集合是集合鍵的底層實(shí)現(xiàn)之一,當(dāng)一個集合只包含整數(shù)值元素,并且這個元素?cái)?shù)量不多時(shí),Redis就會使用整數(shù)集合作為集合鍵的底層實(shí)現(xiàn)。

contents數(shù)組是整數(shù)集合的底層實(shí)現(xiàn):整數(shù)集合的每個元素都是contents數(shù)組的一個數(shù)組項(xiàng),各個項(xiàng)在數(shù)組中從小到大有序排列,并且數(shù)組中不包含任何重復(fù)項(xiàng)。length屬性記錄了整數(shù)集合包含的元素?cái)?shù)量,也即是contents數(shù)組的長度。一、Redis數(shù)據(jù)結(jié)構(gòu)—整數(shù)集合

壓縮列表是列表鍵和哈希鍵的底層實(shí)現(xiàn),當(dāng)一個列表鍵只包含少量列表項(xiàng),并且每個列表項(xiàng)要么就是小整數(shù)值,要么就是長度較短的字符串,那么Redis就會使用壓縮列表作為列表鍵的底層實(shí)現(xiàn)。壓縮列表是Redis為了節(jié)約內(nèi)存而開發(fā)的,是由一系列特殊編碼的連續(xù)內(nèi)存塊組成的順序型數(shù)據(jù)結(jié)構(gòu)。一個壓縮列表可以包含任意多個節(jié)點(diǎn),每個節(jié)點(diǎn)可以保存一個字節(jié)數(shù)組或者一個整數(shù)值。一、Redis數(shù)據(jù)結(jié)構(gòu)—壓縮列表

二、Redis對象Redis并沒有直接使用前面所述的數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)鍵值對數(shù)據(jù)庫,而是基于這些數(shù)據(jù)結(jié)構(gòu)創(chuàng)立了一個對象系統(tǒng),這個系統(tǒng)包含字符串對象、列表對象、哈希對象、集合對象和有序集合對象五種類型的對象,每種對象都用到了至少一種前面介紹的數(shù)據(jù)結(jié)構(gòu)。Redis使用對象來表示數(shù)據(jù)庫中的鍵和值,每次當(dāng)我們在Redis數(shù)據(jù)庫中新創(chuàng)立一個鍵值對時(shí),至少會創(chuàng)立兩個對象,一個對象用作鍵值對的鍵〔鍵對象〕,另一個用作鍵值對的值〔值對象〕。

raw:簡單動態(tài)字符串linkedlist:雙端鏈表ziplist:壓縮列表int:long類型整數(shù)intset:整數(shù)集合ht:字典string:字符串對象list:列表對象hash:哈希對象Set:集合對象Sortedset:有序集合對象

二、Redis對象通過encoding屬性來設(shè)定對象所使用的編碼,而不是為特定的對象關(guān)聯(lián)一種固定的編碼,極大地提升了Redis的靈活性和效率,可以根據(jù)不同的場景設(shè)置不同的編碼,從而優(yōu)化對象在某一場景下的效率。例如,當(dāng)列表對象包含元素比較少時(shí),Redis使用壓縮列表作為列表對象的底層實(shí)現(xiàn)。每種類型的對象都至少使用了兩種不同的編碼,如下表所示:

二、Redis對象—內(nèi)存回收、對象共享由于C語言并不具備自動內(nèi)存回收功能,所以Redis在自己的對象系統(tǒng)中構(gòu)建了一個引用計(jì)數(shù)〔referencecounting〕技術(shù)實(shí)現(xiàn)內(nèi)存回收機(jī)制,通過這一機(jī)制,程序可以跟蹤對象的引用計(jì)數(shù)信息,在適當(dāng)?shù)臅r(shí)候自動釋放對象并進(jìn)行內(nèi)存回收。 Redis還通過引用計(jì)數(shù)技術(shù)實(shí)現(xiàn)對象共享機(jī)制,這一機(jī)制可以在適當(dāng)?shù)臈l件下,通過讓多個數(shù)據(jù)庫鍵共享一個對象來節(jié)省內(nèi)存。當(dāng)數(shù)據(jù)庫中保存的相同值對象越多,對象共享機(jī)制就能節(jié)約越多的內(nèi)存?!?〕在創(chuàng)立一個新對象時(shí),引用計(jì)數(shù)的值會被初始化為1;〔2〕當(dāng)對象被一個新程序使用時(shí),它的引用計(jì)數(shù)值會被增一;〔3〕當(dāng)對象不再被一個程序使用時(shí),它的引用計(jì)數(shù)值會被減一;〔4〕當(dāng)對象的引用計(jì)數(shù)值變?yōu)?時(shí),對象所占用的內(nèi)存會被釋放;〔1〕將數(shù)據(jù)庫鍵的值指針指向一個現(xiàn)有的值對象〔2〕將被共享的值對象的引用計(jì)數(shù)增一第三章Redis功能實(shí)現(xiàn)機(jī)制持久化、事務(wù)、發(fā)布與訂閱、集群、排序、事件等

一、持久化—RDB

由于Redis是內(nèi)存數(shù)據(jù)庫,它將自己的數(shù)據(jù)庫狀態(tài)存儲在內(nèi)存里面,所以如果不想方法將儲存在內(nèi)存中的數(shù)據(jù)庫狀態(tài)保存到磁盤里面,那么一旦效勞器退出,效勞器中的數(shù)據(jù)庫狀態(tài)也會消失不見。為了解決這個問題,Redis提供了RDB、AOF持久化方式,將內(nèi)存中的數(shù)據(jù)保存到磁盤中,防止數(shù)據(jù)意外喪失。〔1〕RDB:RDB持久化通過將效勞器某個時(shí)間點(diǎn)上的數(shù)據(jù)庫狀態(tài)〔非空數(shù)據(jù)庫以及相關(guān)鍵值對〕保存到一個RDB文件中,Redis效勞器可以用它來復(fù)原數(shù)據(jù)庫狀態(tài)。SAVE命令會阻塞Redis效勞器進(jìn)程。而BGSAVE會派生出一個子進(jìn)程,然后由子進(jìn)程負(fù)責(zé)創(chuàng)立RDB文件,效勞器父進(jìn)程繼續(xù)處理命令請求。還可以SAVE命令設(shè)置自動間隔保存,例如SAVE6010000效勞器在60秒之內(nèi),對數(shù)據(jù)庫進(jìn)行了至少10000次修改,自動執(zhí)行BGSAVE命令。RDB文件是一個經(jīng)過壓縮的二進(jìn)制文件?!?〕效勞器狀態(tài)結(jié)構(gòu)redisServer的saveparams屬性用來保存一個save選項(xiàng)設(shè)置的保存條件?!?〕dirty計(jì)數(shù)器記錄距離上一次成功執(zhí)行SAVE命令或者BGSAVE命令之后,效勞器對數(shù)據(jù)庫狀態(tài)進(jìn)行了多少次修改。lastsave屬性是一個時(shí)間戳,記錄了效勞器上一次成功執(zhí)行SAVE或BGSAVE命令的時(shí)間一、持久化—AOF

〔2〕AOF:AOF持久化通過保存Redis效勞器所執(zhí)行的寫命令來記錄數(shù)據(jù)庫狀態(tài)的。被寫入AOF文件的所有命令都是以Redis的命令請求協(xié)議格式保存的,Redis的命令請求協(xié)議保存為純文本格式。AOF持久化功能的實(shí)現(xiàn)分為命令追加、文件寫入、文件同步三個步驟:當(dāng)AOF持久化處于翻開狀態(tài)時(shí),效勞器在執(zhí)行完一個寫命令后,會以協(xié)議格式將被執(zhí)行的寫命令〔如SET、SADD、RPUSH〕追加到效勞器狀態(tài)的aof_buf緩沖區(qū)的末尾。效勞器在每次結(jié)束一個事件循環(huán)之前,它都會調(diào)用flushAppendOnlyFile函數(shù),考慮是否需要將aof_buf緩沖區(qū)中的內(nèi)容寫入和保存到AOF文件里面。flushAppendOnlyFile函數(shù)的行為由效勞器配置的appendfsync選項(xiàng)的值〔always、everysec〔默認(rèn)〕、no〕來決定。一、持久化—RDB與AOF比較

RDB優(yōu)點(diǎn):RDB是一個非常緊湊的文件,它保存了Redis在某個時(shí)間點(diǎn)上的數(shù)據(jù)集。這種文件非常適合用于進(jìn)行備份。缺點(diǎn):如果你需要盡量防止在效勞器故障時(shí)喪失數(shù)據(jù),那么RDB不適合你。雖然Redis允許你設(shè)置不同的保存點(diǎn)〔savepoint〕來控制保存RDB文件的頻率,但是,因?yàn)镽DB文件需要保存整個數(shù)據(jù)集的狀態(tài),所以它并不是一個輕松的操作。因此你可能會至少5分鐘才保存一次RDB文件。在這種情況下,一旦發(fā)生故障停機(jī),你就可能會喪失好幾分鐘的數(shù)據(jù)。AOF優(yōu)點(diǎn):使用AOF持久化會讓Redis變得非常耐久:你可以設(shè)置不同的fsync策略,比方無fsync,每秒鐘一次fsync,或者每次執(zhí)行寫入命令時(shí)fsync。AOF的默認(rèn)策略為每秒鐘fsync一次,在這種配置下,Redis仍然可以保持良好的性能,并且就算發(fā)生故障停機(jī),也最多只會喪失一秒鐘的數(shù)據(jù)〔fsync會在后臺線程執(zhí)行,所以主線程可以繼續(xù)努力地處理命令請求〕。缺點(diǎn):對于相同的數(shù)據(jù)集來說,AOF文件的體積通常要大于RDB文件的體積。根據(jù)所使用的fsync策略,AOF的速度可能會慢于RDB。二、事務(wù)

Redis中的事務(wù)是一組命令的集合。事務(wù)同命令一樣都是Redis的最小執(zhí)行單位,一個事務(wù)中的命令要么都執(zhí)行,要么都不執(zhí)行。一個事務(wù)從開始到結(jié)束通常會經(jīng)過事務(wù)開始、命令入隊(duì)、事務(wù)執(zhí)行三個階段。

每個Redis客戶端都有自己的事務(wù)狀態(tài),保存在mstate屬性中。進(jìn)一步,每一個事務(wù)狀態(tài)包含一個事務(wù)隊(duì)列以及已入隊(duì)命令的計(jì)數(shù)器,事務(wù)隊(duì)列是一個數(shù)組,數(shù)組中的每個元素保存了已入隊(duì)命令的相關(guān)信息,包含指向命令實(shí)現(xiàn)函數(shù)的指針、命令的參數(shù),以及參數(shù)的數(shù)量。三、消息訂閱

Redis提供了一組命令可以讓開發(fā)者實(shí)現(xiàn)“發(fā)布/訂閱”(publish/subscribe)模式?!鞍l(fā)布/訂閱”模式可以實(shí)現(xiàn)進(jìn)程間的消息傳遞,“發(fā)布/訂閱”模式中包含兩種角色,分別是發(fā)布者和訂閱者。訂閱者可以訂閱一個或假設(shè)干個頻道,發(fā)布者可以向指定的頻道發(fā)送消息,所有訂閱此頻道的人都會收到此消息。

命令:

PUBLISHnews.it“helloworld”//發(fā)送消息

SUBSCRIBEnews.it//訂閱消息三、消息訂閱

—實(shí)現(xiàn)原理

Redis將所有頻道的訂閱關(guān)系都保存在效勞器狀態(tài)的pubsub_channels字典里面,這個字典的鍵是某個被訂閱的頻道,而鍵的值那么是一個鏈表,鏈表里面記錄了所有訂閱這個頻道的客戶端。 每當(dāng)客戶端執(zhí)行SUBSCRIBE命令訂閱某個或某些頻道的時(shí)候,效勞器都會將客戶端與被訂閱的頻道在pubsub_channels字典中進(jìn)行關(guān)聯(lián)。如果頻道已經(jīng)有其他訂閱者,那么它在pubsub_channels字典中必然有相應(yīng)的訂閱者鏈表,程序唯一要做的就是將客戶端添加到訂閱者鏈表的末尾如果頻道還未有任何訂閱者,程序首先在pubsub_channels字典中為頻道創(chuàng)立一個鍵,并將這個鍵的值設(shè)置為空鏈表,然后成為第一個鏈表中的元素。四、Redis集群—節(jié)點(diǎn)握手

Redis集群是Redis提供的分布式數(shù)據(jù)庫方案,集群通過分片來進(jìn)行數(shù)據(jù)共享,并提供復(fù)制和故障轉(zhuǎn)移功能。一個Redis集群通常由多個節(jié)點(diǎn)〔node〕組成,在剛開始的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論