Redis知識點總結

一、redis介紹:

       redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)和zset(有序集合)、Hash(哈希類型的映射表)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。

二、特性:

  • 速度快
    • 數據存在內存當中
    • c語言編寫,5w行代碼
    • 單線程數據模型
  • 持久化
  • 多種數據類型
  • 支持多種編輯語言
  • 功能豐富
  • 簡單
  • 主從複製

三、redis的安裝

#解壓安裝
$ wget http://download.redis.io/releases/redis-5.0.4.tar.gz
$ tar xzf redis-5.0.4.tar.gz
$ cd redis-5.0.4
$ make

#啓動
$ ./src/redis-server redis.conf

#試用
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"

安裝過程中遇到以下錯誤說明gcc-c++環境未安裝,直接運行yum -y install gcc-c++先安裝環境:

[root@localhost redis-5.0.4]# make
cd src && make all
make[1]: 進入目錄“/opt/redis-5.0.4/src”
    CC adlist.o
/bin/sh: cc: 未找到命令
make[1]: *** [adlist.o] 錯誤 127
make[1]: 離開目錄“/opt/redis-5.0.4/src”
make: *** [all] 錯誤 2

遇到一下錯誤運行make distclean

[root@bogon redis-3.2.0]# make
cd src && make all
make[1]: 進入目錄“/usr/local/redis-3.2.0/src”
CC adlist.o
In file included from adlist.c:34:0:
zmalloc.h:50:31: 致命錯誤:jemalloc/jemalloc.h:沒有那個文件或目錄
#include <jemalloc/jemalloc.h>                              ^
編譯中斷。
make[1]: *** [adlist.o] 錯誤 1
make[1]: 離開目錄“/usr/local/redis-3.2.0/src”
make: *** [all] 錯誤 2

解決“jemalloc/jemalloc.h:沒有那個文件或目錄“問題,在進行編譯(因爲上次編譯失敗,有殘留的文件)。直接運行make distclean命令。

客戶端

四、redis命令

  • http://doc.redisfans.com/
  • SCAN 命令用於迭代當前數據庫中的數據庫鍵。
  • SSCAN 命令用於迭代集合鍵中的元素。
  • HSCAN 命令用於迭代哈希鍵中的鍵值對。
  • ZSCAN 命令用於迭代有序集合中的元素(包括元素成員和元素分值)。

 

五、redis單線程

爲什麼這麼快?

  • 純內存操作
  • 非阻塞IO
  • 避免線程切換和競態消耗

如何使用?

  • 拒絕長(慢)命令
  • keys、flushall。。
  • 一次只運行一個命令

六、redis存儲機制

Redis存儲機制分成兩種Snapshot和AOF。無論是那種機制,Redis都是將數據存儲在內存中。

 

Snapshot工作原理

是將數據先存儲在內存,然後當數據累計達到某些設定的伐值的時候,就會觸發一次DUMP操作,將變化的數據一次性寫入數據文件(RDB文件)。

 

AOF 工作原理

是將數據也是先存在內存,但是在存儲的時候會使用調用fsync來完成對本次寫操作的日誌記錄,這個日誌揭露文件其實是一個基於Redis網絡交互協議的文本文件。AOF調用fsync也不是說全部都是無阻塞的,在某些系統上可能出現fsync阻塞進程的情況,對於這種情況可以通過配置修改,但默認情況不要修改。AOF最關鍵的配置就是關於調用fsync追加日誌文件的平率,有兩種預設頻率,always每次記錄進來都添加,everysecond 每秒添加一次。兩個配置各有所長後面分析。由於是採用日誌追加的方式來持久話數據,所以引出了第二個日誌的概念:rewrite. 後面介紹它的由來。

 

存儲模式性能和安全比較

1.性能

Snapshot方式的性能是要明顯高於AOF方式的,原因有兩點:

採用2進制方式存儲數據,數據文件比較小,加載快速。

存儲的時候是按照配置中的save策略來存儲,每次都是聚合很多數據批量存儲,寫入的效率很好,而AOF則一般都是工作在實時存儲或者準實時模式下。相對來說存儲的頻率高,效率卻偏低。

 

2.數據安全

AOF數據安全性高於Snapshot存儲,原因:

Snapshot存儲是基於累計批量的思想,也就是說在允許的情況下,累計的數據越多那麼寫入效率也就越高,但數據的累計是靠時間的積累完成的,那麼如果在長時間數據不寫入RDB,但Redis又遇到了崩潰,那麼沒有寫入的數據就無法恢復了,但是AOF方式偏偏相反,根據AOF配置的存儲頻率的策略可以做到最少的數據丟失和較高的數據恢復能力。

 

說完了性能和安全,這裏不得不提的就是在Redis中的Rewrite的功能,AOF的存儲是按照記錄日誌的方式去工作的,那麼成千上萬的數據插入必然導致日誌文件的擴大,Redis這個時候會根據配置合理觸發Rewrite操作,所謂Rewrite就是將日誌文件中的所有數據都重新寫到另外一個新的日誌文件中,但是不同的是,對於老日誌文件中對於Key的多次操作,只保留最終的值的那次操作記錄到日誌文件中,從而縮小日誌文件的大小。這裏有兩個配置需要注意:

auto-aof-rewrite-percentage 100 (當前寫入日誌文件的大小佔到初始日誌文件大小的某個百分比時觸發Rewrite)

auto-aof-rewrite-min-size 64mb (本次Rewrite最小的寫入數據良)

兩個條件需要同時滿足。

七、redis的數據結構

 

 

字符串

緩存、計數器、分佈式鎖、分佈式ID、、

 

HASH

存儲用戶信息、用戶主頁訪問量

 

LIST

微博關注人微博時間軸列表

SET

贊、踩、標籤

ZSET

排行榜

 八、redis的主從模式

主從配置

主從機器一般是分開的兩臺機器,這裏爲了演示方便,使用了一臺機器,所以配置文件中,處理端口的區分之外,還需要注意日誌文件,數據庫文件,pid文件等的區分。

啓動redis命令

redis-server redis.conf

直接自定加載的配置文件即可

主機配置

複製一份redis.conf成redis-6379.conf。修改配置:

#演示方便,開放ip連接

bind 0.0.0.0

#後臺運行

daemonize yes

#pid文件

pidfile /var/run/redis_6379.pid

dbfilename dump-6379.rdb

#日誌文件

logfile "6379.log"

 

從機配置

複製一份redis.conf成redis-6380.conf。修改配置:

bind 0.0.0.0

port 6380

daemonize yes

pidfile /var/run/redis_6380.pid

dbfilename dump-6380.rdb

logfile "6380.log"

#slaveof表示作爲從庫的配置

slaveof 127.0.0.1 6379

#從庫只能讀操作

slave-read-only yes

查看redis的信息

redis-cli -p 6379 info replication

  • 其中6379表示指定端口
  • replication表示主從的信息

 

查看主庫信息:

[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6379 info replication

# Replication

role:master

connected_slaves:1

slave0:ip=127.0.0.1,port=6380,state=online,offset=1183,lag=0

master_replid:32125185597f85a2155d187ccd57168cf6681395

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:1183

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:1183

查看從庫信息:

[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6380 info replication

# Replication

role:slave

master_host:127.0.0.1

master_port:6379

master_link_status:up

master_last_io_seconds_ago:0

master_sync_in_progress:0

slave_repl_offset:1239

slave_priority:100

slave_read_only:1

connected_slaves:0

master_replid:32125185597f85a2155d187ccd57168cf6681395

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:1239

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:1239

查看配置效果:複製成功!!

[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6379 set hello helloworld

OK

[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6380 get hello

"helloworld"

redis的高可用

sentinel啓動命令

redis-sentinel sentinel.conf

sentinel機制

過程:

  1. 多個sentinel發現並確認master有問題
  1. 選舉出一個sentinel作爲領導
  1. 選出一個slave作爲master
  1. 通知其餘slave成爲新的master的slave
  1. 通知客戶端主從變化
  1. 等待老的master復活成爲新的master的slave

創建sentinel.conf配置文件

  1. port 26379
  1. daemonize yes
  1. # sentinel announce-ip <ip>
  1. # sentinel announce-port <port>
  1. dir /opt/redis-5.0.4/data
  1. logfile "26379.log"
  1. sentinel monitor mymaster 127.0.0.1 6379 2
  1. # sentinel auth-pass <master-name> <password>
  1. sentinel down-after-milliseconds mymaster 30000
  1. sentinel parallel-syncs mymaster 1
  1. sentinel failover-timeout mymaster 180000
  1. # sentinel notification-script <master-name> <script-path>

配置文件說明:

1. port :當前Sentinel服務運行的端口

2. dir : Sentinel服務運行時使用的臨時文件 

3.sentinel monitor master001 192.168.110.101 6379 2:Sentinel去監視一個名爲master001的主redis實例,這個主實例的IP地址爲本機地址192.168.110.101,端口號爲6379,而將這個主實例判斷爲失效至少需要2個 Sentinel進程的同意,只要同意Sentinel的數量不達標,自動failover就不會執行

4.sentinel down-after-milliseconds master001 30000:指定了Sentinel認爲Redis實例已經失效所需的毫秒數。當實例超過該時間沒有返回PING,或者直接返回錯誤,那麼Sentinel將這個實例標記爲主觀下線。只有一個 Sentinel進程將實例標記爲主觀下線並不一定會引起實例的自動故障遷移:只有在足夠數量的Sentinel都將一個實例標記爲主觀下線之後,實例纔會被標記爲客觀下線,這時自動故障遷移纔會執行

5.sentinel parallel-syncs master001 1:指定了在執行故障轉移時,最多可以有多少個從Redis實例在同步新的主實例,在從Redis實例較多的情況下這個數字越小,同步的時間越長,完成故障轉移所需的時間就越長

6.sentinel failover-timeout master001 180000:如果在該時間(ms)內未能完成failover操作,則認爲該failover失敗

7.sentinel notification-script <master-name> <script-path>:指定sentinel檢測到該監控的redis實例指向的實例異常時,調用的報警腳本。該配置項可選,但是很常用

 

 

三個定時任務

(1)每隔10s每個sentinel會對master節點和slave節點執行info命令

      作用就是發現slave節點,並且確認主從關係,因爲redis-Sentinel節點啓動的時候是知道

       master節點的,只是沒有配置相應的slave節點的信息

 

(2)每隔兩秒,sentinel都會通過master節點內部的channel來交換信息(基於發佈訂閱)

       作用是通過master節點的頻道來交互每個Sentinel對master節點的判斷信息

 

(3) 每隔一秒每個sentinel對其他的redis節點(master,slave,sentinel)執行ping操作,對於master來說,若超過30s內沒有回覆,就對該master進行主觀下線並詢問其他的Sentinel節點是否可以客觀下線

 

故障轉移過程

1. 領導者選舉

作用:選舉出一個sentenel節點作爲領導者去進行故障轉移操作。

過程:

1). 每個做主觀下線的sentinel節點向其他sentinel節點發送上面那條命令,要求將它設置爲領導者。

2). 收到命令的sentinel節點如果還沒有同意過其他的sentinel發送的命令(還未投過票),那麼就會同意,否則拒絕。

3). 如果該sentinel節點發現自己的票數已經過半且達到了quorum的值,就會成爲領導者。

4). 如果這個過程出現多個sentinel成爲領導者,則會等待一段時間重新選舉。

2. 選出新的master節點

redis sentinel會選一個合適的slave來升級爲master,那麼,如何選擇一個合適的slave呢?順序如下:

1). 選擇slave-priority最高的slave節點(默認是相同)。

2). 選擇複製偏移量最大的節點。

3). 如果以上兩個條件都不滿足,選runId最小的(啓動最早的)。

3. 更改slave節點的master節點

當選舉出新的master節點後,會將其餘的節點變更爲新的master節點的slave節點,如果原有的master節點重新上線,成爲新的master節點的slave節點。

4. 通知客戶端

當所有節點配置結束後,sentinel會通知客戶端節點變更信息。

5. 客戶端連接新的master節點

客戶端收到節點信息後,會連接新的master節點。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章