Redis 是 C 實(shí)現(xiàn)的基于內(nèi)存并可持久的鍵值對(duì)數(shù)據(jù)庫(kù),在分布式服務(wù)中常常被用作緩存。除此之外還可以利用其特點(diǎn)做許多有趣的應(yīng)用,所以我們不僅需要會(huì)用,更需要理解其工作機(jī)制。 Redis 的具體介紹在官方網(wǎng)站和維基百科都有,這里我們只要記住幾個(gè)關(guān)鍵詞既可:開(kāi)源、C 語(yǔ)言、網(wǎng)絡(luò)交互、基于內(nèi)存、可持久化、鍵值對(duì)、數(shù)據(jù)庫(kù)。作者是 Salvatore Sanfilippo,他的博客和 github 主頁(yè)都放到文末的參考鏈接里,有興趣的同學(xué)可以去看看。 根據(jù) Redis 主頁(yè)上的介紹,許多公司都在使用 Redis,比較著名的有 Twitter GitHub Weibo Pinterest Snapchat Craigslist Digg StackOverflow Flickr 等等,想要了解更多的話(huà),可以參考 Who uses Redis? 也有另一種叫法,稱(chēng)為數(shù)據(jù)結(jié)構(gòu)服務(wù)器,因?yàn)楸4娴?value 可以是字符串(string)、字典(map)、列表(list)、集合(sets)或有序集合(sorted set)。那么鍵值對(duì)存儲(chǔ)這么多,到底 Redis 有什么不同之處呢?一是原子性操作,二是在內(nèi)存中運(yùn)行。 Redis 腳本使用 Lua 解釋器來(lái)執(zhí)行腳本。 Reids 2.6 版本通過(guò)內(nèi)嵌支持 Lua 環(huán)境。執(zhí)行腳本的常用命令為 EVAL?;菊Z(yǔ)法為 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...] 基本使用 安裝 在 Mac 下的安裝非常簡(jiǎn)單,只需要 brew install redis 即可,如果需要開(kāi)機(jī)啟動(dòng),按照安裝完成后的提示輸出一條命令即可。然后我們輸入 redis-server 應(yīng)該就能看到如下信息 我們看到目前 Redis 運(yùn)行在 standalone 模式(相對(duì)于分布式),對(duì)應(yīng)的端口是 6379。至于為什么是 6379,這背后是有故事的,原文在這里 http://oldblog./post/redis-as-LRU-cache.html(打開(kāi)之后搜索6379),我簡(jiǎn)要翻譯一下:
除了前面使用過(guò)的 redis-server 命令,我們還可以使用 redis-cli 命令來(lái)啟動(dòng) redis 客戶(hù)端,比如: 如果需要在遠(yuǎn)程 Redis 上執(zhí)行命令,也可以用 redis-cli 命令,具體的方式為 redis-cli -h host -p port -a password 連接 基本命令有 5 個(gè),可以覆蓋日常使用的大部分場(chǎng)景,比方說(shuō)心跳檢測(cè)、切換數(shù)據(jù)庫(kù)之類(lèi)的:
狀態(tài) 我們可以使用 INFO 命令來(lái)了解當(dāng)前 Redis 數(shù)據(jù)庫(kù)的基本狀態(tài),更多的命令請(qǐng)查閱參考鏈接中給出的地址,這里不贅述: 配置 Redis 的配置文件可以在安裝目錄下找到,名為 redis.conf,我們來(lái)看看都有什么配置 具體解釋
數(shù)據(jù)結(jié)構(gòu) Redis 中的 value 支持五種數(shù)據(jù)類(lèi)型: strings, lists, sets, sorted sets, hashes。關(guān)于 key 的設(shè)計(jì),有幾點(diǎn)需要注意:
另外本文只是一個(gè)基本的指南,不會(huì)涵蓋太多的命令,具體請(qǐng)參考 Redis 的官方文檔。 Strings 有人說(shuō),如果只使用 redis 中的字符串類(lèi)型,且不使用 redis 的持久化功能,那么,redis 就和 memcache 非常非常的像了。我們可以做一些基本的嘗試: 在遇到數(shù)值操作的時(shí)候,redis 會(huì)將字符串類(lèi)型轉(zhuǎn)換成數(shù)值,但是如果不是數(shù)值會(huì)怎么樣呢?我們來(lái)試試看: Redis 中的數(shù)值操作指令有一個(gè)很好的特性是原子性,很多網(wǎng)站都利用 redis 的這個(gè)特性來(lái)做技術(shù)統(tǒng)計(jì) Lists Redis 中的 list 的底層實(shí)現(xiàn)不是數(shù)組而是鏈表,這就使得在頭尾插入新元素的復(fù)雜度是常數(shù)級(jí)別的,但定位元素的時(shí)候如果 list 的大小比較大的話(huà)就會(huì)很耗時(shí)。lists 的常用操作包括LPUSH、RPUSH、LRANGE 等。我們可以用 LPUSH 在 lists 的左側(cè)插入一個(gè)新元素,用 RPUSH 在 lists 的右側(cè)插入一個(gè)新元素,用 LRANGE 命令從 lists 中指定一個(gè)范圍來(lái)提取元素。簡(jiǎn)單來(lái)試一下: lists 的應(yīng)用相當(dāng)廣泛,隨便舉幾個(gè)例子:
Sets Redis 中的集合是無(wú)序集合,基本的操作對(duì)應(yīng)于集合的操作,比方說(shuō)添加、刪除、交并差集等等,例如: 集合的常見(jiàn)應(yīng)用場(chǎng)景也很多,比方說(shuō)文章的標(biāo)簽;群聊中的成員等等。 Sorted Sets 顧名思義,就是把無(wú)序的集合弄有序了,每個(gè)元素會(huì)關(guān)聯(lián)一個(gè)分?jǐn)?shù) score,也就是排序的依據(jù)。因?yàn)殛P(guān)于有序集合的相關(guān)操作都是以 z 開(kāi)頭的,所以通常我們把有序集合稱(chēng)為 zsets。還是來(lái)看看具體的例子: Hashes 哈希是 Redis 2.0 之后才增加支持的數(shù)據(jù)結(jié)構(gòu),簡(jiǎn)單來(lái)說(shuō)就是一個(gè)字典,直接看具體例子就很好懂了: Redis 2.8.9 版本中添加了這個(gè)新的結(jié)構(gòu),命名也很有趣,走 ABB 的套路,比如范冰冰高圓圓李思思就是這么個(gè)意思。這個(gè)結(jié)構(gòu)是用來(lái)做基數(shù)統(tǒng)計(jì)的,基數(shù)統(tǒng)計(jì)是什么,來(lái)看兩個(gè)例子:1) 數(shù)據(jù)集 {1, 3, 5, 7, 5, 7, 8}, 那么這個(gè)數(shù)據(jù)集的基數(shù)集為 {1, 3, 5 ,7, 8}, 基數(shù)(不重復(fù)元素)為 5。2) 一個(gè)網(wǎng)站有很多訪客記錄,因?yàn)槊總€(gè)人不一定只訪問(wèn)一次,如果我想知道獨(dú)立訪客的人數(shù)的話(huà),就需要計(jì)算一個(gè)基數(shù),這時(shí)候就可以用 HyperLogLog。好處在于即使數(shù)據(jù)量非常大,計(jì)算所需的空間是小而固定的。每個(gè) HyperLogLog 的鍵只占用 12KB 的內(nèi)存,但是可以計(jì)算 264264 個(gè)不同的基數(shù)。具體怎么實(shí)現(xiàn)的我還沒(méi)有看源碼,但估計(jì)跟 bloomfilter 的思路是一樣的。簡(jiǎn)單舉個(gè)例子: 因?yàn)閮?nèi)部設(shè)計(jì)的算法,會(huì)盡量避免出現(xiàn)碰撞,所以在例子中大概不會(huì)出現(xiàn)統(tǒng)計(jì)不準(zhǔn)的情況,不過(guò)在數(shù)據(jù)量變大之后,統(tǒng)計(jì)數(shù)值就不再是準(zhǔn)確值。 持久化 雖然是內(nèi)存數(shù)據(jù)庫(kù),一般來(lái)說(shuō)為了保險(xiǎn)起見(jiàn),還是會(huì)有一些持久化的機(jī)制,Redis 采用了其中兩種方式,一是 RDB(Redis DataBase),也就是存數(shù)據(jù),另一種是 AOF(Append Only File),也就是存操作。當(dāng)然,即使是 Redis 本身提供的,我們也可以選擇用還是不用,如果兩種都不用的化,Redis 就和 memcache 差不多了。 具體的命令也很簡(jiǎn)單,直接 SAVE 即可,會(huì)在安裝目錄中創(chuàng)建 dump.rdb 文件?;謴?fù)數(shù)據(jù)時(shí),只需要將備份文件移動(dòng)到 redis 安裝目錄并啟動(dòng) redis 即可,具體目錄在哪里可以通過(guò) CONFIG GET dir 來(lái)查看,比方說(shuō)在我的機(jī)器上:
如果用 BGSAVE 的話(huà),就是在后臺(tái)進(jìn)行備份,不會(huì)阻塞進(jìn)程。 RDB 本段內(nèi)容來(lái)自 Linux大棚版redis入門(mén)教程(http:///?p=3196) RDB 方式,是將 redis 某一時(shí)刻的數(shù)據(jù)持久化到磁盤(pán)中,是一種快照式的持久化方法。 Redis 在進(jìn)行數(shù)據(jù)持久化的過(guò)程中,會(huì)先將數(shù)據(jù)寫(xiě)入到一個(gè)臨時(shí)文件中,待持久化過(guò)程都結(jié)束了,才會(huì)用這個(gè)臨時(shí)文件替換上次持久化好的文件。正是這種特性,讓我們可以隨時(shí)來(lái)進(jìn)行備份,因?yàn)榭煺瘴募偸峭暾捎玫摹?/span> 對(duì)于 RDB 方式,redis 會(huì)單獨(dú)創(chuàng)建(fork)一個(gè)子進(jìn)程來(lái)進(jìn)行持久化,而主進(jìn)程是不會(huì)進(jìn)行任何IO操作的,這樣就確保了redis極高的性能。 如果需要進(jìn)行大規(guī)模數(shù)據(jù)的恢復(fù),且對(duì)于數(shù)據(jù)恢復(fù)的完整性不是非常敏感,那 RDB 方式要比 AOF 方式更加的高效。 雖然 RDB 有不少優(yōu)點(diǎn),但它的缺點(diǎn)也是不容忽視的。如果你對(duì)數(shù)據(jù)的完整性非常敏感,那么 RDB 方式就不太適合你,因?yàn)榧词鼓忝?5 分鐘都持久化一次,當(dāng) redis 故障時(shí),仍然會(huì)有近 5 分鐘的數(shù)據(jù)丟失。所以,redis 還提供了另一種持久化方式,那就是 AOF。 AOF 本段內(nèi)容來(lái)自 Linux大棚版redis入門(mén)教程(http:///?p=3196) AOF,英文是 Append Only File,即只允許追加不允許改寫(xiě)的文件。如前面介紹的,AOF 方式是將執(zhí)行過(guò)的寫(xiě)指令記錄下來(lái),在數(shù)據(jù)恢復(fù)時(shí)按照從前到后的順序再將指令都執(zhí)行一遍,就這么簡(jiǎn)單。 我們通過(guò)配置 redis.conf 中的 appendonly yes 就可以打開(kāi) AOF 功能。如果有寫(xiě)操作(如SET等),redis 就會(huì)被追加到 AOF 文件的末尾。 默認(rèn)的 AOF 持久化策略是每秒鐘 fsync 一次(fsync 是指把緩存中的寫(xiě)指令記錄到磁盤(pán)中),因?yàn)樵谶@種情況下,redis 仍然可以保持很好的處理性能,即使 redis 故障,也只會(huì)丟失最近 1 秒鐘的數(shù)據(jù)。 如果在追加日志時(shí),恰好遇到磁盤(pán)空間滿(mǎn)、inode 滿(mǎn)或斷電等情況導(dǎo)致日志寫(xiě)入不完整,也沒(méi)有關(guān)系,redis 提供了 redis-check-aof 工具,可以用來(lái)進(jìn)行日志修復(fù)。 因?yàn)椴捎昧俗芳臃绞?,如果不做任何處理的?huà),AOF 文件會(huì)變得越來(lái)越大,為此,redis 提供了 AOF 文件重寫(xiě)(rewrite)機(jī)制,即當(dāng) AOF 文件的大小超過(guò)所設(shè)定的閾值時(shí),redis 就會(huì)啟動(dòng) AOF 文件的內(nèi)容壓縮,只保留可以恢復(fù)數(shù)據(jù)的最小指令集。舉個(gè)例子或許更形象,假如我們調(diào)用了 100 次INCR指令,在 AOF 文件中就要存儲(chǔ) 100 條指令,但這明顯是很低效的,完全可以把這 100 條指令合并成一條 SET 指令,這就是重寫(xiě)機(jī)制的原理。 在進(jìn)行 AOF 重寫(xiě)時(shí),仍然是采用先寫(xiě)臨時(shí)文件,全部完成后再替換的流程,所以斷電、磁盤(pán)滿(mǎn)等問(wèn)題都不會(huì)影響 AOF 文件的可用性,這點(diǎn)大家可以放心。 AOF方式的另一個(gè)好處,我們通過(guò)一個(gè)“場(chǎng)景再現(xiàn)”來(lái)說(shuō)明。某同學(xué)在操作 redis 時(shí),不小心執(zhí)行了 FLUSHALL,導(dǎo)致 redis 內(nèi)存中的數(shù)據(jù)全部被清空了,這是很悲劇的事情。不過(guò)這也不是世界末日,只要 redis 配置了 AOF 持久化方式,且 AOF 文件還沒(méi)有被重寫(xiě)(rewrite),我們就可以用最快的速度暫停 redis 并編輯 AOF 文件,將最后一行的 FLUSHALL 命令刪除,然后重啟 redis,就可以恢復(fù) redis 的所有數(shù)據(jù)到 FLUSHALL 之前的狀態(tài)了。是不是很神奇,這就是 AOF 持久化方式的好處之一。但是如果 AOF 文件已經(jīng)被重寫(xiě)了,那就無(wú)法通過(guò)這種方法來(lái)恢復(fù)數(shù)據(jù)了。 雖然優(yōu)點(diǎn)多多,但 AOF 方式也同樣存在缺陷,比如在同樣數(shù)據(jù)規(guī)模的情況下,AOF 文件要比 RDB 文件的體積大。而且,AOF 方式的恢復(fù)速度也要慢于 RDB 方式。 如果你直接執(zhí)行 BGREWRITEAOF 命令,那么 redis 會(huì)生成一個(gè)全新的 AOF 文件,其中便包括了可以恢復(fù)現(xiàn)有數(shù)據(jù)的最少的命令集。 如果運(yùn)氣比較差,AOF 文件出現(xiàn)了被寫(xiě)壞的情況,也不必過(guò)分擔(dān)憂(yōu),redis 并不會(huì)貿(mào)然加載這個(gè)有問(wèn)題的 AOF 文件,而是報(bào)錯(cuò)退出。這時(shí)可以通過(guò)以下步驟來(lái)修復(fù)出錯(cuò)的文件:
AOF 重寫(xiě)的內(nèi)部運(yùn)行原理,我們有必要了解一下。在重寫(xiě)即將開(kāi)始之際,redis 會(huì)創(chuàng)建(fork)一個(gè)“重寫(xiě)子進(jìn)程”,這個(gè)子進(jìn)程會(huì)首先讀取現(xiàn)有的 AOF 文件,并將其包含的指令進(jìn)行分析壓縮并寫(xiě)入到一個(gè)臨時(shí)文件中。 與此同時(shí),主工作進(jìn)程會(huì)將新接收到的寫(xiě)指令一邊累積到內(nèi)存緩沖區(qū)中,一邊繼續(xù)寫(xiě)入到原有的 AOF 文件中,這樣做是保證原有的 AOF 文件的可用性,避免在重寫(xiě)過(guò)程中出現(xiàn)意外。 當(dāng)“重寫(xiě)子進(jìn)程”完成重寫(xiě)工作后,它會(huì)給父進(jìn)程發(fā)一個(gè)信號(hào),父進(jìn)程收到信號(hào)后就會(huì)將內(nèi)存中緩存的寫(xiě)指令追加到新 AOF 文件中。 當(dāng)追加結(jié)束后,redis 就會(huì)用新 AOF 文件來(lái)代替舊 AOF 文件,之后再有新的寫(xiě)指令,就都會(huì)追加到新的 AOF 文件中了。 我們應(yīng)該選擇RDB還是AOF,官方的建議是兩個(gè)同時(shí)使用。這樣可以提供更可靠的持久化方案。 增強(qiáng)功能 主從同步 本段內(nèi)容大部分來(lái)自 Linux大棚版redis入門(mén)教程 像 MySQL 一樣,redis 是支持主從同步的,而且也支持一主多從以及多級(jí)從結(jié)構(gòu)。主從結(jié)構(gòu),一是為了純粹的冗余備份,二是為了提升讀性能,比如很消耗性能的 SORT 就可以由從服務(wù)器來(lái)承擔(dān)。在具體的實(shí)踐中,可能還需要考慮到具體的法律法規(guī)原因,單純的主從結(jié)構(gòu)沒(méi)有辦法應(yīng)對(duì)多機(jī)房跨國(guó)可能帶來(lái)的數(shù)據(jù)存儲(chǔ)問(wèn)題,這里需要特別注意一下 redis 的主從同步是異步進(jìn)行的,這意味著主從同步不會(huì)影響主邏輯,也不會(huì)降低 redis 的處理性能。主從架構(gòu)中,可以考慮關(guān)閉主服務(wù)器的數(shù)據(jù)持久化功能,只讓從服務(wù)器進(jìn)行持久化,這樣可以提高主服務(wù)器的處理性能。 在主從架構(gòu)中,從服務(wù)器通常被設(shè)置為只讀模式,這樣可以避免從服務(wù)器的數(shù)據(jù)被誤修改。但是從服務(wù)器仍然可以接受 CONFIG 等指令,所以還是不應(yīng)該將從服務(wù)器直接暴露到不安全的網(wǎng)絡(luò)環(huán)境中。如果必須如此,那可以考慮給重要指令進(jìn)行重命名,來(lái)避免命令被外人誤執(zhí)行。 具體的同步原理也值得了解一下: 從服務(wù)器會(huì)向主服務(wù)器發(fā)出 SYNC 指令,當(dāng)主服務(wù)器接到此命令后,就會(huì)調(diào)用 BGSAVE 指令來(lái)創(chuàng)建一個(gè)子進(jìn)程專(zhuān)門(mén)進(jìn)行數(shù)據(jù)持久化工作,也就是將主服務(wù)器的數(shù)據(jù)寫(xiě)入 RDB 文件中。在數(shù)據(jù)持久化期間,主服務(wù)器將執(zhí)行的寫(xiě)指令都緩存在內(nèi)存中。 在 BGSAVE 指令執(zhí)行完成后,主服務(wù)器會(huì)將持久化好的 RDB 文件發(fā)送給從服務(wù)器,從服務(wù)器接到此文件后會(huì)將其存儲(chǔ)到磁盤(pán)上,然后再將其讀取到內(nèi)存中。這個(gè)動(dòng)作完成后,主服務(wù)器會(huì)將這段時(shí)間緩存的寫(xiě)指令再以 redis 協(xié)議的格式發(fā)送給從服務(wù)器。 另外,要說(shuō)的一點(diǎn)是,即使有多個(gè)從服務(wù)器同時(shí)發(fā)來(lái) SYNC 指令,主服務(wù)器也只會(huì)執(zhí)行一次BGSAVE,然后把持久化好的 RDB 文件發(fā)給多個(gè)下游。在 redis2.8 版本之前,如果從服務(wù)器與主服務(wù)器因某些原因斷開(kāi)連接的話(huà),都會(huì)進(jìn)行一次主從之間的全量的數(shù)據(jù)同步;而在 2.8 版本之后,redis 支持了效率更高的增量同步策略,這大大降低了連接斷開(kāi)的恢復(fù)成本。 主服務(wù)器會(huì)在內(nèi)存中維護(hù)一個(gè)緩沖區(qū),緩沖區(qū)中存儲(chǔ)著將要發(fā)給從服務(wù)器的內(nèi)容。從服務(wù)器在與主服務(wù)器出現(xiàn)網(wǎng)絡(luò)瞬斷之后,從服務(wù)器會(huì)嘗試再次與主服務(wù)器連接,一旦連接成功,從服務(wù)器就會(huì)把“希望同步的主服務(wù)器ID”和“希望請(qǐng)求的數(shù)據(jù)的偏移位置(replication offset)”發(fā)送出去。主服務(wù)器接收到這樣的同步請(qǐng)求后,首先會(huì)驗(yàn)證主服務(wù)器ID是否和自己的ID匹配,其次會(huì)檢查“請(qǐng)求的偏移位置”是否存在于自己的緩沖區(qū)中,如果兩者都滿(mǎn)足的話(huà),主服務(wù)器就會(huì)向從服務(wù)器發(fā)送增量?jī)?nèi)容。 事務(wù)處理 本段內(nèi)容大部分來(lái)自 Linux大棚版redis入門(mén)教程 數(shù)據(jù)庫(kù)原理中很重要的一個(gè)概念是『事務(wù)』,簡(jiǎn)單來(lái)說(shuō)就是把一系列動(dòng)作看做一個(gè)整體,如果其中一個(gè)出了問(wèn)題,應(yīng)該把狀態(tài)恢復(fù)到執(zhí)行該整體之前的狀態(tài)。在 Redis 中,MULTI、EXEC、DISCARD、WATCH 這四個(gè)指令是事務(wù)處理的基礎(chǔ)。
舉個(gè)例子: 在上面的例子中,我們看到了 QUEUED 的字樣,這表示我們?cè)谟?MULTI 組裝事務(wù)時(shí),每一個(gè)命令都會(huì)進(jìn)入到內(nèi)存隊(duì)列中緩存起來(lái),如果出現(xiàn) QUEUED 則表示我們這個(gè)命令成功插入了緩存隊(duì)列,在將來(lái)執(zhí)行 EXEC 時(shí),這些被 QUEUED 的命令都會(huì)被組裝成一個(gè)事務(wù)來(lái)執(zhí)行。 對(duì)于事務(wù)的執(zhí)行來(lái)說(shuō),如果 redis 開(kāi)啟了 AOF 持久化的話(huà),那么一旦事務(wù)被成功執(zhí)行,事務(wù)中的命令就會(huì)通過(guò) write 命令一次性寫(xiě)到磁盤(pán)中去,如果在向磁盤(pán)中寫(xiě)的過(guò)程中恰好出現(xiàn)斷電、硬件故障等問(wèn)題,那么就可能出現(xiàn)只有部分命令進(jìn)行了 AOF 持久化,這時(shí) AOF 文件就會(huì)出現(xiàn)不完整的情況,這時(shí),我們可以使用 redis-check-aof 工具來(lái)修復(fù)這一問(wèn)題,這個(gè)工具會(huì)將 AOF 文件中不完整的信息移除,確保 AOF 文件完整可用。 然后我們來(lái)說(shuō)說(shuō) WATCH 這個(gè)指令,它可以幫我們實(shí)現(xiàn)類(lèi)似于“樂(lè)觀鎖”的效果,即CAS(check and set)。WATCH本身的作用是“監(jiān)視key是否被改動(dòng)過(guò)”,而且支持同時(shí)監(jiān)視多個(gè)key,只要還沒(méi)真正觸發(fā)事務(wù),WATCH都會(huì)盡職盡責(zé)的監(jiān)視,一旦發(fā)現(xiàn)某個(gè)key被修改了,在執(zhí)行EXEC時(shí)就會(huì)返回nil,表示事務(wù)無(wú)法觸發(fā)。例如: 因?yàn)?name 在 exec 之前被改變了,可以認(rèn)為這個(gè)值是臟(dirty) 的,于是之后的操作很可能是危險(xiǎn)且沒(méi)有意義的,自然就不會(huì)執(zhí)行了。 發(fā)布訂閱 Redis 的發(fā)布/訂閱(pub/sub) 是一種消息通信模型,Redis 客戶(hù)端可以訂閱任意數(shù)量的頻道,一旦某頻道接收到消息時(shí),訂閱它的客戶(hù)端便會(huì)收到消息。這里我們需要兩個(gè)終端來(lái)完成這次實(shí)驗(yàn),在終端 1 中做如下操作:
然后在終端 2 中向該頻道發(fā)送消息
然后我們?cè)诮K端 1 中就可以看到對(duì)應(yīng)的消息:
性能測(cè)試 在配置好 Redis 后,我們可以通過(guò)自帶的性能測(cè)試來(lái)查看 Redis 在這臺(tái)服務(wù)器上的表現(xiàn),據(jù)此決定是否應(yīng)該進(jìn)行配置和服務(wù)調(diào)整,例如: 測(cè)試內(nèi)容還是不少的,可以根據(jù)這些數(shù)據(jù)來(lái)進(jìn)行優(yōu)化相關(guān)工作。 連接與管道 Redis 通過(guò)監(jiān)聽(tīng)一個(gè) TCP 端口或者 Unix socket 的方式來(lái)接收來(lái)自客戶(hù)端的連接,當(dāng)一個(gè)連接建立后,Redis 內(nèi)部會(huì)進(jìn)行以下一些操作:
Redis 管道技術(shù)可以在服務(wù)端未響應(yīng)時(shí),客戶(hù)端可以繼續(xù)向服務(wù)端發(fā)送請(qǐng)求,并最終一次性讀取所有服務(wù)端的響應(yīng)。管道技術(shù)最顯著的優(yōu)勢(shì)是提高了 redis 服務(wù)的性能。 分區(qū) 本段內(nèi)容主要來(lái)自 Redis 分區(qū)(http://www.runoob.com/redis/redis-partitioning.html) 分區(qū)是分割數(shù)據(jù)到多個(gè) Redis 實(shí)例的處理過(guò)程,因此每個(gè)實(shí)例只保存 key 的一個(gè)子集。分區(qū)的優(yōu)勢(shì)有很多,尤其是在大數(shù)據(jù)當(dāng)?shù)赖慕裉欤枰煤侠淼姆謪^(qū)機(jī)制來(lái)完成更加復(fù)雜的工作。
分區(qū)實(shí)際上把數(shù)據(jù)進(jìn)行了隔離,如果原本應(yīng)該在同一分區(qū)的數(shù)據(jù)被放在了不同分區(qū),或者原本沒(méi)有太多關(guān)系的數(shù)據(jù)因?yàn)樾碌臉I(yè)務(wù)產(chǎn)生了關(guān)系,就會(huì)遇到一些問(wèn)題:
Redis 有兩種類(lèi)型分區(qū)。 假設(shè)有 4 個(gè) Redis實(shí)例 R0,R1,R2,R3,和類(lèi)似 user:1,user:2 這樣的表示用戶(hù)的多個(gè) key,對(duì)既定的 key 有多種不同方式來(lái)選擇這個(gè) key 存放在哪個(gè)實(shí)例中。也就是說(shuō),有不同的系統(tǒng)來(lái)映射某個(gè) key 到某個(gè) Redis 服務(wù)。 范圍分區(qū) 最簡(jiǎn)單的分區(qū)方式是按范圍分區(qū),就是映射一定范圍的對(duì)象到特定的 Redis 實(shí)例。比如,ID 從 0 到 10000 的用戶(hù)會(huì)保存到實(shí)例 R0,ID 從 10001 到 20000 的用戶(hù)會(huì)保存到 R1,以此類(lèi)推。這種方式的不足之處是要有一個(gè)區(qū)間范圍到實(shí)例的映射表,同時(shí)還需要各種對(duì)象的映射表,通常對(duì) Redis 來(lái)說(shuō)并非是好的方法。 哈希分區(qū) 另外一種分區(qū)方法是 hash 分區(qū)。這對(duì)任何 key 都適用,也無(wú)需是 object_name: 這種形式,只需要確定統(tǒng)一的哈希函數(shù),然后通過(guò)取模確定應(yīng)該保存在哪個(gè)分區(qū)即可。 總結(jié) 相比于在學(xué)校必須手寫(xiě)自己的緩存,使用 Redis(或是 memcache)簡(jiǎn)直太爽了,工作一段時(shí)間了,越發(fā)覺(jué)得技術(shù)的門(mén)檻其實(shí)越來(lái)越低,如何打造高效團(tuán)隊(duì),如何把架構(gòu)設(shè)計(jì)得更加合理,才是真正體現(xiàn)差距的地方。
|
|
來(lái)自: lguo001 > 《數(shù)據(jù)庫(kù)》