1. 程式人生 > >redis快速入門教程

redis快速入門教程

redis是什麼

redis的作者何許人也

誰在使用redis

學會安裝redis

學會啟動redis

使用redis客戶端

redis資料結構 – 簡介

redis資料結構 – strings

redis資料結構 – lists

redis資料結構 – 集合

redis資料結構 – 有序集合

redis資料結構 – 雜湊

聊聊redis持久化 – 兩種方式

聊聊redis持久化 – RDB

聊聊redis持久化 – AOF

聊聊redis持久化 – AOF重寫

聊聊redis持久化 – 如何選擇RDB和AOF

聊聊主從 – 用法

聊聊主從 – 同步原理

聊聊redis的事務處理

教你看懂redis配置 – 簡介

教你看懂redis配置 -通用

教你看懂redis配置 – 快照

教你看懂redis配置 – 複製

教你看懂redis配置 – 安全

教你看懂redis配置 -限制

教你看懂redis配置 – 追加模式

教你看懂redis配置 – LUA指令碼

教你看懂redis配置 – 慢日誌

教你看懂redis配置 – 事件通知

教你看懂redis配置 – 高階配置

redis是什麼

redis是一個開源的、使用C語言編寫的、支援網路互動的、可基於記憶體也可持久化的Key-Value資料庫。

redis的官網地址,非常好記,是redis.io。(特意查了一下,域名字尾io屬於國家域名,是british Indian Ocean territory,即英屬印度洋領地)

目前,Vmware在資助著redis專案的開發和維護。

redis的作者何許人也

開門見山,先看照片:

是不是出乎了你的意料,嗯,高手總會有些地方與眾不同的。

這位便是redis的作者,他叫Salvatore Sanfilippo,來自義大利的西西里島,現在居住在卡塔尼亞。目前供職於Pivotal公司。

他使用的網名是antirez,如果你有興趣,可以去他的部落格逛逛,地址是antirez.com,當然也可以去follow他的github,地址是http://github.com/antirez。

誰在使用redis

Blizzard、digg、stackoverflow、github、flickr …

學會安裝redis

從redis.io下載最新版redis-X.Y.Z.tar.gz後解壓,然後進入redis-X.Y.Z資料夾後直接make即可,安裝非常簡單。

make成功後會在src資料夾下產生一些二進位制可執行檔案,包括redis-server、redis-cli等等:

$ find .-type f -executable
./redis-benchmark //用於進行redis效能測試的工具./redis-check-dump//用於修復出問題的dump.rdb檔案./redis-cli //redis的客戶端./redis-server //redis的服務端./redis-check-aof //用於修復出問題的AOF檔案./redis-sentinel //用於叢集管理

學會啟動redis

啟動redis非常簡單,直接./redis-server就可以啟動服務端了,還可以用下面的方法指定要載入的配置檔案:

./redis-server ../redis.conf

預設情況下,redis-server會以非daemon的方式來執行,且預設服務埠為6379。

有關作者為什麼選擇6379作為預設埠,還有一段有趣的典故,英語好的同學可以看看作者這篇博文中的解釋。

使用redis客戶端

我們直接看一個例子:

這樣來啟動redis客戶端了

$ ./redis-cli
//用set指令來設定key、value127.0.0.1:6379>set name "roc" 
OK
//來獲取name的值127.0.0.1:6379>get name 
"roc"//通過客戶端來關閉redis服務端127.0.0.1:6379> shutdown 
127.0.0.1:6379>

redis資料結構 – 簡介

redis是一種高階的key:value儲存系統,其中value支援五種資料型別:

  • 字串(strings)
  • 字串列表(lists)
  • 字串集合(sets)
  • 有序字串集合(sorted sets)
  • 雜湊(hashes)

而關於key,有幾個點要提醒大家:

  1. key不要太長,儘量不要超過1024位元組,這不僅消耗記憶體,而且會降低查詢的效率;
  2. key也不要太短,太短的話,key的可讀性會降低;
  3. 在一個專案中,key最好使用統一的命名模式,例如user:10000:passwd。

redis資料結構 – strings

有人說,如果只使用redis中的字串型別,且不使用redis的持久化功能,那麼,redis就和memcache非常非常的像了。這說明strings型別是一個很基礎的資料型別,也是任何儲存系統都必備的資料型別。

我們來看一個最簡單的例子:

set mystr "hello world!"//設定字串型別get mystr //讀取字串型別

字串型別的用法就是這麼簡單,因為是二進位制安全的,所以你完全可以把一個圖片檔案的內容作為字串來儲存。

另外,我們還可以通過字串型別進行數值操作:

127.0.0.1:6379>set mynum "2"
OK
127.0.0.1:6379>get mynum
"2"127.0.0.1:6379> incr mynum
(integer)3127.0.0.1:6379>get mynum
"3"

看,在遇到數值操作時,redis會將字串型別轉換成數值。

由於INCR等指令本身就具有原子操作的特性,所以我們完全可以利用redis的INCR、INCRBY、DECR、DECRBY等指令來實現原子計數的效果,假如,在某種場景下有3個客戶端同時讀取了mynum的值(值為2),然後對其同時進行了加1的操作,那麼,最後mynum的值一定是5。不少網站都利用redis的這個特性來實現業務上的統計計數需求。

redis資料結構 – lists

redis的另一個重要的資料結構叫做lists,翻譯成中文叫做“列表”。

首先要明確一點,redis中的lists在底層實現上並不是陣列,而是連結串列,也就是說對於一個具有上百萬個元素的lists來說,在頭部和尾部插入一個新元素,其時間複雜度是常數級別的,比如用LPUSH在10個元素的lists頭部插入新元素,和在上千萬元素的lists頭部插入新元素的速度應該是相同的。

雖然lists有這樣的優勢,但同樣有其弊端,那就是,連結串列型lists的元素定位會比較慢,而陣列型lists的元素定位就會快得多。

lists的常用操作包括LPUSH、RPUSH、LRANGE等。我們可以用LPUSH在lists的左側插入一個新元素,用RPUSH在lists的右側插入一個新元素,用LRANGE命令從lists中指定一個範圍來提取元素。我們來看幾個例子:

//新建一個list叫做mylist,並在列表頭部插入元素"1"127.0.0.1:6379> lpush mylist "1"//返回當前mylist中的元素個數(integer)1//在mylist右側插入元素"2"127.0.0.1:6379> rpush mylist "2"(integer)2//在mylist左側插入元素"0"127.0.0.1:6379> lpush mylist "0"(integer)3//列出mylist中從編號0到編號1的元素127.0.0.1:6379> lrange mylist 011)"0"2)"1"//列出mylist中從編號0到倒數第一個元素127.0.0.1:6379> lrange mylist 0-11)"0"2)"1"3)"2"

lists的應用相當廣泛,隨便舉幾個例子:

  • 我們可以利用lists來實現一個訊息佇列,而且可以確保先後順序,不必像MySQL那樣還需要通過ORDER BY來進行排序。
  • 利用LRANGE還可以很方便的實現分頁的功能。
  • 在部落格系統中,每片博文的評論也可以存入一個單獨的list中。

redis資料結構 – 集合

redis的集合,是一種無序的集合,集合中的元素沒有先後順序。

集合相關的操作也很豐富,如新增新元素、刪除已有元素、取交集、取並集、取差集等。我們來看例子:

//向集合myset中加入一個新元素"one"127.0.0.1:6379> sadd myset "one"(integer)1127.0.0.1:6379> sadd myset "two"(integer)1//列出集合myset中的所有元素127.0.0.1:6379> smembers myset 
1)"one"2)"two"//判斷元素1是否在集合myset中,返回1表示存在127.0.0.1:6379> sismember myset "one"(integer)1//判斷元素3是否在集合myset中,返回0表示不存在127.0.0.1:6379> sismember myset "three"(integer)0//新建一個新的集合yourset127.0.0.1:6379> sadd yourset "1"(integer)1127.0.0.1:6379> sadd yourset "2"(integer)1127.0.0.1:6379> smembers yourset
1)"1"2)"2"//對兩個集合求並集127.0.0.1:6379> sunion myset yourset 
1)"1"2)"one"3)"2"4)"two"

對於集合的使用,也有一些常見的方式,比如,QQ有一個社交功能叫做“好友標籤”,大家可以給你的好友貼標籤,比如“大美女”、“土豪”、“歐巴”等等,這時就可以使用redis的集合來實現,把每一個使用者的標籤都儲存在一個集合之中。

redis資料結構 – 有序集合

redis不但提供了無需集合(sets),還很體貼的提供了有序集合(sorted sets)。有序集合中的每個元素都關聯一個序號(score),這便是排序的依據。

很多時候,我們都將redis中的有序集合叫做zsets,這是因為在redis中,有序集合相關的操作指令都是以z開頭的,比如zrange、zadd、zrevrange、zrangebyscore等等

老規矩,我們來看幾個生動的例子:

//新增一個有序集合myzset,並加入一個元素baidu.com,給它賦予的序號是1127.0.0.1:6379> zadd myzset 1 baidu.com 
(integer)1//向myzset中新增一個元素360.com,賦予它的序號是3127.0.0.1:6379> zadd myzset 3360.com(integer)1//向myzset中新增一個元素google.com,賦予它的序號是2127.0.0.1:6379> zadd myzset 2 google.com 
(integer)1//列出myzset的所有元素,同時列出其序號,可以看出myzset已經是有序的了。127.0.0.1:6379> zrange myzset 0-1with scores 
1)"baidu.com"2)"1"3)"google.com"4)"2"5)"360.com"6)"3"//只列出myzset的元素127.0.0.1:6379> zrange myzset 0-11)"baidu.com"2)"google.com"3)"360.com"

redis資料結構 – 雜湊

最後要給大家介紹的是hashes,即雜湊。雜湊是從redis-2.0.0版本之後才有的資料結構。

hashes存的是字串和字串值之間的對映,比如一個使用者要儲存其全名、姓氏、年齡等等,就很適合使用雜湊。

我們來看一個例子:

//建立雜湊,並賦值127.0.0.1:6379> HMSET user:001 username antirez password P1pp0 age 34 
OK
//列出雜湊的內容127.0.0.1:6379> HGETALL user:0011)"username"2)"antirez"3)"password"4)"P1pp0"5)"age"6)"34"//更改雜湊中的某一個值127.0.0.1:6379> HSET user:001 password 12345(integer)0//再次列出雜湊的內容127.0.0.1:6379> HGETALL user:0011)"username"2)"antirez"3)"password"4)"12345"5)"age"6)"34"

有關hashes的操作,同樣很豐富,需要時,大家可以從這裡查詢。

聊聊redis持久化 – 兩種方式

redis提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)。

RDB,簡而言之,就是在不同的時間點,將redis儲存的資料生成快照並存儲到磁碟等介質上;

AOF,則是換了一個角度來實現持久化,那就是將redis執行過的所有寫指令記錄下來,在下次redis重新啟動時,只要把這些寫指令從前到後再重複執行一遍,就可以實現資料恢復了。

其實RDB和AOF兩種方式也可以同時使用,在這種情況下,如果redis重啟的話,則會優先採用AOF方式來進行資料恢復,這是因為AOF方式的資料恢復完整度更高。

如果你沒有資料持久化的需求,也完全可以關閉RDB和AOF方式,這樣的話,redis將變成一個純記憶體資料庫,就像memcache一樣。

聊聊redis持久化 – RDB

RDB方式,是將redis某一時刻的資料持久化到磁碟中,是一種快照式的持久化方法。

redis在進行資料持久化的過程中,會先將資料寫入到一個臨時檔案中,待持久化過程都結束了,才會用這個臨時檔案替換上次持久化好的檔案。正是這種特性,讓我們可以隨時來進行備份,因為快照檔案總是完整可用的。

對於RDB方式,redis會單獨建立(fork)一個子程序來進行持久化,而主程序是不會進行任何IO操作的,這樣就確保了redis極高的效能。

如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

雖然RDB有不少優點,但它的缺點也是不容忽視的。如果你對資料的完整性非常敏感,那麼RDB方式就不太適合你,因為即使你每5分鐘都持久化一次,當redis故障時,仍然會有近5分鐘的資料丟失。所以,redis還提供了另一種持久化方式,那就是AOF。

聊聊redis持久化 – AOF

AOF,英文是Append Only File,即只允許追加不允許改寫的檔案。

如前面介紹的,AOF方式是將執行過的寫指令記錄下來,在資料恢復時按照從前到後的順序再將指令都執行一遍,就這麼簡單。

我們通過配置redis.conf中的appendonly yes就可以開啟AOF功能。如果有寫操作(如SET等),redis就會被追加到AOF檔案的末尾。

預設的AOF持久化策略是每秒鐘fsync一次(fsync是指把快取中的寫指令記錄到磁碟中),因為在這種情況下,redis仍然可以保持很好的處理效能,即使redis故障,也只會丟失最近1秒鐘的資料。

如果在追加日誌時,恰好遇到磁碟空間滿、inode滿或斷電等情況導致日誌寫入不完整,也沒有關係,redis提供了redis-check-aof工具,可以用來進行日誌修復。

因為採用了追加方式,如果不做任何處理的話,AOF檔案會變得越來越大,為此,redis提供了AOF檔案重寫(rewrite)機制,即當AOF檔案的大小超過所設定的閾值時,redis就會啟動AOF檔案的內容壓縮,只保留可以恢復資料的最小指令集。舉個例子或許更形象,假如我們呼叫了100次INCR指令,在AOF檔案中就要儲存100條指令,但這明顯是很低效的,完全可以把這100條指令合併成一條SET指令,這就是重寫機制的原理。

在進行AOF重寫時,仍然是採用先寫臨時檔案,全部完成後再替換的流程,所以斷電、磁碟滿等問題都不會影響AOF檔案的可用