NoSQL之Redis配置優化
- 一、Redis
- 1.關系數據庫與非關系型數據庫
- 關系型數據庫
- 非關系型數據庫
- 非關系型數據庫產生背景
- 2.Redis基礎
- Redis簡介
- Redis安裝部署
- 配置參數
- 3.Redis命令工具
- redis-cli命令行工具
- redis-benchmark 測試工具
- 4.Redis數據庫常用命令
- key相關命令
- (1)keys
- (2)exists
- (3)del
- (4)type
- (5)rename
- (6)renamenx
- (7)dbsize
- 5.多數據庫常用命令
- (1)多數據庫切換
- (2)多數據庫間移動數據
- (3)清理數據庫內數據
- 二、Redis持久化
- 1.RDB和AOF的區別
- 2.RDB和AOF的優缺點
- 3.Redis持久化配置
- 4. AOF 重寫
一、Redis
Redis 數據庫是一個非關系型數據庫,在正式學習 Redis 之前,先來了解關系型數據庫與非關系型數據庫的概念。
1.關系數據庫與非關系型數據庫
數據庫按照數據庫的結構可以分為關系型數據庫與其他數據庫,而這些其他數據庫我們將其統稱為非關系型數據庫。
關系型數據庫
關系型數據庫是一個結構化的數據庫,創建在關系模型基礎上,一般面向于記錄。它借助于集合代數等數學概念和方法來處理數據庫中的數據。關系模型就是指二維表格模型,因而一個關系型數據庫就是由二維表及其之間的聯系組成的一個數據組織。現實世界中,各種實體與實體之間的各種聯系都可以用關系模型來表示。SQL 語句(標準數據查詢語言)就是一種基于關系型數據庫的語言,用于執行對關系型數據庫中數據的檢索和操作。
主流的關系型數據庫包括 0racle、MySQL、SQL Server、Microsoft Access、DB2 等
非關系型數據庫
NoSQL(NoSQL = Not 0nly SQL),意思是“不僅僅是 SQL”,是非關系型數據庫的總稱。主流的 NoSQL 數據庫有 Redis、MongBD、Hbase、CouhDB 等等。以上這些非關系型數據庫,他們的存儲方式、存儲結構以及使用的場景都是完全不同的。所以我們認為它是一個非關系型數據庫的集合,而不是像關系型數據庫一樣,是一個統稱。換言之,除了主流的關系型數據庫以外的數據庫,都可以認為是非關系型的。NoSQL 數據庫憑借著其非關系型、分布式、開源及橫向擴展等優勢,被認為是下一代數據庫產品。
非關系型數據庫產生背景
(1)High performance–對數據庫高并發讀寫需求
Web2.0 網站會根據用戶的個性化信息來實時生成動態頁面和提供動態信息,因此無法使用動態頁面靜態化技術。所以數據庫的并發負載非常高,一般會達到10000 次/s以上的讀寫請求。關系型數據庫對于上萬次的查詢請求還是可以勉強支撐的,但出現上萬次的寫數據請求,硬盤I0 就已經無法承受了。對于普通的 BBS 網站,往往也會存在高并發的寫數據請求。
(2)Huge Storage–對海量數據高效存儲與訪問需求
類似于 Facebook、Friendfeed 這樣的 SNS 網站,每天會產生大量的用戶動態信息。如 Friendfeed,一個月就會產生不少于 2.5 億條用戶動態信息,對于關系型數據庫來說,在一個包含 2.5 億條記錄的表中執行 SQL 查詢,查詢效率是非常低的。
(3)High Scalability && High Availability–對數據庫高可擴展性與高可用
用性需求在 Web 架構中,數據庫是最難進行橫向擴展的。當應用系統的用戶量與訪問量與日俱增時,數據庫是沒辦法像Web 服務一樣,簡單地通過添加硬件和服務器節點來擴展其性能和負載能力的。尤其對于一些需要24 小時對外提供服務的網站來說,數據庫的升級與擴展往往伴隨著停機維護與數據遷移,其工作量是非常龐大的。
2.Redis基礎
Redis簡介
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 的安裝相對于其他服務來說比較簡單 。首先需要到 Redis 官網(https://www.redis.io)下載相應的源碼軟件包,然后上傳至 Linux 系統的服務器中進行解壓、安裝。本章中以 redis-4.0.9.tar.gz為例進行 Redis 服務的安裝和配置講解。
通常情況下,在 Linux 系統中進行源碼編譯安裝,需要先執行./configure進行環境檢查與配置,從而生成 Makefile 文件,再執行 make && make install命令進行編譯安裝。而 Redis 源碼包中直接提供了 Makefile 文件,所以在解壓完軟件包后,可直接進入解壓后的軟件包目錄,執行make與make install命令進行安裝。
make install 只是安裝了二進制文件到系統中,并沒有啟動腳本和配置文件。軟件包中默認提供了一個 install_server.sh 腳本文件,通過該腳本文件可以設置 Redis 服務所需要的相關配置文件。當腳本運行完畢,Redis 服務就已經啟動,默認偵聽端口為 6379。
初始化之后自動啟動
Redis 安裝完成,可通過 Redis 的服務控制腳本/etc/init.d/redis 6379來對 Redis 服務進行控制,如停止 Redis 服務、啟動 Redis 服務、重啟 Redis服務、查看 Redis 運行狀態。
配置參數
Redis 主配置文件為/etc/redis/6379.conf,由注釋行與設置行兩部分組成與大多數 Linux 配置文件一樣,注釋性的文字以“#”開始,包含了對相關配置內容進行的說明和解釋。除了注釋行與空行以外的內容即為設置行。可根據生產環境的需求調整相關參數,如下:
除了上述配置參數外,Redis 主配置文件中還包含很多其它的配置參數,具體內容如表所示。
?參數? | ?作用? |
---|---|
?timeout 300? | 當客戶端閑置?300秒?后關閉連接,指定為0則關閉該功能 |
?dbfilename dump.rdb? | 指定本地數據庫文件名為?dump.rdb?,為默認值 |
?dir /var/lib/redis/6379? | 指定本地數據庫存放目錄為?/var/lib/redis/6379? |
?maxclients 10000? | 設置同一時間最大客戶端連接數為?10000?,達到限制時Redis會關閉新連接并返回錯誤信息。如果設置 maxclients0,表示不限制。 |
?rdbcompression yes? | 指定存儲至本地數據庫時?啟用?數據壓縮,采用LZF算法,關閉可節省CPU但數據庫文件會增大 |
?slaveof ? | 當本機為從服務器時,設置主服務的 IP 地址及端口。?在 Redis 啟動時,從服務器會自動從主服務進行數據同步?。 |
?masterauth ? | 當主服務設置了密碼保護時,從服務連接主服務所需的密碼。 |
?requirepass foobared? | 指定 Redis 連接密碼。如果配置了連接密碼,客戶端在連接 Redis 時需要通過 ?AUTH 命令? 提供密碼,默認關閉。 |
?maxmemory ? | 指定 Redis 最大內存限制。Redis 啟動時會加載數據到內存中,達到最大內存后,會先嘗試清除已到期或即將到期的 Key。若仍超出限制,則無法進行寫入操作,但可讀取。Redis 新 VM 機制會將 Key 存放在內存,Value 存放在 Swap 分區。 |
?appendonly no? | 指定是否在每次更新操作后進行日志記錄。Redis 默認異步寫入磁盤,不開啟可能導致斷電時數據丟失。因為 Redis 按 save 條件同步數據,所以部分數據可能僅存在于內存中。默認為 no。 |
?appendfilename appendonly.aof? | 指定更新日志文件名,默認為 appendonly.aof。 |
?appendfsync everysec? | 指定更新日志條件: - ?no?:等待操作系統同步數據到磁盤(快) - ?always?:每次更新后手動調用 fsync() 寫入磁盤(慢,安全) - ?everysec?:每秒同步一次(折衷,默認值) |
?activerehashing yes? | 指定是否激活重置哈希,默認為開啟。 |
?include /path/to/local.conf? | 指定包含其他配置文件。可在同一主機上多個 Redis 實例間使用同一份配置文件,同時各實例擁有特定配置文件。 |
3.Redis命令工具
Redis 軟件提供了多個命令工具。安裝 Redis 服務時,所包含的軟件工具會同時被安裝到系統中,在系統中可以直接使用。這些命令工具的作用分別如下所示。
redis - server: 用于啟動 Redis 的工具
redis - benchmark: 用于檢測 Redis 在本機的運行效率
redis - check - aof: 修復 AOF 持久化文件
redis - check - rdb: 修復 RDB 持久化文件
redis - cli: Redis 命令行工具
redis-cli命令行工具
Redis 數據庫系統是典型 C/S(客戶端 / 服務器端)架構應用,訪問其數據庫需用專門客戶端軟件,自帶的 redis-cli 命令行工具就是 Redis 服務的客戶端軟件。使用 redis-cli 連接指定數據庫,成功后進入提示符為 “遠程主機 IP 地址:端口號>”(如 “127.0.0.1:6379>” )的數據庫操作環境,用戶可輸入操作語句管理數據庫,執行 ping 命令可檢測 Redis 服務是否啟動 。
以下是提取的內容: 在進行數據庫連接操作時,可以通過選項來指定遠程主機上的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環境。
…//省略
在數據庫操作環境中,使用 help 命令可以獲取命令類型的幫助。有三種獲取命令幫助的方式。
help @< group> :獲取< group>中的命令列表
help < command>: 獲取某個命令的幫助
help < tab>: 獲取可能幫助的主題列表
具體操作方法如下所示。
redis-benchmark 測試工具
redis-benchmark 是官方自帶的 Redis 性能測試工具,可以有效的測試 Redis 服務的性能。
基本的測試語法為:
redis-benchmark [option] [option value]
結合上述選項,可以針對某臺 Redis 服務器進行性能檢測,如執行 redis - benchmark - h 192.168.10.161 -p 6379 -c 100 -n 100000 命令即可向 IP 地址為 192.168.10.161、端口為 6379 的 Redis 服務器發送 100 個并發連接與 100000 個請求測試性能 。 主要介紹了利用 redis - benchmark 命令對特定 Redis 服務器(IP 192.168.10.161 、端口 6379 )進行性能檢測的操作及參數含義,-h 指定 IP,-p 指定端口,-c 指定并發連接數,-n 指定請求數
… …
測試存取大小為 100 字節的數據包的性能
測試本機上 Redis 服務在進行 set 與 lpush 操作時的性能
4.Redis數據庫常用命令
前面提到 Redis 數據庫采用 key - value(鍵值對)的數據存儲形式。所使用的命令是 set 與 get 命令
set: 存放數據 set key value
get: 獲取數據 get key
例如,在 Redis 的命令行模式下執行”set teacher zs”,表示在當前數據庫下存放一個 key 為teacher,value 為 zs 的數據,而執行get teacher“命令即可查看剛才存放的數據。
key相關命令
在 Redis 數據庫中,與 key 相關的命令主要包含以下幾種。
(1)keys
使用 keys 命令可以取符合規則的鍵值列表,通常情況可以結合*、?等選項來使用。
(2)exists
exists命令可以判斷鍵值是否存在
(3)del
del 命令可以刪除當前數據庫的指定 key。
(4)type
使用 type 命令可以獲取 key 對應的 value 值類型
(5)rename
命令是對已有 key 進行重命名,其命令格式為:rename 源key 目標renamekey。使 用 rename 命令進行重命名時,無論目標 key 是否存在都進行重命名,且源 key 的值會覆蓋目標 key 的值。在實際使用過程中,建議先用 exists 命令查看目標 key 是否存在,然后再決定是否執行 rename 命令,以避免覆蓋重要數據。
(6)renamenx
renamenx 命令的作用是對已有 key 進行重命名,并檢測新名是否存在。其命令格式與 rename 的命令格式除命令關鍵字不同外基本相同:renamenx 源 key 目標 key。使用 renamenx 命令進行重命名時,如果目標 key 存在則不進行重命名。
(7)dbsize
dbsize 命令的作用是查看當前數據庫中 key 的數目。
5.多數據庫常用命令
(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 的數據庫。
(2)多數據庫間移動數據
Redis 的多數據庫在一定程度上是相對獨立的,例如在數據庫0上面存放king的數據,在其它 1-15 的數據庫上是無法査看到的。
Redis 數據庫提供了一個 move 的命令,可以進行多數據庫之間的數據移動。命令的基本語法格式為“move key dbindex”。其中“key”表示當前數據庫的目標鍵,“dbindex”表示目標數據庫的序號,具體操作方法如下所示。
(3)清理數據庫內數據
Redis 數據庫的整庫數據刪除主要分為兩個部分:清空當前數據庫數據,使用FLUSHDB 命令實現:清空所有數據庫的數據,使用FLUSHALL命令實現。但是,數據清空操作比較危險,生產環境下一般不建議使用。
二、Redis持久化
Redis 是一種高級 key-value 數據庫。它跟 Memcached 類似,不過數據可以持久化,而且支持的數據類型很豐富,有字符串、列表、集合和有序集合。支持在服務器端計算集合(difference)等,還支持多種排序功能。所以 Redis 也可以被看成是一個數據結構服務器。
Redis 的所有數據都是保存在內存中,然后不定期的通過異步方式保存到磁盤上(這稱為 “半持久化模式” );也可以把每一次數據變化都寫入到一個 append only file(aof)里面(這稱為 “全持久化模式” )。
由于 Redis 的數據都存放在內存中,如果沒有配置持久化,Redis 重啟后數據就全丟失了。所以,需要開啟 Redis 的持久化功能,將數據保存到磁盤上,當 Redis 重啟后,可以從磁盤中恢復數據。Redis 提供兩種方式進行持久化,一種是 RDB 持久化(原理是將 Reids 在內存中的數據庫記錄定時 dump 到磁盤上的 RDB 持久化),另外一種是 AOF(append only file)持久化(原理是將 Reids 的操作日志以追加的方式寫入文件)。那么這兩種持久化方式有什么區別呢?在實際使用的時候該如何選擇呢?下面簡單介紹一下二者的區別
1.RDB和AOF的區別
RDB 持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操作過程是 fork 一個子進程,先將數據集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲,如圖所示。
AOF 持久化以日志的形式記錄服務器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄
2.RDB和AOF的優缺點
RDB優缺點
(1)RDB優點
一旦采用該方式,那么整個 Redis 數據庫將只包含一個文件,這對于文件備份而言是非常完美的。比如,計劃每個小時歸檔一次最近 24 小時的數據,同時還要每天歸檔一次最近 30 天的數據。通過這樣的備份策略,一旦系統出現災難性故障,可以非常容易地進行恢復。
對于災難恢復而言,RDB 是非常不錯的選擇。可以非常輕松的將一個單獨的文件壓縮后再轉移到其它存儲介質上。
性能最大化,對于 Redis 的服務進程而言,在開始持久化時,它唯一需要做的只是 fork 出子進程,之后再由子進程完成這些持久化的工作,這樣就可以極大的避免服務進程執行 IO 操作了。
相比于 AOF 機制,如果數據集很大,RDB 的啟動效率會更高。
(2)RDB 缺點
如果想保證數據的高可用性,即最大限度的避免數據丟失,那么 RDB 將不是一個很好的選擇。因為系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。
由于 RDB 是通過 fork 子進程來協助完成數據持久化工作的,因此當數據集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是 1 秒鐘
AOF優缺點
(1)AOF優點
AOF 機制可帶來更高數據安全性(數據持久性)。Redis 提供每秒同步、每次修改同步、不同步 3 種同步策略。每秒同步異步完成,效率高,但系統宕機時一秒內修改數據可能丟失;每次修改同步是同步持久化,數據變化立即記錄到磁盤,效率最低 。
因對日志文件寫入用 append 模式,寫入中宕機不破壞已有內容。若操作寫一半系統崩潰,Redis 下次啟動前可用 redis - check - aof 工具解決數據一致性問題 。
日志過大時,Redis 可自動啟用 rewrite 機制。Redis 以 append 模式寫修改數據到舊磁盤文件,同時創建新文件記錄期間修改命令,rewrite 切換時能更好保證數據安全 。
AOF 包含格式清晰、易理解的日志文件記錄所有修改操作,可通過該文件重建數據 。
(2)AOF缺點
相同數據集下,AOF 文件通常比 RDB 文件大,RDB 恢復大數據集速度比 AOF 快 。
因同步策略不同,AOF 運行效率往往慢于 RDB。每秒同步策略效率較高,同步禁用策略效率和 RDB 一樣高效 。
二者選擇標準:看系統愿犧牲性能換更高緩存一致性(AOF),還是寫操作頻繁時不用備份換更高性能,待手動運行 save 再備份(RDB)
3.Redis持久化配置
RDB 持久化配置
Redis 會將數據集的快照 dump 到 dump.rdb 文件中。此外,也可以通過配置文件來修改 Redis 服務器 dump 快照的頻率。在打開 6379.conf 文件之后,搜索 save,可以看到如下所示配置信息。
背景知識:RDB(Redis DataBase)是 Redis 的一種持久化方式,它按照指定時間間隔將內存中的數據集生成快照并保存到磁盤(即 dump 到 dump.rdb 文件 ),重啟 Redis 時可通過加載該文件恢復數據,常用于數據備份、災難恢復等場景 ,通過配置 save 相關規則(如 “save 900 1” 表示 900 秒內有 1 次修改就觸發快照生成 )來控制 RDB 持久化的頻率
AOF 持久化配置
appendonly no 改為yes 開啟 AOF
在 Redis 的配置文件中存在三種同步方式,它們分別是:
appendfsync always 每次有數據修改發生時都會寫入 AOF 文件
appendfsync everysec 每秒鐘同步一次,為 AOF 的缺省策略
appendfsync no 從不同步,高效但數據不會被持久化
4. AOF 重寫
Redis 會不斷地將被執行的命令記錄到 AOF 文件里,隨著 Redis 持續運行,AOF 文件體積會不斷增長,極端情況下可能用盡硬盤可用空間。Redis 重啟后需通過重新執行 AOF 文件記錄的寫命令還原數據集,若 AOF 文件體積過大,還原操作時間會很長。
為解決 AOF 文件體積增大問題,用戶可向 Redis 發送 BGREWRITEAOF 命令,該命令通過移除 AOF 文件中的冗余命令來重寫 AOF 文件,減小其體積 。
BGREWRITEAOF 工作原理和 BGSAVE 創建快照相似:Redis 會創建子進程,由子進程負責重寫 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 ,且比上一次重寫后的體積大至少一倍(100%)時,Redis 將執行 BGREWRITEAOF 命令。若重寫執行過頻,可考慮將 auto - aof - rewrite - percentage 選項值設為 100 以上,這會讓 Redis 在 AOF 文件體積更大后才執行重寫,但也會使 Redis 啟動時還原數據集所需時間更長