緣起
- 想找一個開源技術點深入下去的,於是找到了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
後,再輸入PING
或ECHO hi
無關大小寫
-
-
-
2.3.2 命令返回值
- 狀態回覆
- 錯誤回覆
- 整數回覆
- 字串回覆
- 多行字串回覆
2.4、配置
-
redis-server /path/to/redis.conf
這個路徑我沒找到,只是解壓目錄下有個redis.conf
檔案 -
$redis> CONFIG SET
命令在不重新啟動Redis的情況下動態修改部分Redis配置
2.5、多資料庫
- 預設支付16個資料庫
select 0
到select 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目錄下,後面會用到。
- 解壓後放入專案目錄中,引用autoload.php檔案
-
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`);
- 載入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管理的話,只是作了部分的瞭解。