1. 程式人生 > >Zhu_Julian's Notes (朱顯傑的技術部落格)

Zhu_Julian's Notes (朱顯傑的技術部落格)

Redis概述

Redis是Salvatore Sanfilippo在2009年為其初創公司LLOOGG開發的,目前仍是獨立專案,但VMWare贊劣了專案(作者是其僱員)。它採用C語言實現,因此效能很好。採用BSD許可證,使用鍵值儲存,和Amazon Dynamo,Cassandra,Riak,Voldemort,Memcache類似。支援豐富的資料型別,比如陣列,連結串列,集合等,非常適合需要表達時間線的web服務,例如微博。

Redis支援的資料型別有:

  • 字串
  • 連結串列
  • 集合
  • 有序集合
  • 散列表

Redis的主從複製

Redis自帶有主從複製的功能,只要設定配置檔案redis.conf的slaveof選項即可,如下所示:

Redis的高可用

目前為止,Redis官方還在開發redis-cluster,可參考http://redis.io/topics/cluster-spec,中譯版http://www.cnblogs.com/chang290/archive/2012/09/05/2672506.html

但我們可以使用keepalived+redis的方法實現高可用,如下所示:

1. redis的配置
主機     埠   角色
redis0 6379   master
redis1 6379   slave

2. keepalived的配置
redis0和redis1使用一個虛擬ip

並使用如下指令碼監控redis服務是否存活:

#!/bin/bash
/usr/local/bin/redis-cli -h 192.168.1.53 -p 6379 info > /dev/null
if [ $? -eq 0 ]; then
        echo "redis OK"
        exit 0
else
        echo "no redis service found!"
        /usr/local/bin/redis-server /path/to/redis.conf
        # try to start it again
        /usr/local/bin/redis-cli -h 192.168.11.53 -p 6380 info > /dev/null
        if [ $? -eq 0 ]; then
                exit 0
        else
                # restart failed
                killall keepalived
                echo "error"
        fi
fi
要實現redis的故障恢復,可以使用keepalived配置的notify_master, notify_backup這兩個方法執行特有的指令碼。實際上只要在slave(即redis1)上有2個指令碼,第一個用於在redis1接管虛擬ip之後,執行slaveof no one把自己變成master。第二個是在redis1交出虛擬ip之後,在redis0執行slaveof no one確保redis0恢復為主的狀態,並對redis1執行slaveof redis0 6379開始重新從master同步資料,如果自己已經是slave就沒必要同步了。
redis1上keepalived的配置方法如下,redis0只要去掉notify_master, notify_backup兩行即可。
! Configuration File for keepalived
global_defs {
router_id redis1
}
vrrp_script Monitor_Redis {
 script "/opt/redis_keepalive.sh"
 interval 10
 weight 2
}
vrrp_instance 360 {
 state BUCKUP #(主機為MASTER,備用機為BACKUP)
 interface eth0 #(HA監測網路介面)
 virtual_router_id 110 #(主、備機的virtual_router_id必須相同)
 mcast_src_ip 192.168.11.53 #(多播的源IP,設定為本機外網IP,與VIP同一網絡卡)此項可不設定
 priority 70 #(主、備機取不同的優先順序,主機值較大,備份機值較小,值越大優先順序越高)
 advert_int 1 #(VRRP Multicast廣播週期秒數)
 authentication {
  ......
}
 notify_master /opt/redis_2master.sh
 notify_backup /opt/redis_2backup.sh
 track_script {
 Monitor_Redis #(呼叫nginx程序檢測指令碼)
}
 virtual_ipaddress {
 192.168.11.4 #(VRRP HA虛擬地址)
 }
}

Redis的持久化

Redis的有以下2種的持久化機制:
  • 快照(snapshot)
  • AOF(Append Only File)
Redis的快照功能配置如下:

Redis快照原理如下:

  • Redis藉助了fork命令的copy on write機制。在生成快照時,將當前迚程fork出一個子程序,然後在子迚程中迴圈所有的資料,將資料寫成為RDB檔案。
  • Redis原來的RDB檔案不會壞掉,因為其寫操作是在一個新迚程中迚行的,當生成一個新的,RDB檔案時,Redis生成的子迚程會先將資料寫到一個臨時檔案中,然後通過原子性rename系統呼叫將臨時檔案重新命名為RDB檔案,這樣在仸何時候出現故障,Redis的RDB檔案都總是可用的。
  • 同時,Redis的RDB檔案也是Redis主從同步內部實現中的一環。
  • 我們可以很明顯的看到,RDB有它的不足,就是一旦資料庫出現問題,那麼我們的RDB檔案中儲存的資料並不是全新的,從上次RDB檔案生成到Redis停機這段時間的資料全部丟掉了。在某些業務下,這是可以忍受的,我們也推薦這些業務使用RDB的方式進行持久化,因為開啟RDB的代價並不高。
AOF的配置如下:
AOF優先於RDB(即快照),RDB效能優於AOF,因為裡面沒有重複。
AOF Rewrite: 重新生成一份AOF檔案,新的AOF檔案中一條記錄的操作只會有一次,而不像一份老檔案那樣,可能記錄了對同一個值的多次操作。其生成過程和RDB類似, 也是fork一個程序,直接遍歷資料,寫入新的AOF臨時檔案。在寫入新檔案的過程中,所有的寫操作日誌還是會寫到原來老的 AOF檔案中,同時還會記錄在記憶體緩衝區中。當重完操作完成後,會將所有緩衝區中的日誌一次性寫入到臨時檔案中。然後呼叫原子性的rename命令用新的 AOF檔案取代老的AOF檔案。