《Redis入門指南(第2版)》摘要

im天行發表於2018-11-27

緣起

  • 想找一個開源技術點深入下去的,於是找到了redis,比較好的是,他有相應的學習曲線。
  • 全書第1遍用了3h19min的樣子,20181117開始讀的,20181123讀完。還會繼續閱讀第2遍或第3遍,雖然原理性可能不太多,但我還沒有很好的消化它,雖然這本書不是每個點都要了解,但還是要讀到覺得能放下為止。
  • 下一本讀《Redis實戰》

內容

  • 目錄 8/224

chap1 簡介 11/224

1.1、歷史與發展

  • 網站實時統計系統LLOOGG,創始人是義大利的Salvatore Sanfilippo
  • 是REmote DIctionary Server(遠端字典伺服器)的縮寫。

1.2、特性

  • 1.2.1 儲存結構
  • 1.2.2 記憶體儲存與持久化

    • 資料都在記憶體中,程式退出後記憶體中的資料如何儲存?
  • 1.2.3 功能豐富

    • 為每個鍵設定生存時間(Time To Live)
  • 1.2.4 簡單穩定

    • HGET post:1 title // 讀取鍵名為post:1 的雜湊型別鍵的title欄位的值

chap2 準備 17/224

2.1、安裝Redis

  • 2.1.1 在POSIX系統中安裝

  • 2.1.2 在OS X系統中安裝
  • 2.1.3 在Windows中安裝

    • 比較麻煩

2.2、啟動和停止Redis 11(21/224)

  • make後繼續執行make install相應的6個命令會拷貝到/usr/local/bin目錄下。
  • 2.2.1 啟動Redis

    • 直接啟動

      • redis-server,預設埠是6379;可以用port引數指定,即redis-server --port 6380
    • 通過初始化指令碼啟動

      • redis/utils/redis_init_script的指令碼檔案
      • 複製指令碼到/etc/init.d目錄中
  • 2.2.2 停止Redis

    • redis-cli SHUTDOWN

2.3、Redis命令列客戶端

  • 2.3.1 傳送命令

    • 引數模式

      • redis-cli -h 127.0.0.1 -p 6379
      • redis-cli PING
    • 互動模式

      • redis-cli後,再輸入PINGECHO hi 無關大小寫
  • 2.3.2 命令返回值

    • 狀態回覆
    • 錯誤回覆
    • 整數回覆
    • 字串回覆
    • 多行字串回覆

2.4、配置

  • redis-server /path/to/redis.conf 這個路徑我沒找到,只是解壓目錄下有個redis.conf檔案
  • $redis> CONFIG SET命令在不重新啟動Redis的情況下動態修改部分Redis配置

2.5、多資料庫

  • 預設支付16個資料庫select 0select 15
  • 這些資料庫更像是一種名稱空間;一個空Redis例項佔用的記憶體只有1M左右。

chap3 入門 29/224

3.1、熱身

  • 1、獲得符合規則的鍵名列表

    • KEYS pattern patern支援glob風格萬用字元
    • set bar 1
    • keys * keys命令需要遍歷Redis中的所有鍵,會影響效能,不建議用
  • 2、判斷一個鍵是否存在

    • exists bar
    • exists no //返回值是(integer) 0
  • 3、刪除鍵

    • del bar del命令不支付萬用字元
    • redis-cli keys "user:*" | xargs redis-cli del來實現刪除
  • 4、獲取鍵值的資料型別

    • type bar

3.2、字串型別

  • 3.2.1 介紹

    • 一個字串型別鍵允許儲存的資料的最大容量是512MB
  • 3.2.2 命令

    • 1、複製與取值

      • set key hello
      • get key
    • 2、遞增數字

      • INCR num
  • 3.2.3 實踐

    • 1、文章訪問量統計
    • 2、生成自增ID
    • 3、儲存文章資料
  • 3.2.4 命令拾遺

    • 1、增加指定的整數

      • INCRBY bar 2
    • 2、減少指定的整數

      • DECR bar 只是遞減,無法減多少
    • 3、增加指定浮點數

      • INCRBYFLOAT bar 2.7
    • 4、向尾部追加值

      • set key hello
      • append key " world!" // 返回的是總長度
    • 5、獲取字串長度

      • STRLEN key
    • 6、位操作 lionel這部分沒看

3.3、雜湊型別

  • 3.3.1 介紹

    • 一個雜湊型別鍵可以包含至多2的32次方-1個欄位
  • 3.3.2 命令

    • 1、賦值與取值

      • HSET car price 500
      • HSET car name BMW
      • HGET car name
      • 需要同時設定多個欄位的值時,可以使用HMSET命令
      • HMGET car price name // 同時獲得多個欄位的值
      • HGETALL car // 想獲取鍵中所有欄位和這段值都不知道鍵中有哪些欄位時
    • 2、判斷欄位是否存在

      • HEXISTS car model
    • 3、當欄位不存在時賦值

      • HSETNX // 是原子操作,不用擔心競態條件
    • 4、增加數字

      • HINCRBY person score 60 // person鍵不存在,會建立該鍵並預設score欄位在執行命令前的值為“0”。返回值是60
      • HINCRBY person score 1 // 因為存在了,所以返回值是61
    • 5、刪除欄位

      • `HDEL`
  • 3.3.3 實踐 lionel也沒怎麼好好看

    • 1、儲存文章資料
    • 2、儲存文章縮略名
  • 3.3.4 命令拾遺

    • 1、只獲取欄位名或欄位值

      • HKEYS car
      • HVALS car
    • 2、獲取欄位數量

      • HLEN car

3.4、列表型別

  • 3.4.1 介紹

    • 一個列表(List)型別鍵可以包含至多2的32次方-1個元素
  • 3.4.2 命令

    • 1、向列表兩端增加元素

      • LPUSH numbers 1 // 返回列表的長度 1
      • RPUSH numbers 0 -1 // 返回列表的長度 3
    • 2、從列表兩端彈出元素

      • LPOP numbers
      • RPOP numbers
    • 3、獲取列表中元素的個數

      • HLEN numbers
    • 4、獲取列表片斷

      • LRANGE numbers 0 2 // 獲取一個區間的資料
    • 5、刪除列表中指定的值

      • LREM numbers 0 -1 // count=0,刪除所有“-1”的元素
      • LREM numbers -1 // count<0,從列表右邊開始刪除第1個元素;cout>0時,從左邊刪
  • 3.4.3 實踐 lionel沒怎麼看

    • 1、儲存文章ID列表
    • 2、儲存評論列表
  • 3.4.4 命令拾遺

    • 1、獲得/設定指定索引的元素值

      • LINDEX numbers 0
      • LSET numbers 1 7
    • 2、只保留列表指定片段

      • LRANGE numbers 0 -1
    • 3、向列表中插入元素

      • LINSERT numbers AFTER 7 3
      • LINSERT numbers BEFORE 2 1
    • 4、將元素從一個列表轉到另一個列表

      • RPOPLPUSH

3.5、集合型別

  • 3.5.1 介紹

    • 一個集合(set)型別鍵可以包含至多2的32次方-1個字串
  • 3.5.2 命令

    • 1、增加/刪除元素

      • SADD letters a b c // 返回增加的個數 3
      • SREM letters c d // 返回刪除的個數1,因為d本身就不存 在
    • 2、獲得集合中的所有元素

      • SEMBERS letters
    • 3、判斷元素是否在集合中

      • SISMEMBER letters a
    • 4、集合間運算

      • SDIFF
      • SINTER
      • SUNION
  • 3.5.3 實踐

    • 1、儲存文章標籤
    • 2、通過標籤搜尋文章
  • 3.5.4 命令拾遺

    • 1、獲得集合中元素個數

      • SCARD letters
    • 2、進行集合運算並將結果儲存

      • SINTERSTORE
    • 3、隨機獲得集合中的元素

      • SRANDMEMBER letters
    • 4、從集合中彈出一個元素

      • SPOP letters

3.6、有序集合型別

  • 3.6.1 介紹

    • 有序集合與連結串列的異同
  • 3.6.2 命令

    • 1、增加元素

      • ZADD scoreboard 89 Tom 67 Peter 100 David
    • 2、獲得元素的分數

      • ZSCORE scoreboard Tom 69/224 lionel 沒怎麼讀
  • 3.6.3 實踐

    • 1、實現按點選量排序
    • 2、改進按時間排序
  • 3.6.4 命令拾遺

    • 1、獲得集合中元素的數量

      • ZCARD scoreboard
    • 2、獲得指定分數範圍內的元素個數
    • 3、刪除一個或多個元素
    • 4、按照排名範圍刪除元素 lionel也沒怎麼看呢

chap4 進階 67(77/224)

4.1、事務

  • 4.1.1 概述

    • MULTI命令告訴Redis,下面的命令屬於事務。
  • 4.1.2 錯誤處理

    • 語法錯誤 直接不執行,返回錯誤碼
    • 執行錯誤 不支援回滾功能,只能將資料庫復原到之前的狀態
  • 4.1.3 WATCH命令介紹

    • WATCH命令可以監控一個或多個鍵,一旦其中有一個鍵被修改(或刪除),之後的事務就不會執行
    • UNWATCH取消監控

4.2、過期時間

  • 4.2.1 命令介紹

    • SET session:29e3d uid1314
    • EXPIRE session:29e3d 900 // 讓session:29e3d鍵在15分鐘後被刪除。 EXPIRE命令設定一個鍵的過期時間,到時期後Redis會自動刪除它
    • TTL session:29e3d // session:29e3d鍵的剩餘時間
    • PERSIST session:29e3d // 取消session:29e3d鍵的過期時間設定
  • 4.2.2 實現訪問頻率限制之一

    • 限制每分鐘每個使用者最多隻能訪問100個頁面。
  • 4.2.3 實現訪問頻率限制之二
  • 4.2.4 實現快取

    • 修改配置檔案的maxmemory引數,限制Redis最大可用記憶體大小,超出限制時Redis會依據maxmemory-policy引數指定的策略來刪除不需要的鍵,直到Redis佔用的記憶體小於指定記憶體。

4.3、排序

  • 4.3.1 有序集合的集合操作
  • 4.3.2 SORT命令
  • 4.3.3 BY引數

    • SORT sortbylist BY somkey->somefield:* // *只能在->符號前面才有用,否則只會被當作欄位名本身
  • 4.3.4 GET引數

    • SORT tag:ruby:posts BY post:*->time DESC post:*->title // GET引數不影響排序,作用是使SORT命令的返回結果不再是元素自身的值,而是GET引數中指定的鍵值。
  • 4.3.5 STORE引數

    • SORT tag:ruby:posts BY post:*->time DESC GET post:*->title GET post:*->time GET # STORE sort.result // 儲存排序結果,預設是直接返回排序結果的
  • 4.3.6 效能優化

    • SORT的時間複雜度是O(n+mlog(m))
    • 使用SORT命令時有幾點注意:

      • 儘可能減少待排序的資料(N儘可能小)
      • 使用LIMIT引數只獲取需要的資料(使M儘可能小)
      • 如果要排序的資料量較大,儘可能使用STORE引數將結果快取

4.4、訊息通知

  • 4.4.1 任務佇列
  • 4.4.2 使用Redis實現任務佇列
  • 4.4.3 優先順序佇列 lionel沒好好看,以及4.4到目前
  • 4.4.4 “釋出/訂閱”模式

    • PUBLISH channel.2 hi // 向channel.2說一聲“hi” 釋出者
    • SUBSCRIBE chanel.2 // 訂閱者
  • 4.4.5 按照規則訂閱

    • PSUBSCRIBE channel.?* // 訂閱指令的規則,支援glob風格萬用字元

4.5、管道

4.6 節省空間

  • 4.6.1 精簡鍵名和鍵值
  • 4.6.2 內部編碼優化 lionel沒好好看

    • 0、
    • 1、字串型別

chap5 實踐 103(113/224)

5.1、PHP與Redis

  • 5.1.1 安裝

    • 解壓後放入專案目錄中,引用autoload.php檔案require `./dir/autoload.php` 假設在dir目錄下,後面會用到
  • 5.1.2 使用方法

    • 建立一個連線

      • $redis = new dirClient();
      • $redis = new dirClient(arry(`scheme`=>`tcp`,`host`=>`127.0.0.1`,`port`=>6379,));
      • echo $redis->get(`foo`);
  • 5.1.3 簡便用法
  • 5.1.4 實踐:使用者註冊登入功能

5.2、Ruby與Redis

  • 5.2.1 安裝

    • gem install redis安裝新版的redis-rb
  • 5.2.2 使用方法
  • 5.2.3
  • 5.2.4

5.3、Python與Redis

  • 5.3.1 安裝

    • pip install redis
  • 5.3.2 使用方法

    • import redis // 引入redis-py
  • 5.3.3 簡便用法

    • 1、HMSET/HGETALL
    • 2、事務和管道
  • 5.3.4 實踐:線上的好友

5.4、Node.js與Redis

  • 5.4.1 安裝

    • npm install ioredis
  • 5.4.2 使用方法

    • 載入ioredis模組var Redis = require(`ioredis`);
  • 5.4.3 簡便用法

    • 1、HMSET/HGETALL
    • 2、事務
    • 3、“釋出/訂閱”模式
  • 5.4.4 實踐:IP地址查詢

chap6 指令碼 131(141/224)

6.1、概覽

  • 6.1.1 指令碼介紹

    • 允許開發者使用Lua語言編寫指令碼傳到Redis中執行。
    • 指令碼的好處:

      • (1)減少網路開銷
      • (2)原子操作
      • (3)複用
  • 6.1.2 例項:訪問頻率限制

6.2、Lua語言

  • 6.2.1 Lua語法

    • 資料型別
    • 變數
    • 註釋
    • 賦值
    • 操作符
    • if語句
    • 迴圈語句
    • 表型別
    • 函式
  • 6.2.2 標準庫

    • String庫
    • Table庫
    • Math庫
  • 6.2.3 其他庫

    • cjson庫
    • cmsgpack庫

6.3、Redis與Lua

  • 6.3.1 在指令碼中呼叫Redis命令
  • 6.3.2 從指令碼中返回值
  • 6.3.3 指令碼相關命令

    • 1、EVAL命令
    • 2、EVALSHA命令
  • 6.3.4 應用例項

    • 1、同時獲取多個雜湊型別鍵的鍵值
    • 2、獲利並刪除有序集合中分數最小的元素
    • 3、處理JSON

6.4、深入指令碼

  • 6.4.1 KEYS與ARGV
  • 6.4.2 沙盒與隨機數
  • 6.4.3 其他指令碼相關命令

    • 1、將指令碼加入快取:SCRIPT LOAD
    • 2、判斷指令碼是否已經被快取:SCRIPT EXISTS
    • 3、清空指令碼快取:SCRIPT FLUSH
    • 4、強制終止當前指令碼的執行:SCRIPT KILL
  • 6.4.4 原子性和執行時間

chap7 持久化 157(167/224)

7.1、RDB方式

  • 0、

    • 通過快照(snapshotting)完成的。當符合一定條件的Redis會自動將記憶體中的所有資料生成一份副本並儲存在硬碟上,這個過程即為“快照“。
    • 在以下情況對資料進行快照:

      • 根據配置規則進行自動快照
      • 使用者執行SAVE或BGSAVE命令
      • 執行FLUSHALL命令
      • 執行復制(replication)時
  • 7.1.1 根據配置規則進行自動快照
  • 7.1.5 快照原理

    • 在執行fork時OS會使用寫時複製(copy-on-write)策略,即fork函式發生的一刻子程式共享同一記憶體資料
    • 所以新的RDB檔案儲存的是執行fork一刻的記憶體資料。
    • 我們通過定時備份RDB檔案來實現Redis資料庫備份

7.2、AOF方式

  • 7.2.1 開啟AOF

    • appendonly yes**通過手工開啟,預設沒有開啟(AOF append only file)
  • 7.2.2 AOF的實現
  • 7.2.3 同步硬碟資料

    • 作業系統的快取機制,資料並沒有真正地寫入硬碟,而是進入了系統的硬碟快取。在預設情況下系統每30秒會執行一次同步操作,以便將硬碟快取中的內容真正地寫入硬碟。
    • appendfsync everysec // 採用everysec規則

chap8 叢集 165(175/224)

8.1、複製

  • 8.1.1 配置

    • $ redis-server --port 6380 --slaveof 127.0.0.1 6379
    • SALVEOF命令會停止和原來資料庫的同步轉而和新資料庫同步。
  • 8.1.2 原理
  • 8.1.3 圖結構
  • 8.1.4 讀寫分離與一致性

    • 一主多從的結構很適合讀多寫少的場景,主資料庫只進行寫操作,從資料庫負責讀操作。
  • 8.1.5 從資料庫持久化
  • 8.1.6 無硬碟複製
  • 8.1.7 增量複製

8.2、哨兵

  • 8.2.1 什麼是哨兵
  • 8.2.2 馬上上手
  • 8.2.3 實現原理

    • 一個哨兵節點可以同時監控多個Redis主從系統,只需要提供多個sentinel monitor配置即可。
  • 8.2.4 哨兵的部署

    • 哨兵以獨立程式的方式對一個主從系統進行監控

8.3、叢集

  • 8.3.1 配置叢集

    • 需要將每個資料庫節點的cluster-enabled配置選項開啟即可。
  • 8.3.2 節點的增加
  • 8.3.3 插槽的分配
  • 8.3.4 獲取與插槽對應的節點
  • 8.3.5 故障恢復

chap9 管理 193(203/224)

9.1、安全

  • 9.1.1 可信的環境
  • 9.1.2 資料庫密碼
  • 9.1.3 命名命令

9.2、通訊協議

  • 9.2.1 簡單協議

    • 適合在telnet程式中和Redis通訊。
  • 9.2.2 統一請求協議

9.3、管理工具

  • 9.3.1 redis-cli

    • 耗時命令日誌

      • redis> SLOWLOG GET
    • 命令監控

      • redis> MONITOR
  • 9.3.2 phpRedisAdmin
  • 9.3.3 Rdbtools

附錄 203(213/224)

附錄A

  • A.1 REDIS_CMD_WRITE
  • A.2 REDIS_CMD_DENYOOM
  • A.3 REDIS_CMD_NOSCRIPT

附錄B

附錄C CRC16 實現參考

收穫

履歷

  • 20181117從頭開始看到3.2.4節(1-37/224),用時1h16min。不太理解的地方

    • (1)用命令列配置啟動;(2)redis配置; 雖然照著會做,但知識點上沒有融匯貫通
  • 20181119從3.2.4看到4.1.2(37-80/224),用時1h02min。差不多我只能堅持看1小時書

    • 中間有幾個地方跳過沒好好看,後期要補上,主要是單純的用命令,不知道場景在哪,可能屬於基礎吧,還是需要熟悉。
    • 要確認各個型別的區別,以及知道他們的優缺點。
  • 20181120從4.1.2看到5.3.1(80-126/224),用時40min

    • 在4.4訊息通知方面沒怎麼看,包括4.6節省空間方面。
    • 其它方面的知識呢,差不多都能理解。可以搜搜面試指南來查漏或夯實知識
  • 20181121從5.3.1看到7.1.4(126-169/224),用時21min。其實沒怎麼看,就是過了下結構

    • 畢竟第chap6的Lua和chap5實踐,都需要搭建環境去跑的,算是個大概瞭解吧,估計後期會選用Python進行實踐,因為《Redis實戰》用的是這個。
    • chap7持久化開了個頭,因為前期還搜了部分知道,看起來不覺得費勁。
  • 20181123從7.1.5看到結束(169-224/224),用時26min。也沒有過多學習新知識,就是看個大概。

    • 瞭解了下AOF方式。
    • 叢集的話,面試環境可能會在複製這部分有些問題要問,自己也有點感觸,但哨兵和叢集,可能在架構或配置時要用。
    • chap9管理的話,只是作了部分的瞭解。