1. 程式人生 > 實用技巧 >Redis資料庫

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檔案時,伺服器執行以下操作: