redis簡介
redis單純程模型,支持主從模式,提升可用性,是一個開源項目,常常用來當一個數據結構服務器。其是內存級別的緩存服務器並可實現持久化功能. 據稱一百萬的變量存儲(字串)佔用100M內存空間,單臺redis服務器可達到5萬併發的能力。
redis與memcache的對比
redis的優點正則表達式
支持豐富的操做
主從複製和集羣
就地更新操做
支持持久化(磁盤),避免雪崩效應redis
memcache優點數據庫
多線程,善用多核CPU,更少的阻塞操做
更少的內存開銷
更少的內存分配壓力
可能有更少的內存碎片vim
redis的組件後端
redis-server緩存
redis-cli安全
redis-benchmark服務器
redis-check-dump & redis-check-aof網絡
redis的工做端口數據結構
6379/TCP
redis-cli命令的參數
-h HOST : 鏈接的主機地址或主機名
-p PORT :鏈接的端口
-s socket : 指定套接字
-a password : 指定鏈接密碼
-r <repeat> : 指定命令運行屢次
redis-cli中相關的命令
connection相關的命令
auth PASS : 認證
ping : 測試服務器是否在線
echo "string" : 顯示string
quit : 退出
select # : 挑選指定的名稱空間(即數據庫)
help @connection : 獲取與鏈接相關的命令幫助
與服務器端支持的命令
help @server : 獲取與服務器端相關的命令幫助
bgsave : 實現異步將數據集同步到磁盤上
client getname : 獲取當前客戶端的鏈接名
client kill IP:PORT : 指定IP:PORT可關閉相關的鏈接信息
client list : 查看客戶端的鏈接信息
172.16.36.70:6379> client list id=5 addr=172.16.36.70:57606 fd=8 name= age=904 idle=879 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get
client setname CONNECTION-NAME: 設定當前鏈接的名稱
info : 查看當前服務器的狀態信息
info memory : 只顯示memory段的相關信息
config resetstart : 重置info中所統計的數據
config set PARAMETER value : 運行時修改設定指定參數的值,只保存在內存中
config rewrite : 將修改在內存中的參數值同步到配置文件中
config get dir : 查看redis的文件保存目錄
dbsize : 顯示數據庫中全部鍵的數量
lastsave : 用來獲取最新一次save執行的時間戳
save : 保存數據到磁盤
monitor : 實時監控所接收到的請求
shutdown : 將全部數據從內存同步到磁盤,並安全關閉
shutdown [nosave][save] : 關閉程序並選擇是否將數據同步到磁盤上
salveof HOST PORT :配置主從,當前節點將變成從節點
slowlog : 查看慢查詢日誌,須要開啓慢查詢日誌功能
sync : 複製功能的內建命令
與訂閱相關的命令
help @pubsub : 獲取與訂閱相關的命令
psubscribe : 基於模式進行訂閱
publish : 向頻道發送消息
subscribe CHANNEL : 訂閱一個頻道
redis的認證功能
vim /etc/redis.conf
requirepass zhenping.com
重啓redis服務
systemctl restart redis
鏈接redis並認證的方法
redis-cli -h 172.16.36.70
172.16.36.70:6379> select 0
(error) NOAUTH Authentication required.
172.16.36.70:6379> auth zhenping
OK
redis清空數據庫
flushdb : 清空當前庫
flushall : 清空全部庫
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> flushall
OK
172.16.36.70:6379> flushdb
OK
redis的事務功能
經過multi,exec,watch等命令來實現事務功能,將多個命令打包,多個命令按順序執行,並一次執行完成,並將執行結果一次性所有返回給客戶端。redis事務不支持回滾操做,在事務中應避免發生錯誤(如命令寫錯等),事務了也將會執行失敗。
multi : 啓動一個事務
exec : 執行事務,一次性將事務中的全部操做執行完成後,返回給客戶端
watch : 樂觀鎖機制,在EXEC命令執行以前 ,用於監視指定數據鍵,若是監視的某任意鍵數據被修改,服務器拒絕執行事務
####創建一個事務
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> multi
OK
172.16.36.70:6379> set ip 172.16.36.70
QUEUED
172.16.36.70:6379> get ip
QUEUED
172.16.36.70:6379> set prot 8080
QUEUED
172.16.36.70:6379> exec
1) OK
2) "172.16.36.70"
3) OK
####使用watch機制監控鍵
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> watch ip
OK
172.16.36.70:6379> multi
OK
172.16.36.70:6379> set ip 172.16.36.71
QUEUED
172.16.36.70:6379> get ip
QUEUED
172.16.36.70:6379> exec
(nil)
說明: 當watch ip指令發出後,其它的請求操做改變了IP鍵的值,此時新發起的事務中,若是也要改變其值, 此事務申請將會失敗
redis的發佈和訂閱功能(publish/subscribe)
發佈和訂閱功能被普遍用於構建即時通訊應用,好比:網絡聊天室和實時廣播、實時提醒等。 訂閱發佈功能就能幫你很輕鬆地實現通知、監控程序
subsciribe CHANNEL_NAME : 訂閱一個頻道
publish CHANNEL_NAME : 向頻道發送一個消息
unsubscribe CHANNEL_NAME : 退訂頻道
psubscribe CHANNEL_NAME_PATTERN : 基於正則表達式模式定義多個頻道
一、訂閱一個頻道:
72.16.36.70:6379> subscribe news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1
二、向頻道發送消息
172.16.36.70:6379> publish news weizhenping
(integer) 1
三、頻道會接收下來消息
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> subscribe news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1
1) "message"
2) "news"
3) "weizhenping" #此內容爲頻道發送過來的消息
基於模式的頻道訂閱示例
一、基於模式訂閱頻道
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> PSUBSCRIBE news.i[to] #訂閱了news.io,news,io兩個頻道
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.i[to]"
3) (integer) 1
二、向頻道發送消息
172.16.36.70:6379> PUBLISH news.io hello
(integer) 1
三、頻道會接收下來消息
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> PSUBSCRIBE news.i[to]
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.i[to]"
3) (integer) 1
1) "pmessage"
2) "news.i[to]"
3) "news.io"
4) "hello"
redis的持久化功能
一、RDB(redisDB)
工做原理
RDB爲snapshot(快照)存儲機制,其也是redis默認的存儲機制,按照事先定製的策略,週期性地將數據從內存中讀取出來保存至磁盤,當到達save指令指定的時間,redis主進程將fork一個子進程,負責內存中的內容快照並保存到磁盤中。 Linux系統有寫時複製機制,父進程與子進程會共享相同的物理頁面,當父進程處理寫請求時,操做系統爲寫的數據建立一個副本,所以子進程保存的數據必定是與時間點一致的數據。當子進程將快照寫入臨時文件後,會使用臨時文件替換舊的文件,而後子進程完成退出 。保存的數據文件默認爲dump.rdb. 若是在SAVE週期以前停電了,會形成部分數據丟失。
數據保存機制
save : 在主線程中保存快照,保存時會阻塞全部客戶端請求,每次將完整數據寫至dump.rdb文件中,會帶來大量的IO壓力
bgsave : 異步保存機制,在後端自動保存,其不會阻塞窩客戶端請求
RDB相關的配置參數(/etc/redis/redis.conf)
stop-writes-on-bgsave-error yes : 在基於快照備份時,一旦發生錯誤,是否中止寫操做
rdbcompression yes : rdb文件是否壓縮來節約空間
rdbchecksum yes : 是否對rdb的鏡像文件作校驗碼檢測,當redis啓動時會根據事先保存好的校驗碼進行對比,保證數據的完整性
dbfilename dump.rdb : 保存的文件名
dir /var/lib/redis/ : 文件保存目錄
save "" : 關閉rdb功能
二、AOF(append only file)
工做原理
redis以順序IO的方式附加在文件的尾部,將每一次的寫命令操做都經過write函數追加到文件後面,其是比RDB更好的持久化方案,但文件會變得愈來愈大。當redis重啓時,可經過執行文件中的命令在內存中重建數據庫
數據保存機制
bgrewriteaof : AOF文件重寫,它不會讀取正在使用的AOF文件,而是經過將內存中的數據以命令的方式保存至臨時文件中,完成以後替換原來的AOF文件,這樣能夠減小AOF的大小
AOF重寫過程
一、redis主進程經過fork機制建立子線程
二、子進程根據redis內存中現有的數據經過重建命令建立數據庫於臨時文件中
三、父進程繼續接收客戶請求,並會把這些請求中的寫操做繼續追加到原來的AOF文件中,額外地,也將新的寫請求放置於一個緩衝隊列中
四、子進程重寫完成,會通知父進程,父進程把緩衝中的隊列命令寫到臨時文件中
五、父進程用臨時文件替換老的AOF文件
AOF相關的配置參數(/etc/redis/redis.conf)
appendonly no : 是否啓用AOF功能,yes表示啓用
appendfilename "appendonly.aof" : aof存儲文件
appendfsync always : 每次收到寫命令,當即寫入磁盤
appendfsync everysec : 每秒鐘寫一次,推薦操做
appendfsync no : append功能本身觸發寫操做,將全部操做都提交給OS,由操做系統決定何時寫
no-appendfsync-no-rewrite no: 在重寫的過程當中是否調用fsync
auto-aof-rewrite-percentage 100 : 在aof文件已是上次重寫時的2倍大小,將自動啓動重寫操做
auto-aof-rewrite-min-size 64mb : 當文件達到64MB才執行重寫操做
RDB與AOF同時啓用時:
一、bgsave和bgrewriteaof不會同時執行
二、在redis服務器啓動用於恢復數據時,會優先使用AOF
redis的主從複製
一、redis的主從複製特色
一個master能夠有多個slave
支持鏈式複製
master以非阻塞方式同步數據至slave,意味着可同時與多個slave同步
二、複製的工做原理
一、主庫會本身基於ping check機制來檢查從庫是否在線
二、若是從庫在線就同步數據文件至從服務器端
三、從服務器也能夠發送請求同步的請求,主庫將啓動一個線程,把內存中的數據同步給從庫,從庫將數據保存至文件中
四、從庫再把文件裝載到內存中,從而完成複製功能
三、主從相關配置(/etc/redis.conf)
slave-serve-stale-data yes : 當主服務器鏈接不上了,從服務器是否可使用過時數據響應
repl-diskless-sync no : 是否基於diskless機制同步
slave-priority 100 : 指定從服務器優先級
min-slave-to-write 3 : 若是從節點小於三個,主服務器將拒絕寫操做
min-slave-max-lag 10 : 從服務器不能晚於主服務器10秒鐘,是否將中止複製
若是master使用了requirepass開啓了認證功能,從服務器要使用masterauth <password>來鏈接,使用指定的密碼進行認證
主從設置示例:
172.16.36.70 : 主redis服務
172.16.36.71 : 從redis服務
172.16.36.70配置
vim /etc/redis.conf
bind 172.16.36.70
172.16.36.71配置:
vim /etc/redis.conf
bind 172.16.36.71
[root@Centos7 ~]# redis-cli -h 172.16.36.71
172.16.36.71:6379> SLAVEOF 172.16.36.70 6379
OK
172.16.36.71:6379> get ip #查看是否能獲取到主庫數據
"172.16.36.70"
172.16.36.71:6379> dbsize
(integer) 3
redis高可用的實現
sentinel機制
工做原理
找一臺專用的監控主機,即能提供監控又能夠提供配置功能,若是發現master離線了,監控主機會從從節點選擇新的主節點。爲了避免誤判,setinel至少奇數個節點,同時監控。若是主節點不在線,多個setinel會協調一個新的主節點,以避免發生誤判,全部setinel每秒一次向全部服務器發送ping請求,判斷節點是否在線。setinel是一個分佈式系統,使用流言協議和投票協議來決定故障遷移。能夠監控多組redis實例。
sentinel的功用
用於管理多個redis服務,實現HA
監控
通知
自動故障轉移
工做過程
啓用sentinel時, 首先服務器作自身初始化,運行redis-server中專用於sentinel功能中的代碼
初始化sentinel狀態,根據給定的配置文件,初始化監控的master服務列表(能夠根據master的配置,獲取從服務器節點)
建立連向Master的鏈接
sentinel下線機制
主觀下線 : 一個sentinel實例判斷出某節點下線
客觀下線 : 多個sentinel節點協商後判斷出某節點下線
setinel程序
redis-sentinel /path/to/sentinel.conf
redis-server /path/to/sentinel --sentinel
setinel的工做端口
26379/TCP
專用配置文件
/etc/redis-sentinel.conf
redis-sentinel.conf配置參數
prot 26379
dir /tmp
sentinel monitor mymaster 127.0.0.1 6379 2
mymaster: sentinel要監控的實例名稱,此名稱能夠隨意取
127.0.0.1 : 主節點的IP地址
6379 : 主節點的端口
2 : sentinel節點的票數,此值要大於sentinel節點數量的半數
sentinel down-after-milliseconds mymaster 30000 : 判斷主節點不在線的默認超時時長,默認30秒
sentinel parallel-syncs mymaster 1 : 故障轉移時最多能有多少個從服務器向主服務器發起同步請求
sentinel failover-timeout mymaster 180000 : 提高主節點的超時時長,表示提高新的主節點在3分鐘內未完成,操做將失敗
sentinel專用命令
sentinel masters : 列出全部主服務器
sentinel slaves <master name> : 獲取全部當前redis實例中的從節點信息
sentinel get-master-addr-by name <master name> :直接獲取當前redis實例主節點的IP地址及端口
172.16.36.74:26379> sentinel get-master-addr-by-name mymaster
1) "172.16.36.72"
2) "6379"
sentinel reset : 重置服務器全部狀態
sentinel failover <master name> : 手動實現故障轉移
sentinel配置實例
實驗環境說明:
172.16.36.70 : redis主節點
172.16.36.71 : redis從節點
172.16.36.72 : redis從節點
172.16.36.74 : sentinel節點1
172.16.36.75 : sentinel節點2
172.16.36.76 : sentinel節點3
####配置redis主節點
操做主機: 172.16.36.70
#vim /etc/redis.conf
bind 172.16.36.70
daemonize yes
啓動服務
#redis-server /etc/redis.conf
[root@Centos7 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 172.16.36.70:6379 *:*
####配置redis從節點
操做主機: 172.16.36.71
#vim /etc/redis.conf
bind 172.16.36.71
daemonize yes
啓動服務
#redis-server /etc/redis.conf
[root@Centos7 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 172.16.36.70:6379 *:*
配置主節點信息
[root@Centos7 ~]# redis-cli -h 172.16.36.71 -p 6379
172.16.36.71:6379> SLAVEOF 172.16.36.70 6379
OK
操做主機: 172.16.36.72
#vim /etc/redis.conf
bind 172.16.36.72
daemonize yes
啓動服務
#redis-server /etc/redis.conf
[root@Centos7 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 172.16.36.70:6379 *:*
配置主節點信息
[root@Centos7 ~]# redis-cli -h 172.16.36.71 -p 6379
172.16.36.71:6379> SLAVEOF 172.16.36.70 6379
OK
####配置sentinel節點
操做主機: 172.16.36.74
# vim /etc/redis-sentinel.conf
port 26379
dir "/tmp"
daemonize yes
sentinel monitor mymaster 172.16.36.70 6379 2
sentinel parallel-syncs mymaster 3
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
啓動服務
redis-sentinel /etc/redis-sentinel.conf
查看服務啓動狀態
users:(("master",2112,14))
[root@Centos7 ~]# ss -tln
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
操做主機: 172.16.36.75
# vim /etc/redis-sentinel.conf
port 26379
dir "/tmp"
daemonize yes
sentinel monitor mymaster 172.16.36.70 6379 2
sentinel parallel-syncs mymaster 3
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
啓動服務
redis-sentinel /etc/redis-sentinel.conf
查看服務啓動狀態
users:(("master",2112,14))
[root@Centos7 ~]# ss -tln
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
操做主機: 172.16.36.76
# vim /etc/redis-sentinel.conf
port 26379
dir "/tmp"
daemonize yes
sentinel monitor mymaster 172.16.36.70 6379 2
sentinel parallel-syncs mymaster 3
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
啓動服務
redis-sentinel /etc/redis-sentinel.conf
查看服務啓動狀態
users:(("master",2112,14))
[root@Centos7 ~]# ss -tln
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
查看sentinel相關的日誌信息
tailf /var/log/redis/redis-sentinel.log
[32524] 25 Mar 10:05:02.290 # Sentinel runid is a44025e518b65c512340c48535df119496f7a0d8
[32524] 25 Mar 10:05:02.291 # +monitor master mymaster 172.16.36.70 6379 quorum 2
[32524] 25 Mar 10:05:32.322 # +sdown slave 172.16.36.71:6379 172.16.36.71 6379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:05:46.311 * +sentinel sentinel 172.16.36.76:26379 172.16.36.76 26379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:05:57.071 * +sentinel sentinel 172.16.36.75:26379 172.16.36.75 26379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:09:03.727 # +sdown master mymaster 172.16.36.70 6379
將當前的Master節點shudown,查看sentinel的相關日誌信息
[32524] 25 Mar 10:09:03.747 # +new-epoch 4
[32524] 25 Mar 10:09:03.749 # +vote-for-leader 90c011868befc3047a8527886efce8f8c6f9ea34 4
[32524] 25 Mar 10:09:03.836 # +odown master mymaster 172.16.36.70 6379 #quorum 3/2
[32524] 25 Mar 10:09:03.836 # Next failover delay: I will not start a failover before Fri Mar 25 10:15:04 2016
[32524] 25 Mar 10:09:04.854 # +config-update-from sentinel 172.16.36.75:26379 172.16.36.75 26379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:09:04.854 # +switch-master mymaster 172.16.36.70 6379 172.16.36.72 6379
[32524] 25 Mar 10:09:04.855 * +slave slave 172.16.36.71:6379 172.16.36.71 6379 @ mymaster 172.16.36.72 6379
[32524] 25 Mar 10:09:04.856 * +slave slave 172.16.36.70:6379 172.16.36.70 6379 @ mymaster 172.16.36.72 6379
對當前主節點監控sentinel的活躍探測信息
root@Centos7 ~]# redis-cli -h 172.16.36.72
172.16.36.72:6379> monitor
OK
1458878723.052705 [0 172.16.36.76:53255] "PING"
1458878723.402835 [0 172.16.36.75:38413] "PING"
1458878723.586806 [0 172.16.36.74:32824] "PING"
1458878723.859748 [0 172.16.36.75:38413] "PUBLISH" "__sentinel__:hello" "172.16.36.75,26379,90c011868befc3047a8527886efce8f8c6f9ea34,4,mymaster,172.16.36.72,6379,4"
1458878724.099837 [0 172.16.36.76:53255] "PING"
1458878724.152776 [0 172.16.36.76:53255] "PUBLISH" "__sentinel__:hello" "172.16.36.76,26379,21a0a795010287138b6efc636d03edcce66bcd56,4,mymaster,172.16.36.72,6379,4"
1458878724.454214 [0 172.16.36.75:38413] "PING"
1458878724.617819 [0 172.16.36.74:32824] "PING"
1458878724.693888 [0 172.16.36.74:32824] "PUBLISH" "__sentinel__:hello" "172.16.36.74,26379,a44025e518b65c512340c48535df119496f7a0d8,4,mymaster,172.16.36.72,6379,4"
使用info sentinel命令查看主從信息
172.16.36.74:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=172.16.36.72:6379,slaves=2,sentinels=3
Redis Clustering
在redis3.0版本中引入clustering功能, 是去中心化的分佈式數據庫,經過分片機制進行數據分佈,clustering內的每一個節點僅有數據庫一部分數據,每一個節點都有全局元數據,經過查找元數據,便可查詢到數據存放在哪臺服務器
分佈式解決方案
Twemproxy(Twitter)
代理分片機制
優勢
很是穩定,企業方案
缺點
單點故障
須要依賴第三方軟件,如Keeplived
沒法平滑地橫向擴展
沒有後臺界面
代理分片機制引入更多的來回次數並提升延遲
單核模式,沒法充分利用多核,除非多實例
Twitter官方肉串再也不繼續使用
Codis(豌豆莢)
代理分片機制
2014年11月開源
基於GO以及C語言開發
優勢
很是穩定,企業級方案
數據自動平衡
高性能
簡單的測試顯示較Twemproxy快一倍
善用多核CPU
簡單
沒有paxos類的協調機制
沒有主從複製
有後臺界面
缺點
代理分片機制引入更多的來回次數並提升延遲
須要第三方軟件支持協調機制
目前支持zookeeper及Etcd
不支持主從複製 ,須要另外實現
Codis採用proxy方案,全部必然會帶來單機性能的損失
經測試,在不開Pipeline的狀況下,大概會損失40%左右的性能
Redis Cluster(官方)
官方實現
須要3.0或更高版本
優勢
無中心的P2P Gossip分散式模式
更少的來回次數並下降延遲
自動於多個redis節點進行分片
不須要第三方軟件支持協調機制
缺點依賴於redis 3.0或更高版本須要時間驗證其穩定性沒有後臺界面須要智能客戶端redis客戶端必須支持redis cluster架構 較Codis有更多的維護升級版本