天天看點

Redis詳細解說

歡迎大家關注我的其他Github部落格和簡書,互相交流!

1. Redis 簡介

•Redis是一款開源的、高性能的鍵-值存儲(key-value store)。它常被稱作是一款資料結構伺服器(data structure server)。Redis的鍵值可以包括字元串(strings)類型,同時它還包括哈希(hashes)、清單(lists)、集合(sets)和 有序集合(sorted sets)等資料類型。 對于這些資料類型,你可以執行原子操作。例如:對字元串進行附加操作(append);遞增哈希中的值;向清單中增加元素;計算集合的交集、并集與差集等。

•為了獲得優異的性能,Redis采用了記憶體中(in-memory)資料集(dataset)的方式。同時,Redis支援資料的持久化,你可以每隔一段時間将資料集轉存到磁盤上(snapshot),或者在日志尾部追加每一條操作指令(append only file,aof)。

•Redis同樣支援主從複制(master-slave replication),并且具有非常快速的非阻塞首次同步( non-blocking first synchronization)、網絡斷開自動重連等功能。同時Redis還具有其它一些特性,其中包括簡單的事物支援、釋出訂閱 ( pub/sub)、管道(pipeline)和虛拟記憶體(vm)等 。

•Redis具有豐富的用戶端,支援現階段流行的大多數程式設計語言。

2. Redis安裝

下載下傳最新穩定版 redis-2.2.11 (http://redis.io/download)

tar zxvf redis-2.2.11 解壓縮

Redis詳細解說

cd src 進入src目錄

•m ake 編譯Redis

•make test 可以測試一下(本步可省略)

•make install 安裝,預設安裝目錄是 /usr/local/bin,生成如下圖中的5個二進制檔案,可以将其拷到建立目錄下,例如: /usr/local/redis/bin

cp 源碼/src/redis.conf /usr/local/redis/etc 配置檔案複制

•cd /usr/local/redis

•./bin/redis-server ./etc/redis.conf 啟動Redis服務

•此時redis已經運作,但要獲得好的性能,還需要對配置檔案進行合理的配置

3. Redis配置

  1. Redis預設不是以守護程序的方式運作,可以通過該配置項修改,使用yes啟用守護程序

    • daemonize no

    •2. 當Redis以守護程序方式運作時,Redis預設會把pid寫入/var/run/redis.pid檔案,可以通過pidfile指定

    • pidfile /var/run/redis.pid

    •3. 指定Redis監聽端口,預設端口為6379,作者在自己的一篇博文中解釋了為什麼選用6379作為預設端口,因為6379在手機按鍵上MERZ對應的号碼,而MERZ取自意大利歌女Alessia Merz的名字

    • port 6379

    •4. 綁定的主機位址

    • bind 127.0.0.1

    •5.當 用戶端閑置多長時間後關閉連接配接,如果指定為0,表示關閉該功能

    • timeout 300

    •6. 指定日志記錄級别,Redis總共支援四個級别:debug、verbose、notice、warning,預設為verbose

    loglevel verbose

    •7. 日志記錄方式,預設為标準輸出,如果配置Redis為守護程序方式運作,而這裡又配置為日志記錄方式為标準輸出,則日志将會發送給/dev/null

    • logfile stdout

    •8. 設定資料庫的數量,預設資料庫為0,可以使用SELECT 指令在連接配接上指定資料庫id

    • databases 16

    •9. 指定在多長時間内,有多少次更新操作,就将資料同步到資料檔案,可以多個條件配合

    • save

    • Redis預設配置檔案中提供了三個條件:

    • save 900 1

    • save 300 10

    • save 60 10000

    • 分别表示900秒(15分鐘)内有1個更改,300秒(5分鐘)内有10個更改以及60秒内有10000個更改。

    •10. 指定存儲至本地資料庫時是否壓縮資料,預設為yes,Redis采用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導緻資料庫檔案變的巨大

    • rdbcompression yes

    •11. 指定本地資料庫檔案名,預設值為dump.rdb

    • dbfilename dump.rdb

    •12. 指定本地資料庫存放目錄

    • dir ./

    •13. 設定當本機為slav服務時,設定master服務的IP位址及端口,在Redis啟動時,它會自動從master進行資料同步

    • slaveof

    •14. 當master服務設定了密碼保護時,slav服務連接配接master的密碼

    • masterauth

    •15. 設定Redis連接配接密碼,如果配置了連接配接密碼,用戶端在連接配接Redis時需要通過AUTH 指令提供密碼,預設關閉

    • requirepass foobared

    •16. 設定同一時間最大用戶端連接配接數,預設無限制,Redis可以同時打開的用戶端連接配接數為Redis程序可以打開的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當用戶端連接配接數到達限制時,Redis會關閉新的連接配接并向用戶端傳回max number of clients reached錯誤資訊

    • maxclients 128

    •17. 指定Redis最大記憶體限制,Redis在啟動時會把資料加載到記憶體中,達到最大記憶體後,Redis會先嘗試清除已到期或即将到期的Key,當此方法處理 後,仍然到達最大記憶體設定,将無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放記憶體,Value會存放在swap區

    • maxmemory

    •18. 指定是否在每次更新操作後進行日志記錄,Redis在預設情況下是異步的把資料寫入磁盤,如果不開啟,可能會在斷電時導緻一段時間内的資料丢失。因為 redis本身同步資料檔案是按上面save條件來同步的,是以有的資料會在一段時間内隻存在于記憶體中。預設為no

    • appendonly no

    •19. 指定更新日志檔案名,預設為appendonly.aof

    • appendfilename appendonly.aof

    •20. 指定更新日志條件,共有3個可選值:

    no:表示等作業系統進行資料緩存同步到磁盤(快)

    always:表示每次更新操作後手動調用fsync()将資料寫到磁盤(慢,安全)

    everysec:表示每秒同步一次(折衷,預設值)

    • appendfsync everysec

    •21. 指定是否啟用虛拟記憶體機制,預設值為no,簡單的介紹一下,VM機制将資料分頁存放,由Redis将通路量較少的頁即冷資料swap到磁盤上,通路多的頁面由磁盤自動換出到記憶體中(在後面的文章我會仔細分析Redis的VM機制)

    • vm-enabled no

    •22. 虛拟記憶體檔案路徑,預設值為/tmp/redis.swap,不可多個Redis執行個體共享

    • vm-swap-file /tmp/redis.swap

    •23. 将所有大于vm-max-memory的資料存入虛拟記憶體,無論vm-max-memory設定多小,所有索引資料都是記憶體存儲的(Redis的索引資料 就是keys),也就是說,當vm-max-memory設定為0的時候,其實是所有value都存在于磁盤。預設值為0

    • vm-max-memory 0

    •24. Redis swap檔案分成了很多的page,一個對象可以儲存在多個page上面,但一個page上不能被多個對象共享,vm-page-size是要根據存儲的 資料大小來設定的,作者建議如果存儲很多小對象,page大小最好設定為32或者64bytes;如果存儲很大大對象,則可以使用更大的page,如果不 确定,就使用預設值

    • vm-page-size 32

    •25. 設定swap檔案中的page數量,由于頁表(一種表示頁面空閑或使用的bitmap)是在放在記憶體中的,,在磁盤上每8個pages将消耗1byte的記憶體。

    • vm-pages 134217728

    •26. 設定通路swap檔案的線程數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是串行的,可能會造成比較長時間的延遲。預設值為4

    • vm-max-threads 4

    •27. 設定在向用戶端應答時,是否把較小的包合并為一個包發送,預設為開啟

    • glueoutputbuf yes

    •28. 指定在超過一定的數量或者最大的元素超過某一臨界值時,采用一種特殊的雜湊演算法

    • hash-max-zipmap-entries 64

    • hash-max-zipmap-value 512

    •29. 指定是否激活重置哈希,預設為開啟

    • activerehashing yes

    •30. 指定包含其它的配置檔案,可以在同一主機上多個Redis執行個體之間使用同一份配置檔案,而同時各個執行個體又擁有自己的特定配置檔案

    • include /path/to/local.conf

4. Redis支援的資料類型

Keys

–非二進制安全的字元類型( not binary-safe strings )

•Values

–Strings (Binary-safe strings )

–Lists (Lists of binary-safe strings )

–Sets (Sets of binary-safe strings)

–Sorted sets (Sorted sets of binary-safe strings)

–Hash

Key說明

•redis本質上一個key-value 資料庫,是以我們首先來看看他的key.首先key也是字元串類型,由于key不是binary safe的字元串,是以像“my key”和“mykey\n”這樣包含空格和換行的key是不允許的。

•我們在使用的時候可以自己定義一個Key的格式。例如 object-type:id:field

•Key不要太長。占記憶體,查詢慢。

•Key不要太短。u:1000:pwd 不如 user:1000:password 可讀性好

Key相關指令

•exits key 測試指定key是否存在,傳回1表示存在,0不存在

•del key1 key2 ….keyN 删除給定key,傳回删除key的數目,0表示給定key都不存在

•type key 傳回給定key的value類型。傳回 none 表示不存在,key有string字元類型,list 連結清單類型 set 無序集合類型等…

keys pattern 傳回比對指定模式的所有key(支援*,?,[abc ]的方式)

•randomkey 傳回從目前資料庫中随機選擇的一個key,如果目前資料庫是空的,傳回空串

•rename oldkey newkey 原子的重命名一個key,如果newkey存在,将會被覆寫,傳回1表示成功,0失敗。失敗可能是oldkey不存在或者和newkey相同

•renamenx oldkey newkey 同上,但是如果newkey存在傳回失敗

•dbsize 傳回目前資料庫的key數量

•expire key seconds 為key指定過期時間,機關是秒。傳回1成功,0表示key已經設定過過期時間或者不存在

•ttl key 傳回設定了過期時間的key的剩餘過期秒數, -1表示key不存在或者沒有設定過過期時間

•select db-index 通過索引選擇資料庫,預設連接配接的資料庫所有是0,預設資料庫數是16個。傳回1表示成功,0失敗

•move key db-index 将key從目前資料庫移動到指定資料庫。傳回1成功。0 如果key不存在,或者已經在指定資料庫中

•flushdb 删除目前資料庫中所有key,此方法不會失敗。慎用

flushall 删除所有資料庫中的所有key,此方法不會失敗。更加慎用

Value說明

String

•string是redis最基本的類型,而且string類型是二進制安全的。

•redis的string可以包含任何資料。包括jpg圖檔或者序列化的對象。

•最大上限是1G位元組。

•如果隻用string類型,redis就可以被看作加上持久化特性的memcached

String 相關指令

•set key value 設定key對應的值為string類型的value,傳回1表示成功,0失敗

•setnx key value 同上,如果key已經存在,傳回0 。nx 是not exist的意思

•get key 擷取key對應的string值,如果key不存在傳回nil

•getset key value 設定key的值,并傳回key的舊值。如果key不存在傳回nil

•mget key1 key2 … keyN 一次擷取多個key的值,如果對應key不存在,則對應傳回nil。下面是個實驗, nonexisting不存在,對應傳回nil

•mset key1 value1 … keyN valueN 一次設定多個key的值,成功傳回1表示所有的值都設定了,失敗傳回0表示沒有任何值被設定

•msetnx key1 value1 … keyN valueN 同上,但是不會覆寫已經存在的key

•incr key 對key的值做加加操作,并傳回新的值。注意incr一個不是int的value會傳回錯誤,incr一個不存在的key,則設定key為1

•decr key 同上,但是做的是減減操作,decr一個不存在key,則設定key為-1

•incrby key integer 同incr,加指定值 ,key不存在時候會設定key,并認為原來的value是 0

decrby key integer 同decr,減指定值。decrby完全是為了可讀性,我們完全可以通過incrby一個負值來實作同樣效果,反之一樣。

append key value 給指定key的字元串值追加value,傳回新字元串值的長度。

•substr key start end 傳回截取過的key的字元串值,注意并不修改key的值。下标是從0開始的。

List

•redis的list類型其實就是一個每個子元素都是string類型的雙向連結清單。我們可以通過push,pop操作從連結清單的頭部或者尾部添加删除元素。這使得list既可以用作棧,也可以用作隊列。

•list的pop操作還有阻塞版本的。當我們[lr]pop一個list對象是,如果list是空,或者不存在,會立即傳回nil。但是阻塞版本的b[lr]pop可以則可以阻塞,當然可以加逾時時間,逾時後也會傳回nil。為什麼要阻塞版本的pop呢,主要是為了避免輪詢。舉個簡單的例子如果我們用list來實作一個工作隊列。執行任務的thread可以調用阻塞版本的pop去擷取任務這樣就可以避免輪詢去檢查是否有任務存在。當任務來時候工作線程可以立即傳回,也可以避免輪詢帶來的延遲。

List相關指令

•lpush key string 在key對應list的頭部添加字元串元素,傳回1表示成功,0表示key存在且不是list類型

•rpush key string 同上,在尾部添加

•llen key 傳回key對應list的長度,key不存在傳回0,如果key對應類型不是list傳回錯誤

•lrange key start end 傳回指定區間内的元素,下标從0開始,負值表示從後面計算,-1表示倒數第一個元素 ,key不存在傳回空清單

•ltrim key start end 截取list,保留指定區間内元素,成功傳回1,key不存在傳回錯誤

•lset key index value 設定list中指定下标的元素值,成功傳回1,key或者下标不存在傳回錯誤

•lrem key count value 從key對應list中删除count個和value相同的元素。count為0時候删除全部

lpop key 從list的頭部删除元素,并傳回删除元素。如果key對應list不存在或者是空傳回nil,如果key對應值不是list傳回錯誤

•rpop 同上,但是從尾部删除

•blpop key1…keyN timeout 從左到右掃描傳回對第一個非空list進行lpop操作并傳回,比如blpop list1 list2 list3 0 ,如果list不存在,list2,list3都是非空則對list2做lpop并傳回從list2中删除的元素。如果所有的list都是空或不存在,則會阻塞timeout秒,timeout為0表示一直阻塞。

當阻塞時,如果有client對key1…keyN中的任意key進行push操作,則第一在這個key上被阻塞的client會立即傳回。如果逾時發生,則傳回nil。

•brpop 同blpop,一個是從頭部删除一個是從尾部删除

•rpoplpush srckey destkey 從srckey對應list的尾部移除元素并添加到destkey對應list的頭部,最後傳回被移除的元素值,整個操作是原子的.如果srckey是空

或者不存在傳回nil

Set

•redis的set是string類型的無序集合。

•set元素最大可以包含(2的32次方-1)個元素。

•set的是通過hash table實作的,hash table會随着添加或者删除自動的調整大小

關于set集合類型除了基本的添加删除操作,其他有用的操作還包含集合的取并集(union),交集(intersection),差集(difference)。通過這些操作可以很容易的實作sns中的好友推薦和blog的tag功能。

Set相關指令

•sadd key member 添加一個string元素到,key對應的set集合中,成功傳回1,如果元素以及在集合中傳回0,key對應的set不存在傳回錯誤

•srem key member 從key對應set中移除給定元素,成功傳回1,如果member在集合中不存在或者key不存在傳回0,如果key對應的不是set類型的值傳回錯誤

•spop key 删除并傳回key對應set中随機的一個元素,如果set是空或者key不存在傳回nil

•srandmember key 同spop,随機取set中的一個元素,但是不删除元素

•smove srckey dstkey member 從srckey對應set中移除member并添加到dstkey對應set中,整個操作是原子的。成功傳回1,如果member在srckey中不存在傳回0,如果key不是set類型傳回錯誤

•scard key 傳回set的元素個數,如果set是空或者key不存在傳回0

•sismember key member 判斷member是否在set中,存在傳回1,0表示不存在或者key不存在

•sinter key1 key2…keyN 傳回所有給定key的交集

•sinterstore dstkey key1…keyN 同sinter,但是會同時将交集存到dstkey下

•sunion key1 key2…keyN 傳回所有給定key的并集

•sunionstore dstkey key1…keyN 同sunion,并同時儲存并集到dstkey下

•sdiff key1 key2…keyN 傳回所有給定key的差集

•sdiffstore dstkey key1…keyN 同sdiff,并同時儲存差集到dstkey下

•smembers key 傳回key對應set的所有元素,結果是無序的

Sorted set

•和set一樣sorted set也是string類型元素的集合,不同的是每個元素都會關聯一個double類型的score。sorted set的實作是skip list和hash table的混合體。當元素被添加到集合中時,一個元素到score的映射被添加到hash table中,另一個score到元素的映射被添加到skip list

并按照score排序,是以就可以有序的擷取集合中的元素。

Sorted set 相關指令

•zadd key score member 添加元素到集合,元素在集合中存在則更新對應score

•zrem key member 删除指定元素,1表示成功,如果元素不存在傳回0

•zincrby key incr member 增加對應member的score值,然後移動元素并保持skip list有序。傳回更新後的score值

•zrank key member 傳回指定元素在集合中的排名(下标,非score),集合中元素是按score從小到大排序的

•zrevrank key member 同上,但是集合中元素是按score從大到小排序

•zrange key start end 類似lrange操作從集合中取指定區間的元素。傳回的是有序結果

•zrevrange key start end 同上,傳回結果是按score逆序的

•zrangebyscore key min max 傳回集合中score在給定區間的元素

•zcount key min max 傳回集合中score在給定區間的數量

•zcard key 傳回集合中元素個數

•zscore key element 傳回給定元素對應的score

•zremrangebyrank key min max 删除集合中排名在給定區間的元素

•zremrangebyscore key min max 删除集合中score在給定區間的元素

Hash

•redis hash是一個string類型的field和value的映射表。

•hash特别适合用于存儲對象。相較于将對象的每個字段存成單個string類型。将一個對象存儲在hash類型中會占用更少的記憶體,并且可以更友善的存取整個對象。

Hash相關指令

•hset key field value 設定hash field為指定值,如果key不存在,則先建立

•hget key field 擷取指定的hash field

•hmget key filed1….fieldN 擷取全部指定的hash filed

•hmset key filed1 value1 … filedN valueN 同時設定hash的多個field

•hincrby key field integer 将指定的hash filed 加上給定值

•hexists key field 測試指定field是否存在

•hdel key field 删除指定的hash field

•hlen key 傳回指定hash的field數量

•hkeys key 傳回hash的所有field

•hvals key 傳回hash的所有value

hgetall 傳回hash的所有filed和value

繼續閱讀