redis 冰山一角

redis命令參考手冊:http://redisdoc.com/
redis相關學習視頻資料:https://zhuanlan.zhihu.com/p/28073983

一、安裝

2. Unix和MacOSX平臺

Unix和MacOSX平臺官方支持,windows官方不支持,所以玩虛擬機或者裝linux把,從源文件來安裝就行。通過版本號來選擇,地址於http://redis.io/download。比如老版本的安裝2.4.6,我們可以運行下面的命令來安裝該版本:

wget http://redis.googlecode.com/files/redis-2.4.6.tar.gz
tar xzf redis-2.4.6.tar.gz
cd redis-2.4.6
make
(當然,Redis同樣可以通過套件管理程序來安裝。例如,使用Homebrew的MaxOSX用戶可以只鍵入brew install redis即可安裝最新版。)

如果你是通過源文件來安裝,二進制可執行文件會被放置在src目錄裏。通過運行cd src可跳轉到src目錄。

3. 運行和連接Redis

運行./redis-server.

如果你仔細看了啓動信息,你會看到一個警告,指沒能找到redis.conf文件。Redis將會採用內置的默認設置,這對於我們將要做的已經足夠了。

然後,通過運行./redis-cli(*nix/MacOSX平臺),啓動Redis的控制檯。控制檯將會通過默認的端口(6379)來連接本地運行的服務器。

安裝完畢後,會在 /usr/local/etc 路徑下有 redis.conf 文件,該文件就是redis的配置文件。
爲了方便開發者的使用,我們需要修改幾個配置,如下:
daemonize的默認配置是no,將其改爲yes。這個配置項意思是Redis的守護模式是否開啓。no:不開啓,那這意味着redis要必須保持命令終端開啓而不能
後臺啓動,改爲yes則代表開啓守護模式,這樣一來就可以後臺啓動redis不需要一直停留在終端啓動窗口,提高開發使用效率。
port 是redis的端口屬性,默認是6379,一般來說在開發環境下很少去改動這個默認的端口配置,如果需要修改則改成自己想設置的即可。
loglevel 是日誌的級別,默認是notice。將其設置爲debug,如此一來的設置對於開發者是很友好的,看到更多和開發相關的信息。
logfile 是redis日誌文件的保存位置,默認是空的,需要自行添加一個日誌保存路徑,這裏建議把保存redis日誌文件創建在無需sudo命令就能夠打開執行的位置,否則redis啓動時加載日誌時顯示沒有足夠權限訪問,那麼就會啓動失敗,所以這裏建議用戶設置爲不需要sudo權限就可以讀寫的位置中去,【建議在Users路徑下創建目錄來進行保存日誌】。

二、基礎知識

Redis通常被人們認爲是一種持久化的存儲器關鍵字-值型存儲(in-memory persistent key-value store)。我認爲這種對Redis的描述並不太準確。Redis的確是將所有的數據存放於存儲器(更多是是按位存儲),而且也確實通過將數據寫入磁盤來實現持久化,但是Redis的實際意義比單純的關鍵字-值型存儲要來得深遠。糾正腦海裏的這種誤解觀點非常關鍵,否則你對於Redis之道以及其應用的洞察力就會變得越發狹義。

事實是,Redis引入了5種不同的數據結構,只有一個是典型的關鍵字-值型結構。理解Redis的關鍵就在於搞清楚這5種數據結構,其工作的原理都是如何,有什麼關聯方法以及你能怎樣應用這些數據結構去構建模型。首先,讓我們來弄明白這些數據結構的實際意義。

應用上面提及的數據結構概念到我們熟悉的關係型數據庫裏,我們可以認爲其引入了一個單獨的數據結構——表格。表格既複雜又靈活,基於表格的存儲和管理,沒有多少東西是你不能進行建模的。然而,這種通用性並不是沒有缺點。具體來說就是,事情並不是總能達到假設中的簡單或者快速。相對於這種普遍適用(one-size-fits-all)的結構體系,我們可以使用更爲專門化的結構體系。當然,因此可能有些事情我們會完成不了(至少,達不到很好的程度)。但話說回來,這樣做就能確定我們可以獲得想象中的簡單性和速度嗎?

針對特定類型的問題使用特定的數據結構?我們不就是這樣進行編程的嗎?你不會使用一個散列表去存儲每份數據,也不會使用一個標量變量去存儲。對我來說,這正是Redis的做法。如果你需要處理標量、列表、散列或者集合,爲什麼不直接就用標量、列表、散列和集合去存儲他們?爲什麼不是直接調用exists(key)去檢測一個已存在的值,而是要調用其他比O(1)(常量時間查找,不會因爲待處理元素的增長而變慢)慢的操作?

1. 數據庫(Databases)

與你熟悉的關係型數據庫一致,Redis有着相同的數據庫基本概念,即一個數據庫包含一組數據。典型的數據庫應用案例是,將一個程序的所有數據組織起來,使之與另一個程序的數據保持獨立。

在Redis裏,數據庫簡單的使用一個數字編號來進行辨認,默認數據庫的數字編號是0。如果你想切換到一個不同的數據庫,你可以使用select命令來實現。在命令行界面裏鍵入select 1,Redis應該會回覆一條OK的信息,然後命令行界面裏的提示符會變成類似redis 127.0.0.1:6379[1]>這樣。如果你想切換回默認數據庫,只要在命令行界面鍵入select 0即可。默認會有16個數據庫,編號從0-15,數據庫與數據庫之間的數據是隔離的

2. 命令、關鍵字和值(Commands, Keys and Values)

Redis不僅僅是一種簡單的關鍵字-值型存儲,從其核心概念來看,Redis的5種數據結構中的每一個都至少有一個關鍵字和一個值。在轉入其它關於Redis的有用信息之前,我們必須理解關鍵字和值的概念。

關鍵字(Keys)是用來標識數據塊。我們將會很常跟關鍵字打交道,不過在現在,明白關鍵字就是類似於users:leto這樣的表述就足夠了。一般都能很好地理解到,這樣關鍵字包含的信息是一個名爲leto的用戶。這個關鍵字裏的冒號沒有任何特殊含義,對於Redis而言,使用分隔符來組織關鍵字是很常見的方法。

值(Values)是關聯於關鍵字的實際值,可以是任何東西。有時候你會存儲字符串,有時候是整數,還有時候你會存儲序列化對象(使用JSON、XML或其他格式)。在大多數情況下,Redis會把值看做是一個字節序列,而不會關注它們實質上是什麼。要注意,不同的Redis載體處理序列化會有所不同(一些會讓你自己決定)。因此,在這本書裏,我們將僅討論字符串、整數和JSON。

現在讓我們活動一下手指吧。在命令行界面鍵入下面的命令:

set users:leto "{name: leto, planet: dune, likes: [spice]}"

這就是Redis命令的基本構成。首先我們要有一個確定的命令,在上面的語句裏就是set。然後就是相應的參數,set命令接受兩個參數,包括要設置的關鍵字,以及相應要設置的值。很多的情況是,命令接受一個關鍵字(當這種情況出現,其經常是第一個參數)。你能想到如何去獲取這個值嗎?我想你會說(當然一時拿不準也沒什麼):

get users:leto

關鍵字和值的是Redis的基本概念,而get和set命令是對此最簡單的使用。你可以創建更多的用戶,去嘗試不同類型的關鍵字以及不同的值,看看一些不同的組合。

3. 查詢(Querying)

隨着學習的持續深入,兩件事情將變得清晰起來。對於Redis而言,關鍵字就是一切,而值是沒有任何意義。更通俗來看就是,Redis不允許你通過值來進行查詢。回到上面的例子,我們就不能查詢生活在dune行星上的用戶。

對許多人來說,這會引起一些擔憂。在我們生活的世界裏,數據查詢是如此的靈活和強大,而Redis的方式看起來是這麼的原始和不高效。不要讓這些擾亂你太久。要記住,Redis不是一種普遍使用(one-size-fits-all)的解決方案,確實存在這麼一些事情是不應該由Redis來解決的(因爲其查詢的限制)。事實上,在考慮了這些情況後,你會找到新的方法去構建你的數據。

很快,我們就能看到更多實際的用例。很重要的一點是,我們要明白關於Redis的這些基本事實。這能幫助我們弄清楚爲什麼值可以是任何東西,因爲Redis從來不需要去讀取或理解它們。而且,這也可以幫助我們理清思路,然後去思考如何在這個新世界裏建立模型。

4. 存儲器和持久化(Memory and Persistence)

我們之前提及過,Redis是一種持久化的存儲器內存儲(in-memory persistent store)。對於持久化,默認情況下,Redis會根據已變更的關鍵字數量來進行判斷,然後在磁盤裏創建數據庫的快照(snapshot)。你可以對此進行設置,如果X個關鍵字已變更,那麼每隔Y秒存儲數據庫一次。默認情況下,如果1000個或更多的關鍵字已變更,Redis會每隔60秒存儲數據庫;而如果9個或更少的關鍵字已變更,Redis會每隔15分鐘存儲數據庫。

除了創建磁盤快照外,Redis可以在附加模式下運行。任何時候,如果有一個關鍵字變更,一個單一附加(append-only)的文件會在磁盤裏進行更新。在一些情況裏,雖然硬件或軟件可能發生錯誤,但用那60秒有效數據存儲去換取更好性能是可以接受的。而在另一些情況裏,這種損失就難以讓人接受,Redis爲你提供了選擇。在第5章裏,我們將會看到第三種選擇,其將持久化任務減荷到一個從屬數據庫裏。

至於存儲器,Redis會將所有數據都保留在存儲器中。顯而易見,運行Redis具有不低的成本:因爲RAM仍然是最昂貴的服務器硬件部件。

我很清楚有一些開發者對即使是一點點的數據空間都是那麼的敏感。一本《威廉·莎士比亞全集》需要近5.5MB的存儲空間。對於縮放的需求,其它的解決方案趨向於IO-bound或者CPU-bound。這些限制(RAM或者IO)將會需要你去理解更多機器實際依賴的數據類型,以及應該如何去進行存儲和查詢。除非你是存儲大容量的多媒體文件到Redis中,否則存儲器內存儲應該不會是一個問題。如果這對於一個程序是個問題,你就很可能不會用IO-bound的解決方案。

Redis有虛擬存儲器的支持。然而,這個功能已經被認爲是失敗的了(通過Redis的開發者),而且它的使用已經被廢棄了。

(從另一個角度來看,一本5.5MB的《威廉·莎士比亞全集》可以通過壓縮減小到近2MB。當然,Redis不會自動對值進行壓縮,但是因爲其將所有值都看作是字節,沒有什麼限制讓你不能對數據進行壓縮/解壓,通過犧牲處理時間來換取存儲空間。)

5. 整體來看(Putting It Together)

我們已經接觸了好幾個高層次的主題。在繼續深入Redis之前,我想做的最後一件事情是將這些主題整合起來。這些主題包括,查詢的限制,數據結構以及Redis在存儲器內存儲數據的方法。

當你將這3個主題整合起來,你最終會得出一個絕妙的結論:速度。一些人可能會想,當然Redis會很快速,要知道所有的東西都在存儲器裏。但這僅僅是其中的一部分,讓Redis閃耀的真正原因是其不同於其它解決方案的特殊數據結構。

能有多快速?這依賴於很多東西,包括你正在使用着哪個命令,數據的類型等等。但Redis的性能測試是趨向於數萬或數十萬次操作每秒。你可以通過運行redis-benchmark(就在redis-server和redis-cli的同一個文件夾裏)來進行測試。

我曾經試過將一組使用傳統模型的代碼轉向使用Redis。在傳統模型裏,運行一個我寫的載入測試,需要超過5分鐘的時間來完成。而在Redis裏,只需要150毫秒就完成了。你不會總能得到這麼好的收穫,但希望這能讓你對我們所談的東西有更清晰的理解。

理解Redis的這個特性很重要,因爲這將影響到你如何去與Redis進行交互。擁有SQL背景的程序員通常會致力於讓數據庫的數據往返次數減至最小。這對於任何系統都是個好建議,包括Redis。然而,考慮到我們是在處理比較簡單的數據結構,有時候我們還是需要與Redis服務器頻繁交互,以達到我們的目的。剛開始的時候,可能會對這種數據訪問模式感到不太自然。實際上,相對於我們通過Redis獲得的高性能而言,這僅僅是微不足道的損失。

三、小結

雖然我們只接觸和擺弄了Redis的冰山一角,但我們討論的主題已然覆蓋了很大範圍內的東西。如果覺得有些事情還是不太清楚(例如查詢),不用爲此而擔心,在下一章我們將會繼續深入探討,希望你的問題都能得到解答。

這一章的要點包括:

關鍵字(Keys)是用於標識一段數據的一個字符串

值(Values)是一段任意的字節序列,Redis不會關注它們實質上是什麼

Redis展示了(也實現了)5種專門的數據結構

上面的幾點使得Redis快速而且容易使用,但要知道Redis並不適用於所有的應用場景

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章