1. 程式人生 > 實用技巧 >Redis基礎命令和多例項03

Redis基礎命令和多例項03

二、redis管理命令

1.info命令

#檢視redis相關資訊
127.0.0.1:6379> info
#服務端資訊
# Server
#版本號
redis_version:3.2.12
#redis版本控制安全hash演算法
redis_git_sha1:00000000
#redis版本控制髒資料
redis_git_dirty:0
#redis建立id
redis_build_id:3b947b91b7c31389
#執行模式:單機(如果是叢集:cluster)
redis_mode:standalone
#redis所在宿主機的作業系統
os:Linux 2.6.32-431.el6.x86_64 x86_64
#架構(64位)
arch_bits:64
#redis事件迴圈機制
multiplexing_api:epoll
#GCC的版本
gcc_version:4.4.7
#redis程序的pid
process_id:33007
#redis伺服器的隨機識別符號(用於sentinel和叢集)
run_id:46b07234cf763cab04d1b31433b94e31b68c6e26
#redis的埠
tcp_port:6379
#redis伺服器的執行時間(單位秒)
uptime_in_seconds:318283
#redis伺服器的執行時間(單位天)
uptime_in_days:3
#redis內部排程(進行關閉timeout的客戶端,刪除過期key等等)頻率,程式規定serverCron每秒執行10次
hz:10
#自增的時鐘,用於LRU管理,該時鐘100ms(hz=10,因此每1000ms/10=100ms執行一次定時任務)更新一次
lru_clock:13601047
#服務端執行命令路徑
executable:/application/redis-3.2.12/redis-server
#配置檔案路徑
config_file:/etc/redis/6379/redis.conf

#客戶端資訊
# Clients
#已連線客戶端的數量(不包括通過slave的數量)
connected_clients:2
##當前連線的客戶端當中,最長的輸出列表,用client list命令觀察omem欄位最大值
client_longest_output_list:0
#當前連線的客戶端當中,最大輸入快取,用client list命令觀察qbuf和qbuf-free兩個欄位最大值
client_biggest_input_buf:0
#正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客戶端的數量
blocked_clients:0

#記憶體資訊
# Memory
#由redis分配器分配的記憶體總量,以位元組為單位
used_memory:845336
#以人類可讀的格式返回redis分配的記憶體總量
used_memory_human:825.52K
#從作業系統的角度,返回redis已分配的記憶體總量(俗稱常駐集大小)。這個值和top命令的輸出一致
used_memory_rss:1654784
#以人類可讀方式,返回redis已分配的記憶體總量
used_memory_rss_human:1.58M
#redis的記憶體消耗峰值(以位元組為單位)
used_memory_peak:845336
#以人類可讀的格式返回redis的記憶體消耗峰值
used_memory_peak_human:825.52K
#整個系統記憶體
total_system_memory:1028517888
#以人類可讀的格式,顯示整個系統記憶體
total_system_memory_human:980.87M
#Lua指令碼儲存佔用的記憶體
used_memory_lua:37888
#以人類可讀的格式,顯示Lua指令碼儲存佔用的記憶體
used_memory_lua_human:37.00K
#Redis例項的最大記憶體配置
maxmemory:0
#以人類可讀的格式,顯示Redis例項的最大記憶體配置
maxmemory_human:0B
#當達到maxmemory時的淘汰策略
maxmemory_policy:noeviction
#記憶體分裂比例(used_memory_rss/ used_memory)
mem_fragmentation_ratio:1.96
#記憶體分配器
mem_allocator:jemalloc-4.0.3

#持久化資訊
# Persistence
#伺服器是否正在載入持久化檔案
loading:0
#離最近一次成功生成rdb檔案,寫入命令的個數,即有多少個寫入命令沒有持久化
rdb_changes_since_last_save:131
#伺服器是否正在建立rdb檔案
rdb_bgsave_in_progress:0
#最近一次rdb持久化儲存時間
rdb_last_save_time:1540009420
#最近一次rdb持久化是否成功
rdb_last_bgsave_status:ok
#最近一次成功生成rdb檔案耗時秒數
rdb_last_bgsave_time_sec:-1
#如果伺服器正在建立rdb檔案,那麼這個域記錄的就是當前的建立操作已經耗費的秒數
rdb_current_bgsave_time_sec:-1
#是否開啟了aof
aof_enabled:0
#標識aof的rewrite操作是否在進行中
aof_rewrite_in_progress:0
#rewrite任務計劃,當客戶端傳送bgrewriteaof指令,如果當前rewrite子程序正在執行,那麼將客戶端請求的bgrewriteaof變為計劃任務,待aof子程序結束後執行rewrite
aof_rewrite_scheduled:0
#最近一次aof rewrite耗費的時長
aof_last_rewrite_time_sec:-1
#如果rewrite操作正在進行,則記錄所使用的時間,單位秒
aof_current_rewrite_time_sec:-1
#上次bgrewriteaof操作的狀態
aof_last_bgrewrite_status:ok
#上次aof寫入狀態
aof_last_write_status:ok

#統計資訊
# Stats
#新建立連線個數,如果新建立連線過多,過度地建立和銷燬連線對效能有影響,說明短連線嚴重或連線池使用有問題,需調研程式碼的連線設定
total_connections_received:19
#redis處理的命令數
total_commands_processed:299
#redis當前的qps,redis內部較實時的每秒執行的命令數
instantaneous_ops_per_sec:0
#redis網路入口流量位元組數
total_net_input_bytes:10773
#redis網路出口流量位元組數
total_net_output_bytes:97146
#redis網路入口kps
instantaneous_input_kbps:0.00
#redis網路出口kps
instantaneous_output_kbps:0.00
#拒絕的連線個數,redis連線個數達到maxclients限制,拒絕新連線的個數
rejected_connections:0
#主從完全同步次數
sync_full:0
#主從完全同步成功次數
sync_partial_ok:0
#主從完全同步失敗次數
sync_partial_err:0
#執行以來過期的key的數量
expired_keys:5
#過期的比率
evicted_keys:0
#命中次數
keyspace_hits:85
#沒命中次數
keyspace_misses:17
#當前使用中的頻道數量
pubsub_channels:0
#當前使用的模式的數量
pubsub_patterns:0
#最近一次fork操作阻塞redis程序的耗時數,單位微秒
latest_fork_usec:0
#是否已經快取了到該地址的連線
migrate_cached_sockets:0

#主從複製資訊
# Replication
#角色主庫
role:master
#連線slave的個數
connected_slaves:0
#主從同步偏移量,此值如果和上面的offset相同說明主從一致沒延遲,與master_replid可被用來標識主例項複製流中的位置
master_repl_offset:0
#複製積壓緩衝區是否開啟
repl_backlog_active:0
#複製積壓緩衝大小
repl_backlog_size:1048576
#複製緩衝區裡偏移量的大小
repl_backlog_first_byte_offset:0
#此值等於 master_repl_offset - repl_backlog_first_byte_offset,該值不會超過repl_backlog_size的大小
repl_backlog_histlen:0

#CPU資訊
# CPU
#將所有redis主程序在核心態所佔用的CPU時求和累計起來
used_cpu_sys:203.44
#將所有redis主程序在使用者態所佔用的CPU時求和累計起來
used_cpu_user:114.57
#將後臺程序在核心態所佔用的CPU時求和累計起來
used_cpu_sys_children:0.00
#將後臺程序在使用者態所佔用的CPU時求和累計起來
used_cpu_user_children:0.00

#叢集資訊
# Cluster
#例項是否啟用叢集模式
cluster_enabled:0

#庫相關統計資訊
# Keyspace
#db0的key的數量,以及帶有生存期的key的數,平均存活時間
db0:keys=17,expires=0,avg_ttl=0

#單獨檢視某一個資訊(例:檢視CPU資訊)
127.0.0.1:6379> info cpu
# CPU
used_cpu_sys:203.45
used_cpu_user:114.58
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

2.client命令

#檢視該例項有幾個連線,id遞增,重啟後才重新整理
#38988為隨機埠,age連線的時間(秒),

127.0.0.1:6379> CLIENT LIST
id=2 addr=127.0.0.1:38988 fd=7 name= age=86036 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
id=4 addr=127.0.0.1:38992 fd=8 name= age=52 idle=52 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=command

3.config命令

#檢視redis所有的配置,沒有配置就走預設
127.0.0.1:6379> CONFIG GET *
  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) ""
  .......

4.dbsize命令

#檢視當前redis有多少資料
127.0.0.1:6379> DBSIZE
(integer) 18

5.select命令

在Redis中也是有庫這個概念的,不過不同於MySQL,Redis的庫是預設的,並不是我們手動去建立的,在Redis中一共有16(0-15)個庫。在MySQL中進入某一個庫,我們需要使用use dbname,在Redis中,只需要select即可。'預設情況下,我們是在0庫中進行操作',每個庫之間都是隔離的。

#切換1庫
127.0.0.1:6379> select 1
OK
#檢視1庫資料
127.0.0.1:6379[1]> DBSIZE
(integer) 0

6.flush命令(flushdb、flushall)

1.flushdb(清空當前庫)
127.0.0.1:6379[1]> keys *
1) "k2"
2) "k1"
127.0.0.1:6379[1]> FLUSHDB
OK
127.0.0.1:6379[1]> keys *
(empty list or set)

2.flushall(清空所有庫資料)
127.0.0.1:6379[1]> FLUSHALL
OK
127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> keys *
(empty list or set)

7.monitor監控命令

#視窗1執行,監控所有庫
127.0.0.1:6379> MONITOR
OK

#視窗2執行命令
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> del k1
(integer) 1

#視窗1檢視
1596591822.059876 [0 127.0.0.1:38988] "set" "k1" "v1"
1596591827.003306 [0 127.0.0.1:38988] "set" "k2" "v2"
1596591830.524161 [0 127.0.0.1:38988] "set" "k3" "v3"
1596591833.501550 [0 127.0.0.1:38988] "del" "k1"

#將監控的內容寫到檔案方法(類似於MySQL的一般查詢日誌)
[root@db01 ~]# redis-cli MONITOR >> /tmp/caozuo.log &
[1] 15333
[root@db01 ~]# tail -f /tmp/caozuo.log

三、redis訊息佇列

1、問:什麼是訊息佇列?
   答:是一個訊息的連結串列,是一個'非同步處理'的'資料處理引擎'。

2、問:有什麼好處?
     答:不僅能夠提高系統的負荷能力,還能夠'改善因網路阻塞'導致的資料缺失。

3、問:用途有哪些?
     答:郵件傳送、手機簡訊傳送,資料表單提交、圖片生成、視訊轉換、日誌儲存等。

4、問:有哪些軟體?
     答:ZeroMQ、Posix、SquirrelMQ、'Redis'、QDBM、Tokyo Tyrant、HTTPSQS等(linux平臺下)。

5、問:怎麼實現?
     答:顧名思義,先入隊,後出隊;先把資料丟到訊息佇列(入隊),後根據相應的key來獲取資料(出隊)。
     佇列,先進先出
     堆疊,先進後出

6、問:Redis可以做訊息佇列?
     答:首先,redis設計用來做'快取'的,
     但是由於它自身的某種特性使得它可以用來做'訊息佇列',它有幾個阻塞式的API可以使用,正是這些阻塞式的API讓其有能力做訊息佇列;另外,做訊息佇列的其他特性例如FIFO(先入先出)也很容易實現,只需要一個list物件從頭取資料,從尾部塞資料即可;
     redis能做訊息佇列還得益於其list物件blpop brpop介面以及Pub/Sub(釋出/訂閱)的某些介面,它們都是阻塞版的,所以可以用來做訊息佇列
     
#一般Redis結合ELK做訊息佇列

1.什麼是訊息佇列

在生活中,其實有很多的例子,都類似訊息佇列。

比如:工廠生產出來的麵包,交給超市,商場來出售,客戶通過超市,商場來買麵包,客戶不會針對某一個工廠去選擇,只管從超市買出來,工廠也不會管是哪一個客戶買了麵包,只管生產出來之後,交給超市,商場來處理。

訊息佇列(Message Queue)是一種應用間的'通訊方式',訊息傳送後可以立即返回,有訊息系統來確保資訊的可靠傳遞,訊息生產者只管把訊息釋出到訊息佇列中而不管誰來取,訊息消費者只管從訊息佇列中取訊息而不管誰釋出的,這樣'釋出者和使用者都不用知道對方的存在。'

2.為什麼使用訊息佇列

首先,我們可以知道,訊息佇列是一種'非同步的工作機制',
比如說日誌收集系統,為了'避免資料在傳輸過程中丟失',
還有訂單系統,下單後,會生成對應的單據,庫存的扣減,消費資訊的傳送,一個下單,產生這麼多的訊息,都是通過一個操作的觸發,然後將其他的訊息放入訊息佇列中,依次產生。
再就是很多網站的,秒殺活動之類的,前多少名使用者會便宜,都是通過訊息佇列來實現的。
這些例子,都是通過訊息佇列,來實現,業務的解耦,最終資料的一致性,廣播,錯峰流控等等,從而完成業務的邏輯。

3.訊息佇列產品

1)rabbit-MQ(最初起源於金融系統,用於分散式系統中儲存轉發訊息。OpenStack)
2)Zero-MQ(SaltStack)
3)Kafka(JAVA)
4)redis(key:value資料庫,快取,訊息佇列)

4.Redis釋出訊息-任務佇列模式(queuing)

任務佇列:顧名思義,就是“傳遞訊息的佇列”。與任務佇列進行互動的實體有兩類,一類是生產者(producer),另一類則是消費者(consumer)。生產者將需要處理的任務放入任務佇列中,而消費者則不斷地從任務佇列中讀入任務資訊並執行。

任務佇列的好處
1)鬆耦合。
生產者和消費者只需'按照約定'的任務描述格式,進行編寫程式碼。
2)易於擴充套件。
多消費者模式下,消費者可以分佈在多個不同的伺服器中,由此降低單臺伺服器的負載。

5.Redis釋出訊息-釋出-訂閱模式(publish-subscribe)

其實從Pub/Sub的機制來看,它更像是一個廣播系統,多個訂閱者(Subscriber)可以訂閱多個頻道(Channel),多個釋出者(Publisher)可以往多個頻道(Channel)中釋出訊息。

可以這麼簡單的理解:
1)Subscriber:收音機,可以收到多個頻道,並以佇列方式顯示
2)Publisher:電臺,可以往不同的FM頻道中發訊息
3)Channel:不同頻率的FM頻道

6.訂閱模式實踐

1)訂閱單個頻道

#第一個視窗,訂閱一個頻道
127.0.0.1:6379> SUBSCRIBE gongsiqun
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "gongsiqun"
3) (integer) 1

#第二個視窗向頻道釋出訊息
127.0.0.1:6379> PUBLISH gongsiqun 今晚大保健
(integer) 1

#回到第一個頻道檢視
1) "message"
2) "gongsiqun"
3) "\xe4\xbb\x8a\xe6\x99\x9a\xe5\xa4\xa7\xe4\xbf\x9d\xe5\x81\xa5"

2)訂閱多個頻道

#第一個視窗訂閱多個頻道
127.0.0.1:6379> SUBSCRIBE gongsiqun jiatingqun
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "gongsiqun"
3) (integer) 1
1) "subscribe"
2) "jiatingqun"
3) (integer) 2

#第二個視窗向頻道釋出訊息
127.0.0.1:6379> PUBLISH gongsiqun jiwnandabaojian
(integer) 1
127.0.0.1:6379> PUBLISH jiatingqun jinwanjiaban
(integer) 1

#回到第一個視窗檢視
1) "message"
2) "gongsiqun"
3) "jiwnandabaojian"

1) "message"
2) "jiatingqun"
3) "jinwanjiaban"

四、Redis事務

[

](https://imgchr.com/i/aynz6A)

1.MySQL事務

#成功的事務
begin;
sql1;
sql2;
...
commit;

#失敗的事務
begin;
sql1;
sql2;
...
rollback;

2.redis事務命令

#1.開啟事務
MULTI

#2.結束事務(執行所有事務塊內的命令)
EXEC

#3.取消事務(放棄執行事務塊內的所有命令)
DISCARD

#4.watch只能監控一次事務,可以一次監視一個(或多個) key,如果在事務執行之前這個(或這些) key 被其他命令所改動,那麼事務將被打斷。(多個key有一個被打斷則全部被打斷)
WATCH

#5.取消監控
UNWATCH

#如果用Redis做儲存,一定要使用watch+事務,先x先x

3.事務的示例

#使用事務執行
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k100 v100
QUEUED
127.0.0.1:6379> set k200 v200
QUEUED
127.0.0.1:6379> get k200
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) "v200"

#事務取消
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> keys *
(empty list or set)

#監控一個key
127.0.0.1:6379> WATCH k1
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1000000
QUEUED

#另一個視窗修改k1
127.0.0.1:6379> set k1 00000
OK

#回到第一個視窗提交事務
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> get k1
"00000"

4.注意

1.redis只支援樂觀鎖
2.事務在'不使用watch'監控時,'誰後提交誰為準'
3.事務在'使用watch'監控時,'誰先提交誰為準'
4.watch只監控一次事務並且是當前連線的事務

五、redis多例項

1.建立多例項目錄

[root@db01 ~]# mkdir /service/redis/{6380,6381}

2.配置多例項配置檔案

#第一臺多例項配置
[root@db01 ~]# vim /service/redis/6379/redis.conf 
bind 172.16.1.51 127.0.0.1
port 6379
daemonize yes
pidfile /service/redis/6379/redis_6379.pid
loglevel notice
logfile /service/redis/6379/redis_6379.log
dir /service/redis/6379
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000

#第二臺多例項配置
[root@db01 ~]# vim /service/redis/6380/redis.conf 
bind 172.16.1.51 127.0.0.1
port 6380
daemonize yes
pidfile /service/redis/6380/redis_6380.pid
loglevel notice
logfile /service/redis/6380/redis_6380.log
dir /service/redis/6380
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000

#第三臺多例項配置
[root@db01 ~]# vim /service/redis/6381/redis.conf 
bind 172.16.1.51 127.0.0.1
port 6381
daemonize yes
pidfile /service/redis/6381/redis_6381.pid
loglevel notice
logfile /service/redis/6381/redis_6381.log
dir /service/redis/6381
dbfilename dump.rdb
save 900 1
save 300 10
save 60 10000

3.啟動多例項

[root@db01 ~]# redis-server /service/redis/6379/redis.conf 
[root@db01 ~]# redis-server /service/redis/6380/redis.conf 
[root@db01 ~]# redis-server /service/redis/6381/redis.conf

4.檢測啟動

[root@db01 ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      14002/redis-server  
tcp        0      0 172.16.1.51:6379        0.0.0.0:*               LISTEN      14002/redis-server  
tcp        0      0 127.0.0.1:6380          0.0.0.0:*               LISTEN      15541/redis-server  
tcp        0      0 172.16.1.51:6380        0.0.0.0:*               LISTEN      15541/redis-server  
tcp        0      0 127.0.0.1:6381          0.0.0.0:*               LISTEN      15545/redis-server  
tcp        0      0 172.16.1.51:6381        0.0.0.0:*               LISTEN      15545/redis-server   

[root@db01 ~]# ps -ef | grep redis
root      14002      1  0 Aug04 ?        00:01:34 redis-server 172.16.1.51:6379
root      15541      1  0 11:50 ?        00:00:00 redis-server 172.16.1.51:6380
root      15545      1  0 11:50 ?        00:00:00 redis-server 172.16.1.51:6381

5.連線多例項

[root@db01 ~]# redis-cli -p 6379
127.0.0.1:6379> quit

[root@db01 ~]# redis-cli -p 6380
127.0.0.1:6380> quit

[root@db01 ~]# redis-cli -p 6381
127.0.0.1:6381> quit

六、redis主從

參考網站

1.主從複製特點

1.使用非同步複製。
2.一個主伺服器可以有多個從伺服器。
3.從伺服器也可以有自己的從伺服器。(#級聯複製)
4.複製功能不會'阻塞'主伺服器。
5.可以通過複製功能來'讓主伺服器免於執行持久化操作',由從伺服器去執行持久化操作即可。但是一般配置主庫開啟持久化

#詳細版本
1)Redis 使用非同步複製。從 Redis2.8開始,從伺服器會以'每秒一次'的頻率向主伺服器報告複製流(replication stream)的處理進度。
2)一個主伺服器可以有多個從伺服器。
3)不僅主伺服器可以有從伺服器,從伺服器也可以有自己的從伺服器,多個從伺服器之間可以構成一個圖狀結構。(#級聯結構)
4)複製功能不會阻塞主伺服器:即使有一個或多個從伺服器正在進行初次同步, 主伺服器也可以繼續處理命令請求。(#bgsave)
5)'複製功能也不會阻塞從伺服器':只要在 redis.conf 檔案中進行了相應的設定, 即使從伺服器正在進行初次同步, 伺服器也可以使用舊版本的資料集來處理命令查詢。
6)在從伺服器刪除舊版本資料集並載入新版本資料集的那段時間內',連線請求會被阻塞'。
7)還可以配置從伺服器,讓它在與主伺服器之間的連線斷開時,向客戶端傳送一個錯誤。(#實時監控主從狀態)
8)複製功能可以單純地用於資料冗餘(data redundancy),也可以通過讓多個從伺服器處理'只讀命令'請求來提升擴充套件性(scalability): 比如說,繁重的SORT命令可以交給附屬節點去執行。

級聯複製

2.主從複製的原理

... 上一秒 ...
1.從伺服器向主伺服器傳送 SYNC 命令
2.主庫接到 SYNC 命令會呼叫 BGSAVE 命令建立一個 RDB 檔案
3.主庫將新的資料'記錄到緩衝區'
4.主庫將 RDB 檔案傳輸到從庫
5.從庫拿到 RDB 檔案以後,'會清空自己的資料'  #小心,相當於flushall
6.從庫讀取 RDB 檔案並匯入資料
7.主庫將新的資料從'緩衝區傳到從庫'進行同步
... 下一秒 ...

3.主從複製的機制

#SYNC與PSYNC

1)在 Redis2.8版本之前,'斷線之後重連'的從伺服器總要執行一次完整重同步(fullresynchronization)操作。
2)從 Redis2.8開始,Redis使用'PSYNC命令代替SYNC命令'。
3)PSYNC比起SYNC的最大改進在於PSYNC實現了部分重同步(partial resync)特性:
在主從伺服器斷線並且重新連線的時候,只要條件允許,PSYNC可以讓主伺服器只向從伺服器同步斷線期間缺失的資料,而不用重新向從伺服器同步整個資料庫。

PSYNC這個特性需要主伺服器為被髮送的複製流建立一個'記憶體緩衝區'(in-memory backlog), 並且主伺服器和所有從伺服器之間都記錄一個'複製偏移量'(replication offset)和一個主伺服器 'ID'(master run id),當出現網路連線斷開時,從伺服器會重新連線,並且向主伺服器請求繼續執行原來的複製程序:
1)如果從伺服器記錄的主伺服器ID和當前要連線的主伺服器的ID相同,並且從伺服器記錄的偏移量所指定的資料仍然儲存在主伺服器的複製流緩衝區裡面,那麼主伺服器會向從伺服器傳送斷線時缺失的那部分資料,然後複製工作可以繼續執行。
2)否則的話,從伺服器就要執行完整重同步操作。
#總結
主從剛剛連線的時候,進行'全量同步';全同步結束後,進行'增量同步'。當然,如果有需要,slave 在任何時候都可以發起全量同步。redis 策略是,'無論如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。'

#PSYNC優點:
1)PSYNC只會將從伺服器斷線期間缺失的資料傳送給從伺服器。兩個例子的情況是相同的,但SYNC 需要傳送包含整個資料庫的 RDB 檔案,而PSYNC 只需要傳送三個命令。
2)如果主從伺服器所處的網路環境並不那麼好的話(經常斷線),那麼請儘量使用 Redis 2.8 或以上版本:#通過使用 PSYNC 而不是 SYNC 來處理斷線重連線,可以避免因為重複建立和傳輸 RDB檔案而浪費大量的網路資源、計算資源和記憶體資源。

注意

1.主伺服器開啟持久化
在進行主從複製設定時,強烈建議在主伺服器上開啟持久化,當不能這麼做時,比如考慮到延遲的問題,應該將例項配置為'避免自動重啟'。
2.主伺服器密碼
主從伺服器之間會定期進行通話,但是如果master上設定了密碼,那麼如果不給slave設定密碼就會導致slave不能跟master進行任何操作,所以如果你的master伺服器
上有密碼,那麼也給slave相應的設定一下密碼吧(通過設定配置檔案中的'masterauth');
3.使用者訪問從伺服器的'阻塞問題'
主從複製對於從redis伺服器來說也是非阻塞的,這意味著,即使從redis在進行主從複製過程中也可以接受外界的查詢請求,只不過這時候從redis返回的是'以前老的資料',
   如果你不想這樣,那麼在啟動redis時,可以在配置檔案中進行設定,那麼從redis在複製同步過程中來自外界的查詢請求都會'返回錯誤給客戶端';(雖然說主從複製過程中
   對於從redis是非阻塞的,但是當從redis從主redis同步過來最新的資料後還需要將新資料載入到記憶體中,在載入到記憶體的過程中是阻塞的,在這段時間內的請求將會被阻,
   但是即使對於大資料集,載入到記憶體的時間也是比較多的);

主從複製的方式

1.全部同步
舊的主從中使用SYNC命令

2.部分同步
部分重新同步這個新特性內部使用PSYNC命令,舊的實現中使用SYNC命令

3.無磁碟複製
通常來講,一個完全重新同步需要'在磁碟上建立一個RDB檔案',然後載入這個檔案以便為從伺服器傳送資料。
如果使用比較低速的磁碟,這種操作會給主伺服器帶來較大的壓力。'Redis從2.8.18版本開始嘗試支援無磁碟的複製。'
使用這種設定時,子程序直接將RDB通過網路傳送給從伺服器,不使用磁碟作為中間儲存。
使用repl-diskless-sync配置引數來啟動無磁碟複製。使用repl-diskless-sync-delay 引數來配置傳輸開始的延遲時間

3.從伺服器只讀
從Redis 2.6開始,從伺服器支援只讀模式,並且是預設模式。這個行為是由Redis.conf檔案中的slave-read-only 引數控制的,
可以在執行中通過CONFIG SET來啟用或者禁用。

4.配置主從

1)準備環境

角色 主機
主庫 172.16.1.51 6379
從庫 172.16.1.51 6380
從庫 172.16.1.51 6381

2)連線三臺機器

[root@db01 ~]# redis-cli -p 6379
[root@db01 ~]# redis-cli -p 6380
[root@db01 ~]# redis-cli -p 6381

3)檢視主從狀態

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

4)配置主從

127.0.0.1:6380> SLAVEOF 172.16.1.51 6379
OK

127.0.0.1:6381> SLAVEOF 172.16.1.51 6379
OK

5)檢視主從狀態

#檢視主庫
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.1.51,port=6380,state=online,offset=263,lag=0
slave1:ip=172.16.1.51,port=6381,state=online,offset=263,lag=1
master_repl_offset:263		#偏移量
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:262

#檢視從庫
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:172.16.1.51
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:319		#偏移量
slave_priority:100			#提升為主庫的優先順序(越低優先順序越高)
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0