Redis資料庫
1.1 Redis簡介
1.1.1介紹
Redis是一個使用ANSI C編寫的開源、支援網路、基於記憶體、可選永續性的鍵值對(key-value)儲存資料庫。從2015年6月開始,Redis的開發由Redis Labs贊助,而2013年5月至2015年6月期間,其開發由Pivotal贊助。在2013年5月之前,其開發由VMware贊助。根據月度排行網站DB-Engines.com的資料顯示,Redis是最流行的鍵值對儲存資料庫。
資料來源:https://db-engines.com/en/ranking
Redis採用記憶體(In-Memory)資料集(DataSet)。
支援多種資料型別。
運行於大多數POSIX系統,如Linux、*BSD、OS X等。
Redis作者:Salvatore Sanfilippo
作者GitHUB:https://github.com/antirez/redis
1.1.2軟體獲取和幫助
官方網站:https://redis.io
官方各版本下載地址:http://download.redis.io/releases/
Redis中文命令參考:http://redisdoc.com
中文網站1:http://redis.cn
中文網站2:http://www.redis.net.cn
1.1.3 Redis特性
高速讀寫,資料型別豐富
支援持久化,多種記憶體分配及回收策略
支援弱事務,訊息佇列、訊息訂閱
支援高可用,支援分散式分片叢集
1.1.4企業快取資料庫解決方案對比
Memcached:
優點:高效能讀寫、單一資料型別、支援客戶端式分散式叢集、一致性hash多核結構、多執行緒讀寫效能高。
缺點:無持久化、節點故障可能出現快取穿透、分散式需要客戶端實現、跨房資料同步困難、架構擴容複雜度高
Redis:
優點:高效能讀寫、多資料型別支援、資料持久化、高可用架構、支援自定義虛擬記憶體、支援分散式分片叢集、單執行緒讀寫效能極高
缺點:多執行緒讀寫較Memcached慢
Tair:官方網站:http://tair.taobao.org
優點:高效能讀寫、支援三種儲存引擎(ddb、rdb、ldb)、支援高可用、支援分散式分片叢集、支撐了幾乎所有淘寶業務的快取。
缺點:單機情況下,讀寫效能較其他兩種產品較慢。
1.1.5 Redis應用場景
資料快取記憶體,web會話快取(Session Cache)
排行榜應用
訊息佇列,釋出訂閱
附錄- Redis的企業應用
1.2 Redis簡單部署
1.2.1典型安裝-單例項
系統環境說明
[root@Redis ~]# cat /etc/redhat-release CentOS release 6.9 (Final) [root@Redis ~]# uname -r 2.6.32-696.el6.x86_64 [root@Redis ~]# sestatus SELinux status: disabled [root@Redis ~]# /etc/init.d/iptables status iptables: Firewall is not running. [root@Redis ~]# hostname -I 10.0.0.186 172.16.1.186
安裝redis
[root@Redis ~]# cd /usr/local/ [root@Redis local]# wget http://download.redis.io/releases/redis-3.2.10.tar.gz [root@Redis local]# tar xzf redis-3.2.10.tar.gz [root@Redis local]# \rm redis-3.2.10.tar.gz [root@Redis local]# mv redis-3.2.10 redis [root@Redis local]# cd redis/ [root@Redis redis]# make
至此redis就安裝完成
1.2.2啟動第一個redis例項
建立客戶端軟連線
[root@Redis src]# ln -s /usr/local/redis/src/redis-cli /usr/bin/
簡單啟動方法,都使用預設配置
[root@Redis ~]# cd /usr/local/redis/src [root@Redis src]# ./redis-server &
編寫配置檔案
1、精簡化配置檔案
[root@Redis redis]# cp redis.conf{,.bak} [root@Redis redis]# grep -Ev '^$|#' redis.conf.bak > redis.conf [root@Redis redis]# cp redis.conf /etc/
2、編輯配置檔案
[root@Redis ~]# cat /etc/redis.conf bind 127.0.0.1 10.0.0.186 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize yes supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "/var/log/redis_6379.log" dir /usr/local/redis/data/ # ···
配置檔案說明:https://www.cnblogs.com/zhang-ke/p/5981108.html
3、編寫啟動指令碼(適用於CentOS 6.X)
#!/bin/sh # # Simple Redis init.d script conceived to work on Linux systems # as it does use of the /proc filesystem. # chkconfig: - 85 15 # url: http://blog.nmtui.com # user: clsn ### END INIT INFO REDISPORT=6379 EXEC=/usr/local/redis/src/redis-server CLIEXEC=/usr/local/redis/src/redis-cli PIDFILE=/var/run/redis_6379.pid CONF="/etc/redis.conf" # source function library . /etc/rc.d/init.d/functions rd_start() { if [ -f $PIDFILE ] then action "$PIDFILE exists" /bin/false else $EXEC $CONF if [ $? -eq 0 ] then action "Starting Redis server..." /bin/true else action "Starting Redis server..." /bin/false fi fi } rd_stop() { if [ ! -f $PIDFILE ] then action "$PIDFILE does not exist, process is not running" /bin/false else PID=$(cat $PIDFILE) $CLIEXEC -p $REDISPORT shutdown while [ -x /proc/${PID} ] do echo "Waiting for Redis to shutdown ..." sleep 1 done action "Redis stopped" /bin/true fi } rd_status() { if [ -f $PIDFILE ] then echo "redis server is running....." else echo "redis is stopped" fi } rd_restart() { rd_stop sleep 2 rd_start } case "$1" in start) rd_start ;; stop) rd_stop ;; status) rd_status ;; restart) rd_restart ;; *) echo $"Usage: $0 {start|stop|restart|status}" ;; esac
注意:自編寫指令碼注意執行許可權。
1.2.3 Redis多例項配置
注意:本次多例項配置基於單例項配置完成後
建立並進入程式目錄
[root@Redis redis]# mkdir /application/redis -p [root@Redis redis]# cd /application/redis/
修改配置檔案
for i in 0 1 2 do # 建立多例項(埠命名)目錄 mkdir -p 638$i # 複製啟動程式到各例項 \cp /usr/local/redis/src/redis-server /application/redis/638$i/ # 複製配置檔案。注意:此處基於單例項配置完成 \cp /etc/redis.conf /application/redis/638$i/ # 修改程式儲存目錄 sed -i "/dir/s#.*#dir /application/redis/638$i/#g" /application/redis/638$i/redis.conf # 修改其他埠資訊 sed -i "s#6379#638$i#g" /application/redis/638$i/redis.conf # 允許遠端連線redis sed -i '/protected-mode/s#yes#no#g' /application/redis/638$i/redis.conf done
#啟動例項
for i in 0 1 2 do /application/redis/638$i/redis-server /application/redis/638$i/redis.conf done
連線redis
[root@Redis redis]# redis-cli -h 10.0.0.186 -p 6379 10.0.0.186:6379>
1.2.4 redis.conf配置說明
是否後臺執行:
daemonize no/yes
預設埠:
port 6379
AOF日誌開關是否開啟:
appendonly no/yes
日誌檔案位置
logfile /var/log/redis.log
RDB持久化資料檔案:
dbfilename dump.rdb
指定IP進行監聽
bind 10.0.0.51 ip2 ip3 ip4
禁止protected-mode
protected-mode yes/no (保護模式,是否只允許本地訪問)
增加requirepass {password}
requirepass root
在redis-cli中使用
auth {password} 進行認證
1.2.5線上變更配置
獲取當前配置
CONFIG GET *
變更執行配置
CONFIG SET loglevel "notice"
修改密碼為空
10.0.0.186:6379> config set requirepass "" 10.0.0.186:6379> exit 10.0.0.186:6379> config get dir 1) "dir" 2) "/usr/local/redis/data"
1.3 Redis資料持久化
1.3.1持久化策略
redis提供了多種不同級別的持久化方式:一種是RDB,另一種是AOF.
RDB持久化
可以在指定的時間間隔內生成資料集的時間點快照(point-in-time snapshot)。
AOF持久化
記錄伺服器執行的所有寫操作命令,並在伺服器啟動時,通過重新執行這些命令來還原資料集。AOF檔案中的命令全部以Redis協議的格式來儲存,新命令會被追加到檔案的末尾。
Redis還可以在後臺對AOF檔案進行重寫(rewrite),使得AOF檔案的體積不會超出儲存資料集狀態所需的實際大小。Redis還可以同時使用AOF持久化和RDB持久化。在這種情況下,當Redis重啟時,它會優先使用AOF檔案來還原資料集,因為AOF檔案儲存的資料集通常比RDB檔案所儲存的資料集更完整。
你甚至可以關閉持久化功能,讓資料只在伺服器執行時存在。
1.3.2 RDB持久化
RDB的優點
⚔RDB是一個非常緊湊(compact)的檔案,它儲存了Redis在某個時間點上的資料集。這種檔案非常適合用於進行備份:比如說,你可以在最近的24小時內,每小時備份一次RDB檔案,並且在每個月的每一天,也備份一個RDB檔案。這樣的話,即使遇上問題,也可以隨時將資料集還原到不同的版本。
⚔RDB非常適用於災難恢復(disaster recovery):它只有一個檔案,並且內容都非常緊湊,可以(在加密後)將它傳送到別的資料中心,或者亞馬遜S3中。
⚔RDB可以最大化Redis的效能:父程序在儲存RDB檔案時唯一要做的就是fork出一個子程序,然後這個子程序就會處理接下來的所有儲存工作,父程序無須執行任何磁碟I/O操作。
⚔RDB在恢復大資料集時的速度比AOF的恢復速度要快。
RDB的缺點
如果你需要儘量避免在伺服器故障時丟失資料,那麼RDB不適合你。
雖然Redis允許你設定不同的儲存點(save point)來控制儲存RDB檔案的頻率,但是,因為RDB檔案需要儲存整個資料集的狀態,所以它並不是一個輕鬆的操作。因此你可能會至少5分鐘才儲存一次RDB檔案。在這種情況下,一旦發生故障停機,你就可能會丟失好幾分鐘的資料。
每次儲存RDB的時候,Redis都要fork()出一個子程序,並由子程序來進行實際的持久化工作。在資料集比較龐大時,fork()可能會非常耗時,造成伺服器在某某毫秒內停止處理客戶端;如果資料集非常巨大,並且CPU時間非常緊張的話,那麼這種停止時間甚至可能會長達整整一秒。雖然AOF重寫也需要進行fork(),但無論AOF重寫的執行間隔有多長,資料的耐久性都不會有任何損失。
1.3.3 AOF持久化
AOF優點
使用AOF會讓你的Redis更加耐久:你可以使用不同的fsync策略:無fsync,每秒fsync,每次寫的時候fsync.使用預設的每秒fsync策略,Redis的效能依然很好(fsync是由後臺執行緒進行處理的,主執行緒會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的資料.
Redis可以在AOF檔案體積變得過大時,自動地在後臺對AOF進行重寫:重寫後的新AOF檔案包含了恢復當前資料集所需的最小命令集合。整個重寫操作是絕對安全的,因為Redis在建立新AOF檔案的過程中,會繼續將命令追加到現有的AOF檔案裡面,即使重寫過程中發生停機,現有的AOF檔案也不會丟失。
一旦新AOF檔案建立完畢,Redis就會從舊AOF檔案切換到新AOF檔案,並開始對新AOF檔案進行追加操作。
AOF檔案有序地儲存了對資料庫執行的所有寫入操作,這些寫入操作以Redis協議的格式儲存,因此AOF檔案的內容非常容易被人讀懂,對檔案進行分析(parse)也很輕鬆。匯出(export)AOF檔案也非常簡單:舉個例子,如果你不小心執行了FLUSHALL命令,但只要AOF檔案未被重寫,那麼只要停止伺服器,移除AOF檔案末尾的FLUSHALL命令,並重啟Redis,就可以將資料集恢復到FLUSHALL執行之前的狀態。
AOF缺點
對於相同的資料集來說,AOF檔案的體積通常要大於RDB檔案的體積。根據所使用的fsync策略,AOF的速度可能會慢於RDB。
在一般情況下,每秒fsync的效能依然非常高,而關閉fsync可以讓AOF的速度和RDB一樣快,即使在高負荷之下也是如此。不過在處理巨大的寫入載入時,RDB可以提供更有保證的最大延遲時間(latency)。
AOF在過去曾經發生過這樣的bug:因為個別命令的原因,導致AOF檔案在重新載入時,無法將資料集恢復成儲存時的原樣。(舉個例子,阻塞命令BRPOPLPUSH就曾經引起過這樣的bug。)測試套件裡為這種情況添加了測試:它們會自動生成隨機的、複雜的資料集,並通過重新載入這些資料來確保一切正常。
雖然這種bug在AOF檔案中並不常見,但是對比來說,RDB幾乎是不可能出現這種bug的。
1.3.4如何選擇使用哪種持久化方式
一般來說,如果想達到足以媲美PostgreSQL的資料安全性,你應該同時使用兩種持久化功能。
如果你非常關心你的資料,但仍然可以承受數分鐘以內的資料丟失,那麼你可以只使用RDB持久化。
有很多使用者都只使用AOF持久化,但我們並不推薦這種方式:因為定時生成RDB快照(snapshot)非常便於進行資料庫備份,並且RDB恢復資料集的速度也要比AOF恢復的速度要快,除此之外,使用RDB還可以避免之前提到的AOF程式的bug。
Note:因為以上提到的種種原因,未來redis可能會將AOF和RDB整合成單個持久化模型(這是一個長期計劃)。
1.3.5快照實現持久化
在預設情況下,Redis將資料庫快照儲存在名字為dump.rdb的二進位制檔案中。你可以對Redis進行設定,讓它在“N秒內資料集至少有M個改動”這一條件被滿足時,自動儲存一次資料集。
你也可以通過呼叫SAVE或者BGSAVE,手動讓Redis進行資料集儲存操作。
比如說,以下設定會讓Redis在滿足“60秒內有至少有1000個鍵被改動”這一條件時,自動儲存一次資料集:save 60 1000
這種持久化方式被稱為快照snapshotting.
當Redis需要儲存dump.rdb檔案時,伺服器執行以下操作: