花了一週左右,全面的學習redis的知識,並記錄學習筆記
原文請訪問我的技術部落格番茄技術小棧
redis初識
導學
盛讚redis
- 高效能key-value伺服器
- 多種資料結構
- 豐富的功能
- 高可用的分散式支援
redis初識
定義
Redis是一個使用ANSI C編寫的開源、支援網路、基於記憶體、可選永續性的鍵值對儲存資料庫
特性
- 開源
- 多種資料結構
- 基於鍵值的儲存服務系統
- 高效能,功能服務
redis的前世今生
誰在使用redis
- github
- 微博
- Stack Overflow
- 阿里巴巴
- 百度
- 美團
- 搜狐
- ......
redis特性目錄
- 速度快
- 持久化
- 多種資料結構
- 支援多種程式語言
- 功能豐富
- 簡單:程式碼短小精悍
- 主從複製
- 高可用、分散式
特性1:速度快
10w QPS
原因
- 資料存在記憶體
- c語言編寫
- 單執行緒編寫
特性2:持久化
- redis所有的資料儲存在記憶體中,對資料的更新將非同步地儲存到磁碟上
特性3:資料結構
特性4:多語言客戶端
- java
- php
- python
- ruby
- lua
- nodejs
特性5:功能豐富
- 釋出訂閱
- lua指令碼
- 事務
- pipeline
特性6:簡單
- 23000行程式碼實現核心功能
- 不依賴外部庫
- 單執行緒模型
特性7:複製
特性8: 高可用
- redis-sentinel支援高可用
- 分散式 redis-cluster支援分散式
redis典型使用場景
- 快取系統
- 計數器
- 訊息佇列系統
- 排行榜
- 社交網路
- 實時系統
redis三種啟動方式
redis安裝(mac&linux)
$ wget http://download.redis.io/releases/redis-4.0.8.tar.gz
$ tar xzf redis-4.0.8.tar.gz
$ cd redis-4.0.8
$ make
複製程式碼
redis可執行檔案說明
命令名 | 命令說明 |
---|---|
redis-server | redis伺服器 |
redis-cli | redis命令列客戶端 |
redis-benchmark | redis效能測試工具 |
redis-check-aof | aof檔案修復工具 |
redis-check-dump | RDB檔案檢查工具 |
redis-sentinel | sentinel伺服器(2.8以後) |
reids三種啟動方法
- 最簡啟動(採用預設配置檔案啟動)
redis-server
複製程式碼
驗證
ps aux | grep redis
複製程式碼
redis-cli -h 127.0.0.1 -p 6379 ping
複製程式碼
- 配置檔案啟動 (將需要配置的引數寫入檔案)
redis-server configPath
複製程式碼
- 動態引數啟動
redis-server --port 6380
複製程式碼
三種啟動方式比較
- 生產環境選擇配置啟動
- 單機多例項配置檔案可以用埠區分開
redis客戶端連線
redis-cli -h 127.0.0.1 -p 6379
複製程式碼
redis客戶端返回值
返回值 | 返回值說明 |
---|---|
狀態回覆 | ping -> pong |
錯誤回覆 | hget hello field -> (error) ERR wrong number of arguments for 'hget' command |
整數回覆 | incr hello -> (integer) 1 |
字串回覆 | get hello -> "1" |
多行字串回覆 | mget hello foo -> 1) "1" 2) (nil) |
redis常用配置
配置名 | 說明 |
---|---|
daemonize | 是否是守護程式(no/yes) |
port | redis對外埠號 |
logfile | redis系統日誌 |
dir | redis工作目錄 |
redis安裝啟動(配置檔案方式)
配置方式
- 配置檔案
vim redis-6382.conf
port 6382
daemonize yes
logfile "6382.log"
dir ./workdata/
複製程式碼
- 啟動
redis-server redis-6382.conf
複製程式碼
- 檢查
ps -aux | grep -v redis-server | grep 6382
複製程式碼
- 日誌檔案
vim workdata/6382.log
複製程式碼
API的理解和使用
通用命令
命令 | 說明 | 時間複雜度 |
---|---|---|
keys [pattern] | 遍歷所有key | O(N) |
dbsize | 遍歷所有key | O(1) |
exists | 檢查key是否存在 | O(1) |
del key | 刪除指定的key-value | O(1) |
expire key seconds | key在seconds秒後過期 | O(1) |
ttl key | 檢視key剩餘的過期時間 | O(1) |
persist key | 去掉key的過期時間 | O(1) |
type key | 返回key的型別 | O(1) |
注意 keys命令一般不再生產環境使用
** 演示**
➜ redis-4.0.8 redis-cli -h 127.0.0.1 -p 6382
127.0.0.1:6382> set hello word
OK
127.0.0.1:6382> set php good
OK
127.0.0.1:6382> set java best
OK
127.0.0.1:6382> keys *
1) "java"
2) "hello"
3) "php"
127.0.0.1:6382> dbsize
(integer) 3
127.0.0.1:6382> exists php
(integer) 1
127.0.0.1:6382> del php java
(integer) 2
127.0.0.1:6382> keys *
1) "hello"
127.0.0.1:6382> expire hello 20
(integer) 1
127.0.0.1:6382> ttl hello
(integer) 16
127.0.0.1:6382> ttl hello
(integer) 12
127.0.0.1:6382> persist hello
(integer) 1
127.0.0.1:6382> ttl hello
(integer) -1
127.0.0.1:6382> type hello
string
複製程式碼
資料結構和內部編碼
圖示
reidsObject
單執行緒
定義
單執行緒在程式執行時,所走的程式路徑按照連續順序排下來,前面的必須處理好,後面的才會執行。
單執行緒為什麼這麼快
- 純記憶體
- 非阻塞IO
- 避免執行緒切換和競態消耗
使用單執行緒要注意什麼
- 一次只能執行一條命令
- 拒絕長(慢)命令
- keys
- flushall
- flushdb
- slow lua script
- mutil/exec
- operate big value(collection)
string
結構
key | value |
---|---|
hello | world |
counter | 1 |
bits | 101111101110 |
可以是字串(json);數字,以及二進位制
使用場景
- 快取
- 計數器
- 分散式鎖
API
命令 | 說明 | 時間複雜度 |
---|---|---|
get key | 獲取key對應的value | O(1) |
set key value | 設定key value | O(1) |
del key | 刪除key-value | O(1) |
incr | key自增1, 如果key不存在,自增後get(key) = 1 | O(1) |
decr | key自減1, 如果key不存在,自增後get(key) = -1 | O(1) |
incrby key k | key自增k, 如果key不存在,自增後get(key) = k | O(1) |
decr key k | key自減k, 如果key不存在,自增後get(key) = -k | O(1) |
set key value | 不管可以是否存在 | O(1) |
setnx key value | key不存在,才設定 | O(1) |
set key value xx | key存在,才設定 | O(1) |
mget key1 key2 key3 | 批量獲取key,原子操作 | O(N) |
mset key1 value1 key2 value2 | 批量設定key-value | O(1) |
getset key newvalue | set key newvalue並返回舊的value | O(1) |
append key value | 將value追加到舊的value | O(1) |
strlen key | 返回字串的長度(注意中文,utf8下一個中文佔用3個字元) | O(1) |
incrbyfloat key 3.5 | 增加key對應的值3.5 | O(1) |
getrange key start end | 獲取字串指定下標所有的值 | O(1) |
setrange key index value | 設定指定下標所有對應的值 | O(1) |
練習
127.0.0.1:6382> set hello "world"
OK
127.0.0.1:6382> get hell
(nil)
127.0.0.1:6382> get hello
"world"
127.0.0.1:6382> del hello
(integer) 1
127.0.0.1:6382> get hello
(nil)
127.0.0.1:6382> get counter
(nil)
127.0.0.1:6382> incr counter
(integer) 1
127.0.0.1:6382> get counter
"1"
127.0.0.1:6382> incrby counter 99
(integer) 100
127.0.0.1:6382> get counter
"100"
127.0.0.1:6382> decr counter
(integer) 99
127.0.0.1:6382> get counter
"99"
127.0.0.1:6382> decrby counter 100
(integer) -1
127.0.0.1:6382> get counter
"-1"
127.0.0.1:6382> exists php
(integer) 0
127.0.0.1:6382> set php good
OK
127.0.0.1:6382> setnx php bad
(integer) 0
127.0.0.1:6382> set php best xx
OK
127.0.0.1:6382> get php
"best"
127.0.0.1:6382> exists java
(integer) 0
127.0.0.1:6382> setnx java best
(integer) 1
127.0.0.1:6382> set java easy xx
OK
127.0.0.1:6382> get java
"easy"
127.0.0.1:6382> set hello world
OK
127.0.0.1:6382> getset hello php
"world"
127.0.0.1:6382> get hello
"php"
127.0.0.1:6382> append hell ",php"
(integer) 4
127.0.0.1:6382> get hello
"php"
127.0.0.1:6382> append hello ",php"
(integer) 7
127.0.0.1:6382> get hello
"php,php"
127.0.0.1:6382> strlen hello
(integer) 7
127.0.0.1:6382> set hello "吳軍旗"
OK
127.0.0.1:6382> strlen hello
(integer) 9
複製程式碼
n次get操作
** 1次mget操作**
實戰
- 記錄網站每個使用者個人主頁的訪問量
incr userid: pageview (**主要的是:單執行緒,所以無競爭)**)
複製程式碼
- 快取視訊的基本資訊(資料來源在mysql中)虛擬碼
- 分散式id生成器(單執行緒的好處)
incr id
複製程式碼
hash
雜湊鍵值結構
特點
- mapmap
- small redis
- field不能相同,value可以相同
API
命令 | 說明 | 時間複雜度 |
---|---|---|
hget key field | 獲取hash key對應field的value | O(1) |
hset key field value | 設定has key 對應的field的value | O(1) |
hexists key field | 判斷hash key 是否有field | O(1) |
hlen key | 獲取hash key field的數量 | O(1) |
hmget key field1 field2...fieldN | 批量獲取hash key的一批field對應的值 | O(N) |
hset key field1 value1 field2 value2...fieldN valueN | 批量設定hash key的一批field value | O(1) |
hgetall key | 返回hash key對應所有的field和value | O(N) |
hvals key | 返回hash key對應所有的field的value | O(N) |
hkeys key | 返回hash key對應所有的field | O(N) |
hsetnx key field value | 設定has key 對應的field的value(如果field已經存在,則失敗) | O(1) |
hincrby key field intCounter | hash key對應的field的value自增intCounter | O(1) |
hincrbyfloat key field floatCounter | 浮點數版本 | O(1) |
注意 小心使用hgetall(牢記單執行緒)
練習
127.0.0.1:6382> hset user1 age 26
(integer) 1
127.0.0.1:6382> hset user1 name wujunqi
(integer) 1
127.0.0.1:6382> hget all user1
(nil)
127.0.0.1:6382> hgetall user1
1) "age"
2) "26"
3) "name"
4) "wujunqi"
127.0.0.1:6382> hdel user1 age
(integer) 1
127.0.0.1:6382> hgetall user1
1) "name"
2) "wujunqi"
127.0.0.1:6382> hget user1 name
"wujunqi"
127.0.0.1:6382> hexists user1 name
(integer) 1
127.0.0.1:6382> hlen user1
(integer) 1
127.0.0.1:6382> hmset user2 name xiaofang age 26
OK
127.0.0.1:6382> hmget user2 name age
1) "xiaofang"
2) "26"
127.0.0.1:6382> hgetall user2
1) "name"
2) "xiaofang"
3) "age"
4) "26"
127.0.0.1:6382> hvals user2
1) "xiaofang"
2) "26"
127.0.0.1:6382> hkeys user2
1) "name"
2) "age"
127.0.0.1:6382> hincrby user age 2
(integer) 2
127.0.0.1:6382> hgetall user2
1) "name"
2) "xiaofang"
3) "age"
4) "26"
127.0.0.1:6382> hincrby user2 age 2
(integer) 28
127.0.0.1:6382> hgetall user2
1) "name"
2) "xiaofang"
3) "age"
4) "28"
127.0.0.1:6382> hincrbyfloat user2 age 2.0
"30"
127.0.0.1:6382> hincrbyfloat user2 age 2.5
"32.5"
127.0.0.1:6382> hgetall user2
1) "name"
2) "xiaofang"
3) "age"
4) "32.5"
複製程式碼
list
列表結構
特點
- 有序
- 可以重複
- 左右兩邊插入彈出
API
練習
127.0.0.1:6382> rpush list1 a b c d
(integer) 4
127.0.0.1:6382> lpush list1 e f g h i
(integer) 9
127.0.0.1:6382> lrange list1 0 -1
1) "i"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
9) "d"
127.0.0.1:6382> linsert list1 before i wu
(integer) 10
127.0.0.1:6382> lrange list1 0 -1
1) "wu"
2) "i"
3) "h"
4) "g"
5) "f"
6) "e"
7) "a"
8) "b"
9) "c"
10) "d"
127.0.0.1:6382> linsert list1 after i jun
(integer) 11
127.0.0.1:6382> lrange list1 0 -1
1) "wu"
2) "i"
3) "jun"
4) "h"
5) "g"
6) "f"
7) "e"
8) "a"
9) "b"
10) "c"
11) "d"
127.0.0.1:6382> lpop list1
"wu"
127.0.0.1:6382> rpop list1
"d"
127.0.0.1:6382> lrange list1 0 -1
1) "i"
2) "jun"
3) "h"
4) "g"
5) "f"
6) "e"
7) "a"
8) "b"
9) "c"
127.0.0.1:6382> lrem list1 1 i
(integer) 1
127.0.0.1:6382> lrange list1 0 -1
1) "jun"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
127.0.0.1:6382> rpush list1 c c c c c
(integer) 13
127.0.0.1:6382> ltrem list1 -3 c
(error) ERR unknown command 'ltrem'
127.0.0.1:6382> lrem list1 -3 c
(integer) 3
127.0.0.1:6382> lrange list1 0 -1
1) "jun"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
9) "c"
10) "c"
127.0.0.1:6382> lindex list 0
(nil)
127.0.0.1:6382> lindex list1 0
"jun"
127.0.0.1:6382> llen list1
(integer) 10
127.0.0.1:6382> lset list 0 wu
(error) ERR no such key
127.0.0.1:6382> lset list1 0 wu
OK
127.0.0.1:6382> lrange list1 0 -1
1) "wu"
2) "h"
3) "g"
4) "f"
5) "e"
6) "a"
7) "b"
8) "c"
9) "c"
10) "c"
複製程式碼
應用
set
定義
Redis 的 Set 是 String 型別的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的資料。 Redis 中集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。
特點
- 無序
- 無重複
- 集合間操作
API
- 集合內的操作
命令 | 說明 | 時間複雜度 |
---|---|---|
sadd key element | 向集合key新增element(如果element已經存在,新增失敗) | O(1) |
srem key element | 將集合key中的element移除掉 | O(1) |
scard key | 計算集合大小 | O(1) |
sismember key element | 判斷element 是否在集合中 | O(1) |
srandmember key count | 從集合中隨機挑count個元素 | O(1) |
spop key | 從集合中隨機彈出一個元素 | O(1) |
smembers key | 獲取集合所有元素 | O(1) |
srem key element | 將集合key中的element移除掉 | O(1) |
- 集合間的操作
命令 | 說明 | 時間複雜度 |
---|---|---|
sdiff key1 key2 | 差集 | O(1) |
sinter key1 key2 | 交集 | O(1) |
sunion key1 key2 | 並集 | O(1) |
sidff/sinter/suion + store destkey | 將差集、交集、並集儲存在destkey中 | O(1) |
注意
- srandmember不會破壞集合
- spop會破會
- smembers 返回的是無序集合,並且要注意量很大的時候回阻塞
練習
127.0.0.1:6382> sadd set1 a b c d
(integer) 4
127.0.0.1:6382> srem set1 a
(integer) 1
127.0.0.1:6382> smembers set1
1) "d"
2) "c"
3) "b"
127.0.0.1:6382> scard set1
(integer) 3
127.0.0.1:6382> sismember set1 d
(integer) 1
127.0.0.1:6382> srandmember set1 2
1) "d"
2) "b"
127.0.0.1:6382> srandmember set1 2
1) "b"
2) "c"
127.0.0.1:6382> spop set1
"c"
127.0.0.1:6382> smembers set1
1) "d"
2) "b"
127.0.0.1:6382> srem set1 d
(integer) 1
127.0.0.1:6382> smembers set1
1) "b"
127.0.0.1:6382> sadd set1 1 2 3 4 5
(integer) 5
127.0.0.1:6382> sadd set2 a b c 12 8 9 1 2
(integer) 8
127.0.0.1:6382> sdiff set1 set2
1) "3"
2) "4"
3) "5"
127.0.0.1:6382> sinter set1 set2
1) "2"
2) "b"
3) "1"
127.0.0.1:6382> sunion set1 set2
1) "5"
2) "2"
3) "4"
4) "1"
5) "a"
6) "8"
7) "3"
8) "b"
9) "9"
10) "12"
11) "c"
127.0.0.1:6382>
複製程式碼
實戰
- 抽獎系統, 用spop
- 贊過的文章,收藏過的文章等
- 標籤
- 共同關注
總結
zset
定義
Redis 有序集合和集合一樣也是string型別元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分數(score)卻可以重複。
API
命令 | 說明 | 時間複雜度 |
---|---|---|
zadd key score element | 新增score和element | O(logN) |
zrem key element(可以是多個) | 將集合key中的element移除掉 | O(1) |
zscore key element | 返回元素的分數 | O(1) |
zincrby key increScore element | 增加或減少元素的分數 | O(1) |
zcard key | 返回元素的總個數 | O(1) |
zrank(zrevrank) key member | 返回元素的排名 | O(1) |
zrange(zrevrank) key start end [WITHSCORES] | 返回指定索引範圍內的升序元素[分值] | O(logN + m) |
zrangebyscore(zrevrangebyscore) key minScore maxScore | 返回指定分數範圍內的升序元素 | O(logN + m) |
zcount key minScore maxScore | 返回有序集合內在指定分數範圍內的個數 | O(logN + m) |
zremrangebyrank key start end | 刪除指定排名內的升序元素 | O(logN + m) |
zremrangebyscore key minScore maxScore | 刪除指定分數內的升序元素 | O(logN + m) |
ZINTERSTORE destination numkeys(表示key的個數) key [key ...] | 計算給定的一個或多個有序集的交集並將結果集儲存在新的有序集合 key 中 | |
ZUNIONSTORE destination numkeys key [key ...] | 計算給定的一個或多個有序集的並集,並儲存在新的 key 中 |
實戰
- 各種榜單(score:timestamp, saleCount, followCount)
redis客戶端的使用
下載
找相應語言的下載(一般選擇有笑臉和星星的)
https://redis.io/clients#php
複製程式碼
redis的其他功能
慢查詢
生命週期
兩點說明
- 慢查詢發生在第3階段
- 客戶端超時不一定慢查詢,但慢查詢是客戶端超時的一個可能因素
兩個配置
- slowlog-max-len
- slowlog-log-slower-than
如何配置
慢查詢命令
- slowlog get [n] : 獲取慢查詢佇列
- slowlog len: 獲取慢查詢佇列長度
- slowlog reset: 清空慢查詢佇列
運維經驗
pipeline:流水線
什麼是流水線
- 1次網路命令通訊模型
- 批量網路命令通訊模型
什麼是流水線
流水線的作用
兩點注意
- redis的命令時間是微秒級別
- pipeline每次條數要控制(網路)
與原生操作對比
- M操作
- pipeline
使用建議
- 注意每次pipeline攜帶資料量
- pipeline每次只能作用在一個redis節點上
- M操作與pipeline區別
釋出訂閱
角色
- 釋出者
- 訂閱者
- 頻道
模型
API
-
publish channel message
-
subscribe [channel] 一個或者多個
-
unsubscribe [channel] 一個或者多個
練習
127.0.0.1:6382> publish weibomovie "hello world"
(integer) 1
127.0.0.1:6382> publish weibomovie "hello world2"
(integer) 1
複製程式碼
另外一個cli
127.0.0.1:6382> SUBSCRIBE weibomovie
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "weibomovie"
3) (integer) 1
1) "message"
2) "weibomovie"
3) "hello world"
1) "message"
2) "weibomovie"
3) "hello world2"
複製程式碼
釋出訂閱與訊息佇列
Bitmap
點陣圖
API
命令 | 說明 | 時間複雜度 |
---|---|---|
setbit key offset value | 給點陣圖指定索引設定值 | O(1) |
getbit key offset | 獲取點陣圖指定索引的值 | O(1) |
bitcount key start end | 獲取點陣圖指定範圍(start 到end,單位為位元組,如果不指定就獲取全部)位值為1的個數 | O(1) |
bitop op destkey key [key...] | 做多個bitmap的and,or,not,xor操作並將結果儲存在destkey中 | O(1) |
bitpos key targetBit [start][end | 計算點陣圖指定範圍(start到end,單位為位元組,如果不指定就是獲取全部)第一個偏移量對應的值等於targetBit的位置 | O(1) |
練習
127.0.0.1:6382> set hello big
OK
127.0.0.1:6382> getbit hello
(error) ERR wrong number of arguments for 'getbit' command
127.0.0.1:6382> getbit hello 0
(integer) 0
127.0.0.1:6382> setbit hello 0 1
(integer) 0
127.0.0.1:6382> get hello
"\xe2ig"
127.0.0.1:6382> set hell a
OK
127.0.0.1:6382> bitcount hell
(integer) 3
127.0.0.1:6382> bitop and hell hello
(integer) 3
127.0.0.1:6382> set a a
OK
127.0.0.1:6382> set b b
OK
127.0.0.1:6382> bitop and c a b
(integer) 1
127.0.0.1:6382> get c
"`"
127.0.0.1:6382> bitpos a 1
(integer) 1
127.0.0.1:6382> bitpos a 0
(integer) 0
127.0.0.1:6382> set user2 100
OK
複製程式碼
獨立使用者統計
重要理解 使用點陣圖去記錄使用者uid,其實就是記錄索引值,比如userid=100代表點陣圖下標100的值為1
使用經驗
- type=string,最大512MB
- 注意setbit時的偏移量,可能有較大耗時
- 點陣圖不是絕對好
HyperLogLog
新的資料結構
API
命令 | 說明 |
---|---|
pfaddd key element [element...] | 向hyperloglog新增元素 |
pfcount key [key...] | 計算hyperloglog的獨立總數 |
pfmerge destkey sourceKey [sourcekey...] | 合併多個hyperloglog |
練習
127.0.0.1:6382> pfadd puser1 "u1" "u2" "u3"
(integer) 1
127.0.0.1:6382> pfcount puser1
(integer) 3
127.0.0.1:6382> pfadd puser2 "u3" "u4" "u5"
(integer) 1
127.0.0.1:6382> pfmerge puser puser1 puser2
OK
127.0.0.1:6382> pfcount puser
(integer) 5
複製程式碼
記憶體消耗
使用經驗
-
是否能容忍錯誤(錯誤率:0.81%)
-
是否需要單條資料(沒有辦法取出)
GEO
GEO是什麼
5個城市經緯度
API
命令 | 說明 |
---|---|
geoadd key longitude latitude member [longitude latitude member ...] | 增加地理位置資訊 |
geopos key member[member... | 獲取地理位置資訊 |
geodist key member1 member2[unit] | 獲取兩個地理位置的距離,unit:m,km,mi,ft |
georadius | 獲取指定位置範圍內的地理位置資訊集合 |
練習
127.0.0.1:6382> geoadd beijing 116.28 39.55
(error) ERR wrong number of arguments for 'geoadd' command
127.0.0.1:6382> geoadd geo 116.28 39.55 beijing 117.12 39.08 tianjin
(integer) 2
127.0.0.1:6382> geopos geo beijing
1) 1) "116.28000229597091675"
2) "39.5500007245470826"
127.0.0.1:6382> geodist geo beijing tianjin
"89206.0576"
127.0.0.1:6382>
複製程式碼
相關說明
- since 3.2+
- type geoKey = zset
- 沒有刪除API:zrem key member
redis持久化的取捨和選擇
持久化的作用
什麼是持久化
redis所有資料儲存在記憶體中, 對資料的更新將非同步地儲存到磁碟上
持久化的實現方式
- 快照
- mysql dump
- redis RDB
- 寫日誌
- mysql binlog
- hbase hLog
- redis AOF
RDB
什麼是RDB
觸發機制-主要三種方式
- save(同步)
* 檔案策略:如存在老的RDB檔案,新替換老
* 複雜度:O(N)
複製程式碼
- bgsave(非同步)
- 自動配置
**相關配置
配置引數 | 值 |
---|---|
save | 900 1 |
save | 300 10 |
save | 60 10000 |
dbfilename | dump-${port}.rdb |
dir | /bigdishpath |
stop-writes-on-bgsav-error | yes |
rdbcompression | yes |
save與bgsave
觸發機制-不容忽略的方式
其他的方式也會觸發生成RDB檔案
- 全量複製
- debug reload
- shutdown
總結
- RDB是Redis記憶體到硬碟的快照,用於持久化
- save通常會阻塞Redis
- bgsave不會阻塞redis,但是會fork新程式
- save自動配置滿足任一就會被執行
- 有些觸發機制不容忽視
AOF
RDB現存問題
- 耗時,好效能
- 不可控,丟失資料
什麼是AOF
- 建立
- 恢復
AOF三種策略
- always
- everysec
- no
三種策略比較
AOF重寫
AOF重寫的作用
- 減少硬碟佔用量
- 加速恢復速度
AOF重寫實現的兩種方式
- bgrewriteaof
- aof重寫配置
AOF重寫流程
配置
RDB與AOF的選擇
RDB最佳策略
- 關
- 集中管理
- 主從,從開
AOF最佳策略
- 開,快取和儲存
- AOF重寫集中管理
- everysec
-------------------------華麗的分割線--------------------
看完的朋友可以點個喜歡/關注,您的支援是對我最大的鼓勵。
想了解更多,歡迎關注我的微信公眾號:番茄技術小棧