1. 程式人生 > >redis 進階

redis 進階

redis進階

Redis 簡介

Redis 是完全開源免費的,遵守BSD協議,是一個高效能的key-value資料庫。

Redis 與其他 key - value 快取產品有以下三個特點:

  • Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
  • Redis不僅僅支援簡單的key-value型別的資料,同時還提供list,set,zset,hash等資料結構的儲存。
  • Redis支援資料的備份,即master-slave模式的資料備份。

Redis 優勢

  • 效能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的資料型別 – Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。
  • 原子 – Redis的所有操作都是原子性的,同時Redis還支援對幾個操作全並後的原子性執行。
  • 豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。

Redis與其他key-value儲存有什麼不同?

  • Redis有著更為複雜的資料結構並且提供對他們的原子性操作,這是一個不同於其他資料庫的進化路徑。Redis的資料型別都是基於基本資料結構的同時對程式設計師透明,無需進行額外的抽象。

  • Redis執行在記憶體中但是可以持久化到磁碟,所以在對不同資料集進行高速讀寫時需要權衡記憶體,因為資料量不能大於硬體記憶體。在記憶體資料庫方面的另一個優點是,相比在磁碟上相同的複雜的資料結構,
    在記憶體中操作起來非常簡單,這樣Redis可以做很多內部複雜性很強的事情。同時,在磁碟格式方面他們是緊湊的以追加的方式產生的,因為他們並不需要進行隨機訪問。

Linux 下安裝

本教程使用的最新文件版本為 2.8.17,下載並安裝:

$ wget http://download.redis.io/releases/redis-2.8.17.tar.gz
$ tar xzf redis-2.8.17.tar.gz
$ cd redis-2.8.17
$ make

make完後 redis-2.8.17目錄下會出現編譯後的redis**服務程式redis-server**,還有用於測試的客戶端程式redis-cli,兩個程式位於安裝目錄 src 目錄下:
下面啟動redis服務.

$ cd src
$ ./redis-server

注意這種方式啟動redis 使用的是預設配置。也可以通過啟動引數告訴redis使用指定配置檔案使用下面命令啟動。

$ cd src
$ ./redis-server redis.conf
# ./redis-server 命令用來以後面所跟的redis.conf配置檔案的配置方式進行啟動

redis.conf是一個預設的配置檔案。我們可以根據需要使用自己的配置檔案。
啟動redis服務程序後,就可以使用測試客戶端程式redis-cli和redis服務互動了。 比如:

$ cd src
$ ./redis-cli
redis> set foo ba
OK
redis> get foo
"bar"

注意: 可以把src這個目錄新增到環境變數,這樣在任何目錄下就可以使用 redis-server

Redis 配置

Redis 的配置檔案位於 Redis 安裝目錄下,檔名為 redis.conf。

引數說明
redis.conf 配置項說明如下:
1. Redis預設不是以守護程序的方式執行,可以通過該配置項修改,使用yes啟用守護程序

    daemonize no
  1. 當Redis以守護程序方式執行時,Redis預設會把pid寫入/var/run/redis.pid檔案,可以通過pidfile指定

    pidfile /var/run/redis.pid
    
  2. 指定Redis監聽埠,預設埠為6379,作者在自己的一篇博文中解釋了為什麼選用6379作為預設埠,因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自義大利歌女Alessia Merz的名字

    port 6379
    
  3. 繫結的主機地址

        bind 127.0.0.1
    

    5.當 客戶端閒置多長時間後關閉連線,如果指定為0,表示關閉該功能

    timeout 300
    
  4. 指定日誌記錄級別,Redis總共支援四個級別:debug、verbose、notice、warning,預設為verbose

    loglevel verbose
    
  5. 日誌記錄方式,預設為標準輸出,如果配置Redis為守護程序方式執行,而這裡又配置為日誌記錄方式為標準輸出,則日誌將會發送給/dev/null

    logfile stdout
    
  6. 設定資料庫的數量,預設資料庫為0,可以使用SELECT 命令在連線上指定資料庫id

    databases 16
    
  7. 指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合

    save <seconds> <changes>
    Redis預設配置檔案中提供了三個條件:
    save 900 1
    save 300 10
    save 60 10000
    分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。
    
  8. 指定儲存至本地資料庫時是否壓縮資料,預設為yes,Redis採用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大

    rdbcompression yes
    
  9. 指定本地資料庫檔名,預設值為dump.rdb

    dbfilename dump.rdb
    

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

    dir ./
  1. 設定當本機為slav服務時,設定master服務的IP地址及埠,在Redis啟動時,它會自動從master進行資料同步

    slaveof <masterip> <masterport>
    
  2. 當master服務設定了密碼保護時,slav服務連線master的密碼

    masterauth <master-password>
    
  3. 設定Redis連線密碼,如果配置了連線密碼,客戶端在連線Redis時需要通過AUTH 命令提供密碼,預設關閉

    requirepass foobared
    
  4. 設定同一時間最大客戶端連線數,預設無限制,Redis可以同時開啟的客戶端連線數為Redis程序可以開啟的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當客戶端連線數到達限制時,Redis會關閉新的連線並向客戶端返回max number of clients reached錯誤資訊

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

    maxmemory <bytes>
    
  6. 指定是否在每次更新操作後進行日誌記錄,Redis在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為 redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。預設為no

    appendonly no
    
  7. 指定更新日誌檔名,預設為appendonly.aof

     appendfilename appendonly.aof
    
  8. 指定更新日誌條件,共有3個可選值:

    no:表示等作業系統進行資料快取同步到磁碟(快) 
    always:表示每次更新操作後手動呼叫fsync()將資料寫到磁碟(慢,安全) 
    everysec:表示每秒同步一次(折衷,預設值)
    appendfsync everysec
    
  9. 指定是否啟用虛擬記憶體機制,預設值為no,簡單的介紹一下,VM機制將資料分頁存放,由Redis將訪問量較少的頁即冷資料swap到磁碟上,訪問多的頁面由磁碟自動換出到記憶體中(在後面的文章我會仔細分析Redis的VM機制)

     vm-enabled no
    
  10. 虛擬記憶體檔案路徑,預設值為/tmp/redis.swap,不可多個Redis例項共享

     vm-swap-file /tmp/redis.swap
    
  11. 將所有大於vm-max-memory的資料存入虛擬記憶體,無論vm-max-memory設定多小,所有索引資料都是記憶體儲存的(Redis的索引資料 就是keys),也就是說,當vm-max-memory設定為0的時候,其實是所有value都存在於磁碟。預設值為0

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

     vm-page-size 32
    
  13. 設定swap檔案中的page數量,由於頁表(一種表示頁面空閒或使用的bitmap)是在放在記憶體中的,,在磁碟上每8個pages將消耗1byte的記憶體。

     vm-pages 134217728
    
  14. 設定訪問swap檔案的執行緒數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是序列的,可能會造成比較長時間的延遲。預設值為4

     vm-max-threads 4
    
  15. 設定在向客戶端應答時,是否把較小的包合併為一個包傳送,預設為開啟

    glueoutputbuf yes
    
  16. 指定在超過一定的數量或者最大的元素超過某一臨界值時,採用一種特殊的雜湊演算法
    hash-max-zipmap-entries 64
    hash-max-zipmap-value 512

  17. 指定是否啟用重置雜湊,預設為開啟(後面在介紹Redis的雜湊演算法時具體介紹)

    activerehashing yes
    
  18. 指定包含其它的配置檔案,可以在同一主機上多個Redis例項之間使用同一份配置檔案,而同時各個例項又擁有自己的特定配置檔案

    include /path/to/local.conf
    

Redis 資料型別

Redis支援五種資料型別:string(字串),hash(雜湊),list(列表),set(集合)及zset(sorted set:有序集合)。

Redis命令

Redis keys 命令
下表給出了與 Redis 鍵相關的基本命令:

1   DEL key

該命令用於在 key 存在時刪除 key。

2   DUMP key 

序列化給定 key ,並返回被序列化的值。

3   EXISTS key 

檢查給定 key 是否存在。

4   EXPIRE key seconds

為給定 key 設定過期時間。

5   EXPIREAT key timestamp 

EXPIREAT 的作用和 EXPIRE 類似,都用於為 key 設定過期時間。 不同在於 EXPIREAT 命令接受的時間引數是 UNIX 時間戳(unix timestamp)。

6   PEXPIRE key milliseconds 

設定 key 的過期時間以毫秒計。

7   PEXPIREAT key milliseconds-timestamp 

設定 key 過期時間的時間戳(unix timestamp) 以毫秒計

8   KEYS pattern 

查詢所有符合給定模式( pattern)的 key 。

9   MOVE key db 

將當前資料庫的 key 移動到給定的資料庫 db 當中。

10  PERSIST key 

移除 key 的過期時間,key 將持久保持。

11  PTTL key 

以毫秒為單位返回 key 的剩餘的過期時間。

12  TTL key 

以秒為單位,返回給定 key 的剩餘生存時間(TTL, time to live)。

13  RANDOMKEY 

從當前資料庫中隨機返回一個 key 。

14  RENAME key newkey 

修改 key 的名稱

15  RENAMENX key newkey 

僅當 newkey 不存在時,將 key 改名為 newkey 。

16  TYPE key 

返回 key 所儲存的值的型別。

Redis 字串命令

Redis hash 命令

Redis 列表命令

Redis 有序集合命令

Redis 事務

Redis 事務可以一次執行多個命令, 並且帶有以下兩個重要的保證:

  • 事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。
  • 事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。

一個事務從開始到執行會經歷以下三個階段:

  • 開始事務。
  • 命令入隊。
  • 執行事務。

* Redis的持久化

Redis的強大功能很大程度上是由於其將所有資料都儲存在記憶體中,為了使Redis在重啟後仍能保證資料不丟失,需要將資料從記憶體中以某種形式持久化到硬碟中。

Redis支援兩種方式的持久化,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或將兩種結合使用。

RDB方式是通過快照完成的,當符合一定條件時Redis會自動將記憶體中的所有資料進行快照並且儲存到硬碟上。進行快照的條件在配置檔案中指定,有2個引數構成:時間和改動的鍵的個數,當在指定時間內被更改的鍵的個數大於指定數值時就會進行快照。

RDB是Redis的預設持久化方式。

Redis的持久化之RDB

在配置檔案中已經預置了3個條件:

save 900 1  #15分鐘內有至少1個鍵被更改則進行快照
save 300 10  #5分鐘內至少有10個鍵被更改則進行快照
save 60 10000  #1分鐘內至少有100000個鍵被更改則進行快照

以上條件之間是“或”的關係。

預設的rdb的檔案路徑是在當前目錄,檔名是:dump.rdb,可以在配置檔案中修改路徑和檔名,分別是dir和dbfilename。

Redis啟動後會讀取RDB快照檔案,將資料從硬碟載入到記憶體,一般情況下1GB的快照檔案載入到記憶體的時間約為20~30秒鐘。(不同伺服器會有差異)

RDB資料恢復過程

RDB的快照過程如下:

Redis使用fork函式複製一份當前程序(父程序)的副本(子程序);
父程序繼續接收並處理客戶端發來的命令,而子程序開始將記憶體中的資料寫入到硬碟中的臨時檔案;
當子程序寫入完所有資料後會用該臨時檔案替換舊的RDB檔案。

RDB檔案是通過壓縮的,可以通過配置rdbcompression引數來禁用壓縮

Redis的持久化之AOF

Redis的AOF持久化策略是將傳送到Redis服務端的每一條命令都記錄下來,並且儲存到硬碟中的AOF檔案,AOF檔案的位置和RDB檔案的位置相同,都是通過dir引數設定,預設的檔名是appendonly.aof,可以通過appendfilename引數修改。

檔案寫入預設情況下會先寫入到系統的快取中,系統每30秒同步一次,才是真正的寫入到硬碟,如果在這30秒伺服器宕機那資料也會丟失的,Redis可以通過配置來修改同步策略:

    # appendfsync always  每次都同步 (最安全但是最慢)
    appendfsync everysec  每秒同步  (預設的同步策略)
    # appendfsync no  不主動同步,由作業系統來決定 (最快但是不安全)