目錄
#1.1關系數據庫與非關系型數據庫
? 1.1.1關心型數據庫
? 1.1.2非關系型數據庫
? 1.1.3非關系型數據庫產生背景
#2.1redis簡介
? 2.1.1redis安裝部署
? 2.1.2配置參數
#3.1redis命令工具
? 3.1.1redis-cli命令行工具
? 3.1.2redis-benchmark測試工具
#4.1redis數據庫常用命令
? 4.1.1key相關命令
? 4.1.2多數據庫常用的命令
#5.1redis持久化
? 5.1.1RDB和AOF的區別
? 5.1.2RDB和AOF的優缺點
? 5.1.3redis持久化配置
? 5.1.4AOF重寫
? 5.1.5性能管理
1.1關系數據庫與非關系數據庫
1.1.1關系型數據庫
? ? 關系型數據庫是一個結構化的數據庫,創建在關系模型基礎上,一般面向于記錄。它借助于集合代數等數學概念和方法來處理數據庫中的數據。關系模型就是指二維表格模型,因而一個關系型數據庫就是由二維表及其之間的聯系組成的一個數據組織。現實世界中,各種實體與實體之間的各種聯系都可以用關系模型來表示。SQL 語句(標準數據查詢語言)就是一種基于關系型數據庫的語言,用于執行對關系型數據庫中數據的檢索和操作。
? ? 主流的關系型數據庫包括 Oracle、MySQL、SQL Server、Microsoft Access、DB2 等。
1.1.2非關系型數據庫
? ? ?NoSQL (NoSQL = Not Only SQL),意思是 “不僅僅是 SQL”,是非關系型數據庫的總稱。主流的 NoSQL 數據庫有 Redis、MongBD、Hbase、CouhDB 等等。以上這些非關系型數據庫,他們的存儲方式、存儲結構以及使用的場景都是完全不同的。所以我們認為它是一個非關系型數據庫的集合,而不是像關系型數據庫一樣,是一個統稱。換言之,除了主流的關系型數據庫以外的數據庫,都可以認為是非關系型的。NoSQL 數據庫憑借著其非關系型、分布式、開源及橫向擴展等優勢,被認為是下一代數據庫產品。
1.1.3非關系型數據庫產生背景
? ? 隨著 Web2.0 網站的興起,關系型數據庫在應對 Web2.0 網站,特別是海量數據和高并發的 SNS(Social Networking Services,即社交網絡服務)類型的 Web2.0 純動態網站時,暴露出很多難以解決的問題,例如三高問題。
(1)High performance—— 對數據庫高并發讀寫需求
Web2.0 網站會根據用戶的個性化信息來實時生成動態頁面和提供動態信息,因此無法使用動態頁面靜態化技術。所以數據庫的并發負載非常高,一般會達到 10000 次 /s 以上的讀寫請求。關系型數據庫對于上萬次的查詢請求還是可以勉強支撐的,但出現上萬次的寫數據請求,硬盤 IO 就已經無法承受了。對于普通的 BBS 網站,往往也會存在高并發的寫數據請求。
(2)Huge Storage—— 對海量數據高效存儲與訪問需求
類似于 Facebook、Friendfeed 這樣的 SNS 網站,每天會產生大量的用戶動態信息。如 Friendfeed, 一個月就會產生不少于 2.5 億條用戶動態信息,對于關系型數據庫來說,在一個包含 2.5 億條記錄的表中執行 SQL 查詢,查詢效率是非常低的。
(3)High Scalability && High Availability—— 對數據庫高可擴展性與高可
用性需求在 Web 架構中,數據庫是最難進行橫向擴展的。當應用系統的用戶量與訪問量與日俱增時,數據庫是沒辦法像 Web 服務一樣,簡單地通過添加硬件和服務器節點來擴展其性能和負載能力的。尤其對于一些需要 24 小時對外提供服務的網站來說,數據庫的升級與擴展往往伴隨著停機維護與數據遷移,其工作量是非常龐大的。
2.1redis簡介
? ? redis(RemoteDictionaryServer,遠程字典型)是一個開源的、使用 C 語言編寫的 NoSQL 數據庫。Redis 基于內存運行并支持持久化,采用 key-value(鍵值對)的存儲形式,是目前分布式架構中不可或缺的一環。
? ? Redis 服務器程序是單進程模型,也就是在一臺服務器上可以同時啟動多個 Redis 進程,而 Redis 的實際處理速度則是完全依靠于主進程的執行效率。若在服務器上只運行一個 Redis 進程,當多個客戶端同時訪問時,服務器的處理能力是會有一定程度的下降;若在同一臺服務器上開啟多個 Redis 進程,Redis 在提高并發處理能力的同時會給服務器的 CPU 造成很大壓力。即:在實際生產環境中,需要根據實際的需求來決定開啟多少個 Redis 進程。若對高并發要求更高一些,可能會考慮在同一臺服務器上開啟多個進程。若 CPU 資源比較緊張,采用單進程即可。
Redis 具有以下幾個優點:
? ? ?具有極高的數據讀寫速度,數據讀取的速度最高可達到 110000 次 /s,數據寫入速度最高可達到 81000 次 /s。
? ? 支持豐富的數據類型,不僅僅支持簡單的 key-value 類型的數據,還支持 Strings, Lists, Hashes, Sets 及 Ordered Sets 等數據類型操作。
? ? 支持數據的持久化,可以將內存中的數據保存在磁盤中,重啟的時候可以再次加載進行使用。
? ? 原子性,Redis 所有操作都是原子性的。
? ? 支持數據備份,即 master-salve 模式的數據備份。
? Redis 作為基于內存運行的數據庫,緩存是其最常應用的場景之一。除此之外,Redis 常見應用場景還包括獲取最新 N 個數據的操作、排行榜類應用、計數器應用、存儲關系、實時分析系統、日志記錄。
?2.1.1redis安裝部署
? ? 通常情況下,在 Linux 系統中進行源碼編譯安裝,需要先執行./configure 進行環境檢查與配置,從而生成 Makefile 文件,再執行 make && make install 命令進行編譯安裝。而 Redis 源碼包中直接提供了 Makefile 文件,所以在解壓完軟件包后,可直接進入解壓后的軟件包目錄,執行 make 與 make install 命令進行安裝。
[root@localhost src]# dnf -y install tar gcc make zlib-devel
[root@localhost src]# tar xvzf redis-4.0.9.tar.gz
[root@localhost src]# cd redis-4.0.9/
[root@localhost redis-4.0.9]# make
[root@localhost redis-4.0.9]# make PREFIX=/usr/local/redis install
[root@localhost ~]# ln -s /usr/local/redis/bin/* /usr/local/bin/
? ?make install 只是安裝了二進制文件到系統中,并沒有啟動腳本和配置文件。軟件包中默認提供了一個 install_server.sh 腳本文件,通過該腳本文件可以設置 Redis 服務所需要的相關配置文件。當腳本運行完畢,Redis 服務就已經啟動,默認偵聽端口為 6379。
[root@localhost redis-4.0.9]# cd utils/
[root@localhost utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [] /usr/local/redis/bin/redis -server
// 需要手動輸入
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf // 配置文件路徑
Log file : /var/log/redis_6379.log // 日志文件路徑
Data dir : /var/lib/redis/6379 // 數據文件路徑
Executable : /usr/local/redis/bin/redis-server // 可執行文件路徑
Cli Executable : /usr/local/redis/bin/redis-cli // 客戶端命令行工具
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@localhost utils]# netstat -lnupt | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 5494/redis-server 1
2.1.2配置參數
? ? Redis 主配置文件為 /etc/redis/6379.conf,由注釋行與設置行兩部分組成。與大多數 Linux 配置文件一樣,注釋性的文字以 “#” 開始,包含了對相關配置內容進行的說明和解釋。除了注釋行與空行以外的內容即為設置行。可根據生產環境的需求調整相關參數,如下:
[root@localhost ~]# vi /etc/redis/6379.conf
bind 127.0.0.1 192.168.10.161 // 監聽的主機地址
port 6379 // 端口
daemonize yes // 啟用守護進程
pidfile /var/run/redis_6379.pid// 指定 PID 文件
loglevel notice // 日志級別
logfile /var/log/redis_6379.log// 指定日志文件
[root@localhost~]#/etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
參數 | 作用 |
---|---|
timeout 300 | 當客戶端閑置多長時間后關閉連接,如果指定為 0,表示關閉該功能 |
dbfilename dump.rdb | 指定本地數據庫文件名,默認值為dump.rdb |
dir /var/lib/redis/6379 | 指定本地數據庫存放目錄 |
maxclients 10000 | 設置同一時間最大客戶端連接數,默認 10000。Redis 可以同時打開的客戶端連接數為 Redis 進程可以打開的最大文件描述符數,如果設置maxclients 0 表示不限制。當客戶端連接數達到限制時,Redis 會關閉新的連接并給客戶端返回max number of clients reached 錯誤信息 |
rdbcompression yes | 指定存儲至本地數據庫時是否壓縮數據,默認為yes ,Redis 采用 LZF 壓縮。如果為了節省 CPU 時間,可以關閉該選項,但會導致數據庫文件變的巨大 |
slaveof <masterip> <masterport> | 當本機為從服務器時,設置主服務器的 IP 地址及端口,在 Redis 啟動后,從服務器會自動向主服務器進行數據同步 |
masterauth <master-password> | 當主服務器設置了連接密碼,從服務器連主服務器的密碼 |
requirepass foobared | 設置 Redis 連接密碼,如果配置了連接密碼,客戶端在連接 Redis 時需要通過AUTH <password> 命令提供密碼,默認關閉 |
maxmemory <bytes> | 指定 Redis 最大內存限制,Redis 在啟動時會把數據加載到內存中,達到最大內存后,Redis 會先嘗試清除已到期或即將到期的 Key,當此方法處理后,仍然到達最大內存設置,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis 新的 VM 機制,會把 Key 存放內存,Value 存放在 swap 分區 |
appendonly no | 指定是否在每次更新操作后進行日志記錄,Redis 在默認情況下是異步地把數據寫入磁盤,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。因為 Redis 本身同步數據文件是按上面 save 條件來同步的,所以有的數據會在一段時間內只存在于內存中。默認值為no |
appendfilename appendonly.aof | 指定更新日志文件名,默認為appendonly.aof |
appendfsync everysec | 指定更新日志條件,共有 3 個可選值: -? no :表示等操作系統進行數據緩存同步到磁盤(快)-? always :表示每次更新操作后手動調用fsync 將數據寫到磁盤(慢,安全)-? everysec :表示每秒同步一次(默認,推薦) |
activerehashing yes | 指定是否激活重置哈希,默認為開啟 |
include /path/to/local.conf | 指定包含其它的配置文件,可以在同一主機上多個 Redis 實例之間使用同一份配置文件,同時各個實例又擁有自己的特定配置文件 |
?3.1redis命令工具
? ? Redis 軟件提供了多個命令工具。安裝 Redis 服務時,所包含的軟件工具會同時被安裝到系統中,在系統中可以直接使用。這些命令工具的作用分別如下所示。
? ?redis-server:用于啟動 Redis 的工具;
? ?redis-benchmark:用于檢測 Redis 在本機的運行效率;
? ?redis-check-aof:修復 AOF 持久化文件;
? ?redis-check-rdb:修復 RDB 持久化文件;
? ?redis-cli:Redis 命令行工具。
3.1.1redis-cli命令行工具
? ? ? Redis 數據庫系統也是一個典型的 C/S(客戶端 / 服務器端)架構的應用,要訪問 Redis 數據庫需要使用專門的客戶端軟件。Redis 服務的客戶端軟件就是其自帶的 redis-cli 命令行工具。使用 redis-cli 連接指定數據庫,連接成功后會進入提示符為 “遠程主機 IP 地址:端口號>” 的數據庫操作環境,例如 “127.0.0.1:6379>”。用戶可以輸入各種操作語句對數據庫進行管理。如執行 ping 命令可以檢測 Redis 服務是否啟動。
[root@localhost ~]# /usr/local/redis/bin/redis-cli //連接本機 Redis 數據庫
127.0.0.1:6379>ping //檢測 redis 服務是否啟動
PONG
127.0.0.1:6379>
? ? ?在進行數據庫連接操作時,可以通過選項來指定遠程主機上的 Redis 數據庫。命令語法為 redis-cli -h host -p port -a password,其中 -h 指定遠程主機、-p 指定 Redis 服務的端口號、-a 指定密碼。若不添加任何選項表示,連接本機上的 Redis 數據庫;若未設置數據庫密碼可以省略 -a 選項。例如執行以下命令可連接到主機為 192.168.10.161,端口為 6379 的 Redis 數據庫,并查看 Redis 服務的統計信息。若要退出數據庫操作環境,執行 “exit” 或 “quit” 命令即可返還原來的 Shell 環境。
[root@localhost ~]#redis-cli -h 192.168.10.161 -p 6379
192.168.10.161:6379>info
# Server
redis_version:4.0.9
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:7f55f2c1a630cbe5
……
//省略部分內容
192.168.10.161:6379>exit
[root@localhost ~]#
? ? 在數據庫操作環境中,使用 help 命令可以獲取命令類型的幫助。有三種獲取命令幫助的方式。
? ?help @<group>:獲取<group>中的命令列表;
? ?help <command>:獲取某個命令的幫助;
? ?help <tab>:獲取可能幫助的主題列表。
[root@localhost ~]#redis-cli
127.0.0.1:6379>help @list //查看所有與 List 數據類型的相關命令
BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one
is available
since: 2.0.0
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one
is available
since: 2.0.0
BRPOPLPUSH source destination timeout
……
//省略部分內容
127.0.0.1:6379>help set //查看 set 命令的命令幫助
SET key value [EX seconds] [PX milliseconds] [NX|XX]
summary: Set the string value of a key
since: 1.0.0
group: string
3.1.2redis-benchmark測試工具
? ?redis-benchmark 是官方自帶的 Redis 性能測試工具,可以有效的測試 Redis 服務的性能。基本的測試語法為 redis-benchmark [option] [option value]。常用選項如下所示。
-h:指定服務器主機名;
-p:指定服務器端口;
-s:指定服務器 socket;
-c:指定并發連接數;
-n:指定請求數;
-d:以字節的形式指定 SET/GET 值的數據大小;
-k:1=keep alive 0=reconnect;
-r:SET/GET/INCR 使用隨機 key,SADD 使用隨機值;
-P:通過管道傳輸<numreq>請求;
-q:強制退出 redis。僅顯示 query/sec 值;
--csv:以 CSV 格式輸出;
-l:生成循環,永久執行測試;
-t:僅運行以逗號分隔的測試命令列表;
-I:Idle 模式。僅打開 N 個 idle 連接并等待。
? ?結合上述選項,可以針對某臺 Redis 服務器進行性能檢測,如執行 redis-benchmark -h 192.168.10.161 -p 6379 -c 100 -n 100000 命令即可向 IP 地址為 192.168.10.161、端口為 6379 的 Redis 服務器發送 100 個并發連接與 100000 個請求測試性能。
[root@localhost ~]# redis-benchmark -h 192.168.10.161 -p 6379 -c 100 -n 100000
…… //省略部分內容
8225.04 requests per second
====== MSET (10 keys) ======
100000 requests completed in 1.57 seconds
100 parallel clients
3 bytes payload
keep alive: 1
24.75% <= 1 milliseconds
99.02% <= 2 milliseconds
99.57% <= 3 milliseconds
99.90% <= 4 milliseconds
99.98% <= 5 milliseconds
100.00% <= 5 milliseconds
63653.72 requests per second
? ?執行 redis-benchmark -h 192.168.10.161 -p 6379 -q -d 100 命令的作用是測試存取大小為 100 字節的數據包的性能。
[root@localhost ~]#redis-benchmark -h 192.168.10.161 -p 6379 -q -d 100
PING_INLINE: 88261.25 requests per second
PING_BULK: 90991.81 requests per second
SET: 83612.04 requests per second
GET: 84961.77 requests per second
INCR: 83682.01 requests per second
LPUSH: 76745.97 requests per second
RPUSH: 78247.26 requests per second
LPOP: 77519.38 requests per second
RPOP: 79681.27 requests per second
SADD: 83125.52 requests per second
SPOP: 85543.20 requests per second
LPUSH (needed to benchmark LRANGE): 78864.35 requests per second
LRANGE_100 (first 100 elements): 30931.02 requests per second
LRANGE_300 (first 300 elements): 9437.52 requests per second
LRANGE_500 (first 450 elements): 5541.39 requests per second
LRANGE_600 (first 600 elements): 3824.38 requests per second
MSET (10 keys): 64184.86 requests per second
? ?還可以測試某些操作的性能,例如執行 redis-benchmark -t set,lpush -n 100000 -q 命令的作用是測試本機上 Redis 服務在進行 set 與 lpush 操作時的性能。
[root@localhost ~]#redis-benchmark -t set,lpush -n 100000 -q
SET: 85763.29 requests per second
LPUSH: 86580.09 requests per second
4.1redis數據庫常用命令
? ? 前面提到 Redis 數據庫采用 key-value(鍵值對)的數據存儲形式。所使用的命令是 set 與 get 命令。
set:存放數據,基本的命令格式為 set key value。
get:獲取數據,基本的命令格式為 get key。
? ?在 Redis 的命令行模式下執行”set teacher zhanglong”,表示在當前數據庫下存放一個 key 為 teacher,value 為 zhanglong 的數據,而執行 “getteacher“命令即可查看剛才存放的數據。
4.1.1key相關命令
(1)keys
? ? 使用 keys 命令可以取符合規則的鍵值列表,通常情況可以結合 *、? 等選項來使用。
127.0.0.1:6379>set k1 1
OK
127.0.0.1:6379>set k2 2
OK
127.0.0.1:6379>set k3 3
OK
127.0.0.1:6379>set v1 4
OK
127.0.0.1:6379>set v5 5
OK
127.0.0.1:6379>KEYS * //查看當前數據庫中所有鍵
1) "teacher"
2) "k1"
3) "k2"
4) "k3"
5) "v1"
6) "v5"
127.0.0.1:6379>set v22 5
OK
127.0.0.1:6379>KEYS v* //查看當前數據庫中以 v 開頭的數據
1) "v1"
2) "v5"
3) "v22"
127.0.0.1:6379>KEYS v?
//查看當前數據庫中以 v 開頭后面包含任意一位的數據
1) "v1"
2) "v5"
127.0.0.1:6379>KEYS v??
//查看當前數據庫中以 v 開頭后面包含任意兩位的數據
1) "v22"
(2)exists
127.0.0.1:6379>exists teacher
//判斷 teacher 鍵是否存在
(integer) 1
//表示 teacher 鍵是存在
127.0.0.1:6379>exists tea
(integer) 0
//表示 tea 鍵不存在
(3)del
127.0.0.1:6379>keys *
1) "teacher"
2) "v1"
3) "v22"
4) "k3"
5) "k1"
6) "k2"
7) "v5"
127.0.0.1:6379> del v5
(integer) 1
127.0.0.1:6379>get v5
(nil)
(4)type
? ? 使用type命令可以獲取key對應的value值類型。
127.0.0.1:6379>type k1
String
(5)rename
? ? ?rename 命令是對已有 key 進行重命名,其命令格式為:rename 源 key 目標 key。使用 rename 命令進行重命名時,無論目標 key 是否存在都進行重命名,且源 key 的值會覆蓋目標 key 的值。在實際使用過程中,建議先用 exists 命令查看目標 key 是否存在,然后再決定是否執行 rename 命令,以避免覆蓋重要數據。
127.0.0.1:6379>keys v*
1) "v1"
2) "v22"
127.0.0.1:6379>rename v22 v2
OK
127.0.0.1:6379>keys v*
1) "v1"
2) "v2"
127.0.0.1:6379>get v1
"4"
127.0.0.1:6379>get v2
"5"
127.0.0.1:6379>rename v1 v2
OK
127.0.0.1:6379>get v1
(nil)
127.0.0.1:6379>get v2
"4"
(6)renamenx
? ? renamenx 命令的作用是對已有 key 進行重命名,并檢測新名是否存在。其命令格式與 rename 的命令格式除命令關鍵字不同外基本相同:renamenx 源 key 目標 key。使用 renamenx 命令進行重命名時,如果目標 key 存在則不進行重命名。
127.0.0.1:6379>keys *
1) "teacher"
2) "k3"
3) "k1"
4) "k2"
5) "v2"
127.0.0.1:6379>get teacher
"zhanglong"
127.0.0.1:6379>get v2
"4"
127.0.0.1:6379>renamenx v2 teacher
(integer) 0
127.0.0.1:6379>keys *
1) "teacher"
2) "k3"
3) "k1"
4) "k2"
5) "v2"
127.0.0.1:6379>get teacher
"zhanglong"
127.0.0.1:6379>get v2
"4"
(7)dbsize
? ? dbsize 命令的作用是查看當前數據庫中 key 的數目。
127.0.0.1:6379> dbsize
(integer) 5
4.1.2多數據庫常用命令
(1)多數據庫間切換
? ?Redis 支持多數據庫,Redis 在沒有任何改動的情況下默認包含 16 個數據庫,數據庫名稱是用數字 0 - 15 來依次命名的。使用 select 命令可以進行 Redis 的多數據庫之間的切換,命令格式為 selectindex,其中 index 表示數據庫的序號。而使用 redis - cli 連接 Redis 數據庫后,默認使用的是序號為 0 的數據庫。
? ?使用 select 命令切換數據庫后,會在前端的提示符中顯示當前所在的數據庫序號如 “127.0.0.1:6379 [10]>” 表示當前使用的是序號為 10 的數據庫。若當前使用的數據庫是序號為 0 的數據庫,提示符中則不顯示序號,如 “127.0.0.1:6379>” 表示當前使用的是序號為 0 的數據庫。
127.0.0.1:6379>select 10 // 切換至序號為 10 的數據庫
OK
127.0.0.1:6379 [10]>select 15 // 切換至序號為 15 的數據庫
OK
127.0.0.1:6379 [15]>select 0 // 切換至序號為 0 的數據庫
OK
127.0.0.1:6379>
(2)多數據庫間移動數據
127.0.0.1:6379>set k1 100
OK
127.0.0.1:6379>get k1
"100"
127.0.0.1:6379>select 1
OK
127.0.0.1:6379[1]>get k1
(nil)
(3)清除數據庫內數據
? ? Redis 數據庫的整庫數據刪除主要分為兩個部分:清空當前數據庫數據,使用 FLUSHDB 命令實現;清空所有數據庫的數據,使用 FLUSHALL 命令實現。但是,數據清空操作比較危險,生產環境下一般不建議使用。
5.1redis持久化
? ?Redis 是一種高級 key-value 數據庫。它跟 Memcached 類似,不過數據可以持久化,而且支持的數據類型很豐富,有字符串、列表、集合和有序集合。支持在服務器端計算集合 (difference) 等,還支持多種排序功能。所以 Redis 也可以被看成是一個數據結構服務器。
5.1.1RDB和AOF的區別
? ? RDB 持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操作過程是 fork 一個子進程,先將數據集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲,如圖 3.1 所示。
?
? ? AOF 持久化以日志的形式記錄服務器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄。如圖 3.2所示。?
5.1.2RDB和AOF的優缺點
?(1)RDB 優點
-
一旦采用該方式,那么整個 Redis 數據庫將只包含一個文件,這對于文件備份而言是非常完美的。比如,計劃每個小時歸檔一次最近 24 小時的數據,同時還要每天歸檔一次最近 30 天的數據。通過這樣的備份策略,一旦系統出現災難性故障,可以非常容易地進行恢復。
-
對于災難恢復而言,RDB 是非常不錯的選擇。可以非常輕松的將一個單獨的文件壓縮后再轉移到其它存儲介質上。
-
性能最大化,對于 Redis 的服務進程而言,在開始持久化時,它唯一需要做的只是 fork 出子進程,之后再由子進程完成這些持久化的工作,這樣就可以極大的避免服務進程執行 I0 操作了。
-
相比于 AOF 機制,如果數據集很大,RDB 的啟動效率會更高。
(2)RDB 缺點
-
如果想保證數據的高可用性,即最大限度的避免數據丟失,那么 RDB 將不是一個很好的選擇。因為系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。
-
由于 RDB 是通過 fork 子進程來協助完成數據持久化工作的,因此當數據集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是 1 秒鐘。
(1)AOF 的優點
-
AOF 機制可以帶來更高的數據安全性,即數據持久性。Redis 中提供了 3 種同步策略,即每秒同步、每次修改同步和不同步。事實上,每秒同步也是異步完成的,其效率也是非常高的,弊端是一旦系統出現宕機現象,那么這一秒鐘之內修改的數據將會丟失。而每次修改同步,可以將其視為同步持久化,即每次發生的數據變化都會被立即記錄到磁盤中,這種方式在效率上是最低的。
-
由于該機制對日志文件的寫入操作采用的是 append 模式,因此在寫入過程中即使出現宕機現象,也不會破壞日志文件中已經存在的內容。然而如果本次操作只是寫入了一半數據就出現了系統崩潰問題,那么在 Redis 下一次啟動之前,可以通過 redis - check - aof 工具來解決數據一致性的問題。
-
如果日志過大,Redis 可以自動啟用 rewrite 機制。即 Redis 以 append 模式不斷地將修改數據寫入到老的磁盤文件中,同時 Redis 還會創建一個新的文件用于記錄此期間有哪些修改命令被執行。因此在進行 rewrite 切換時可以更好的保證數據安全性。
-
AOF 包含一個格式清晰、易于理解的日志文件用于記錄所有的修改操作。事實上,也可以通過該文件完成數據的重建。
(2)AOF 的缺點
-
對于相同數量的數據集而言,AOF 文件通常要大于 RDB 文件。RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
-
根據同步策略的不同,AOF 在運行效率上往往會慢于 RDB。每秒同步策略的效率是比較高的,同步禁用策略的效率和 RDB 一樣高效。
? ? ? 二者選擇的標準,就是看系統是愿意犧牲一些性能,換取更高的緩存一致性(AOF),還是愿意寫操作頻繁的時候,不啟用備份來換取更高的性能,待手動運行 save 的時候,再做備份(RDB)。
5.1.3redis持久化配置
? ? ?Redis 會將數據集的快照 dump 到 dump.rdb 文件中。此外,也可以通過配置文件來修改 Redis 服務器 dump 快照的頻率。在打開 6379.conf 文件之后,搜索 save,可以看到如下所示配置信息。
-
save 900 1:在 900 秒 (15 分鐘) 內,如果至少有 1 個 key 發生變化,則 dump 內存快照。
-
save 300 10:在 300 秒 (5 分鐘) 內,如果至少有 10 個 key 發生變化,則 dump 內存快照。
-
save 60 10000:在 60 秒 (1 分鐘) 內,如果至少有 10000 個 key 發生變化,則 dump 內存快照。
5.1.4AOF重寫
? ? Redis 會不斷地將被執行的命令記錄到 AOF 文件里面,所以隨著 Redis 不斷運行,AOF 文件的體積也會不斷增長。在極端情況下,體積不斷增大的 AOF 文件甚至可能會用完硬盤的所有可用空間。Redis 在重啟之后需要通過重新執行 AOF 文件記錄的所有寫命令來還原數據集,所以如果 AOF 文件的體積非常大,那么還原操作執行的時間就可能會非常長。
? ?為了解決 AOF 文件體積不斷增大的問題,用戶可以向 Redis 發送 BGREWRITEAOF 命令。BGREWRITEAOF 命令會通過移除 AOF 文件中的冗余命令來重寫(rewrite)AOF 文件,使 AOF 文件的體積盡可能地變小。
? ?BGREWRITEAOF 的工作原理和 BGSAVE 創建快照的工作原理非常相似:Redis 會創建一個子進程,然后由子進程負責對 AOF 文件進行重寫。因為 AOF 文件重寫也需要用到子進程,所以快照持久化因為創建子進程而導致的性能問題和內存占用問題,在 AOF 持久化中也同樣存在。
? ?與快照持久化通過設置 save 選項來自動執行 BGSAVE 一樣,AOF 持久化也可以通過設置 auto - aof - rewrite - percentage 選項和 auto - aof - rewrite - min - size 選項來自動執行 BGREWRITEAOF。
? ?舉個例子,假設用戶對 Redis 設置了配置選項 auto - aof - rewrite - percentage 100 和 auto - aof - rewrite - min - size 64mb,并且啟動了 AOF 持久化,那么當 AOF 文件的體積大于 64MB,并且 AOF 文件的體積比上一次重寫之后的體積大了至少一倍(100%)的時候,Redis 將執行 BGREWRITEAOF 命令。如果 AOF 重寫執行的過于頻繁的話,用戶可以考慮將 auto - aof - rewrite - percentage 選項的值設置為 100 以上,這種做法可以讓 Redis 在 AOF 文件的體積變得更大之后才執行重寫操作,不過也會讓 Redis 在啟動時還原數據集所需的時間變得更長。
5.1.5性能管理
? ? Redis 性能管理需要關注的數據指標有內存使用率、內存碎片率、回收 key 等。這其中有些數據可以通過進入 info 命令進行查看。需要查看某一項的值就后面跟具體參數,執行以下命令查看 Redis 使用內存值。
192.168.9.236:7001> info memory
Memory
used_memory:1789108864
used_memory_human:1.67G
used_memory_rss:1834365054
used_memory_rss_human:1.71G
used_memory_peak:1657473880
used_memory_peak_human:1.54G
used_memory_peak_perc:58.41%
used_memory_overhead:62038390
used_memory_startup:191424
used_memory_dataset:1727070474
used_memory_dataset_perc:96.53%
allocator_allocated:1789471792
allocator_active:1801850880
allocator_resident:1835344200
total_system_memory:10095328256
total_system_memory_human:9.40G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:17179869184
maxmemory_human:16.00G
maxmemory_policy:allkeys-lru
allocator_frag_ratio:1.01
allocator_frag_bytes:12379088
allocator_rss_ratio:1.03
allocator_rss_bytes:49356800
rss_overhead_ratio:0.99
rss_overhead_bytes:-19152896
mem_fragmentation_ratio:1.03
mem_fragmentation_bytes:45321664
mem_not_counted_for_evict:0
mem_replication_backlog:536870912
mem_clients_slaves:10922
mem_clients_normal:218914
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
? ? info stats 信息中的 evicted_keys 字段顯示的是因為 maxmemory 限制導致 key 被回收刪除的數量。當 Redis 由于內存壓力需要回收一個 key 時,Redis 首先考慮的不是回收最舊的數據,而是在最近最少使用的 key 或即將過期的 key 中隨機選擇一個 key,從數據集中刪除。
192.168.9.236:7001> info stats
Stats
total_connections_received:473156108
total_commands_processed:4180290178
instantaneous_ops_per_sec:375
total_net_input_bytes:14676967575477
total_net_output_bytes:102221322391862
instantaneous_input_kbps:1465.97
instantaneous_output_kbps:7011.15
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:1
expired_keys:34158591
expired_stale_perc:0.40
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:3089647498
keyspace_misses:94699798
pubsub_channels:3
pubsub_patterns:2
latest_fork_usec:51400
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0