一、Redis的可執行文件
當我們安裝完Redis之后,src和/usr/local/bin目錄下提供了下面這些可執行程序,我們稱之為Redis Shell:
redis-server | Redis服務器 |
redis-cli | Redis命令行客戶端 |
redis-benchmark | Redis性能測試工具 |
redis-check-aof | Redis AOF持久化文件檢測和AOF文件修復工具 |
redis-check-dump | Redis RDB持久化文件檢測和文件檢查工具 |
redis-sentinel | Sentinel服務器(Redis2.8版本之后) |
二、Redis默認配置文件
Redis的默認配置文件:
在下載的redis源碼包根目錄下有一個名為redis.conf的配置文件,這個配置文件中的參數是redis服務器啟動的默認參數(備注:但是redis-server啟動不是使用這個配置文件)
如果你想自己設置配置參數,那么可以拷貝這個配置文件然后修改,在redis-server啟動時指定配置文件的路徑
相對于很多大型存儲系統,Redis的配置不是很多,到了Redis3.0之后有60多個
①單機模式下的配置參數
總體配置:下圖是Redis的一些總體配置,例如端口、日志、數據庫等
1. Redis默認不是以守護進程的方式運行,可以通過該配置項修改,使用yes啟用守護進程daemonize no2. 當Redis以守護進程方式運行時,Redis默認會把pid寫入/var/run/redis.pid文件,可以通過pidfile指定pidfile /var/run/redis.pid3. 指定Redis監聽端口,默認端口為6379,作者在自己的一篇博文中解釋了為什么選用6379作為默認端口,因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自意大利歌女Alessia Merz的名字port 63794. 綁定的主機地址bind 127.0.0.15.當 客戶端閑置多長時間后關閉連接,如果指定為0,表示關閉該功能timeout 3006. 指定日志記錄級別,Redis總共支持四個級別:debug、verbose、notice、warning,默認為verboseloglevel verbose7. 日志記錄方式,默認為標準輸出,如果配置Redis為守護進程方式運行,而這里又配置為日志記錄方式為標準輸出,則日志將會發送給/dev/nulllogfile stdout8. 設置數據庫的數量,默認數據庫為0,可以使用SELECT <dbid>命令在連接上指定數據庫iddatabases 169. 指定在多長時間內,有多少次更新操作,就將數據同步到數據文件,可以多個條件配合save <seconds> <changes>Redis默認配置文件中提供了三個條件:save 900 1save 300 10save 60 10000分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。10. 指定存儲至本地數據庫時是否壓縮數據,默認為yes,Redis采用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致數據庫文件變的巨大rdbcompression yes11. 指定本地數據庫文件名,默認值為dump.rdbdbfilename dump.rdb12. 指定本地數據庫存放目錄dir ./13. 設置當本機為slav服務時,設置master服務的IP地址及端口,在Redis啟動時,它會自動從master進行數據同步slaveof <masterip> <masterport>14. 當master服務設置了密碼保護時,slav服務連接master的密碼masterauth <master-password>15. 設置Redis連接密碼,如果配置了連接密碼,客戶端在連接Redis時需要通過AUTH <password>命令提供密碼,默認關閉requirepass foobared16. 設置同一時間最大客戶端連接數,默認無限制,Redis可以同時打開的客戶端連接數為Redis進程可以打開的最大文件描述符數,如果設置 maxclients 0,表示不作限制。當客戶端連接數到達限制時,Redis會關閉新的連接并向客戶端返回max number of clients reached錯誤信息maxclients 12817. 指定Redis最大內存限制,Redis在啟動時會把數據加載到內存中,達到最大內存后,Redis會先嘗試清除已到期或即將到期的Key,當此方法處理 后,仍然到達最大內存設置,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放內存,Value會存放在swap區maxmemory <bytes>18. 指定是否在每次更新操作后進行日志記錄,Redis在默認情況下是異步的把數據寫入磁盤,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。因為 redis本身同步數據文件是按上面save條件來同步的,所以有的數據會在一段時間內只存在于內存中。默認為noappendonly no19. 指定更新日志文件名,默認為appendonly.aofappendfilename appendonly.aof20. 指定更新日志條件,共有3個可選值: no:表示等操作系統進行數據緩存同步到磁盤(快) always:表示每次更新操作后手動調用fsync()將數據寫到磁盤(慢,安全)everysec:表示每秒同步一次(折衷,默認值)appendfsync everysec21. 指定是否啟用虛擬內存機制,默認值為no,簡單的介紹一下,VM機制將數據分頁存放,由Redis將訪問量較少的頁即冷數據swap到磁盤上,訪問多的頁面由磁盤自動換出到內存中(在后面的文章我會仔細分析Redis的VM機制)vm-enabled no22. 虛擬內存文件路徑,默認值為/tmp/redis.swap,不可多個Redis實例共享vm-swap-file /tmp/redis.swap23. 將所有大于vm-max-memory的數據存入虛擬內存,無論vm-max-memory設置多小,所有索引數據都是內存存儲的(Redis的索引數據 就是keys),也就是說,當vm-max-memory設置為0的時候,其實是所有value都存在于磁盤。默認值為0vm-max-memory 024. Redis swap文件分成了很多的page,一個對象可以保存在多個page上面,但一個page上不能被多個對象共享,vm-page-size是要根據存儲的 數據大小來設定的,作者建議如果存儲很多小對象,page大小最好設置為32或者64bytes;如果存儲很大大對象,則可以使用更大的page,如果不 確定,就使用默認值vm-page-size 3225. 設置swap文件中的page數量,由于頁表(一種表示頁面空閑或使用的bitmap)是在放在內存中的,,在磁盤上每8個pages將消耗1byte的內存。vm-pages 13421772826. 設置訪問swap文件的線程數,最好不要超過機器的核數,如果設置為0,那么所有對swap文件的操作都是串行的,可能會造成比較長時間的延遲。默認值為4vm-max-threads 427. 設置在向客戶端應答時,是否把較小的包合并為一個包發送,默認為開啟glueoutputbuf yes 28. 指定在超過一定的數量或者最大的元素超過某一臨界值時,采用一種特殊的哈希算法 hash-max-zipmap-entries 64 hash-max-zipmap-value 512 29. 指定是否激活重置哈希,默認為開啟(后面在介紹Redis的哈希算法時具體介紹)activerehashing yes 30. 指定包含其它的配置文件,可以在同一主機上多個Redis實例之間使用同一份配置文件,而同時各個實例又擁有自己的特定配置文件 include /path/to/local.conf
?
AOF相關配置參數說明:?
本文主要描述了aof中的相關參數以及為什么這樣是可以足夠安全的。appendonly:開啟aof特性,這個控制是否啟用aof.appendfilename:寫入文件的文件名。開啟aof之后,每條命令(除讀之外的命令),均會寫入到文件中,這里即實際寫入的文件.appendfsync:寫入策略,默認值everysec,每秒寫一次(調用flush)。另外兩個值,always | no,分別表示每次redis寫命令之外就寫文件,和由操作系統保證。always對硬盤壓力大,everysec是一個平衡值,no對硬盤壓力最小,但調度由系統控制,丟失數據風險最大.no-appendfsync-on-rewrite:是否在后臺寫時同步單寫,默認值no(表示需要同步).這里的后臺寫,表示后臺正在重寫文件(包括bgsave和bgrewriteaof.bgrewriteaof網上很多資料都沒有涉及到。其實關掉bgsave之后,主要的即是aof重寫文件了).no表示新的主進程的set操作會被阻塞掉,而yes表示新的主進程的set不會被阻塞,待整個后臺寫完成之后再將這部分set操作同步到aof文件中。但這可能會存在數據丟失的風險(機率很小),如果對性能有要求,可以設置為yes,僅在后臺寫時會異步處理命令.auto-aof-rewrite-percentage:aof文件增長比例,指當前aof文件比上次重寫的增長比例大小。aof重寫即在aof文件在一定大小之后,重新將整個內存寫到aof文件當中,以反映最新的狀態(相當于bgsave)。這樣就避免了,aof文件過大而實際內存數據小的問題(頻繁修改數據問題).auto-aof-rewrite-min-size:aof文件重寫最小的文件大小,即最開始aof文件必須要達到這個文件時才觸發,后面的每次重寫就不會根據這個變量了(根據上一次重寫完成之后的大小).此變量僅初始化啟動redis有效.如果是redis恢復時,則lastSize等于初始aof文件大小.aof-load-truncated:指redis在恢復時,會忽略最后一條可能存在問題的指令。默認值yes。即在aof寫入時,可能存在指令寫錯的問題(突然斷電,寫了一半),這種情況下,yes會log并繼續,而no會直接恢復失敗.Linux內核參數:另外,與aof重寫相關的一個linux內核參數即是?overcommit_memory。即在進行重寫時,如何分配子進程內存的問題。(重寫是后臺重寫,會分配子進程).默認值為0,建立設置為1,以保證?子進程內存能夠分配成功(即使用copyOnWrite內存分配策略,在沒有set命令時會和主進程使用同一份內存),并且不會判斷當前內存是否夠用.
RDB相關配置:?
save?900?1 #?時間策略 save?300?10 #?時間策略 save?60?10000 #?時間策略 dbfilename?dump.rdb???#文件名稱 dir?/home/work/app/redis/data/????#文件保存路徑? stop-writes-on-bgsave-error yes # 如果持久化出錯,主進程是否停止寫入 rdbcompression?yes????#?是否壓縮? rdbchecksum?yes?????#?導入時是否檢查?
那么為什么需要配置這么多條規則呢?
因為Redis每個時段的讀寫請求肯定不是均衡的,為了平衡性能與數據安全,我們可以自由定制什么情況下觸發備份。
所以這里就是根據自身Redis寫入情況來進行合理配置。
stop-writes-on-bgsave-error?yes?:
這個配置也是非常重要的一項配置,這是當備份進程出錯時,主進程就停止接受新的寫入操作,是為了保護持久化的數據一致性問題。
如果自己的業務有完善的監控系統,可以禁止此項配置,?否則請開啟。
rdbcompression?yes??:
關于壓縮的配置?,建議沒有必要開啟,畢竟Redis本身就屬于CPU密集型服務器,再開啟壓縮會帶來更多的CPU消耗,相比硬盤成本,CPU更值錢。
當然如果你想要禁用RDB配置,也是非常容易的,只需要在save的最后一行寫上:save?""
慢查詢配置:?
slowlog-log-slower-than選項:
指定執行時間超過多少微秒(1秒等于1000 000微秒)的命令請求會被記錄到日志上
舉個例子,如果這個選項的值為100,那么執行時間超過100微秒的命令就會被記錄到慢查詢日志
提示:如果slowlog-log-slower-than=0會記錄所有的命令,slowlog-log-slowerthan<0對于任何命令都不會進行記錄
slowlog-max-len選項:
指定服務器最多保存多少條慢查詢日志
慢查詢日志數量的溢出
Redis使用了一個列表來存儲慢查詢日志,服務器使用先進先出的方式保存多條慢查詢日志,當服務器存儲的慢查詢日志數量等于slowlog-max-len選項的值時,服務器在添加一條新的慢查詢日志之前,會先將最舊的一條慢查詢日志刪除
舉個例子,如果服務器slowlog-max-len的值為100,并且假設服務器已經儲存了100條慢查詢日志,那么如果服務器打算添加一條新日志的話,它就必須先刪除目前保存的最舊的那條日志,然后再添加新日志
配置參數的設置
如果要Redis將配置持久化到本地配置文件,需要執行config rewrite命令
config set slowlog-log-slower-than 20000
config set slowlog-max-len 1000
config rewrite
可以使用CONFIG命令設置配置參數的值
數據結構優化配置:
下圖是Redis數據結構優化的相關配置 :
自從Redis 2.2之后,很多數據類型都可以通過特殊編碼的方式來進行存儲空間的優化。其中,Hash、List和由Integer組成的Sets都可以通過該方式來優化存儲結構,以便占用更少的空間,在有些情況下,可以省去9/10的空間。 這些特殊編碼對于Redis的使用而言是完全透明的,事實上,它只是CPU和內存之間的一個交易而言。如果內存使用率方面高一些,那么在操作數據時消耗的CPU自然要多一些,反之亦然。在Redis中提供了一組配置參數用于設置與特殊編碼相關的各種閾值,如:#如果Hash中字段的數量小于參數值,Redis將對該Key的Hash Value采用特殊編碼。hash-max-zipmap-entries 64#如果Hash中各個字段的最大長度不超過512字節,Redis也將對該Key的Hash Value采用特殊編碼方式。hash-max-zipmap-value 512#下面兩個參數的含義基本等同于上面兩個和Hash相關的參數,只是作用的對象類型為List。list-max-ziplist-entries 512list-max-ziplist-value 64#如果set中整型元素的數量不超過512時,Redis將會采用該特殊編碼。set-max-intset-entries 512倘若某個已經被編碼的值再經過修改之后超過了配置信息中的最大限制,那么Redis會自動將其轉換為正常編碼格式,這一操作是非常快速的,但是如果反過來操作,將一個正常編碼的較大值轉換為特殊編碼,Redis的建議是,在正式做之前最好先簡單測試一下轉換效率,因為這樣的轉換往往是非常低效的。
主從復制相關配置:??
實現Redis的主從復制配置比較簡單,而且容易明白。
下圖是要配置的主從復制結構圖:
1.說明
Redis主從復制中一個主服務可以有多個從服務,一個從服務可以有多個從服務。
配置比較簡單,只需要更改redis.conf文件中的slaveof參數配置即可。
slaveof參數的格式如:slaveof <masterip> <masterport>
如果master服務器設置有密碼則需要配置masterauth參數。
masterauth參數格式如:masterauth <master-password>
2.配置主從服務器
如上圖可見master和slave1,slave2,slave3的服務器的端口的IP。
?
master :port 6379 requirepass redis slave1 : port 6479 slaveof 127.0.0.1 6379 masterauth redis requirepass redis slave2 : port 6579 slaveof 127.0.0.1 6479 masterauth redis requirepass redis slave3 : port 6679 slaveof 127.0.0.1 6379 masterauth redis requirepass redis
需要注意的是如果服務器中為設置requirepass參數,則從服務中不需要設置masterauth參數。
②Sentinel配置說明和分析
?
Redis的主從模式下,主節點一旦發生故障不能提供服務,需要人 工干預,將從節點晉升為主節點,同時還需要修改客戶端配置。 對于很多應用場景這種方式無法接受。
Redis從 2.8發布了一個穩定版本的Redis Sentinel 。當前版本的 Sentinel稱為Sentinel 2。它是使用更強大和更簡單的預測算法來重 寫初始Sentinel實現。(Redis2.6版本提供Sentinel 1版本,但是有 一些問題)
Sentinel(哨兵)架構解決了redis主從人工干預的問題。
Redis Sentinel是redis的高可用實現方案,在實際生產環境中,對 提高整個系統可用性是非常有幫助的。
Redis Sentinel是一個分布式系統,Redis Sentinel為Redis提供高可用性。可以在沒有人為干預的情況下 阻止某種類型的故障。
可以在一個架構中運行多個 Sentinel 進程(progress), 這些進程使用流言協議(gossip protocols)來 接收關于主服務器是否下線的信息, 并使用投票協議(agreement protocols)來決定是否執行自動故 障遷移, 以及選擇哪個從服務器作為新的主服務器。
Redis 的 Sentinel 系統用于管理多個 Redis 服務器(instance) 該系統執行以下三個任務:
監控(Monitoring): Sentinel 會不斷地定期檢查你的主服務器和從服務器是否運作正常。
提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
自動故障遷移(Automaticfailover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中 一個從服務器升級為新的主服務器, 并讓失效主服務器的其他從服務器改為復制新的主服務器; 當客 戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主 服務器代替失效服務器
以下是一些修改sentinel配置的命令:SENTINEL MONITOR <name> <ip> <port> <quorum>這個命令告訴sentinel去監聽一個新的masterSENTINEL REMOVE <name> 命令sentinel放棄對某個master的監聽SENTINEL SET <name> <option> <value> 這個命令很像Redis的CONFIG SET命令,用來改變指定master的配置。
③Cluster配置說明和分析
Cluster節點是特殊的Redis節點,有幾個特殊的配置,如下圖所示
CONFIG SET、CONFIG GET命令
我們可以在不重新啟動Redis的情況下動態修改部分Redis配置(注:并不是所有的配置都支持CONFIG SET命令,具體見上圖)
redis>CONFIG SET loglevel warning
我們也可以通過CONFIG GET來獲取一個配置的值:1)是配置選項名稱,2)是選項值
requirepass配置參數
該參數用于權限控制。當設置了這個參數之后,客戶端連接時就需要輸入密碼才可以連接到服務器
演示案例
在配置文件中加入該參數,密碼為“123456”
requirepass 123456
重啟redis服務器,然后再使用上面的配置文件啟動redis(此處我們的redis以守護進程運行的)
此時我們使用redis-cli雖然可以連接上服務端,但是輸入命令都無權限,需要認證
此時我們需要輸入auth命令和密碼進行認證,認證完之后就可以進行操作了
當然,我們也可以通過redis-cli的“-a”參數指定連接時的密碼,這樣就不需要輸入auth命令進行認證了。備注:不建議這樣做,因為密碼可能會外漏
redis-cli -a 123456
多線程相關的配置參數
在redis 6.0之后支持多線程了
io-threads-do-reads配置參數:要開啟多線程,那么需要在配置文件中將該參數設置為yes
io-threads-do-reads on;
io-threads配置參數:該參數用來設置線程的數量
io-threads 4;
線程數的設置建議:官方有一個建議,4 核的機器建議設置為 2 或 3 個線程,8 核的建議設置為 6 個線程,線程數一定要小于機器核數
bind配置參數
該參數代表redis服務端接受從哪些網絡通道傳來的網絡流量
例如,下面服務端只接受127.0.0.1和172.17.0.14網段的網絡流量
bind 127.0.0.1 172.17.0.14
備注:Redis3.0中bind默認值為””,也就是不限制網卡的訪問,但是在Redis3.2 中必須顯示的配置bind 0.0.0.0才可以達到這種效果
protected-mode配置參數
Redis3.2提供了protected-mode配置(默認開啟)
功能:如果當前Redis沒有配置密碼,沒有配置bind,那么只允許來自本機的訪問,也就是相當于配置了bind 127.0.0.1
演示案例:下面redis服務端開啟了該配置參數,且配置文件中沒有配置密碼,也沒有配置bind,當外網訪問時顯示不能訪問
三、Redis服務端的啟動
有三種方法啟動Redis:默認配置啟動、運行配置啟動、配置文件啟動
①默認配置啟動
直接運行redis-server即可啟動Redis:
sudo redis-server
這種方法會使用Redis的默認配置文件來啟動Redis,例如Redis默認配置文件中指定Redis的端口號為6379、當前版本為6.0.1
實際生產環境中一般不使用這種方法來啟動Redis,因為無法自定義配置
②運行配置啟動
我們在運行時可以指定配置名和值(可以是多對),沒有配置的將仍然使用默認配置
例如,下面以6379端口啟動Redis,其他參數仍使用默認值
sudo redis-server --port 6379
這種方法也不建議使用,因為如果修改的配置較多的話那么比較麻煩,并且這種參數不能保存到文件中
③指定配置文件啟動
將配置寫到指定文件里,例如我們將配置寫到了/opt/redis/redis.conf,那么可以執行下面的命令啟動redis:
sudo redis-server /opt/redis/redis.conf
比較建議使用這種方式啟動Redis
redis有60多個配置參數,在上面介紹了一些,后面文章還會介紹更多。下面列出了一些重要配置參數:
參數 說明 daemonize 是否以守護進程模式運行Redis pidfile 設置Redis的PID文件位置 logfile 日志文件位置 port 設置Redis監聽的端口號 dir Redis工作目錄(存放持久化文件和日志文件)
我們也可以在啟動時同時指定配合文件和配置選項,那么命令行的配置選項就會覆蓋配置文件中的參數。例如:
redis-server 配置文件名.conf --loglevel warning
四、Redis服務端的關閉
shutdown命令
正確停止Redis的方式應該是向Redis發送SHUTDOWN命令,方法為:
當Redis收到SHUTDOWN命令后,會先斷開所有客戶端連接,然后根據配置執行持久化,最后完成退出
Redis可以妥善處理SIGTERM信號,所以使用kill Redis進程的PID也可以正常結束Redis,效果與發送SHUTDOWN命令一樣
①如果客戶端還沒有與服務端進行連接,那么可以執行在命令行輸入下面的命令來關閉服務端:
redis-cli SHUTDOWN
②如果客戶端工具已經連接入服務端,那么直接輸入SHUTDOWN即可:
shutdown還有一個參數,代表是否在關閉Redis前,生成持久化文件
redis-cli shutdown nosave|save
考慮到Redis有可能正在將內存中的數據同步到硬盤中,強行終止Redis進程可能會導致數據丟失,因此不建議使用kill-9強制殺死Redis服務,不但不會做持久化操作,還會造成緩沖區等資源不能被優雅關閉,極端情況會造 成AOF和復制丟失數據的情況
五、Redis服務端的重啟
使用軟件包編譯安裝的redis不支持重啟操作,只能通過redis-cli進行SHUTDOWN關機然后再重新開啟服務端
但是如果使用apt-get或yum形式安裝的redis支持重啟(見文章最后)
六、連接到Redis服務端
使用redis-cli可以連接到redis服務端,有兩種連接方式
①交互式連接
第一種是交互式方式,連接之后不會退出redis-cli命令行
例如,下面連接到IP為127.0.0.1、端口為6379的redis服務端
redis-cli -h 127.0.0.1 -p 6379
可以不寫-h和-p參數,它們的默認值分別為127.0.0.1和6379
②命令方式連接
第二種是命令方式連接,只連接一次就斷開
例如,下面連接的時候獲取一次玩家的數據就退出
關于redis-cli在后面會詳細介紹?
七、redis設置允許外網連接
設置方法如下:
如果沒有為redis設置密碼(也就是沒有設置requirepass配置參數),那么需要將protected-mode配置參數更改為no
如果你的redis設置了密碼(也就是設置了requirepass配置參數),那么不需要更改protected-mode配置參數
第一步:注釋掉配置文件中的bind參數
第二步:如果你的bind參數被注釋了,那么還要分為以下兩種情況:
?
bind 0.0.0.0
# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
#? ? "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode no
?
八、軟件包安裝的redis的開機、關閉、重啟
如果是使用apt-get或yum形式安裝的redis,那么支持下面的幾種方式
sudo /etc/init.d/redis-server stop #關機
sudo /etc/init.d/redis-server start #啟動
sudo /etc/init.d/redis-server restart #重啟