redis

緩存技術:

redis
2.jpg
NoSQL,泛指非關係型的數據庫。NoSQL=Not Only SQLcss

緩存:緩存(cache)cache是一個很是大的概念。html

1、CPU的Cachejava

CPU的Cache,它中文名稱是高速緩衝存儲器,讀寫速度很快,幾乎與CPU同樣。因爲CPU的運算速度太快,內存的數據存取速度沒法跟上CPU的速度,因此在cpu與內存間設置了cache爲cpu的數據快取區。當計算機執行程序時,數據與地址管理部件會預測可能要用到的數據和指令,並將這些數據和指令預先從內存中讀出送到Cache。一旦須要時,先檢查Cache,如有就從Cache中讀取,若無再訪問內存,如今的CPU還有一級cache,二級cache。簡單來講,Cache就是用來解決CPU與內存之間速度不匹配的問題,避免內存與輔助內存頻繁存取數據,這樣就提升了系統的執行效率。node

2、磁盤cache
磁盤也有cache,硬盤的cache做用就相似於CPU的cache,它解決了總線接口的高速需求和讀寫硬盤的矛盾以及對某些扇區的反覆讀取。python

3、瀏覽器緩存mysql

瀏覽器緩存(Browser Caching)是爲了節約網絡的資源加速瀏覽,瀏覽器在用戶磁盤上對最近請求過的文檔進行存儲,當訪問者再次請求這個頁面時,瀏覽器就能夠從本地磁盤顯示文檔,這樣就能夠加速頁面的閱覽,而且能夠減小服務器的壓力。這個過程與下載很是相似,不過下載是用戶的主動過程,而且下載的數據通常是長時間保存,遊覽器的緩存的數據只是短期保存,能夠人爲的清空linux

緩衝:緩衝區(buffer),它是內存空間的一部分。也就是說,在內存空間中預留了必定的存儲空間,這些存儲空間用來緩衝輸入或輸出的數據,這部分預留的空間就叫作緩衝區,顯然緩衝區是具備必定大小的。git

緩存(cache)與緩衝(buffer)的主要區別程序員

Buffer的核心做用是用來緩衝,緩和衝擊。好比你每秒要寫100次硬盤,對系統衝擊很大,浪費了大量時間在忙着處理開始寫和結束寫這兩件事嘛。用個buffer暫存起來,變成每10秒寫一次硬盤,對系統的衝擊就很小,寫入效率高了,日子過得爽了。極大緩和了衝擊。github

Cache的核心做用是加快取用的速度。好比你一個很複雜的計算作完了,下次還要用結果,就把結果放手邊一個好拿的地方存着,下次不用再算了。加快了數據取用的速度。

buffer偏重於寫,而cache偏重於讀

參考文檔:https://www.sohu.com/a/246498483_468626

[root@c7-77]#cat /proc/sys/vm/drop_caches 
0
[root@c7-77]#echo 3 >/proc/sys/vm/drop_caches 
[root@c7-77]#cat /proc/sys/vm/drop_caches 
3

[root@c7-77]#man proc
 Because this is a nondestructive operation and dirty objects are not freeable, the user should run sync(8) first.

       /proc/sys/vm/legacy_va_layout (since Linux 2.6.9)

[root@c7-77]#man 5 proc

redis
1.jpg

緩存保存的位置

用戶層:瀏覽器dns緩存 應用程序dns緩存 
代理層 : cdn
web層 :web服務器緩存
數據層:分佈式緩存:redis  數據庫;mysql
系統層:操做系統 cache
物理層:磁盤cache raid cache  CPU緩存

用戶層緩存

瀏覽器的dns默認是60秒

緩存的特性:

1 自動過時,例如DNS的TTL ,微信紅包

2 強制過時

3 命中率

瀏覽器的緩存:

redis
3.jpg

緩存過時機制

設置瀏覽器緩存有下面幾種方法

Last-Modified:服務器上文件的最後修改時間

Etag:文件標識

Expires:本地緩存目錄中,文件過時的時間(由服務器指定具體的時間)

Cache-control:本地緩存目錄中,文件過時的時間(由服務器指定過時的間隔時間,因爲瀏覽器根據間隔生成具體的時間)

Last-Modified

通常狀況下,iis會在訪問css、js等靜態文件時,返回給瀏覽器Last-Modified和Etag標記,瀏覽器再次訪問服務器的時候會在帶上兩個標記

If-Modified-Since和If-None-Match,服務器檢查參數值,若是文件沒有改變則返回304,此時瀏覽器就訪問本地緩存了。若是服務器上該文件被修改過,那麼參數值就不同,服務器就把最後的文件返回給瀏覽器。

在瀏覽器第一次請求某一個URL時,服務器端的返回狀態會是200,內容是客戶端請求的資源,同時有一個Last-Modified的屬性標記此文件在服務器端最後被修改的時間。
Last-Modified格式相似這樣:
Last-Modified : Fri , 12 May 2006 18:53:33 GMT
客戶端第二次請求此URL時,根據HTTP協議的規定,瀏覽器會向服務器傳送If-Modified-Since報頭,詢問該時間以後文件是否有被修改過:
If-Modified-Since : Fri , 12 May 2006 18:53:33 GMT
若是服務器端的資源沒有變化,則自動返回 HTTP 304(Not Changed.)狀態碼,內容爲空,這樣就節省了傳輸數據量。當服務器端代碼發生改變或者重啓服務器時,則從新發出資源,返回和第一次請求時相似。從而保證不向客戶端重複發出資源,也保證當服務器有變化時,客戶端可以獲得最新的資源。

Etag

ETag 是 Entity Tag 的縮寫,中文譯過來就是實體標籤的意思。在HTTP1.1協議中其實就是請求HEAD中的一個屬性而已

ETag是HTTP1.1中才加入的一個屬性,用來幫助服務器控制Web端的緩存驗證。它的原理是這樣的,當瀏覽器請求服務器的某項資源(A)時, 服務器根據A算出一個哈希值(3f80f-1b6-3e1cb03b)並經過 ETag 返回給瀏覽器,瀏覽器把"3f80f-1b6-3e1cb03b" 和 A 同時緩存在本地,當下次再次向服務器請求A時,會經過相似 If-None-Match: "3f80f-1b6-3e1cb03b" 的請求頭把ETag發送給服務器,服務器再次計算A的哈希值並和瀏覽器返回的值作比較,若是發現A發生了變化就把A返回給瀏覽器(200),若是發現A沒有變化就給瀏覽器返回一個304未修改。這樣經過控制瀏覽器端的緩存,能夠節省服務器的帶寬,由於服務器不須要每次都把全量數據返回給客戶端。

Expires:過時時間

expires是給一個資源設定一個過時時間,也就是說無需去服務端驗證,直接經過瀏覽器自身確認是否過時便可,因此不會產生額外的流量。此種方法很是適合不常常變更的資源。若是文件變更較頻繁,不要使用expires來緩存。
expires起到控制頁面緩存的做用,合理的配置expires能夠減小不少服務器的請求。

以上的兩種均須要請求。即,無論資源過時已否都須要請求協商,消耗沒必要要的時間,所以有了緩存的過時時間。expires由服務器設置,若是帶有
expires 那麼過時前不須要請求。直接從緩存裏面讀取。ctrl + F5 強制除外

Expires能夠下降網站購買的帶寬,節約成本,同時提高了用戶訪問體驗,減輕服務器的壓力,
是web服務很是重要的功能。
缺點:
被緩存的頁面或數據更新了,用戶看到的可能仍是舊的內容,反而影響用戶體驗。

混合使用和緩存刷新

last-modified 和 expire 一塊兒使用,若沒有過時就無需發起http請求。當瀏覽器強制F5的時候纔有last-modified ,很好的達到緩存的效果

Etag 和expire一塊兒使用,先判斷是否過時,若過時就發起http請求,此時若etag 發生變化,那麼返回200的響應,若是Etag沒有發生變化就返回403

last-modified  Etag  expire 三個一塊兒使用:
#先expire 判斷是否過時。若過時才發起http請求
#若expire已過時,服務器會先判斷 last-modified 其次是Etag  必須都沒有發生變化才返回304

緩存刷新

第一次訪問,獲取最新的數據,返回200
鼠標點擊第二次訪問,瀏覽器對全部沒有過時的內容直接使用本地的緩存
F5或刷新,會像服務器發送請求協商,last-modified 和 Etag 會有影響,可是expires 本地的過時時間是不受影響的,無變化,返回304
按Ctrl+F5 全部緩存不在使用,直接返回200

cookie和session

會話(Session)跟蹤是Web程序中經常使用的技術,用來跟蹤用戶的整個會話。經常使用的會話跟蹤技術是Cookie與Session。Cookie經過在客戶端記錄信息肯定用戶身份

Session經過在服務器端記錄信息肯定用戶身份。

redis
4.jpg

CDN 緩存

CDN(Content Delivery Network)是指內容分發網絡,也稱爲內容傳送網絡
CDN負載均衡系統實現CDN的內容路由功能。它的做用是將用戶的請求導向整個CDN網絡中的最佳節點。最佳節點的選定能夠根據多種策略,例如距離最近、節點負載最輕等。負載均衡系統是整個CDN的核心,負載均衡的準確性和效率直接決定了整個CDN的效率和性能。一般負載均衡能夠分爲兩個層次:全局負載均衡(GSLB)和本地負載均衡(SLB)。全局負載均衡主要的目的是在整個網絡範圍內將用戶的請求定向到最近的節點(或者區域)。所以,就近性判斷是全局負載均衡的主要功能。本地負載均衡通常侷限於必定的區域範圍內,其目標是在特定的區域範圍內尋找一臺最適合的節點提供服務,所以,CDN節點的健康性、負載狀況、支持的媒體格式等運行狀態是本地負載均衡進行決策的主要依據。

redis
5.png

302 臨時重定向

redis
6.png

redis

關係型數據庫和NoSQL數據庫數據庫

關係型數據庫和NoSQL數據庫數據庫主要分爲兩大類:關係型數據庫與NoSQL數據庫。
關係型數據庫,是創建在關係模型基礎上的數據庫,其藉助於集合代數等數學概念和方法來處理數據庫中的數據。主流的MySQL、Oracle、MS SQL Server和DB2都屬於這類傳統數據庫。
NoSQL數據庫,全稱爲Not Only SQL,意思就是適用關係型數據庫的時候就使用關係型數據庫,不適用的時候也沒有必要非使用關係型數據庫不可,能夠考慮使用更加合適的數據存儲。主要分爲臨時性鍵值存儲(memcached、Redis)、永久性鍵值存儲(ROMA、Redis)、面向文檔的數據庫
(MongoDB、CouchDB)、面向列的數據庫(Cassandra、HBase),每種NoSQL都有其特有的使用場景及優勢。
Oracle,mysql等傳統的關係數據庫很是成熟而且已大規模商用,爲何還要用NoSQL數據庫呢?主要是因爲隨着互聯網發展,數據量愈來愈大,對性能要求愈來愈高,傳統數據庫存在着先天性的缺陷,即單機(單庫)性能瓶頸,而且擴展困難。這樣既有單機單庫瓶頸,卻又擴展困難,天然沒法知足日益增加的海量數據存儲及其性能要求,因此纔會出現了各類不一樣的NoSQL產品,NoSQL根本性的優點在於在雲計算時代,簡單、易於大規模分佈式擴展,而且讀寫性能很是高

非關係型數據庫

併發性能夠達到10萬

Redis的特色:
內存數據庫,速度快,也支持數據的持久化,能夠將內存中的數據保存在磁盤中,重啓的時候能夠再次加載進行使用。
Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
Redis支持數據的備份,即master-slave模式的數據備份。
支持事務
Redis的優點:
性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。
原子 – Redis的全部操做都是原子性的,同時Redis還支持對幾個操做合併後的原子性執行。(事務)
豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過時等等特性。
Redis與其餘key-value存儲有什麼不一樣?
Redis有着更爲複雜的數據結構而且提供對他們的原子性操做,這是一個不一樣於其餘數據庫的進化路徑。Redis的數據類型都是基於基本數據結構的同時對程序員透明,無需進行額外的抽象。
Redis運行在內存中可是能夠持久化到磁盤,因此在對不一樣數據集進行高速讀寫時須要權衡內存,由於數據量不能大於硬件內存。在內存數據庫方面的另外一個優勢是,相比在磁盤上相同的複雜的數據結構,在內存中操做起來很是簡單,這樣Redis能夠作不少內部複雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,由於他們並不須要進行隨機訪問。

Redis的特色:

redis
7.jpg

單線程

redis

redis
8.png9.png

redis對比memcached

redis

10.jpg

redis 典型應用場景

  • Session 共享:常見於web集羣中的Tomcat或者PHP中多web服務器session共享緩存:數據查詢、電商網站商品信息、新聞內容
  • 計數器:訪問排行榜、商品瀏覽數等和次數相關的數值統計場景微博/微信社交場合:共同好友,粉絲數,關注,點贊評論等
  • 消息隊列:ELK的日誌緩存、部分業務的訂閱發佈系統
  • 地理位置:基於GEO(地理信息定位),實現搖一搖,附近的人,外賣等功能

yum 安裝redis

官方下載地址:http://download.redis.io/releases/

[root@C8-58]#yum install redis -y
[root@C8-58]#id redis 
uid=993(redis) gid=990(redis) groups=990(redis)
[root@C8-58]#systemctl enable --now redis
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         128              127.0.0.1:6379             0.0.0.0:* 
#監聽在127.0.0.1 只能是爲本身服務,因此要改配置文件
[root@C8-58]#grep '^bind' /etc/redis.conf 
bind 0.0.0.0
[root@C8-58]#grep '^bind' /etc/redis.conf 
bind 0.0.0.0
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         128                0.0.0.0:6379             0.0.0.0:* 

[root@centos8 ~]#dnf -y insta17 redis
[root@centos8 ~]#systemct1 enab1e --now redis
[root@centos8 ~]#pstree -plgrep redis
l-redis-server(3383)-+-{redis-server}(3384)
l-iredis-server} (3385)`-{redis-server} (3386)
[root@centos8 ~]#redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info
# server
redis_version :5.0.3redis_git_sha1: 000000ooredis_git_dirty : 0
redis_bui1d_id:8c0bf22bfba82c8fredis_mode :standalone
os :Linux 4.18.0-147.e18.x86_64 x86_64

日誌

[root@C8-58]#tail /var/log/redis/redis.log  -f

查看日誌三個警告報錯

第一次安裝Redis之後看日誌會報警:

redis
11.png

#改第一個內核參數
[root@C8-58]#cat /proc/sys/net/core/somaxconn
128
[root@C8-58]#vim /etc/sysctl.conf 
[root@C8-58]#sysctl -p
net.core.somaxconn = 1024
[root@C8-58]#tail -1 /etc/sysctl.conf 
 net.core.somaxconn=1024
[root@C8-58]#cat /proc/sys/net/core/somaxconn
1024

 #改第二個內核參數
[root@C8-58]#tail -2 /etc/sysctl.conf 
 net.core.somaxconn=1024
 vm.overcommit_memory=1 
[root@C8-58]#cat /proc/sys/vm/overcommit_memory 
1

[root@C8-58]#tail /var/log/redis/redis.log  -f
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

3128:M 04 Aug 2021 20:45:20.535 # Server initialized
3128:M 04 Aug 2021 20:45:20.535 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
3128:M 04 Aug 2021 20:45:20.535 * DB loaded from disk: 0.000 seconds
3128:M 04 Aug 2021 20:45:20.535 * Ready to accept connections

#修改第三個警告報錯:
[root@C8-58]#echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.d/rc.local 
[root@C8-58]#chmod +x /etc/rc.d/rc.local 
[root@C8-58]#/etc/rc.d/rc.local 
[root@C8-58]#

啓動服務的文件

[root@C8-58]#ps -ef |grep  redis |grep -v 'grep'
redis       3211       1  0 20:52 ?        00:00:00 /usr/bin/redis-server 0.0.0.0:6379

#該文件做爲啓動redis的文件

前臺啓動redis

yum安裝Redis之後前臺執行該命令,由於沒有修改配置文件爲後臺的

redis
12.png

編譯安裝redis

官網https://redis.io/download

[root@C8-58]# wget https://download.redis.io/releases/redis-6.2.5.tar.gz
[root@C8-58]#yum install gcc jemalloc-devel -y
[root@C8-58]#tar xf redis-6.2.5.tar.gz 
[root@C8-58]#cd redis-6.2.5/
[root@C8-58]#ls
00-RELEASENOTES  CONDUCT       COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  src    TLS.md
BUGS             CONTRIBUTING  deps     Makefile  README.md  runtest     runtest-moduleapi  sentinel.conf     tests  utils
#指定安裝路徑
[root@C8-58]#make PREFIX=/apps/redis install
#配置變量:
[root@C8-58]#echo 'PATH=/apps/redis/bin:$PATH' >/etc/profile.d/redis.sh
[root@C8-58]#. /etc/profile.d/redis.sh

[root@C8-58]#mkdir /apps/redis/{etc,log,data,run}
[root@C8-58]#useradd -r -s /sbin/nologin redis
[root@C8-58]#chown -R redis.redis /apps/redis/

[root@C8-58]#redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --replicaof 127.0.0.1 8888
       ./redis-server /etc/myredis.conf --loglevel verbose -
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel

#複製配置文件
[root@C8-58]#ls      
00-RELEASENOTES  CONDUCT       COPYING  INSTALL   MANIFESTO  redis.conf  runtest-cluster    runtest-sentinel  src    TLS.md
BUGS             CONTRIBUTING  deps     Makefile  README.md  runtest     runtest-moduleapi  sentinel.conf     tests  utils
[root@C8-58]#pwd
/root/redis-6.2.5
[root@C8-58]#ll redis.conf 
-rw-rw-r-- 1 root root 93724 Jul 22 02:06 redis.conf
#準備配置文件:
[root@C8-58]#cp redis.conf /apps/redis/etc/
[root@C8-58]#ll /apps/redis/etc/redis.conf 
-rw-r--r-- 1 root root 93724 Aug  4 21:28 /apps/redis/etc/redis.conf
[root@C8-58]#chown -R redis.redis /apps/redis/

#前臺運行redis
[root@C8-58]#redis-server   /apps/redis/etc/redis.conf 
8875:C 04 Aug 2021 21:31:49.083 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8875:C 04 Aug 2021 21:31:49.083 # Redis version=6.2.5, bits=64, commit=00000000, modified=0, pid=8875, just started
8875:C 04 Aug 2021 21:31:49.083 # Configuration loaded
8875:M 04 Aug 2021 21:31:49.084 * monotonic clock: POSIX clock_gettime
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.2.5 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 8875
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           https://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

8875:M 04 Aug 2021 21:31:49.085 # Server initialized

#修改成後臺臺執行
[root@C8-58]#grep '^daem' /apps/redis/etc/redis.conf 
daemonize yes #修改此項改成後臺執行

#重啓服務
[root@C8-58]#killall redis-server 
[root@C8-58]#redis-server /apps/redis/etc/redis.conf 
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         511                0.0.0.0:6379             0.0.0.0:* 

[root@C8-58]#pstree -p |grep redis
           |-redis-server(9097)-+-{redis-server}(9098)
           |                    |-{redis-server}(9099)
           |                    |-{redis-server}(9100)
           |                    `-{redis-server}(9101)

#建立命令軟鏈接
[root@centos7 ~]#1n -sv /apps/redis/bin/redis-* /usr/bin/
'/usr/bin/redis-benchmark’ ->'/apps/redis/bin/redis-benchmark'
'/usr/bin/redis-check-aof’-> ‘/apps/redis/bin/redis-check-aof'
'/usr/bin/redis-check-rdb’-> ‘/apps/redis/bin/redis-check-rdb'
'/usr/bin/ redis-cli' -> ' / apps/redis/bin/redis-cli'
'/usr/bin/redis-sentinel’->‘/apps /redis/bin/redis-sentine7'
'/usr/bin/redis-server’-> ' / apps/redis/bin/redis-server'

#編譯安裝後的命令:
[root@centos7 ~]#ll /apps / redis/bin/
tota7 32772
-rwWXr-xr-x 1 root root 4366792 Feb 16 21:12 redis-benchmark #redis性能測試工具
-rwxr-xr-x 1 root root 8125184 Feb 16 21:12 redis-check-aof #AOF文件檢查工具
-rwXr-Xr-x 1 root root 8125184 Feb 16 21:12 redis-check-rdb #RDB文件檢查工具
-rwxr-xr-x 1 root root 4807856 Feb 16 21:12 redi s-c1i
-rwxrwXrwx 1 root root  12 Feb 16 21:12 redis-sentinel -> redis-server #哨兵,軟鏈接到server
-rWxr-Xr-x 1 root root 8125184 Feb 16 21:12 redis-server #redis服務啓動命令

redis多實例

[root@C8-58]#grep '^[^#]' redis_6379.conf 
 bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /apps/redis/run/redis_6379.pid
loglevel notice
logfile "/apps/redis/log/redis_6379.log"
databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump_6379.rdb
rdb-del-sync-files no
dir /apps/redis/data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes

#建立實例配置文件
root@C8-58]#sed 's/6379/6380/g' redis_6379.conf >redis_6380.conf 
[root@C8-58]#sed 's/6379/6381/g' redis_6379.conf >redis_6381.conf 
[root@C8-58]#ll
total 276
-rw-r--r-- 1 redis redis 93829 Aug  4 21:55 redis_6379.conf
-rw-r--r-- 1 root  root  93829 Aug  4 21:57 redis_6380.conf
-rw-r--r-- 1 root  root  93829 Aug  4 21:57 redis_6381.conf
#修改屬組屬主
useradd -r -s  /sbin/nologin redis
[root@C8-58]#chown -R redis:redis /apps/redis/
[root@C8-58]#tree /apps/redis/
/apps/redis/
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof -> redis-server
│   ├── redis-check-rdb -> redis-server
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── data
├── etc
│   ├── redis_6379.conf
│   ├── redis_6380.conf
│   └── redis_6381.conf
├── log
└── run

5 directories, 9 files

#開啓redis多實例:
[root@C8-58]#killall redis-server 
[root@C8-58]#redis-server /apps/redis/etc/redis_6379.conf 
[root@C8-58]#ss -tnl |grep 6379
LISTEN    0         511                0.0.0.0:6379             0.0.0.0:*       
[root@C8-58]#redis-server /apps/redis/etc/redis_6380.conf    
[root@C8-58]#ss -tnl |grep 6380
LISTEN    0         511                0.0.0.0:6380             0.0.0.0:*       
[root@C8-58]#redis-server /apps/redis/etc/redis_6381.conf 
[root@C8-58]#ss -tnl |grep 6381
LISTEN    0         511                0.0.0.0:6381             0.0.0.0:*       
[root@C8-58]#

[root@C8-58]#tree /apps/redis/
/apps/redis/
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof -> redis-server
│   ├── redis-check-rdb -> redis-server
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── data
├── etc
│   ├── redis_6379.conf
│   ├── redis_6380.conf
│   └── redis_6381.conf
├── log
│   ├── redis_6379.log
│   ├── redis_6380.log
│   └── redis_6381.log
└── run
    ├── redis_6379.pid
    ├── redis_6380.pid
    └── redis_6381.pid

5 directories, 15 files

#開啓三個實例
[root@C8-58]#redis-server /apps/redis/etc/redis_6379.conf 
[root@C8-58]#redis-server /apps/redis/etc/redis_6380.conf 
[root@C8-58]#redis-server /apps/redis/etc/redis_6381.conf 
[root@C8-58]#ss -tnl |grep "redis"
[root@C8-58]#ss -tnl 
State             Recv-Q            Send-Q                       Local Address:Port                       Peer Address:Port           
LISTEN            0                 511                                0.0.0.0:6379                            0.0.0.0:*              
LISTEN            0                 511                                0.0.0.0:6380                            0.0.0.0:*              
LISTEN            0                 511                                0.0.0.0:6381                                      

#加入到systemd 管理:
[root@C8-58]#cp  /usr/lib/systemd/system/redis6379.service  /usr/lib/systemd/system/redis6380.service 
[root@C8-58]#cp  /usr/lib/systemd/system/redis6379.service  /usr/lib/systemd/system/redis6381.service 

[root@C8-58]#sed -i 's/6379/6380/'  /usr/lib/systemd/system/redis6380.service
[root@C8-58]#sed -i 's/6379/6381/'  /usr/lib/systemd/system/redis6381.service

[root@C8-58]#cat /usr/lib/systemd/system/redis6379.service 
[Unit]
Description=redis
After=network.target

[Service]
Type=forking
#PIDFile=/apps/redis/run/redis_6379.pid 
ExecStart=/apps/redis/bin/redis-server  /apps/redis/etc/redis_6379.conf 
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
[root@C8-58]#cat /usr/lib/systemd/system/redis6380.service 
[Unit]
Description=redis
After=network.target

[Service]
Type=forking
#PIDFile=/apps/redis/run/redis_6379.pid 
ExecStart=/apps/redis/bin/redis-server  /apps/redis/etc/redis_6380.conf 
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
[root@C8-58]#cat /usr/lib/systemd/system/redis6381.service 
[Unit]
Description=redis
After=network.target

[Service]
Type=forking
#PIDFile=/apps/redis/run/redis_6379.pid 
ExecStart=/apps/redis/bin/redis-server  /apps/redis/etc/redis_6381.conf  --supervised systemd 
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

[root@C8-58]#killall redis-server 
#修改屬組屬主爲redis
[root@C8-58]#ll /apps/redis/log/
total 12
-rw-r--r-- 1 root root 902 Aug  4 22:19 redis_6379.log
-rw-r--r-- 1 root root 902 Aug  4 22:19 redis_6380.log
-rw-r--r-- 1 root root 902 Aug  4 22:19 redis_6381.log
[root@C8-58]#chown -R redis:redis /apps/redis

[root@centos7 ~]#systemctl daemon-reload
[root@centos7 ~]#systemctl start redis_6379  redis_6380  redis_6381

使用客戶端鏈接redis

[root@centos7~]#/apps/redis/bin/redis-cli   -h IP/HOSTNAME   -p PORT   -a PASSWORD
#查看版本信息
127.0.0.1:6379> info [section]

#遠程鏈接別人的redis
[root@C8-58]#redis-cli -h 10.0.0.33
10.0.0.33:6379> 

127.0.0.1:6379> set hello m42
OK
127.0.0.1:6379> get hello
"m42"
[root@C8-33 ~]# redis-cli get hello
"m42"

[root@C8-58]#redis-cli -h 10.0.0.33 get hello
"m42"

一鍵安裝redis腳本

[root@C8-24 ~]# cat redis_instll.sh 
#!/bin/bash
#
#*******************************************************************************
#Author:            hwang
#Data:              2021-08-05-10:46:47
#Description:       redis_instll.sh
#Copyright (C):        2021 All rights reserved
#*******************************************************************************
#Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37)
#Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47)
#*******************************************************************************
. /etc/init.d/functions
VERSION=redis-6.2.5
PASSWORD=123456
INSTALL_DIR=/apps/redis
install(){
yum -y install wget make  gcc jemalloc-devel || { action "軟件安裝失敗,檢查網絡配置" false;exit;}
wget https://download.redis.io/releases/${VERSION}.tar.gz  || { action "Redis reload faild" false;exit; }
tar xf ${VERSION}.tar.gz
cd ${VERSION}
make PREFIX=${INSTALL_DIR} install && action "Redis 編譯完成" || { action "Redis 編譯安裝失敗" false;exit; }
ln -s ${INSTALL_DIR}/bin/redis-* /usr/bin/
mkdir -p ${INSTALL_DIR}/{etc,log,data,run}
cp redis.conf ${INSTALL_DIR}/etc/
sed -i  's/bind 127.0.0.1/bind 0.0.0.0/'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/# requirepass/a requirepass $PASSWORD"'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^dir .*/c dir ${INSTALL_DIR}/data/'     ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/logfile .*/c logfile ${INSTALL_DIR}/log/redis-6397.log'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis-6393.pid'  ${INSTALL_DIR}/etc/redis.conf
sed -i  's/daemonize .*/c  daemonize  yes'  ${INSTALL_DIR}/etc/redis.conf

if id redis &> /dev/null;then
    action "redis 用戶存在" false
else
    useradd -r -s /sbin/nologin redis
    action "redis 用戶建立成功"
fi

chown -R redis.redis ${INSTALL_DIR}
cat >>/etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
sysctl -p
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.d/rc.local 
chmod +x /etc/rc.d/rc.local
/etc/rc.d/rc.local 
cat > /usr/lib/systemd/system/redis6379.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf  --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
#Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemct  enable --now redis &>/dev/null && action "Redis 啓動成功,信息以下:" || { action "redis 啓動失敗" false;exit; }
redis-cli -a $PASSWORD INFO  server 2>/dev/null
}
install

[root@C8-24 ~]# /usr/local/bin/redis-server  /apps/redis/etc/redis.conf

windows安裝redis

https://github.com/MicrosoftArchive/redis/releases

Windows版 Redis下載地址: https://github.com/MicrosoftArchive/redis/releases
不推薦在生產環境使用Windows系統運行Redis服務

[root@C8-33 ~]# wc -l /etc/redis.conf
1378 /etc/redis.conf

#驗證Red is服務端口
C: \Program Files\Redis>netstat -na|findstr 6666

圖像工具

https://github.com/uglide/RedisDesktopManager/releases/tag/0.9.3

鏈接到redis

#本機無密碼鏈接:
redis-cli
#跨主機無密碼鏈接:
redis-cli -h HOSTNAME/IP -p port
#跨主機密碼鏈接:
redis-cli -h HOSTNAME/IP -p port -a PASSWORD

python鏈接方式

python多種開發庫,能夠支持鏈接redis

使用redis-py鏈接redis
官方github :
https://github.com/andymccurdy/redis-py

yum  -y install python3 python3-redis
[root@C8-24 ~]# cat redis_test.py 
#!/bin/env python3
import redis
pool = redis.ConnectionPool(host="127.0.0.1",port="6379",password="")
r = redis.Redis(connection_pool=pool)
for i in range(5000000):
    r.set("k%d" % i,"v%d" % i)
    data=r.get("k%d" % i)
    print(data)

shell腳本寫入數據到redis

[root@C8-58]#cat  redis-test.sh
#!/bin/bash
NUM=100
PASS=""
for i in `seq 100`;do
    redis-cli -h 10.0.0.33 -a "PASS" --no-auth-warning set key${i} value${i}
    echo "key${i} value${i}" 寫入完成
done
echo "$NUM個key寫入到REDIS完成"

 --no-auth-warning :免報警提示

redis主要配置項

bind 0.0.0.0 #監聽地址,能夠用空格隔開後多個監聽IP

protected-mode yes #redis3.2 以後加入的新特性,在沒有設置bind IP和密碼的時候,redis只容許訪問127.0.0.1:6379,遠程訪問將提示警告信息並拒絕遠程訪問

port 6379 #監聽端口

tcp-backlog 511 #三次握手的時候server端收到client ack確認號以後的隊列值。

timeout 0 #客戶端和Redis服務端的鏈接超時時間,默認是0,表示永不超時。

tcp-keepalive 300 #tcp 會話保持時間

daemonize n #認狀況下 redis 不是做爲守護進程運行的,若是你想讓它在後臺運行,你就把它改爲 yes,當redis做爲守護進程運行的時候,它會寫一個 pid 到 /var/run/redis.pid 文件裏面

supervised no #和操做系統相關參數,能夠設置經過upstart和systemd管理Redis守護進程,centos 7之後都使用systemd

pidfile /var/run/redis_6379.pid #pid文件路徑

loglevel notice #日誌級別

logfile "" #日誌路徑

databases 16 #設置db 庫數量,默認16個庫

always-show-logo yes #在啓動redis 時是否顯示log

save 900 1 #在900秒內有一個鍵內容發生更改就出就快照機制
save 300 10 #300秒以內有10個就存一次
save 60 10000

stop-writes-on-bgsave-error no #快照出錯時是否禁止redis 寫入操做

rdbcompression yes #持久化到RDB文件時,是否壓縮,"yes"爲壓縮,"no"則反之

rdbchecksum yes #是否開啓RC64校驗,默認是開啓

dbfilename dump.rdb #快照文件名

dir ./ #快照文件保存路徑

replica-serve-stale-data yes #當從庫同主庫失去鏈接或者複製正在進行,從機庫有兩種運行方式:
一、若是replica-serve-stale-data設置爲yes(默認設置),從庫會繼續響應客戶端的讀請求。
二、若是replica-serve-stale-data設置爲no,除去指定的命令以外的任何請求都會返回一個錯誤"SYNC with master in progress"。

replica-read-only yes #是否設置從庫只讀

repl-diskless-sync no #是否使用socket方式複製數據(無盤同步),新slave鏈接鏈接時候須要作數據的全量同步,redis server就要從內存dump出新的RDB文件,而後從master傳到slave,有兩種方式把RDB文件傳輸給客戶端:
一、基於硬盤(disk-backed):master建立一個新進程dump RDB,RDB完成以後由父進程(即主進程)傳給slaves。
二、基於socket(diskless):master建立一個新進程直接dump RDB到slave的socket,不通過主進程,不通過硬盤。
基於硬盤的話,RDB文件建立後,一旦建立完畢,能夠同時服務更多的slave,可是基於socket的話, 新slave鏈接到master以後得逐個同步數據。
在較慢而且網絡較快的時候,能夠用diskless(yes),不然使用磁盤(no)

repl-diskless-sync-delay 30 #diskless**複製的延遲時間**,設置0爲關閉,在延遲時間內鏈接的新客戶端,會一塊兒經過disk方式同步數據,可是一旦複製開始尚未結束以前,master節點不會再接收新slave的複製請求,直到下一次同步開始。

repl-ping-slave-period 10 #slave根據master指定的時間進行週期性的PING 監測

repl-timeout 60 #複製鏈接的超時時間,須要大於repl-ping-slave-period,不然會常常報超時

repl-disable-tcp-nodelay no #在socket模式下是否在slave套接字發送SYNC以後禁用 TCP_NODELAY,若是選擇「yesRedis將使用更少的TCP包和帶寬來向slaves發送數據,可是這將使數據傳輸到slave上有延遲,Linux內核的默認配置會達到40毫秒,若是你選擇了 "no"** 數據傳輸到salve**的延遲將會減小但要使用更多的帶寬。

repl-backlog-size 512mb #複製緩衝區內存大小,只有在slave鏈接以後才分配內存。

repl-backlog-ttl 3600 #屢次時間master沒有slave鏈接,就清空backlog緩衝區。

replica-priority 100 #當master不可用,Sentinel會根據slave的優先級選舉一個master,最低的優先級的slave,當選master,而配置成0,永遠不會被選舉。

requirepass foobared #設置redis 鏈接密碼

rename-command #重命名一些高危命令

maxclients 10000 #Redis最大鏈接客戶端

maxmemory #最大內存,單位爲bytes字節,8G內存的計算方式8(G)1024(MB)1024(KB)*1024(Kbyte),須要注意的是slave的輸出緩衝區是不計算在maxmemory內。

appendonly no #是否開啓AOF日誌記錄,默認redis使用的是rdb方式持久化,這種方式在許多應用中已經足夠用了,可是redis若是中途宕機,會致使可能有幾分鐘的數據丟失(取決於dumpd數據的間隔時間),根據save來策略進行持久化,Append Only File是另外一種持久化方式,能夠提供更好的持久化特性,Redis會把每次寫入的數據在接收後都寫入 appendonly.aof 文件,每次啓動時Redis都會先把這個文件的數據讀入內存裏,先忽略RDB文件。

appendfilename "appendonly.aof" #AOF文件名

appendfsync everysec #aof持久化策略的配置,no表示不執行fsync,由操做系統保證數據同步到磁盤,always表示每次寫入都執行fsync,以保證數據同步到磁盤,everysec表示每秒執行一次fsync,可能會致使丟失這1s數據。

no-appendfsync-on-rewrite no在aof rewrite期間,是否對aof新記錄的append暫緩使用文件同步策略,主要考慮磁盤IO開支和請求阻塞時間。默認爲no,表示"不暫緩",新的aof記錄仍然會被當即同步,Linux的默認fsync策略是30秒,若是爲yes 可能丟失30秒數據,但因爲yes性能較好並且會避免出現阻塞所以比較推薦。

auto-aof-rewrite-percentage 100 # 當Aof log增加超過指定百分比例時,重寫AOF文件, 設置爲0表示不自動重寫Aof 日誌,重寫是爲了使aof體積保持最小,可是還能夠確保保存最完整的數據,

auto-aof-rewrite-min-size 64mb #觸發aof rewrite的最小文件大小

aof-load-truncated yes #是否加載因爲其餘緣由致使的末尾異常的AOF文件(主進程被kill/斷電等)

aof-use-rdb-preamble no #redis4.0新增RDB-AOF混合持久化格式,在開啓了這個功能以後,AOF重寫產生的文件將同時包含RDB格式的內容和AOF格式的內容,其中RDB格式的內容用於記錄已有的數據,而AOF格式的內存則用於記錄最近發生了變化的數據,這樣Redis就能夠同時兼有RDB持久化和AOF持久化的優勢(既可以快速地生成重寫文件,也可以在出現問題時,快速地載入數據)。

lua-time-limit 5000 #lua腳本的最大執行時間,單位爲毫秒

cluster-enabled yes #是否開啓集羣模式,默認是單機模式

cluster-config-file nodes-6379.conf #由node節點自動生成的集羣配置文件

cluster-node-timeout 15000 #集羣中node節點鏈接超時時間

cluster-replica-validity-factor 10 #在執行故障轉移的時候可能有些節點和master斷開一段時間數據比較舊,這些節點就不適用於選舉爲master,超過這個時間的就不會被進行故障轉移

cluster-migration-barrier 1 #集羣遷移屏障,一個主節點擁有的至少正常工做的從節點,即若是主節點的slave節點故障後會將多餘的從節點分配到當前主節點成爲其新的從節點。

cluster-require-full-coverage no #集羣請求槽位所有覆蓋,若是一個主庫宕機且沒有備庫就會出現集羣槽位不全,那麼yes狀況下redis集羣槽位驗證不全就再也不對外提供服務,而no則能夠繼續使用可是會出現查詢數據查不到的狀況(由於有數據丟失)。

#Slow log 是 Redis 用來記錄查詢執行時間的日誌系統,slow log 保存在內存裏面,讀寫速度很是快,所以你能夠放心地使用它,沒必要擔憂由於開啓 slow log 而損害 Redis 的速度。

slowlog-log-slower-than 10000 #以微秒爲單位的慢日誌記錄,爲負數會禁用慢日誌,爲0會記錄每一個命令操做。

slowlog-max-len 128 #記錄多少條慢日誌保存在隊列,超出後會刪除最先的,以此滾動刪除

127.0.0.1:6379> slowlog len
(integer) 14
127.0.0.1:6379> slowlog get
1) 1) (integer) 14
2) (integer) 1544690617
3) (integer) 4
4) 1) "slowlog"
127.0.0.1:6379> SLOWLOG reset
OK

CONFIG動態修改配置

config命令用於查看當前redis配置、以及不重啓redis服務實現動態更改redis配置等

注意:不是全部配置均可以動態修改,且此方式沒法持久保存

CONFIG SET parameter value
時間複雜度:o(1)
CONFIG SET命令能夠動態地調整Redis 服務器的配置(configuration)而無須重啓。

你能夠使用它修改配置參數,或者改變 Redis 的持久化(Persistence)方式。
CONFIG SET能夠修改的配置參數能夠使用命令CONFIG GET*來列出,全部被CONFIG SET修改的配置參數都會當即生效。

CONFIG GET parameter
時間複雜度:o(N),其中 N爲命令返回的配置選項數量。
CONFIG GET命令用於取得運行中的 Redis 服務器的配置參數(configuration parameters),在Redis 2.4版本中,有部分參數沒有辦法用CONFIG GET訪問,可是在最新的 Redis 2.6 版本中,全部配置參數都已經能夠用CONFIG GET訪問了。

CONFTG GET接受單個參數 parameter做爲搜索關鍵字,查找全部匹配的配置參數,其中參數和值以「鍵-值對」(key-value pairs)的方式排列。

好比執行CONFIG GET s*命令,服務器就會返回全部以s開頭的配置參數及參數的值:

設置鏈接密碼

#設置鏈接密碼
127.0.0.1:6379>CONFIG SET requirepass 123456
oK
#查看鏈接密碼
127.0.0.1:6379>CONFIG GET requirepass
1) "requirepass"
2) "123456"

獲取當前配置

#奇數行爲鍵,偶數行爲值
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> CONFIG GET *
  1) "rdbchecksum"
  2) "yes"
  3) "daemonize"
  4) "no"
  5) "io-threads-do-reads"
  6) "no"
  7) "lua-replicate-commands"
  8) "yes"
  9) "always-show-logo"
 10) "no"
 11) "protected-mode"
 12) "yes"
 13) "rdbcompression"
 14) "yes"
 15) "rdb-del-sync-files"
 16) "no"
 17) "activerehashing"
 18) "yes"

#查看bind
127.0.0.1:6379>CONFIG GET bind
1) "bind"
2) "0.0.0.o"
#有些設置沒法修改
127.0.0.1:6379>CONFIG SET bind 127.0.0.1
(error)ERR Unsupported CONFIG parameter: bind

更改最大內存

[root@C8-33 ~]# echo 2^20*512|bc #512M
536870912

maxmemory 536870912

127.0.0.1:6379>CONFIG SET maxmemory 8589934592
oK
127.0.0.1:6379> CONFIG GET maxmemory
1)"maxmemory"
2) "8589934592"

redis密碼的設置

#永久修改,改配置文件
vim  /etc/redis.conf 
requirepass 123456

[root@C8-33 ~]# systemctl restart redis
[root@C8-33 ~]# redis-cli 
127.0.0.1:6379> info
NOAUTH Authentication required.
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> 

#查看本機的info
[root@C8-33 ~]# redis-cli -a 123456 info

config動態修改配置

臨時修改的沒法永久保存

127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "536870912"

 #查看是否開啓了集羣
127.0.0.1:6379> CONFIG GET cluster_enabled 
(empty list or set)

#查看修改密碼
127.0.0.1:6379> CONFIG GET requirepass
1) "requirepass"
2) "123456"

#修改內存
127.0.0.1:6379> CONFIG set maxmemory 209715200
OK
127.0.0.1:6379> 

#創建一個rdb後綴文件
127.0.0.1:6379> config  set  dir /tmp/
OK
127.0.0.1:6379> save
OK
#查看裏面的內容
[root@C8-33 ~]# ll /tmp -t
total 4
-rw-r--r-- 1 redis redis 1593 Aug  5 08:43 dump.rdb

127.0.0.1:6379> config  get bind
1) "bind"
2) "0.0.0.0"
127.0.0.1:6379> config  get port
1) "port"
2) "6379"

慢查詢

redis慢查詢以微秒爲單位 mysql的慢查詢是默認10秒

redis
14.jpg

兩點說明:
(1)慢查詢發生在第3階段

(2〉客戶端超時不必定慢查詢,但慢查詢是客戶端超時的一個可能因素

和不少關係型數據庫(例如:MySQL)同樣, Redis 也提供了慢查詢日誌記錄,Redis 會把命令執行時間超過 slowlog-log-slower-than 的都記錄在 Reids 內部的一個列表(list)中,該列表的長度最大爲 slowlog-max-len 。須要注意的是,慢查詢記錄的只是命令的執行時間,不包括網絡傳輸和排隊時間:

Redis 慢查詢的配置有兩個,分別是 slowlog-log-slower-than 和 slowlog-max-len。
1.slowlog-log-slower-than,用來控制慢查詢的閾值,全部執行時間超過該值的命令都會被記錄下來。該值的單位爲微秒,默認值爲 10000,若是設置爲 0,那麼全部的記錄都會被記錄下來,若是設置爲小於 0 的值,那麼對於任何命令都不會記錄,即關閉了慢查詢。能夠經過在配置文件中設置,或者用 config set 命令來設置:

config set slowlog-log-slower-than 10000 #超過10000微秒就算慢查詢

2.slowlog-max-len,用來設置存儲慢查詢記錄列表的大小,默認值爲 128,當該列表滿了時,若是有新的記錄進來,那麼 Redis 會把隊最舊的記錄清理掉,而後存儲新的記錄。在生產環境咱們能夠適當調大,好比調成 1000,這樣就能夠緩衝更多的記錄,方便故障的排查。配置方法和 slowlog-log-slower-than 相似,能夠在配置文件中指定,也能夠在命令行執行 config set 來設置:

config set slowlog-max-len 1000 #記錄的慢查詢的條數

查看慢查詢日誌

儘管 Redis 把慢查詢日誌記錄到了內部的列表,但咱們不能直接操做該列表,Redis 專門提供了一組命令來查詢慢查詢日誌:

  1. 獲取慢查詢日誌:
    slowlog get [n]

    1000微秒-1毫秒

    1000毫秒=1秒

[root@C8-33 ~]# vim /etc/redis.conf   微秒
# The following time is expressed in microseconds, so 1000000 is equivalent
# to one second. Note that a negative number disables the slow log, while
# a value of zero forces the logging of every command.
slowlog-log-slower-than 10000 #微秒爲單位,即超過10000微秒就算慢查詢

127.0.0.1:6379> slowlog get   #查看有哪些慢的操做
 1) 1) (integer) 456
    2) (integer) 1531632044
    3) (integer) 3
    4) 1) "get"
       2) "m"
    5) "127.0.0.1:50106"
    6) ""
 2) 1) (integer) 455
    2) (integer) 1531632037
    3) (integer) 14
    4) 1) "keys"
       2) "*"
    5) "127.0.0.1:50106"
    6) ""

結果說明:
1) 慢查詢記錄 id;
2) 發起命令的時間戳;
3) 命令耗時,單位爲微秒;
4) 該條記錄的命令及參數;
5) 客戶端網絡套接字(ip: port);
6) 「」
.獲取當前慢查詢日誌記錄數
slowlog len
127.0.0.1:6379> slowlog len
(integer) 458
.慢查詢日誌重置
slowlog reset
其實是對慢查詢列表作清理操做:
127.0.0.1:6379> slowlog len  #查看慢查詢的記錄數
(integer) 461
127.0.0.1:6379> slowlog reset #清空慢查詢
OK
127.0.0.1:6379> slowlog len
(integer) 1

持久化 RDB和AOF

 RDB是Redis用來進行持久化的一種方式,是把當前內存中的數據集快照寫入磁盤,也就是 Snapshot 快照(數據庫中全部鍵值對數據)。恢復時是將快照文件直接讀到內存裏。RDB其實就是把數據以快照的形式保存在磁盤上。RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤。也是默認的持久化方式,這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdb

RDB 有兩種觸發方式,分別是自動觸發和手動觸發

RDB

①、自動觸發

redis
17.jpg

save 900 1:表示900 秒內若是至少有 1 個 key 的值變化,則保存
save 300 10:表示300 秒內若是至少有 10 個 key 的值變化,則保存
save 60 10000:表示60 秒內若是至少有 10000 個 key 的值變化,則保存

①、save:這裏是用來配置觸發 Redis的 RDB 持久化條件,也就是何時將內存中的數據保存到硬盤。好比「save m n」。表示m秒內數據集存在n次修改時,自動觸發bgsave

  固然若是你只是用Redis的緩存功能,不須要持久化,那麼你能夠註釋掉全部的 save 行來停用保存功能。能夠直接一個空字符串來實現停用:save ""

  ②、stop-writes-on-bgsave-error :默認值爲yes。當啓用了RDB且最後一次後臺保存數據失敗,Redis是否中止接收數據。這會讓用戶意識到數據沒有正確持久化到磁盤上,不然沒有人會注意到災難(disaster)發生了。若是Redis重啓了,那麼又能夠從新開始接收數據了

  ③、rdbcompression ;默認值是yes。對於存儲到磁盤中的快照,能夠設置是否進行壓縮存儲。若是是的話,redis會採用LZF算法進行壓縮。若是你不想消耗CPU來進行壓縮的話,能夠設置爲關閉此功能,可是存儲在磁盤上的快照會比較大。

  ④、rdbchecksum :默認值是yes。在存儲快照後,咱們還可讓redis使用CRC64算法來進行數據校驗,可是這樣作會增長大約10%的性能消耗,若是但願獲取到最大的性能提高,能夠關閉此功能。

  ⑤、dbfilename :設置快照的文件名,默認是 dump.rdb

  ⑥、dir:設置快照文件的存放路徑,這個配置項必定是個目錄,而不能是文件名。默認是和當前配置文件保存在同一目錄。

  也就是說經過在配置文件中配置的 save 方式,當實際操做知足該配置形式時就會進行 RDB 持久化,將當前的內存快照保存在 dir 配置的目錄中,文件名由配置的 dbfilename 決定。

②、手動觸發

  手動觸發Redis進行RDB持久化的命令有兩種:

  一、save

  該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其餘命令,直到RDB過程完成爲止。

redis
16.jpg
  

redis
20.png
顯然該命令對於內存比較大的實例會形成長時間阻塞,這是致命的缺陷,爲了解決此問題,Redis提供了bgsave方式

redis
18.jpg
二、bgsave 異步後臺執行

redis
19.png

執行該命令時,Redis會在後臺異步進行快照操做,快照同時還能夠響應客戶端請求。具體操做是Redis進程執行fork操做建立子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段,通常時間很短。

  基本上 Redis 內部全部的RDB操做都是採用 bgsave 命令。

  執行執行 flushall 命令,也會產生dump.rdb文件,但裏面是空的.

rdb相關配置

save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir  ./     #編澤編譯安裝,默認RDB文件存放在啓動redis的工做目錄,建議明確指定存入目錄
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes

手動保存

[root@C8-24 ~]# vim /apps/redis/etc/redis.conf 

save ""           #將此項設置爲空
 #save 3600 1     #關閉
 #save 300 100    #關閉
 #save 60 10000   #關閉

dbfilename dump_6379.rdb      #保存文件的名字

 dir /data/redis             #路徑

實現RDB方式

save:同步,會阻賽其它命令,不推薦使用

bgsave:異步後臺執行,不影響其它命令的執行

自動:制定規則,自動執行

RDB模式優勢

RDB快照保存了某個時間點的數據,能夠經過腳本執行redis指令bgsave(非阻塞,後臺執行)或者save(會阻塞寫操做,不推薦)命令自定義時間點備份,能夠保留多個備份,當出現問題能夠恢復到不一樣時間點的版本,很適合備份,而且此文件格式也支持有很多第三方工具能夠進行後續的數據分析

好比:能夠在最近的24小時內,每小時備份一次RDB文件,而且在每月的每一天,也備份一個ROB文件。這樣的話,即便趕上問題,也能夠隨時將數據集還原到不一樣的版本。

RDB能夠最大化Redis的性能,父進程在保存RDB文件時惟一要作的就是fork出一個子進程,而後這個子進程就會處理接下來的全部保存工做,父進程無須執行任何磁盤 I/O操做。

RDB在大量數據,好比幾個G的數據,恢復的速度比AOF的快

RDB模式缺點

不能實時保存數據,可能會丟失自上一次執行RDB備份到當前的內存數據

若是你須要儘可能避免在服務器故障時丟失數據,那麼RDB不適合你。雖然Redis容許你設置不一樣的保存點(save point)來控制保存RDB文件的頻率,可是,由於ROB文件須要保存整個數據集的狀態,因此它並非一個輕鬆的操做。所以你可能會至少5分鐘才保存一次RDB文件。在這種狀況下,一旦發生故障停機,你就可能會丟失好幾分鐘的數據。

當數據量很是大的時候,從父進程fork子進程進行保存至RDB文件時須要一點時間,多是毫秒或者秒,取決於磁盤IO性能

在數據集比較龐大時,fork()可能會很是耗時,形成服務器在必定時間內中止處理客戶端﹔若是數據集很是巨大,而且CPU時間很是緊張的話,那麼這種中止時間甚至可能會長達整整一秒或更久。雖然AOF重寫也須要進行fork(),但不管AOF重寫的執行間隔有多長,數據的持久性都不會有任何損失。

RDB每次在fork子進程來執行RDB快照數據文件生成的時候,若是數據文件特別大,可能會致使對客戶端提供的服務暫停數毫秒,或者甚至數秒;

通常不要讓RDB的間隔太長,不然每次生成的RDB文件太大了,對Redis自己的性能可能會有影響的;

RDB沒法實現實時或者秒級持久化

RDB是間隔一段時間進行持久化,若是持久化之間Redis發生故障,會發生數據丟失。

[root@C8-24 ~]# mkdir /data/redis -p
[root@C8-24 ~]# chown redis.redis /data/redis/

yum  -y install  python3  python3-redis
[root@C8-58]#cat redis_test.py 
#!/bin/env python3
import redis
pool = redis.ConnectionPool(host="127.0.0.1",port="6379",password="")
r = redis.Redis(connection_pool=pool)
for i in range(5000000):
    r.set("k%d" % i,"v%d" % i)
    data=r.get("k%d" % i)
    print(data)

手動備份RDB文件腳本(一)

[root@C8-24 ~]# cat redis_rdb.sh 
#!/bin/bash
redis-cli -h 127.0.0.1 save &> /dev/null
DATE=`date +%F-%T`
[ -e /backup/redis-rdb ] || mkdir -p /backup/redis-rdb/
mv /data/redis/dump_6379.rdb   /backup/redis-rdb/dump_6379-${DATE}.rdb

[root@C8-24 ~]# ll /backup/redis-rdb/dump_6379-2021-08-05-22\:34\:44.rdb 
-rw-r--r-- 1 redis redis 59742638 Aug  5 22:34 /backup/redis-rdb/dump_6379-2021-08-05-22:34:44.rdb

手動備份RDB文件腳本(二)

[root@C8-24 ~]# cat  redis_rdb.2.sh 
#!/bin/bash
#Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37)
#Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47)
#******************************************************************************
. /etc/init.d/functions
BACKUP=/backup/redis-rdb
DIR=/data/redis
FILE=dump_6379.rdb
redis-cli -h 127.0.0.1 --no-auth-warning bgsave
result=`redis-cli --no-auth-warning info Persistence |grep rdb_bgsave_in_progress |sed -nr 's/.*:([0-9]+).*/\1/p'`  #結果爲0就備份完畢了,備份完畢就要更名字了
until [ $result -eq 0 ];do
    sleep 1
    result=`redis-cli --no-auth-warning info Persistence |grep rdb_bgsave_in_progress |sed -nr 's/.*:([0-9]+).*/\1/p'`
done
DATE=`date +%F-%T`
[ -e $BACKUP ] ||{ mkdir -p $BACKUP ;chown -R redis:redis $BACKUP; }
mv $DIR/$FILE   $BACKUP/dump_6379-${DATE}.rdb
action "BACK redis RDB"

#執行
[root@C8-24 ~]# bash redis_rdb.2.sh 
Background saving started
BACK redis RDB                                             [  OK  ]

AOF 模式

優先級高於rdb

redis
22.png

AOF rewrite重寫

將一些重複的能夠合併的,過時的數據從新寫入一個新的AOF文件,從而節約AOF備份佔用的硬盤空間,也能加速恢復過程

能夠手動執行bgrewriteaof觸發AOF,或定義自動rewrite策略

AOF rewrite過程

redis

23.png

#開啓aof的配置文件

[root@C8-24 ~]# vim /apps/redis/etc/redis.conf   
appendonly yes       #改成yes                                                                                 appendfilename  "appendonly.aof"

#或者:
[root@centos8 ~]#redis-cli
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
oK

手動執行AOF重寫BGREWRITEAOF命令

BGREWRITEAOF
時間複雜度:o(N),N爲要追加到AOF文件中的數據數量。
執行一個AOF文件重寫操做。重寫會建立一個當前AOF文件的體積優化版本。

即便BGREWRITEAOF 執行失敗,也不會有任何數據丟失,由於舊的 AOF 文件在BGREWRITEAOF成功以前不會被修改。

重寫操做只會在沒有其餘持久化工做在後臺執行時被觸發,也就是說:
若是 Redis 的子進程正在執行快照的保存工做,那麼、AOF重寫的操做會被預約(scheduled),等到保存工做完成以後再執行AOF重寫。在這種狀況下,BGREWRITEAOF的返回值仍然是 OK,但還會加上一條額外的信息,說明BGREWRITEAOF 要等到保存操做完成以後才能執行。在 Redis 2.6或以上的版本,能夠使用工NFO [section]命令查看 BGREWR工TEAOF 是否被預約。

若是已經有別的 AOF文件重寫在執行,那麼BGREWRITEAOF返回一個錯誤,而且這個新的BGREWRITEAOF 請求也不會被預約到下次執行。

從 Redis 2.4開始,AOF重寫由 Redis自行觸發,BGREWRITEAOF僅僅用於手動觸發重寫操做。

AOF的優勢

數據安全性相對較高,根據所使用的fsync策略(fsync是同步內存中redis全部已經修改的文件到存儲設備),默認是appendfsync everysec,即每秒執行一次fsync,在這種配置下,Redis仍然能夠保持良好的性能,而且就算髮生故障停機,也最多隻會丟失一秒鐘的數據( fsync會在後臺線程執行,因此主線程能夠繼續努力地處理命令請求)

因爲該機制對日誌文件的寫入操做採用的是append模式,所以在寫入過程當中不須要seek,即便出現宕機現象,也不會破壞日誌文件中已經存在的內容。然而若是本次操做只是寫入了一半數據就出現了系統崩潰問題,不用擔憂,在Redis下一次啓動以前,能夠經過redis-check-aof 工具來解決數據一致性的問題

Redis能夠在AOF文件體積變得過大時,自動地在後臺對AOF進行重寫,重寫後的新AOF文件包含了恢復當前數據集所需的最小命令集合。整個重寫操做是絕對安全的,由於Redis在建立新AOF文件的過程當中,append模式不斷的將修改數據追加到現有的AOF文件裏面,即便重寫過程當中發生停機,現有的AOF文件也不會丟失。而一旦新AOF文件建立完畢,Redis就會從舊AOF文件切換到新AOF文件,並開始對新AOF文件進行追加操做。

AOF包含一個格式清晰、易於理解的日誌文件用於記錄全部的修改操做。事實上,也能夠經過該文件完成數據的重建

AOF文件有序地保存了對數據庫執行的全部寫入操做,這些寫入操做以Redis協議的格式保存,所以AOF文件的內容很是容易被人讀懂,對文件進行分析(parse)也很輕鬆。導出 (export)AOF文件也很是簡單:舉個例子,若是你不當心執行了FLUSHALL.命令,但只要AOF文件未被重寫,那麼只要中止服務器,移除AOF文件末尾的FLUSHAL命令,並重啓Redis ,就能夠將數據集恢復到FLUSHALL執行以前的狀態。

AOF缺點

即便有些操做是重複的也會所有記錄,AOF的文件大小要大於RDB格式的文件
AOF在恢復大數據集時的速度比RDB的恢復速度要慢
根據fsync策略不一樣,AOF速度可能會慢於RDB
bug 出現的可能性更多

RDB和AOF 的選擇

  • 若是主要充當緩存功能,或者能夠承受數分鐘數據的丟失, 一般生產環境通常只需啓用RDB可,此也是默認值

  • 若是數據須要持久保存,一點不能丟失,能夠選擇同時開啓RDB和AOF,通常不建議只開啓AOF

注意!!!: AOF 模式默認是關閉的,第一次開啓AOF後,並重啓服務生效後,會由於AOF的優先級高於RDB,而AOF默認沒有文件存在,從而致使全部數據丟失

[root@C8-24 ~]# vim /apps/redis/etc/redis.conf   同時開啓:
appendonly yes                                                                                                appendfilename "appendonly.aof"

dbfilename dump_6379.rdb
dir /data/redis  

[root@C8-24 ~]# ll /data/redis/
total 90604
-rw-r--r-- 1 redis redis        0 Aug  6 06:42 appendonly.aof
-rw-r--r-- 1 root  root  92777881 Aug  6 06:45 dump_6379.rdb
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> set a haha
OK
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> 
[root@C8-24 ~]# ll /data/redis/
total 8
-rw-r--r-- 1 redis redis  53 Aug  6 06:49 appendonly.aof
-rw-r--r-- 1 redis redis 105 Aug  6 06:50 dump_6379.rdb   #數據丟失了

[root@C8-24 ~]# cp  /backup/redis-rdb/dump_6379-2021-08-06-06\:38\:19.rdb /data/redis/dump_6379.rdb
cp: overwrite '/data/redis/dump_6379.rdb'? y
[root@C8-24 ~]# ll /data/redis/
total 90608
-rw-r--r-- 1 redis redis       53 Aug  6 06:49 appendonly.aof
-rw-r--r-- 1 redis redis 92777881 Aug  6 06:54 dump_6379.rdb
[root@C8-24 ~]# 

#正確的啓用方法:用命令啓用,而不是直接在配置文件修改
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
OK
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"

以後再去改配置文件
appendonly yes  #改成yes

刪除數據之後恢復

#刪除數據之後恢復:
127.0.0.1:6379> get java
"verygood"
127.0.0.1:6379> del java
(integer) 1
127.0.0.1:6379> get java
(nil)

#編輯此項將verygood^M後面的內容所有刪除
vim /data/redis/appendonly.aof
verygood^M  
*2^M
$6^M
SELECT^M
$1^M
 0^M
 *2^M
 $3^M
 del^M
 $4^M
 java^M

 [root@C8-24 ~]# systemctl start redis #重啓服務數據恢復
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> get java
"verygood"

127.0.0.1:6379> DBSIZE  #查看大小
(integer) 5000004
127.0.0.1:6379> FLUSHALL #刪庫
OK
(3.37s)
127.0.0.1:6379> DBSIZE
(integer) 0

bgrewriteaof

[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> DBSIZE
(integer) 5000000
127.0.0.1:6379> FLUSHALL
OK
(5.04s)
127.0.0.1:6379> DBSIZE
(integer) 0
127.0.0.1:6379>  
[root@C8-24 ~]# ll /data/redis/
total 181208
-rw-r--r-- 1 redis redis 92777922 Aug  6 10:01 appendonly.aof
-rw-r--r-- 1 redis redis 92777881 Aug  6 09:51 dump_6379.rdb
[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> BGREWRITEAOF   #清理磁盤
Background append only file rewriting started
127.0.0.1:6379> 
[root@C8-24 ~]# ll /data/redis/
total 90608
-rw-r--r-- 1 redis redis       92 Aug  6 10:02 appendonly.aof
-rw-r--r-- 1 redis redis 92777881 Aug  6 09:51 dump_6379.rdb
[root@C8-24 ~]#
bind o.0.0.0 #監聽地址,能夠用空格隔開後多個監聽IP
protected-mode yes #redis3.2以後加入的新特性,在沒有設置bind IP和密碼的時候, redis只容許訪問127.0.0.1:6379,能夠遠程鏈接,但當訪問將提示警告信息並拒絕遠程訪問
port 6379 #監聽端口,默認6379/tcp
tcp-backlog 511 #三次握手的時候server端收到client ack確認號以後的隊列值,即全鏈接隊列長度
timeout 0#客戶端和Redis服務端的鏈接超時時間,默認是0,表示永不超時
tcp-keepalive 300 #tcp會話保持時間300s
daemonize no #默認no,即直接運行redis-server程序時,不做爲守護進程運行,而是之前臺方式運行,若是想在後臺運行需改爲yes,當redis做爲守護進程運行的時候,它會寫一個pid到
/var/ run /redis.pid 文件
supervised no #和os相關參數,可設置經過upstart和systemd管理Redis守護進程,centos7後都使用systemd
pidfile /var/run/redis_6379.pid #pid文件路徑,能夠修改成/apps/redi s/run/ redis_6379.pid
logleve1 notice #日誌級別
logfile "/path/redis.log」#日誌路徑,示例:1ogfile " /apps/redis/log/redis_6379.log"
databases 16 #設置數據庫數量,默認:0-15,共16個庫
a1way s-show-7ogo yes #在啓動redis 時是否顯示或在日誌中記錄記錄redis的1ogo
save 900 1 #在900秒內有1個key內容發生更改,就執行快照機制
save 300 10 #在:300秒內有10個key內容發生更改,就執行快照機制
save 60 10000#60秒內若是有10000個key以上的變化,就自動快照備份
stop-writes-on-bgsave-error yes #默認爲yes時,可能會因空間滿等緣由快照沒法保存出錯時,會禁止redi s寫入操做,生產建議爲no
#此項只針對配置文件中的自動s ave有效

rdbcompression yes #持久化到RDB文件時,是否壓縮,"yes"爲壓縮,"no"則反之
rdbchecksum yes #是否對備份文件開啓RC64校驗,默認是開啓
dbfilename dump . rdb #快照文件名
dir ./#快照文件保存路徑,示例: dir " / apps/redis/data"
#主從複製相關
# replicaof <masterip> <masterport>#指定複製的master主機地址和端口,5.0版以前的指令爲s1aveof
# masterauth <master-password>#指定複製的master主機的密碼
replica-serve-stale-data yes #當從庫同主庫失去鏈接或者複製正在進行,從機庫有兩種運行方式:一、設置爲yes(默認設置),從庫會繼續響應客戶端的讀請求,此爲建議值
二、設置爲no,除去特定命令外的任何請求都會返回一個錯誤"sYc with master in progress"。
rep7ica-read-only yes #是否設置從庫只讀,建議值爲yes,不然主庫同步從庫時可能會覆蓋數據,形成數據丟失

rep7-diskless-sync no #是否使用socket方式複製數據(無盤同步),新s7ave第一次鏈接master時須要作數據的全量同步,redis server就要從內存dump出新的RDB文件,而後從master傳到s7ave,有兩種方式把RDB文件傳輸給客戶端:
一、基於硬盤(disk-backed):爲no時,master建立一個新進程dump生成RDB磁盤文件,RDB完成以後由父進程(即主進程)將RDB文件發送給s1aves,此爲默認值
二、基於socket(diskless) : master建立一個新進程直接dump RDB至slave的網絡socket,不通過主進程和硬盤
#推薦使用基於硬盤(爲no),是由於RDB文件建立後,能夠同時傳輸給更多的s1ave,可是基於socket(爲yes),新s1ave鏈接到master以後得逐個同步數據。只有當磁盤I/o較慢且網絡較快時,可用
diskless(yes),不然通常建議使用磁盤(no)
rep7-diskless-sync-delay 5 #diskless時複製的服務器等待的延遲時間,設置0爲關閉,在延遲時間內到達的客戶端,會一塊兒經過diskless方式同步數據,可是一旦複製開始,master節點不會再接收新slave的複製請求,直到下一次同步開始纔再接收新請求。即沒法爲延遲時間後到達的新副本提供服務,新副本將排隊等待下一次RDB傳輸,所以服務器會等待一段時間才能讓更多副本到達。推薦值:30-60
rep7-ping-replica-period 10 #s7ave根據master指定的時間進行週期性的PING master,用於監測master狀態,默認10s
rep7-timeout 60#複製鏈接的超時時間,須要大於rep7-ping-slave-period,不然會常常報超時
rep7-disable-tcp-nodelay no #是否在slave套接字發送SYNC以後禁用TCP_NODELAY,若是選擇"yes",Redis將合併多個報文爲一個大的報文,從而使用更少數量的包向s1aves發送數據,可是將使數據傳輸到slave上有延遲,Linux內核的默認配置會達到40毫秒,若是「no」,數據傳輸到slave的延遲將會減小,但要使用更多的帶寬
rep7-backlog-size 512mb #複製緩衝區內存大小,當s1ave斷開鏈接一段時間後,該緩衝區會累積複製副本數據,所以當slave從新鏈接時,一般不須要徹底從新同步,只需傳遞在副本中的斷開鏈接後沒有同步的部分數據便可。只有在至少有一個slave鏈接以後才分配此內存空間,建議創建主從時此值要調大一些或在低峯期配置,不然會致使同步到s1ave失敗
rep7-back7og-tt1 3600 #多長時間內master沒有s1ave鏈接,就清空backlog緩衝區

rep7ica-priority 100 #當master不可用,哨兵sentine1會根據slave的優先級選舉一個master,此值最低的slave會優先當選master,而配置成0,永遠不會被選舉,通常多個slave都設爲同樣的值,讓其自動選擇

Redis經常使用命令

官方文檔:https://redis.io/commands

參考連接: http://redisdoc.com/

set

#設置有效期:
127.0.0.1:6379> set hongbaos 100 EX 10
OK
127.0.0.1:6379> ttl hongbaos
(integer) 6
127.0.0.1:6379> ttl hongbaos
(integer) 3
127.0.0.1:6379> ttl hongbaos
(integer) 1
127.0.0.1:6379> ttl hongbaos
(integer) 1
127.0.0.1:6379> ttl hongbaos
(integer) -2
127.0.0.1:6379> ttl hongbaos
(integer) -2
127.0.0.1:6379> 

127.0.0.1:6379> set class python NX
(nil)
127.0.0.1:6379> set class2 python NX #class2 不存在就改
OK
127.0.0.1:6379> get class2
"python"
127.0.0.1:6379> get class
"linux"
127.0.0.1:6379> set class python XX  #class存在就改
OK
127.0.0.1:6379> get class
"python"

127.0.0.1:6379> mset city zhengzhou gender male
OK
127.0.0.1:6379> mget city gender
1) "zhengzhou"
2) "male"

127.0.0.1:6379> del city
(integer) 1
127.0.0.1:6379> mget city gender
1) (nil)
2) "male"

#追加內容
127.0.0.1:6379> set content wangyu
OK
127.0.0.1:6379> APPEND content "is very good"
(integer) 18  #追加的字節數
127.0.0.1:6379> get content
"wangyuis very good"

#設新值返回舊值
127.0.0.1:6379> get name
"linux"
127.0.0.1:6379> getset name wangge
"linux"
127.0.0.1:6379> get name
"wangge"

info

顯示當前節點redis運行狀態信息

[root@C8-24 ~]# redis-cli info cluster
# Cluster
cluster_enabled:0
[root@C8-24 ~]# redis-cli info cpu
# CPU
used_cpu_sys:1.069754
used_cpu_user:12.740768
used_cpu_sys_children:0.140771
used_cpu_user_children:3.620287
used_cpu_sys_main_thread:1.047010
used_cpu_user_main_thread:12.744783

select

切換數據庫,至關於在MySQL的USE DBNAME指令

[root@centos8 ~]#redis-cli
127.0.0.1:6379> info cluster
# cluster
cluster_enab1ed:0
127.0.0.1:6379[15]>SELECT ooK
127.0.0.1:6379>SELECT 1OK
127.0.0.1:6379[1]>SELECT 15OK
127.0.0.1:6379[15]>SELECT 16
(error) ERR DB index is out of range127.0.0.1:6379[15]>

注意:在redis cluster模式下不支持多個數據庫,會出現下面錯誤

[root@centos8 ~]#redis-cli
127.0.0.1:6379> info cluster
# cluster
cluster_enabled: 1
127.0.0.1:6379> select 0
oK
127.0.0.1:6379> select 1
(error) ERR SELECT is not a77owed in cluster mode

KEYS

查看當前庫下的全部key,此命令慎用!

127.0.0.1:6379[15]>SELECT 0
oK
127.0.0.1:6379> KEYS *
1) "9527"
2)"9526"
3) "paihangbang"
4)"7ist1"
127.0.0.1:6379>SELECT 1
oK
127.0.0.1:6379[1]>KEYS *
(empty list or set)
127.0.0.1:6379[1]>
redis>MSET one 1 two 2 three 3 four 4#一次設置4個 key
OK
redis> KEYS *o*
1) "four"
2) "two"
3) "one"
redis> KEYS t??
1) "two"
redis> KEYS t[w]*
1) "two"
redis> KEYS *   #匹配數據庫內全部key
1) "four"
2) "three"
3)''two''
4)''one''

bgsave

手動在後臺執行RDB持久化操做

#交互式執行
127.0.0.1:6379[1]>BGSAVE
Background saving started
#非交互式執行
[root@centos8 ~]#ll /var/lib/redis/
total 4
-rw-r--r-- 1 redis redis 326 Feb 18 22:45 dump .rdb
[root@centos8 ~]#redis-cli -h 127.0.0.1 -a '123456' BGSAVE
warning: using a password with '-a' or '-u’ option on the command line interfacemay not be safe.
Background saving started
[root@centos8 ~]#ll /var /lib/redis/
total 4
-rw-r--r-- 1 redis redis 92 Feb 18 22:54 dump.rdb

DBSIZE

返回當前庫下的全部key數量

127.0.0.1:6379> DBSIZE
(integer) 4
127.0.0.1:6379>SELECT  1
oK
127.0.0.1:6379[1]>DBSIZE
(integer) 0

FLUSHDB

強制清空當前庫中的全部key,此命令慎用!
127.0.0.1:6379[1]>SELECT 0
oK
127.0.0.1:6379> DBSIZE
(integer) 4
127.0.0.1:6379> FLUSHDB
oK
127.0.0.1:6379>DBSIZE
(integer) 0
127.0.0.1:6379>

FLUSHALL

強制清空當前redis服務器全部數據庫中的全部key,即刪除全部數據,此命令慎用!
127.0.0.1:6379>FLUSHALL
OK
#生產建議修改配置/etc/redis.confrename-command FLUSHALL ""

SHUTDOwN

可用版本:>= 1.0.0
時間複雜度:O(N),其中 N爲關機時須要保存的數據庫鍵數量。SHUTDOWN命令執行如下操做:
中止全部客戶端
若是有至少一個保存點在等待,執行SAVE命令
若是AOF選項被打開,更新AOF文件
關閉redis 服務器(server)
若是持久化被打開的話,SHUTDOWN命令會保證服務器正常關閉而不丟失任何數據。
另外一方面,假如只是單純地執行SAVE命令,而後再執行QUIT命令,則沒有這一保證--由於在執行SAVE以後、執行 QUIT以前的這段時間中間,其餘客戶端可能正在和服務器進行通信,這時若是執行QUIT就會形成數據丟失。

redis數據類型

參考資料: http://www.redis.cn/topics/data-types.html

相關命令參考: http://redisdoc.com/

字符串string

字符串是全部編程語言中最多見的和最經常使用的數據類型,並且也是redis最基本的數據類型之一,並且redis 中全部的key的類型都是字符串。經常使用於保存Session信息場景,此數據類型比較經常使用

添加一個key

set 指令能夠建立一個key並賦值,使用格式

SET key value [Ex seconds] [Px mi17iseconds] [NX |xX]時間複雜度:o(1)

將字符串值 value關聯到key 。
若是key 已經持有其餘值,SET就覆寫舊值,無視類型。
當SET命令對一個帶有生存時間(TTL)的鍵進行設置以後,該鍵原有的 TTL將被清除。
從Redis 2.6.12版本開始,SET命令的行爲能夠經過一系列參數來修改;
Ex seconds :將鍵的過時時間設置爲 seconds秒。執行 SET key value Ex seconds的效果等同於執行SETEx key seconds value .
Px milliseconds :將鍵的過時時間設置爲 mil7iseconds毫秒。執行 SET key value PXmi7liseconds 的效果等同於執行PSETEx key milliseconds value .
NX:只在鍵不存在時,纔對鍵進行設置操做。執行SET key value NX的效果等同於執行SETNXkey value .
XX:只在鍵已經存在時,纔對鍵進行設置操做。
#不論key是否存在.都設置
127.0.0.1:6379>set key1 value1
OK
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> TYPE key1 #判斷類型
string
127.0.0.1:6379> SET title ceo ex 3 #設置自動過時時間3s
oK
127.0.0.1:6379> set NAME wang
OK
127.0.0.1:6379> get NAME
'wang"

#大小寫敏感
127.0.0.1:6379> get name
(ni1)
127.0.0.1:6379>set name mage
oK
127.0.0.1:6379> get name
"mage"
127.0.0.1:6379> get NAME
'wang"

#key不存在,才設置,至關於add
127.0.0.1:6379> get title
"ceo"
127.0.0.1:6379> setnx title coo  #set key value nx
(integer) 0
127.0.0.1:6379>get title
"ceo"

#key存在,才設置,至關於update
127.0.0.1:6379>get title
"ceo"
127.0.0.1:6379> set title coo xx
oK
127.0.0.1:6379>get title
"coo"
127.0.0.1:6379> get age
(ni1)
127.0.0.1:6379> set age 20 xx
(ni1)
127.0.0.1:6379>get age
(ni1)

獲取一個key的內容

127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> get name age
(error) ERR wrong number of arguments for 'get' command

刪除一個和多個key

127.0.0.1:6379> DEL key1
(integer) 1
127.0.0.1:6379>DEL key1 key2
(integer) 2

批量設置多個key

127.0.0.1:6379>MSET key1 value1 key2 value2
oK

批量獲取多個key

127.0.0.1:6379> MGET key1 key2
1) "value1"
2) "value2"
127.0.0.1:6379>KEYS n*
1) "n1"
2) "name"
127.0.0.1:6379>KEYS*
1)"k2"
2)"k1"
3) "key1"
4)"key2"
5) "n1"
6) "name"
7) "k3"
8) "title"

追加數據

127.0.0.1:6379> APPEND key1 " append new value"
(integer) 12  #添加數據後,key1總共9個字
127.0.0.1:6379> get key1
"value1 append new value"

設置新值並返回舊值

#set key newvalue並返回舊的value
127.0.0.1:6379> set name wang
oK
127.0.0.1:6379> getset name magedu
"wang"
127.0.0.1:6379> get name
"magedu"

返回字符串對應的字節數

127.0.0.1:6379[1]> set name wang
OK
127.0.0.1:6379[1]> strlen name   #返回的字節數
(integer) 4
127.0.0.1:6379[1]> APPEND name wangyu
(integer) 10
127.0.0.1:6379[1]> GET name
"wangwangyu"
127.0.0.1:6379[1]> APPEND name "  yu"
(integer) 14

判斷key是否存在

127.0.0.1:6379>SET name wang ex 10
OK
127.0.0.1:6379> set age 20
oK
127.0.0.1:6379> EXISTS NAME #key的大小寫敏感
(integer) 0

127.0.0.1:6379>EXISTS name age #返回值爲1,表示存在2個key ,0表示不存在
(integer) 2
127.0.0.1:6379> EXISTS name#過幾秒再看
(integer) 0

查看key 的過時時間

tt1 key #查看key的剩餘生存時間,若是key過時後,會自動刪除

-1#返回值表示永不過時,默認建立的key是永不過時,從新對key賦值,也會從有剩餘生命週期變成永不過時
-2#返回值表示沒有此key
num #key的剩餘有效期
127.0.0.1:6379> TTL key1(integer)
-1
127.0.0.1:6379>SET name wang EX 100
OK
127.0.0.1:6379> TTL name
(integer) 96
127.0.0.1:6379> TTL name
(integer) 93
127.0.0.1:6379>SET name mage #從新設置,默認永不過時oK
127.0.0.1:6379> TTL name
(integer) -1
127.0.0.1:6379>SET name wang EX 200
OK
127.0.0.1:6379> TTL name
(integer) 198
127.0.0.1:6379>GET name
"wang"

從新設置key的過時時間

127.0.0.1:6379> TTL name
(integer)148
127.0.0.1:6379> EXPIRE name 1000
(integer) 1
127.0.0.1:6379>TTL name
(integer) 999
127.0.0.1:6379>

取消key的過時時間

#即永不過時
127.0.0.1:6379> TTL name
(integer) 999
127.0.0.1:6379> PERSIST name
(integer) 1
127.0.0.1:6379> TTL name
(integer) -1

數值遞增

利用INCR命令簇(INCR, DECR, INCRBY,DECRBY)來把字符串看成原子計數器使用。
127.0.0.1:6379> set num 10 #設置初始值
oK
127.0.0.1:6379> INCR num
(integer) 11
127.0.0.1:6379> get num
"11"

數值遞減

127.0.0.1:6379> set num 10
OK
127.0.0.1:6379>DECR num
(integer) 9
127.0.0.1:6379> get num
"9"

數值增長

將key對應的數字加decrement(能夠是負數)。若是key不存在,操做以前,key就會被置爲0。若是key的value類型錯誤或者是個不能表示成數字的字符串,就返回錯誤。這個操做最多支持64位有符號的正型數字。
redis> sET mykey 10
OK
redis> INCRBY mykey 5
(integer) 15
127.0.0.1:6379> get mykey
"15"
127.0.0.1:6379> INCRBY mykey -10
(integer) 5
127.0.0.1:6379> get mykey
"5"
127.0.0.1:6379> INCRBY nokey 5
(integer) 5
127.0.0.1:6379> get nokey
"5"

數據減小

decrby能夠減少數值(也能夠增長)
127.0.0.1:6379>SET mykey 10
oK
127.0.0.1:6379> DECRBY mykey 8
(integer) 2
127.0.0.1:6379> get mykey
"2"
127.0.0.1:6379> DECRBY mykey -20
(integer) 22
127.0.0.1:6379> get mykey
"22"
127.0.0.1:6379> DECRBY nokey 3
(integer) -3
127.0.0.1:6379> get nokey
"-3"

列表

列表是一個雙向可讀寫的管道,其頭部是左側,尾部是右側,一個列表最多能夠包含2^32-
1 (4294967295)個元素,下標0表示列表的第一個元素,以1表示列表的第二個元素,以此類推。也能夠使用負數下標,以-1表示列表的最後一個元素,-2表示列表的倒數第二個元素,元素值能夠重複,經常使用於存入日誌等場景,此數據類型比較經常使用
列表特色
有序·可重複
左右均可以操做

lpush 和rpush 均可以插入列表:

LPUSH key value [value ....時間複雜度:O(1)
將一個或多個值value插入到列表 key 的表頭
若是有多個value值,那麼各個value值按從左到右的順序依次插入到表頭:好比說,對空列表mylist 執行命令LPUSH mylist a b c ,列表的值將是 c b a ,這等同於原子性地執行LPUSHmy7ist a . LPUSH mylist b 和 LPUSH mylist c三個命令。
若是key不存在,一個空列表會被建立並執行LPUSH操做。
當key存在但不是列表類型時,返回一個錯誤。
RPUSH key value [value ...]
時間複雜度:o(1)
將一個或多個值 value插入到列表key 的表尾(最右邊)。
若是有多個value值,那麼各個value值按從左到右的順序依次插入到表尾:好比對一個空列表
my1ist 執行 RPUSH mylist a b c ,得出的結果列表爲 a b c ,等同於執行命令RPUSH mylista 、 RPUSH my1ist b 、RPUSH mylist c 。
若是key不存在,一個空列表會被建立並執行RPUSH操做。當key存在但不是列表類型時,返回一個錯誤。
#從左邊添加數據,已添加的需向右移
127.0.0.1:6379>LPUSH name mage wang zhang#根據順序逐個寫入name,最後的zhang會在列表的最左側。
(integer) 3
127.0.0.1:6379> TYPE name
list
#從右邊添加數據
127.0.0.1:6379>RPUSH course 1inux python go
(integer) 3
127.0.0.1:6379> type course
list

向列表追加數據

#向列表追加數據
127.0.0.1:6379> LPUSH list1 tom
(integer) 2
#從右邊添加數據,已添加的向左移
127.0.0.1:6379> RPUSH 1ist1 jack
(integer) 3

獲取列表長度(元素個數)

127.0.0.1:6379> LLEN list1
(integer) 3

獲取列表指定位置數據

redis
24.jpg

127.0.0.1:6379> LPUSH list1 a b c d
(integer) 4
127.0.0.1:6379>LINDEX list1 0#獲取0編號的元素
"d""
127.0.0.1:6379>LINDEX list1 3 #獲取3編號的元素
"a"
127.0.0.1:6379>LINDEX list1 -1 #獲取最後一個的元素
"a"
#元素從0開始編號
127.0.0.1:6379>LPUSH list1 a b c d
(integer) 4
127.0.0.1:6379> LRANGE list1 1 2
1)"c」
2)"b」
127.0.0.1:6379> LRANGE list1 0 3 #全部元素
1) "d""
2) "c"
3) "b"
4) "a"
127.0.0.1:6379>LRANGE list1 0 -1#全部元素
1) "d"
2) "c"
3) "b"
4) "a"
127.0.0.1:6379> RPUSH list2 zhang wang 1i zhao
(integer) 4
127.0.0.1:6379>LRANGE list2 1 2#指定範圍
1) "wang"
2)"li"
127.0.0.1:6379>LRANGE list2 2 2#指定位置
1)"li"
127.0.0.1:6379> LRANGE 7ist2 0 -1#全部元素
1) "zhang"
2) "wang"
3)"li"
4) "zhao"

修改列表指定索引值

127.0.0.1:6379>RPUSH listkey a b c d e f
(integer) 6
127.0.0.1:6379> 1range 1istkey 0 -1
1) "a"
2)"b"
3) "c"
4) "d"
5) "e"
6)"f"
127.0.0.1:6379> lset listkey 2 java
oK
127.0.0.1:6379> lrange listkey 0 -1
1)"a"
2)"b"
3) "java"
4) "d"
5)"e"
6)"f"
127.0.0.1:6379>

移除列表數據

127.0.0.1:6379> LPUSH list1 a b c d
(integer) 4
127.0.0.1:6379>LRANGE list1 0 3
1) "d"
2) "c"
3)"b"
4)"a"
127.0.0.1:6379>LPOP list1 #彈出左邊第一個元素,即刪除第一個
"d"
127.0.0.1:6379> LLEN 1ist1
(integer) 3
127.0.0.1:6379>LRANGE list1 0 2
1)"c"
2)"b"
3) "a"
127.0.0.1:6379> RPOP 1ist1#彈出右邊第一個元素,即刪除最後一個
"a"
127.0.0.1:6379> LLEN 1ist1
(integer)2
127.0.0.1:6379> LRANGE 1ist1 0 1
1)"c"
2)"b"

#LTRIM對一個列表進行修剪(trim),讓列表只保留指定區間內的元素,不在指定區間以內的元素都將被刪除
127.0.0.1:6379> LLEN 1ist1
(integer) 4
127.0.0.1:6379>LRANGE list1 0 3
1)"d"
2) "c"
3)"b"
4) "a"
127.0.0.1:6379> LTRIM list1 1 2#只保留1,2號元素
OK
127.0.0.1:6379> LLEN list1
(integer) 2
127.0.0.1:6379>LRANGE list1 0 1
1)"c"
2)"b"
#刪除list
127.0.0.1:6379>DEL list1
(integer) 1
127.0.0.1:6379>EXISTS list1
(integer) 0

集合

生成集合

Set是String類型的無序集合,集合中的成員是惟一的,這就意味着集合中不能出現重複的數據,能夠在兩個不一樣的集合中對數據進行對比並取值,經常使用於取值判斷,統計,交集等場景
集合特色
無序
無重複
集合間操做

127.0.0.1:6379> sadd set1 v1
(integer) 1
127.0.0.1:6379> sadd set2 v2 v4
(integer) 2
127.0.0.1:6379> TYPE set1
set
127.0.0.1:6379> TYPE set2
set

追加數值

#追加時,只能追加不存在的數據,不能追加已經存在的數值
127.0.0.1:6379> SADD set1 v2 v3 v4
(integer) 3
127.0.0.1:6379> SADD set1 v2#已存在的value,沒法再次添加
(integer) 0
127.0.0.1:6379> TYPE set1
set
127.0.0.1:6379> TYPE set2
set

查看集合的全部數據

127.0.0.1:6379>SMEMBERS set1
1) "v4"
2)"v1"
3) "v3"
4) "v2"
127.0.0.1:6379>SMEMBERS set2
1)"v4"
2) "v2"

刪除集合中的元素

127.0.0.1:6379> sadd goods mobile laptop car
(integer) 3
127.0.0.1:6379> srem goods car
(integer) 1
127.0.0.1:6379> SMEMBERS goods
1) "mobile"
2) "laptop"
127.0.0.1:6379>

獲取集合的交集

交集:已屬於A且屬於B的元素稱爲A與B的交(集)
127.0.0.1:6379> SINTER set1 set2
1) "v4"
2) "v2"

獲取集合的並集

並集:已屬於A或屬於B的元素爲稱爲A與B的並(集)
127.0.0.1:6379>SUNION set1 set2
1) "v2"
2) "v4"
3) "v1"
4) "v3"

獲取集合的差集

差集:已屬於A而不屬於B的元素稱爲A與B的差(集)
127.0.0.1:6379>SDIFF set1 set2
1) "v1"
2) "v3"

有序集合sorted set

Redis有序集合和集合同樣也是string類型元素的集合,且不容許重複的成員,不一樣的是每一個元素都會關聯一個double(雙精度浮點型)類型的分數,redis正是經過該分數來爲集合中的成員進行從小到大的排序,有序集合的成員是惟一的;但分數(score)卻能夠重複,集合是經過哈希表實現的,因此添加,刪除,查找的複雜度都是O⑴),集合中最大的成員數爲2^32-1(4294967295,每一個集合可存儲40多億個成員),常常用於排行榜的場景

有序集合特色
有序
無重複元素
每一個元素是由score和value組成
score 能夠重複
value 不能夠重複

生成有序集合

127.0.0.1:6379>ZADD zset1 1  v1 #分數爲1
(integer) 1
127.0.0.1:6379> ZADD zset1 2  v2
(integer) 1
127.0.0.1:6379>ZADD zset1 2    v3 #分數可重複,元素值不能夠重複
(integer) 1
127.0.0.1:6379> ZADD zset1 3   v4
(integer) 1
127.0.0.1:6379> TYPE zset1
zset
127.0.0.1:6379> TYPE zset2
zset
#一次生成多個數據:
127.0.0.1:6379>ZADD zset2 1 v1 2 v2 3 v3 4 v4 5 v5
(integer) 5

有序集合實現排行榜

127.0.0.1:6379> ZADD paihangbang 90 nezha 199 zhan1ang 60 zhuluoji 30 gangtiexia
(integer)4
127.0.0.1:6379> ZRANGE paihangbang 0 -1 #正序排序後顯示集合內全部的key , score從小到大顯示
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
4) "zhan1ang"
127.0.0.1:6379>ZREVRANGE paihangbang 0 -1 #倒序排序後顯示集合內全部的key, score從大到小顯示
1) "zhan1ang"
2) "nezha"
3) "zhuluoji"
4) "gangtiexia"
127.0.0.1:6379> ZRANGE paihangbang 0 -1 wITHSCORES#正序顯示指定集合內全部key和得分狀況
1) "gangtiexia"
2) "30"
3)"zhu1uoji"
4) "60"
5) "nezha"
6)"90"
7)"zhan1ang"
8)"199"
127.0.0.1:6379> ZREVRANGE paihangbang 0 -1 WITHSCORES#倒序顯示指定集合內全部key和得分狀況
1) "zhan1ang"
2)"199"
3) "nezha"
4) "90"
5)"zhuluoji"
6)"60"
7) "gangtiexia"
8)"30"
127.0.0.1:6379>

獲取集合的個數

127.0.0.1:6379>ZCARD paihangbang
(integer) 4
127.0.0.1:6379>ZCARD zset1
(integer) 4
127.0.0.1:6379>ZCARD zset2
(integer) 4

基於索引返回數值

127.0.0.1:6379>ZRANGE pai hangbang 0 2
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
127.0.0.1:6379>ZRANGE pai hangbang 0 10  #超出範圍不報錯
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
4) "zhanlang"

127.0.0.1:6379>ZRANGE zset1 1 3
1) "v2"
2)"v3"
3) "v4"
127.0.0.1:6379>ZRANGE zset1 0 2
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379>ZRANGE zset1 2 2
1) "v3"

返回某個數值的索引(排名)

127.0.0.1:6379>ZADD paihangbang 90 nezha 199 zhan1ang 60 zhuluoji 30 gangtiexia
(integer)4
127.0.0.1:6379>ZRANK paihangbang zhan1ang
(integer) 3#第4個
127.0.0.1:6379>ZRANK paihangbang zhuluoji
(integer) 1#第2個

獲取分數

127.0.0.1:6379> zscore paihangbang gangtiexia
"30"

刪除元素

127.0.0.1:6379>ZADD paihangbang 90 nezha 199 zhanlang 60 zhuluoji 30 gangtiexia
(integer) 4
127.0.0.1:6379>ZRANGE pai hangbang 0 -1
1) "gangtiexia"
2) "zhuluoji"
3) "nezha"
4) "zhan1ang"
127.0.0.1:6379>ZREM pai hangbang zhuluoji zhan1ang
(integer) 2
127.0.0.1:6379>ZRANGE pai hangbang 0 -1
1) "gangtiexia"
2) "nezha"

哈希hash

hash是一個string類型的字段(field)和值(value)的映射表,Redis 中每一個hash能夠存儲2^32-1鍵值對,相似於字典,存放了多個k/v對,hash特別適合用於存儲對象場景

生成hash

HSET hash field value時間複雜度:o(1)
將哈希表hash中域fie1d 的值設置爲value 。
若是給定的哈希表並不存在,那麼一個新的哈希表將被建立並執行HSET操做。若是域fie1d 已經存在於哈希表中,那麼它的舊值將被新值 value覆蓋。

127.0.0.1:6379> HSET 9527 name zhouxingxing age 20
(integer) 2
127.0.0.1:6379>TYPE 9527
hash
#查看全部字段的值
127.0.0.1:6379> hgetal1 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "20"
#增長字段
127.0.0.1:6379>HSET 9527 gender male
(integer) 1
127.0.0.1:6379> hgetall 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "20"
5) "gender"
6) "male"

獲取hash key的對應字段的值

127.0.0.1:6379> HGET 9527 name
"zhouxingxing"
127.0.0.1:6379> HGET 9527 age
"20"
127.0.0.1:6379>HMGET 9527 name age#獲取多個值
1) "zhouxingxing"
2) "20"
127.0.0.1:6379>

刪除一個hash key的對應字段

127.0.0.1:6379>HDEL 9527 age
(integer) 1
127.0.0.1:6379>HGET 9527 age
(ni1)
127.0.0.1:6379> hgetal1 9527
1) "name"
2) "zhouxingxing"
127.0.0.1:6379> HGET 9527 name
"zhouxingxing"

批量設置hash key的多個field和value

127.0.0.1:6379> HMSET 9527 name zhouxingxing age 50 city hongkong
OK
127.0.0.1:6379> HGETALL 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "50"
5) "city"
6) "hongkong"

獲取hash中指定字段的值

127.0.0.1:6379> HMSET 9527 name zhouxingxing age 50 city hongkong
OK
127.0.0.1:6379> HMGET 9527 name age
1) "zhouxingxing"
2) "50"
127.0.0.1:6379>

獲取hash中的全部字段名field

127.0.0.1:6379>HMSET 9527 name zhouxingxing age 50 city hongkong #從新設置OK
127.0.0.1:6379> HKEYS 9527
1) "name"
2) "age"3) "city"

獲取hash key對應全部field的value

127.0.0.1:6379> HMSET 9527 name zhouxingxing age 50 city hongkongoK
127.0.0.1:6379> HVALS 9527
1) "zhouxingxing"
2) "50"
3) "hongkong"

獲取指定hash key的全部field和value

127.0.0.1:6379> HGETALL 9527
1) "name"
2) "zhouxingxing"
3) "age"
4) "50"
5) "city"
6) "hongkong"
127.0.0.1: 6379>

刪除hash

127.0.0.1:6379> DEL9527
(integer) 1
127.0.0.1:6379> HMGET 9527 name city
1) (ni1)
2) (ni1)
127.0.0.1:6379> EXISTS 9527
(integer) 0

消息隊列

消息隊列:把要傳輸的數據放在隊列中
功能:能夠實現多個系統之間的解耦,異步,削峯/限流等經常使用的消息隊列應用: kafka,rabbitMQ,redis

消息隊列主要分爲兩種,這兩種模式Redis都支持
生產者/消費者模式
發佈者/訂閱者模式

生產者/消費者模式

在生產者/消費者(ProducerlConsumer)模式下,上層應用接收到的外部請求後開始處理其當前步驟的操做,在執行完成後將已經完成的操做發送至指定的頻道(channel,邏輯隊列)當中,並由其下層的應用監聽該頻道並繼續下一步的操做,若是其處理完成後沒有下一步的操做就直接返回數據給外部請求,若是還有下一步的操做就再將任務發佈到另一個頻道,由另一個消費者繼續監聽和處理。此模式應用普遍
2.6.1.1模式介紹
生產者消費者模式下,多個消費者同時監聽一個隊列,可是一個消息只能被最早搶到消息的消費者消費,即消息任務是一次性讀取和處理,此模式在分佈式業務架構中很經常使用,比較經常使用的消息隊列軟件還有RabbitMQ、Kafka、RocketMQ、ActiveMQ等。

隊列介紹

隊列當中的消息由不一樣的生產者寫入,也會有不一樣的消費者取出進行消費處理,可是一個消息必定是隻能被取出一次也就是被消費一次。

redis

redis
25.jpg26.jpg

生產者發佈消息

[root@redis ~]# redis-cli 
127.0.0.1:6379> AUTH 123456oK
127.0.0.1:6379> LPUSH channe11 msg1 #從管道的左側寫入
(integer) 1
127.0.0.1:6379> LPUSH channe11 msg2
(integer) 2
127.0.0.1:6379> LPUSH channe11 msg3
(integer) 3
127.0.0.1:6379> LPUSH channe11 msg4
(integer) 4
127.0.0.1:6379> LPUSH channe11 msg5
(integer) 5

查看消息隊列消息

127.0.0.1:6379> lrange channe11 0 -1
1) "msg5"
2) "msg4"
3) "msg3"
4) "msg2"
5) "msg1"

消費者消費消息

127.0.0.1:6379> rpop channe11    #從管道右側消費,用於消息先進先出
"msg1"
127.0.0.1:6379> rpop channe11
"msg2"
127.0.0.1:6379> rpop channe11
"msg3"
127.0.0.1:6379> rpop channe11
"msg4"
127.0.0.1:6379> rpop channe11
"msg5"
127.0.0.1:6379> rpop channe11
(nil)

再次驗證隊列消息

127.0.0.1:6379> lrange channe11  0 -1
(empty array)

發佈者訂閱模式

在發佈者訂閱者模式下,發佈者將消息發佈到指定的channel裏面,凡是監聽該channel的消費者都會收到一樣的
一份消息,這種模式相似因而收音機的廣播模式,即凡是收聽某個頻道的聽衆都會收到主持人發佈的相同的消息內
容。此模式經常使用語羣聊天、羣通知、羣公告等場景
Publisher:發佈者
Subscriber:訂閱者
Channel:頻道

訂閱者監聽頻道

[root@redis ~]# redis-cli
127.0.0.1:6379> AUTH 123456oK
127.0.0.1:6379>SUBSCRIBE channe11  #訂閱者事先訂閱指定的頻道,以後發佈的消息才 能收到
Readi ng messages. . . (press ctr1-c to quit)
1) "subscribe"
2) "channe11"
3) (integer) 1

發佈者發佈消息

127.0.0.1:6379> PUBLISH channe11 test1  #發佈者發佈消息
(integer) 1
127.0.0.1:6379> PUBLISH channe11 test1
(integer) 2  #訂閱者個數

訂閱者收到消息

[root@C8-24 ~]# redis-cli 
127.0.0.1:6379> SUBSCRIBE channe11
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channe11"
3) (integer) 1
1) "message"
2) "channe11"
3) "test1"
#訂閱指定的多個頻道
127.0.0.1:6379>SUBSCRIBE channe11 channe12

#訂閱全部頻道
127.0.0.1:6379> PSUBSCRIBE *#支持通配符*

#訂閱匹配的頻道
127.0.0.1:6379> PSUBSCRIBE chann*#匹配訂閱多個頻道

#取消訂閱
127.0.0.1:6379> unsubscribe channe11
1) "unsubscribe"
2) "channe11"3)(integer) 0

redis集羣與高可用

雖然Redis能夠實現單機的數據持久化,但不管是RDB也好或者AOF也好,都解決不了單點宕機問題,即一旦單臺redis服務器自己出現系統故障、硬件故障等問題後,就會直接形成數據的丟失
此外單機的性能也是有極限的,所以須要使用另外的技術來解決單點故障和性能擴展的問題。

redis主從複製

redis

27.jpg

主從模式(master/slave) ,能夠實現Redis數據的跨主機備份。

程序端鏈接到高可用負載的VIP,而後鏈接到負載服務器設置的Redis後端real server,此模式不須要在程序裏面配置Redis服務器的真實IP地址,當後期Redis服務器IP地址發生變動只須要更改redis相應的後端real server便可,可避免更改程序中的IP地址設置。

主從複製特色
一個master能夠有多個slave一個slave只能有一個master
數據流向是單向的,master到slave

主從複製實現

Redis Slave也要開啓持久化並設置和master一樣的鏈接密碼,由於後期slave會有提高爲master的可能,Slave端切換master同步後會丟失以前的全部數據,而經過持久化能夠恢復數據
一旦某個Slave成爲一個master的slave,Redis Slave服務會清空當前redis服務器上的全部數據並將master的數據導入到本身的內存,可是若是隻是斷開同步關係後,則不會刪除當前已經同步過的數據。

當配置Redis複製功能時,強烈建議打開主服務器的持久化功能。不然的話,因爲延遲等問題,部署的服務應該要避免自動啓動。
參考案例:致使主從服務器數據所有丟失

1.假設節點A爲主服務器,而且關閉了持久化。而且節點B和節點c從節點A複製數據

2.節點A崩潰,而後由自動拉起服務重啓了節點A.因爲節點A的持久化被關閉了,因此重啓以後沒有任何數據

3.節點B和節點c將從節點A複製數據,可是A的數據是空的,因而就把自身保存的數據副本刪除。

在關閉主服務器上的持久化,並同時開啓自動拉起進程的狀況下,即使使用Sentinel來實現Redis的高可用性,也是很是危險的。由於主
服務器可能拉起得很是快,以致於Sentinel在配置的心跳時間間隔內沒有檢測到主服務器已被重啓,而後仍是會執行上面的數據丟失的流程。不管什麼時候,數據安全都是極其重要的,因此應該禁止主服務器關閉持久化的同時自動啓動。

命令行配置

啓用主從同步
默認redis 狀態爲master,須要轉換爲slave角色並指向master服務器的IP+PORT+Password

REPLICAOF MASTER_IP PORT指令能夠啓用主從同步複製功能,早期版本使用SLAVEOF指令

127.0.0.1:6379>REPLICAOF MASTER_IP PORT
127.0.0.1:6379> CONFIG SET masterauth <masterpass>
#主服務器上設置密碼,便於從服務器鏈接
127.0.0.1:6379> CONFIG SET requirepass 123456
OK

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:d5959a9e7fdfba312bf00e3a410a30a08891b98c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> set key1 v1-master
OK
127.0.0.1:6379> get key1
"v1-master"

#slave 設置:
[root@C8-34 ~]# 
[root@C8-34 ~]# redis-cli 
127.0.0.1:6379> set key1  v1-slave-34
OK
127.0.0.1:6379> get key1
"v1-slave-34"

127.0.0.1:6379> REPLICAOF 10.0.0.24  6379   #指向主服務器的IP和端口
OK
127.0.0.1:6379> CONFIG SET masterauth 123456 #設置master的密碼才能夠
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave             #變爲從服務器了
master_host:10.0.0.24  #指向master的IP
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:42
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42
127.0.0.1:6379> 
127.0.0.1:6379> get key1   #查看已經同步成功
"v1-master"    

#在master上能夠看到slave的信息
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.34,port=6379,state=online,offset=560,lag=1
master_failover_state:no-failover
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:560
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:560
127.0.0.1:6379> 

[root@C8-35 ~]# redis-cli 
127.0.0.1:6379> set key1 v1-slave-28
OK
127.0.0.1:6379> get key1
"v1-slave-28"

刪除主從同步

REPLIATOF NO ONE指令能夠取消主從複製

#取消複製,在sTave上執行REPLIATOF NO ONE,會斷開和master的鏈接再也不主從複製,但不會清除slave上已有的數據

同步日誌

#在master上觀察日誌
[root@C8-24 ~]# tail /var/log/messages -f
Aug  6 20:44:45 C8-24 systemd[1]: Started dnf makecache.
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Replica 10.0.0.34:6379 asks for synchronization
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Full resync requested by replica 10.0.0.34:6379
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Replication backlog created, my new replication IDs are '2ce4131d3563e9ac2ecef1130fa00b46f6f578a5' and '0000000000000000000000000000000000000000'
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.297 * Starting BGSAVE for SYNC with target: disk
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.306 * Background saving started by pid 116940
Aug  6 21:12:38 C8-24 redis-server[4834]: 116940:C 06 Aug 2021 21:12:38.465 * DB saved on disk
Aug  6 21:12:38 C8-24 redis-server[4834]: 116940:C 06 Aug 2021 21:12:38.466 * RDB: 0 MB of memory used by copy-on-write
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.521 * Background saving terminated with success
Aug  6 21:12:38 C8-24 redis-server[4834]: 4834:M 06 Aug 2021 21:12:38.542 * Synchronization with replica 10.0.0.34:6379 succeeded

#在從服務器上看日誌
[root@C8-34 ~]# tail /var/log/redis/redis.log -f
22508:S 06 Aug 2021 21:12:38.713 * Full resync from master: 2ce4131d3563e9ac2ecef1130fa00b46f6f578a5:0
22508:S 06 Aug 2021 21:12:38.928 * MASTER <-> REPLICA sync: receiving 3967032 bytes from master
22508:S 06 Aug 2021 21:12:38.952 * MASTER <-> REPLICA sync: Flushing old data
22508:S 06 Aug 2021 21:12:38.952 * MASTER <-> REPLICA sync: Loading DB in memory
22508:S 06 Aug 2021 21:12:39.129 * MASTER <-> REPLICA sync: Finished with success
22508:S 06 Aug 2021 21:17:35.034 * 1 changes in 900 seconds. Saving...
22508:S 06 Aug 2021 21:17:35.039 * Background saving started by pid 22524
22524:C 06 Aug 2021 21:17:35.164 * DB saved on disk
22524:C 06 Aug 2021 21:17:35.165 * RDB: 6 MB of memory used by copy-on-write
22508:S 06 Aug 2021 21:17:35.251 * Background saving terminated with success

修改slave節點配置文件

[root@C8-34 ~]# vim /etc/redis.conf 
replicaof   10.0.0.24 6379
 masterauth 123456

[root@C8-34 ~]# systemctl restart redis

master和slave查看狀態

#從服務器查看狀態
127.0.0.1:6379> get key1        #同步成功後,slave上的key1信息丟失,從master複製過來新的值
"v1-master"
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:2436
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2436
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2073
repl_backlog_histlen:364

#master上查看狀態
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.34,port=6379,state=online,offset=2338,lag=0
master_failover_state:no-failover
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2338
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2338

[root@C8-24 ~]# systemctl stop redis 
#中止master的redis服務: systemct7 stop redis,在s7ave上能夠觀察到如下現象
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:down      #顯示down,表示沒法鏈接master
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:2688
master_link_down_since_seconds:65
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2ce4131d3563e9ac2ecef1130fa00b46f6f578a5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2688
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2073
repl_backlog_histlen:616
127.0.0.1:6379>

slave日誌觀察

主服務器關閉之後從服務器沒法在同步主服務器了

redis
28.jpg

slave狀態只讀沒法寫入數據

127.0.0.1:6379> get key1
"v1-master"
127.0.0.1:6379> set key1 v1-slave
(error) READONLY You can't write against a read only replica.

配置不一致

主從節點的maxmemory不一致,主節點內存大於從節點內存,主從複製可能丟失數據
rename-command命令不一致,如在主節點定義了lfushall,flushdb,從節點沒定義,結果執行flushdb,不一樣步

#master有一個rename-command flushdb "magedu" ,而islave沒有這個配置,則同步時從節點能夠看到如下同步錯誤
3181:S 21 oct 2020 17:34:50.581 # == CRITICAL == This replica is sending anerror to its master: 'unknown command magedu ', with args beginning with: 'after processing the command '<unknown>'

主從複製故障恢復

須要提高新的slave爲master

redis
29.jpg

master故障後,只能手動提高一個slave爲新master,不支持自動切換。Master的切換會致使
master_replid發生變化, slave以前的master_replid就和當前master不一致從而會引起全部slave的全量同步。

手動提高從節點爲主節點

假設當前主節點10.0.0.24故障,提高10.0.0.34爲新的master

中止slave同步並提高爲新的master

#提高爲新主:
127.0.0.1:6379> replicaof no one
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:36e741346c800d3e741affff50bc69b4be7332c7
master_replid2:59e582a48445cd539281c3282ab518b17c285aaf
master_repl_offset:2100
second_repl_offset:2101
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2100
127.0.0.1:6379> 
#測試能夠寫入數據了
127.0.0.1:6379> set keytest1 vtest1
OK
#添加密碼:
127.0.0.1:6379> CONFIG SET requirepass 123456
OK

#修改全部的從節點指向新的master (10.0.0.34)
以10.0.0.38 爲例:
127.0.0.1:6379> get key1
"v1-slave-38"
127.0.0.1:6379> SLAVEOF 10.0.0.34 6379
OK
127.0.0.1:6379> CONFIG SET masterauth 123456
OK
127.0.0.1:6379> GET key1
"v1-master"
#查看日誌
[root@C8-35 ~]# tail -f /var/log/redis/redis.log 
1977:S 06 Aug 2021 22:38:03.691 * Connecting to MASTER 10.0.0.34:6379
1977:S 06 Aug 2021 22:38:03.691 * MASTER <-> REPLICA sync started
1977:S 06 Aug 2021 22:38:03.691 * Non blocking connect for SYNC fired the event.
1977:S 06 Aug 2021 22:38:03.691 * Master replied to PING, replication can continue...
1977:S 06 Aug 2021 22:38:03.692 * Partial resynchronization not possible (no cached master)
1977:S 06 Aug 2021 22:38:03.696 * Full resync from master: 36e741346c800d3e741affff50bc69b4be7332c7:2162
1977:S 06 Aug 2021 22:38:03.899 * MASTER <-> REPLICA sync: receiving 3967050 bytes from master
1977:S 06 Aug 2021 22:38:03.923 * MASTER <-> REPLICA sync: Flushing old data
1977:S 06 Aug 2021 22:38:03.923 * MASTER <-> REPLICA sync: Loading DB in memory
1977:S 06 Aug 2021 22:38:04.103 * MASTER <-> REPLICA sync: Finished with success

在新的master 10.0.0.34上看slave的狀態

[root@C8-34 ~]# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.35,port=6379,state=online,offset=2706,lag=0
master_replid:36e741346c800d3e741affff50bc69b4be7332c7
master_replid2:59e582a48445cd539281c3282ab518b17c285aaf
master_repl_offset:2706
second_repl_offset:2101
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2706
127.0.0.1:6379>

實現redis的級聯複製

即實現基於Slave節點的Slave

master和slave1節點無需修改,只須要修改slave2及slave3指向slave1作爲mater便可

<img src="D:\雲計算\31redis\30.png" style="zoom:200%;" />
30.png
master 和slave1無須要修改,只須要修改slave2 和slave3 將slave1做爲master便可:

slave1:

[root@C8-34 ~]# sed -rn '287p' /etc/redis.conf  #所鏈接的masterIP
 replicaof   10.0.0.24 6379
[root@C8-34 ~]# sed -rn '295p' /etc/redis.conf  #所鏈接的IP的密碼
 masterauth 123456

[root@C8-34 ~]# grep 'requirepass *123456'  /etc/redis.conf  #本身主機的密碼
requirepass 123456

slave 2 和slave3上執行

[root@C8-23 ~]#  sed -rn '287p' /etc/redis.conf 
 replicaof  10.0.0.34 6379
[root@C8-23 ~]# sed -rn '295p' /etc/redis.conf
 masterauth  123456

或者用命令的方式:

127.0.0.1:6379> REPLICAOF 10.0.0.34 6379
OK
127.0.0.1:6379> CONFIG sET masterauth 123456
OK

在master設置key,觀察是否同步

#在master新建key
127.0.0.1:6379> set key2 
v2
OK
127.0.0.1:6379> get key2
"v2"
#在slave1和s1ave和slave3驗證key127.0.0.1:6379> get key2
"v2"
#在slave1和s1ave2和slave3都沒法新建key127.0.0.1:6379> set key3 v3
(error) READONLY You can't write against a read only replica.

查看master的信息

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:1715
slave_priority:100
slave_read_only:1
connected_slaves:2
slave0:ip=10.0.0.35,port=6379,state=online,offset=1715,lag=0
slave1:ip=10.0.0.23,port=6379,state=online,offset=1715,lag=0
master_replid:cf8b971aa09f6a8cf0b7b969bf3b4054b491ccec
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1715
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1715
127.0.0.1:6379>

查看中間那個slave查看狀態

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.24
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2 #最近一次與master通訊已通過去多少秒。master_sync_in_progress:0#是否正在與master通訊。
master_sync_in_progress:0
slave_repl_offset:1715 #當前同步的偏移量
slave_priority:100 #s1ave優先級,master故障後值越小越優先同步。s1ave_read_on1y :1
slave_read_only:1
connected_slaves:2
slave0:ip=10.0.0.35,port=6379,state=online,offset=1715,lag=0  #slave的slave節點
slave1:ip=10.0.0.23,port=6379,state=online,offset=1715,lag=0   #slave的slave節點
master_replid:cf8b971aa09f6a8cf0b7b969bf3b4054b491ccec
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1715
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1715
127.0.0.1:6379>

主從複製優化

Redis主從複製分爲全量同步和增量同步

首次同步是全量同步,主從同步可讓從服務器從主服務器同步數據,並且從服務器還可再有其它的從服務器,即另一臺redis服務器能夠從一臺從服務器進行數據同步,redis的主從同步是非阻塞的,master收到從服務器的psync(2.8版本以前是SYNC)命令,會fork一個子進程在後臺執行bgsave命令,並將新寫入的數據寫入到一個緩衝區中,bgsave執行完成以後,將生成的RDB文件發送給slave,而後master再將緩衝區的內容以redis協議格式再所有發送給slave,slave先刪除舊數據,slave將收到後的RDB文件載入本身的內存,再加載全部收到緩衝區的內容從而這樣一次完整的數據同步
Redis全量複製通常發生在Slave首次初始化階段,這時Slave須要將Master上的全部數據都複製一份。

全量同步以後再次須要同步時,從服務器只要發送當前的offset位置(等同於My5QL的binlog的位置)給主服務器,而後主服務器根據相應的位置將以後的數據(包括寫在緩衝區的積壓數據)發送給從服務器,再次其保存到其內存便可。

主從同步完整過程具體主從同步過程以下:
1)從服務器鏈接主服務器,發送PSYNC命令
2)主服務器接收到PSYNC命令後,開始執行BGSAVE命令生成RDB快照文件並使用緩衝區記錄此後執行的全部寫命令
3)主服務器BGSAVE執行完後,向全部從服務器發送RDB快照文件,並在發送期間繼續記錄被執行的寫命令

4)從服務器收到快照文件後丟棄全部舊數據,載入收到的快照至內存
5)主服務器快照發送完畢後,開始向從服務器發送緩衝區中的寫命令
6)從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩衝區的寫命令7〉)後期同步會先發送本身s1ave_repl_offset位置,只同步新增長的數據,再也不全量同步

複製緩衝區(環形隊列)配置參數:
#複製緩衝區大小,建議要設置足夠大rep1-backlog-size 1mb
#Redis同時也提供了當沒有s1ave須要同步的時候,多久能夠釋放環形隊列:rep1-back1og-ttl3600

避免全量複製
·第一次全量複製不可避免,後續的全量複製能夠利用小主節點(內存小),業務低峯時進行全量
節點運行ID不匹配:主節點重啓會致使RUNID變化,可能會觸發全量複製,能夠利用故障轉移,例如哨兵或集羣,而從節點重啓動,不會致使全量複製
複製積壓緩衝區不足:當主節點生成的新數據大於緩衝區大小,從節點恢復和主節點鏈接後,會致使全量複製.解決方法將repl-backlog-size 調大

避免複製風暴
單主節點複製風暴
當主節點重啓,多從節點複製解決方法:更換複製拓撲

單機器複製風暴
機器宕機後,大量全量複製解決方法:主節點分散多機器

主從同步優化配置

Redis在2.8版本以前沒有提供增量部分複製的功能,當網絡閃斷或者slave Redis重啓以後會致使主從之間的全量同步,即從2.8版本開始增長了部分複製的功能。
性能相關配置

rep7-diskless-sync no #是否使用無盤同步RDB文件,默認爲no,no爲不使用無盤,須要將RDB文件保存到磁盤後再發送給slave,yes爲支持無盤,支持無盤就是RDB文件不須要保存至本地磁盤,並且直接經過socket文件發送給s1ave
repl-diskless-sync-delay 5 #diskless時複製的服務器等待的延遲時間
rep7-ping-slave-period 10 #s1ave端向server端發送ping的時間間隔,默認爲10秒
rep7-timeout 60 #設置主從ping鏈接超時時間,超過此值沒法鏈接,master_link_status顯示爲down,並記錄錯誤日誌
rep7-disable-tcp-nodelay no #是否啓用TCP_NODELAY,如設置成yes,則redis會合並小的TCP包從而節省帶寬,但會增長同步延遲(40ms),形成master與slave數據不一致,假如設置成no,則redismaster會當即發送同步數據,沒有延遲,yes關注性能,no關注redis服務中的數據一致性
rep7-backlog-size 1mb #master的寫入數據緩衝區,用於記錄自上一次同步後到下一次同步過程當中間的寫入命令,計算公式: rep7-backlog-size = 容許從節點最大中斷時長*主實例offset每秒寫入量,好比master每秒最大寫入64mb,最大容許60秒,那麼就要設置爲64mb*60秒=3840MB(3.8G),建議此值是設置的足夠大
rep7-backlog-tt1 3600#若是一段時間後沒有slave鏈接到master,則backlog size的內存將會被釋放。若是值爲0則表示永遠不釋放這部分內存。
slave-priority 100 #s7ave端的優先級設置,值是一個整數,數字越小表示優先級越高。當master故障時將會按照優先級來選擇s7ave端進行恢復,若是值設置爲0,則表示該s1ave永遠不會被選擇。
min-rep7icas-to-write 1 #設置一個master的可用s7Tave不能少於多少個,不然master沒法執行寫
min-s7aves-max-7ag 20 #設置至少有上面數量的slave延遲時間都大於多少秒時,master不接收寫操做(拒絕寫入)

常見主從複製故障彙總

master密碼不對

即配置的master密碼不對,致使驗證不經過而沒法創建主從同步關係。
[root@centos8 ~]#tail -f /var /log /redis/redis .1og
24930:S 20 Feb 2020 13:53:57.029 * connecting to MASTER 10.0.0.8:637924930:S 20 Feb 2020 13:53:57.030 * MASTER <-> REPLICA sync started
24930:S 20 Feb 2020 13:53:57.030 * Non blocking connect for sYNc fired theevent.
24930:s 20 Feb 2020 13:53:57.030 * Master replied to PING,replication cancontinue. . .
24930:S 20 Feb 2020 13:53:57.031 # unable to AUTH to MASTER: -ERR invalidpassword

Redis版本不一致

不一樣的redis大版本之間存在兼容性問題,好比:3和4,4和5之間,所以各master和slave之間必須保持版本一致

redis
31.png

沒法遠程鏈接

#在開啓了安全模式狀況下,沒有設置bind地址或者密碼
[root@centos8 ~]#vim /etc/redis.conf
#bind 127.0.0.1#將此行註釋
[root@centos8 ~]#systemctl restart redis

配置不一致

主從節點的maxmemory不一致,主節點內存大於從節點內存,主從複製可能丟失數據
rename-command命令不一致,如在主節點定義了lfushall,flushdb,從節點沒定義,結果執行flushdb,不一樣步
#master有一個rename-command flushdb "magedu" ,而is1ave沒有這個配置,則同步時從節點能夠看到如下同步錯誤
3181:s 21 oct 2020 17:34:50.581 # == CRITICAL == This replica is sending anerror to its master: 'unknown command magedu ', with args beginning with: 'after processing the command '<unknown>'

redis哨兵(Sentinel)

redis
32.png

3.2.1 redis集羣介紹
主從架構沒法實現master和slave角色的自動切換,即當master出現redis服務異常、主機斷電、磁盤損壞等問題致使master沒法使用,而redis主從複製沒法實現自動的故障轉移(將slave自動提高爲新
master),須要手動修改環境配置,才能切換到slave redis服務器,另外也沒法橫向擴展Redis服務的並行寫入性能,當單臺Redis服務器性能沒法知足業務寫入需求的時候,也須要解決以上的兩個核心問題,即: 1.master和slave角色的無縫切換,讓業務無感知從而不影響業務使用2.可橫向動態擴展Redis服務器,從而實現多臺服務器並行寫入以實現更高併發的目的。
Redis 集羣實現方式:
·客戶端分片:由應用決定將不一樣的KEY發送到不一樣的Redis服務器
·代理分片:由代理決定將不一樣的KEY發送到不一樣的Redis服務器,代理程序如:codis,twemproxy等. Redis Cluster

Sentinel進程是用於監控redis集羣中Master主服務器工做的狀態,在Master主服務器發生故障的時候,能夠實現Master和Slave服務器的切換,保證系統的高可用,此功能在redis2.6+的版本已引用,Redis的哨兵模式到了2.8版本以後就穩定了下來。通常在生產環境也建議使用Redis的2.8版本的之後版本
哨兵(Sentinel)是一個分佈式系統,能夠在一個架構中運行多個哨兵(sentinel)進程,這些進程使用流言協議(gossip protocols)來接收關於Master主服務器是否下線的信息,並使用投票協議(AgreementProtocols)來決定是否執行自動故障遷移,以及選擇哪一個Slave做爲新的Master
每一個哨兵(Sentinel)進程會向其它哨兵(Sentinel)、Master,Slave定時發送消息,以確認對方是否"活"着,若是發現對方在指定配置時間(此項可配置)內未獲得迴應,則暫時認爲對方已離線,也就是所謂的」"主觀認爲宕機"」(主觀:是每一個成員都具備的獨自的並且可能相同也可能不一樣的意識),英文名稱:
Subjective Down,簡稱SDOWN
有主觀宕機,對應的有客觀宕機。當"哨兵羣"中的多數Sentinel進程在對Master主服務器作出SDOWN的判斷,而且經過SENTINEL is-master-down-by-addr命令互相交流以後,得出的Master Server下線判斷,這種方式就是"客觀宕機"(客觀:是不依賴於某種意識而已經實際存在的一切事物),英文名稱是:Objectively Down,簡稱ODOWN
經過必定的vote算法,從剩下的slave從服務器節點中,選一臺提高爲Master服務器節點,而後自動修改相關配置,並開啓故障轉移(failover)
Sentinel機制能夠解決master和slave角色的自動切換問題,但單個Master的性能瓶頸問題沒法解決,相似於MySQL中的MHA功能
Redis Sentinel中的Sentinel節點個數應該爲大於等於3且最好爲奇數
客戶端初始化時鏈接的是Sentinel節點集合,再也不是具體的Redis節點,但Sentinel只是配置中心不是代理。
Redis Sentinel節點與普通redis沒有區別,要實現讀寫分離依賴於客戶端程序
redis 3.0以前版本中,生產環境通常使用哨兵模式,但3.0後推出redis cluster功能後,能夠支持更大規模的生產環境

sentinel中的三個定時任務
·每10秒每一個sentinel對master和slave執行info

發現slave節點
確認主從關係
·每2秒每一個sentinel經過master節點的channel交換信息(pub/sub)

經過sentinel_:hello頻道交互
交互對節點的"見解"和自身信息
·每1秒每一個sentinel對其餘sentinel和redis執行ping

實現哨兵

哨兵的準備實現主從複製架構

哨兵的前提是已經實現了一個redis的主從複製的運行環境,從而實現一個一主兩從基於哨兵的高可用redis架構
注意: master的配置文件中masterauth 和slave都必須相同全部主從節點的redis.conf中關健配置
範例:

[root@C8-58]#sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf
[root@C8-58]#echo "replicaof 10.0.0.22 6379" >>/etc/redis.conf
[root@C8-58]#systemctl restart redis

<img src="D:\雲計算\31redis\33.png" style="zoom: 80%;" />
33.png

[root@C8-22 ~]# grep -e "^bind 0" -e  "^masterauth"  -e "^requirepass" -e "^replicaof"  /etc/redis.conf 
bind 0.0.0.0
masterauth "123456"
requirepass "123456"

[root@C8-58]# grep -e "^bind 0" -e  "^masterauth"  -e "^requirepass" -e "^replicaof"  /etc/redis.conf 
bind 0.0.0.0
masterauth "123456"
requirepass "123456"
replicaof 10.0.0.22 6379

[root@C8-34 ~]# grep -e "^bind 0" -e  "^masterauth"  -e "^requirepass" -e "^replicaof"  /etc/redis.conf
bind 0.0.0.0
replicaof 10.0.0.22 6379
masterauth "123456"
requirepass "123456"

systemctl restart redis

編輯哨兵的配置文件

sentinel配置
Sentinel其實是一個特殊的redis服務器,有些redis指令支持,但不少指令並不支持.默認監聽在26379/tcp端口.
哨兵能夠不和Redis服務器部署在一塊兒,但通常部署在一塊兒,全部redis節點使用相同的如下示例的配置文件

#若是是編譯安裝,在源碼目錄有sentine1.conf,複製到安裝目錄便可,如: /apps/redis/etc/sentine1.conf

[root@C8-22 ~]# grep '^[^#]' /etc/redis-sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel.log"
dir "/tmp"   #工做目錄
sentinel myid 5e152ed23f189a8a5e2337c7a6f73ccc0e139328  #自動生成的
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.22 6379 2  #指定當前mymaster集羣中master服務器的地址和端口 #2爲法定人數限制(quorum),即有幾個sentine1認爲master down了就進行故障轉移,通常此值是全部sentine1節點(通常總數是>=3的奇數,如:3,5,7等)的一半以上的整數值,好比,總數是3,即3/2=1.5,取整爲2,是master的ODOwN客觀下線的依據
sentinel down-after-milliseconds mymaster 3000  #(SDOwN)判斷mymaster集羣中全部節點的主觀下線的時間,單位:毫秒,建議3000
sentinel auth-pass mymaster 123456  #mymaster集羣中master的密碼,注意此行要在上面行的下面
sentinel config-epoch mymaster 2
protected-mode no
supervised systemd
sentinel leader-epoch mymaster 2
sentinel known-replica mymaster 10.0.0.34 6379
sentinel known-replica mymaster 10.0.0.58 6379
sentinel known-sentinel mymaster 10.0.0.58 26379 0906444c851c4a671d10696aabc4a1370b54dc9b
sentinel known-sentinel mymaster 10.0.0.34 26379 4c3e19074b91564ab99b66eb042913069e951c6f
sentinel current-epoch 2

三個哨兵的配置文件

[root@redis-master ~]#grep -vE "^#|^$"/etc/redis-sentinel.conf
port 26379
daemonize no
pidfile "/var/run/redis-sentinel.pid"
1ogfile "/var/log/redis/sentine1. log"
dir " / tmp"
sentinel monitor mymaster 10.0.0.22 6379 2      #增長此行
sentine1 auth-pass mymaster 123456             #增長此行
sentine1 down-after-mi77iseconds mymaster 3000 #增長此行
sentinel paral1e1-syncs mymaster 1
sentine7 failover-timeout mymaster 180000
sentine1 deny-scripts-reconfig yes
#如下內容自動生成,不須要修改
sentine1 myid 50547f34ed71fd48c197924969937e738a39975b #此行自動生成必須惟一,修改此值需重啓redis和sentinel服務
.....
# Generated by CONFIG REWR工TEprotected-mode no
supervised systemd
sentinel 1eader-epoch mymaster 0
sentinel known-replica mymaster 10.0.0.28 6379
sentine1 known-replica mymaster 10.0.0.18 6379
sentinel current-epoch 0
[root@redis-22 ~]#scp /etc/redis-sentinel.conf 10.0.0.58:/etc/
[root@redis-22 ~]#scp /etc/redis-sentinel.conf 10.0.0.34:/etc/

啓動哨兵

三臺哨兵服務器都要啓動

#確保每一個哨兵主機myid不一樣,要註釋
[root@redi s-s1ave1 ~]#vim /etc/redis-sentinel.conf
#sentine1 myid 50547f34ed71fd48c197924969937e738a39975
[root@redi s-slave2 ~]#vim /etc/redis-sentinel.conf
#sentine1 myid 50547f34ed71fd48c197924969937e738a39975
[root@redis-master ~]#systemctl enable --now redis-sentinel.service
[root@redis-s1ave1 ~]#systemctl enable --now redis-sentinel.service
[root@redis-slave2 ~]#systemctl enable --now redis-sentinel.service

若是是編譯安裝,在全部哨兵服務器執行下面操做啓動哨兵

#vim /apps /redis/etc/sentine1.conf
bind 0.0.0.o
port 26379
daemonize yes
pidfile "redis-sentinel.pid"
logfi1e "sentine1_26379.1og"
dir " /apps/redis/data"
sentine1 monitor mymaster 10.0.0.8 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 15000
sentine1 para11e1-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
#/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf

驗證哨兵:

ss -tnl |grep 26379

查看哨兵日誌

[root@C8-58]#tail -f /var/log/redis/sentinel.log

當前sentinel狀態

在sentinel狀態中尤爲是最後一行,涉及到masterlP是多少,有幾個slave,有幾個sentinels,必須是符合所有服務器數量

[root@C8-34 ~]# redis-cli  -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=2,sentinels=3
127.0.0.1:26379> 
#兩個s1ave,三個sentine1服務器,若是sentine1s值不符合,檢查myid可能衝突

[root@C8-22 ~]#  redis-cli  -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=2,sentinels=3

[root@C8-58]#
[root@C8-58]#redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=2,sentinels=3

中止Redis Master測試故障轉移

[root@C8-22 ~]# redis-cli -a 123456 -p 26379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=4,sentinels=3
127.0.0.1:26379> 
#如今的10.0.0.22 是主服務器

[root@C8-22 ~]# systemctl stop redis
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=4,sentinels=3
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.58:6379,slaves=4,sentinels=3
127.0.0.1:26379> 
#10.0.0.22 關閉服務之後 10.0.0.58 變成 主服務了

#日誌裏面也記錄了  10.0.0.58 成爲新的主節點
[root@C8-22 ~]# tail -f -n0 /var/log/redis/sentinel.log 
2611:X 07 Aug 2021 18:45:55.427 # +sdown master mymaster 10.0.0.22 6379
2611:X 07 Aug 2021 18:45:55.501 # +new-epoch 8
2611:X 07 Aug 2021 18:45:55.502 # +vote-for-leader 4c3e19074b91564ab99b66eb042913069e951c6f 8
2611:X 07 Aug 2021 18:45:56.188 # +config-update-from sentinel 4c3e19074b91564ab99b66eb042913069e951c6f 10.0.0.34 26379 @ mymaster 10.0.0.22 6379
2611:X 07 Aug 2021 18:45:56.188 # +switch-master mymaster 10.0.0.22 6379 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.23:6379 10.0.0.23 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.34:6379 10.0.0.34 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:56.189 * +slave slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:59.192 # +sdown slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
2611:X 07 Aug 2021 18:45:59.192 # +sdown slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379

故障轉移後的redis配置文件會被自動修改

[root@C8-34 ~]# grep '^replicaof' /etc/redis.conf
replicaof 10.0.0.58 6379

哨兵配置文件的sentinel monitor lP一樣也會被修改

[root@C8-34 ~]# grep '^[^#]' /etc/redis-sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel.log"
dir "/tmp"
sentinel myid 4c3e19074b91564ab99b66eb042913069e951c6f
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.58 6379 2   #自動被修改
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster 123456
protected-mode no
supervised systemd
sentinel config-epoch mymaster 8
sentinel leader-epoch mymaster 8
sentinel known-replica mymaster 10.0.0.22 6379
sentinel known-replica mymaster 10.0.0.34 6379
sentinel known-replica mymaster 10.0.0.23 6379
sentinel known-replica mymaster 10.0.0.35 6379
sentinel known-sentinel mymaster 10.0.0.22 26379 5e152ed23f189a8a5e2337c7a6f73ccc0e139328
sentinel known-sentinel mymaster 10.0.0.58 26379 0906444c851c4a671d10696aabc4a1370b54dc9b
sentinel current-epoch 8

[root@C8-22 ~]# grep '^[^#]' /etc/redis-sentinel.conf 
bind 0.0.0.0
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel.log"
dir "/tmp"
sentinel myid 5e152ed23f189a8a5e2337c7a6f73ccc0e139328
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.58 6379 2       #自動被修改
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster 123456
sentinel config-epoch mymaster 8
protected-mode no
supervised systemd
sentinel leader-epoch mymaster 8
sentinel known-replica mymaster 10.0.0.23 6379
sentinel known-replica mymaster 10.0.0.22 6379
sentinel known-replica mymaster 10.0.0.34 6379
sentinel known-replica mymaster 10.0.0.35 6379
sentinel known-sentinel mymaster 10.0.0.34 26379 4c3e19074b91564ab99b66eb042913069e951c6f
sentinel known-sentinel mymaster 10.0.0.58 26379 0906444c851c4a671d10696aabc4a1370b54dc9b
sentinel current-epoch 8

當前的新master狀態

[root@C8-58]#redis-cli  -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master   提高爲新的master 
connected_slaves:2
slave0:ip=10.0.0.34,port=6379,state=online,offset=2470761,lag=1
slave1:ip=10.0.0.23,port=6379,state=online,offset=2470894,lag=0
master_replid:a0350e113544c867896f36eff8fe98fd9acefba1
master_replid2:bafd8cb985865b7666333ade0d8e53d0f1036b4b
master_repl_offset:2471160
second_repl_offset:2345236
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2290158
repl_backlog_histlen:181003

另外一個slave指向新的master

[root@C8-34 ~]# redis-cli  -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.58
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:2495667
slave_priority:100
slave_read_only:1
connected_slaves:1
slave0:ip=10.0.0.35,port=6379,state=online,offset=2495534,lag=0
master_replid:a0350e113544c867896f36eff8fe98fd9acefba1
master_replid2:bafd8cb985865b7666333ade0d8e53d0f1036b4b
master_repl_offset:2495667
second_repl_offset:2345236
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2288525
repl_backlog_histlen:207143

恢復故障的原master從新加入redis集羣

[root@C8-22 ~]# systemctl restart redis
#哨兵自動修改下面的行,指向新的master
[root@C8-22 ~]# grep '^replicaof'  /etc/redis.conf 
replicaof 10.0.0.58 6379
#在原master上觀察:
 [root@C8-22 ~]# redis-cli -a 123456  info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.58
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:2580348
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a0350e113544c867896f36eff8fe98fd9acefba1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2580348
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2527147
repl_backlog_histlen:53202
[root@C8-22 ~]# redis-cli -a 123456  -p 26379 info sentinel
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.58:6379,slaves=4,sentinels=3
[root@C8-22 ~]#

觀察新master 上日誌:

root@C8-58]#tail -f /var/log/redis/sentinel.log
1960:X 07 Aug 2021 18:45:56.256 # +config-update-from sentinel 4c3e19074b91564ab99b66eb042913069e951c6f 10.0.0.34 26379 @ mymaster 10.0.0.22 6379
1960:X 07 Aug 2021 18:45:56.256 # +switch-master mymaster 10.0.0.22 6379 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.34:6379 10.0.0.34 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.23:6379 10.0.0.23 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:56.256 * +slave slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:59.293 # +sdown slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 18:45:59.293 # +sdown slave 10.0.0.35:6379 10.0.0.35 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 19:01:09.748 # -sdown slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379
1960:X 07 Aug 2021 19:01:19.705 * +reboot slave 10.0.0.22:6379 10.0.0.22 6379 @ mymaster 10.0.0.58 6379

sentinel運維

手動讓主節點下線redis
34.png
命令行修改優先級

127.0.0.1:6379> set a A
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379> 
[root@C8-58]#redis-cli -a 123456 -h 10.0.0.22
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.0.0.22:6379> set a A
OK

sentine1 failover <masterName>
範例:手動故障轉移
[root@centos8 ~]#vim /etc/redis.conf
replica-priority 10 #指定優先級,值越小sentine1會優先將之選爲新的master,默爲值爲100
[root@centos8 ~]#redis-cli -p 26379
127.0.0.1:26379> sentinel failover mymaster
oK
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=10.0.0.22:6379,slaves=4,sentinels=3

#10.0.0.22 再次成爲新的master

python鏈接Sentinel哨兵

[root@C8-34 ~]# vim sentinel_test.py

#!/usr/bin/python3 
import redis
from redis.sentinel import Sentinel
#鏈接哨兵的服務器
sentinel = Sentinel([('10.0.0.22',26379),('10.0.0.58',26379),('10.0.0.34',26379)],socket_timeout=0.5)
redis_auth_pass= "123456"

#mymaster是配置哨兵模式的redis集羣名稱,此爲默認值,實際名稱按照我的部署案例來填寫
#獲取主服務器地址
master = sentinel.discover_master('mymaster')
print(master)

#獲取從服務器的地址
slave = sentinel.discover_slaves('mymaster')
print(slave)

#獲取主服務器進行寫入
master = sentinel.master_for('mymaster',socket_timeout=0.5,
password=redis_auth_pass,db=0)
w_ret = master.set('name','wang')

#獲取從服務器讀取(默認是route-roubin)
slave = sentinel.slave_for('mymaster',socket_timeout=0.5,password=redis_auth_pass,db=0)
r_ret = slave.get('name')
print(r_ret)
#輸出wang

[root@C8-34 ~]# chmod +x sentinel_test.py 
[root@C8-34 ~]# ./sentinel_test.py 
('10.0.0.22', 6379)
[('10.0.0.23', 6379), ('10.0.0.58', 6379), ('10.0.0.34', 6379)]
b'wang'

redis cluster

redis
35.png
在哨兵sentinel機制中,能夠解決redis高可用問題,即當master故障後能夠自動將slave提高爲
master,從而能夠保證redis服務的正常使用,可是沒法解決redis單機寫入的瓶頸問題,即單機redis寫入性能受限於單機的內存大小、併發數量、網卡速率等因素。

早期Redis 分佈式集羣部署方案:
1.客戶端分區︰由客戶端程序決定key寫分配和寫入的redis node,可是須要客戶端本身處理寫入分配、高可用管理和故障轉移等
2.代理方案:基於三方軟件實現redis proxy,客戶端先鏈接之代理層,由代理層實現key的寫入分配,對客戶端來講是有比較簡單,可是對於集羣管節點增減相對比較麻煩,並且代理自己也是單點和性能瓶頸。
redis 3.0版本以後推出了無中心架構的redis cluster機制,在無中心的redis集羣當中,其每一個節點保存當前節點數據和整個集羣狀態,每一個節點都和其餘全部節點鏈接

Redis Cluster特色以下:
1.全部Redis節點使用(PING機制)互聯
⒉集羣中某個節點的是否失效,是由整個集羣中超過半數的節點監測都失效,才能算真正的失效

3.客戶端不須要proxy便可直接鏈接redis,應用程序中須要配置有所有的redis服務器IP
4.redis cluster把全部的redis node平均映射到0-16383個槽位(slot)上,讀寫須要到指定的redisnode上進行操做,所以有多少個redis node至關於redis併發擴展了多少倍,每一個redis node 承擔16384/N個槽位
5.Redis cluster預先分配16384個(slot)槽位,當須要在redis集羣中寫入一個key-value的時候,會使用CRC16(key) mod 16384以後的值,決定將key寫入值哪個槽位從而決定寫入哪個Redis節點上,從而有效解決單機瓶頸。

[root@C8-22 ~]# sed  -i.bak '/# cluster-enabled yes/a cluster-enabled yes' /etc/redis.conf
[root@C8-22 ~]# sed  -i.bak  '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf'  /etc/redis.conf
[root@C8-22 ~]# sed -i.bak '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no' /etc/redis.conf

sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf

==========================================================================================
sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf

sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no' /etc/redis.conf

==============================================================================================
[root@C8-34 ~]# sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf

執行meet 各個節點之間相互ping 通

[root@C8-22 ~]# ps aux |grep redis
redis       2611  0.3  1.4  53520 11360 ?        Ssl  18:27   0:46 /usr/bin/redis-sentinel 0.0.0.0:26379 [sentinel]
redis       2921  0.1  1.2  56592  9972 ?        Ssl  22:10   0:02 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root        2935  0.0  0.1  12108   972 pts/1    R+   22:35   0:00 grep --color=auto redis
root        2937  0.0  0.1  12108  1072 pts/3    S+   22:35   0:00 grep --color=auto redis
[root@C8-22 ~]# redis-cli  -a 123456 --no-auth-warning cluster nodes
185c2ff48708fb65cfbcf445a7a60fc6ca508246 :6379@16379 myself,master - 0 0 0 connected 5649 5798 15495

root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.21 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.23 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.34 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.35 6379
OK
[root@C8-22 ~]# redis-cli -h 10.0.0.22 -a 123456 --no-auth-warning cluster meet  10.0.0.58 6379
OK

#各個節點之間相互的ping 通了
[root@C8-22 ~]# redis-cli  -a 123456 --no-auth-warning cluster nodes
715d2c7dded4d1b944a4ff894d205190a2e275c6 10.0.0.34:6379@16379 slave 92659fe7e61ab39c3db658bed90e534143703c78 0 1628347372228 3 connected
563cebc14be57e76c45ef3b3451218c7646930e4 10.0.0.58:6379@16379 slave 92659fe7e61ab39c3db658bed90e534143703c78 0 1628347373000 3 connected
92659fe7e61ab39c3db658bed90e534143703c78 10.0.0.35:6379@16379 master - 0 1628347370213 3 connected 5649 5798 15495
c7f8594a7e02724c159f2e7edc46cfca8b622f68 10.0.0.21:6379@16379 master - 0 1628347373235 0 connected
185c2ff48708fb65cfbcf445a7a60fc6ca508246 10.0.0.22:6379@16379 myself,slave 715d2c7dded4d1b944a4ff894d205190a2e275c6 0 1628347372000 1 connected
b000b3f13a4a93da220f3f206170db78bf49d04a 10.0.0.23:6379@16379 slave 185c2ff48708fb65cfbcf445a7a60fc6ca508246 0 1628347374243 3 connected

#因爲沒有創建槽位,沒法建立Key
[root@centos8 ~]#redis-cli -a 123456--no-auth-warning set name wang
(error) CLUSTERDOWN Hash slot not served

[root@centos8~]#redis-c1i -h 10.0.0.8 -a 123456 --no-auth-warning clusterinfo
cluster_state:fai7
cluster_slots_assigned : 0
cluster_slots_ok : 0
cluster_slots_pfai1:0
cluster_slots_fai7:0
cluster_known_nodes : 6cluster_size:0
cluster_current_epoch : 5cluster_my_epoch : 3
cluster_stats_messages_ping_sent: 584
cluster_stats_messages_pong_sent : 145
cluster_stats_messages_meet_sent: 8
cluster_stats_messages_sent : 737
cluster_stats_messages_ping_received : 145
cluster_stats_messages_pong_received : 151

爲各個master節點指派槽位範圍

[root@C8-23 ~]# vim addsolt.sh
#!/bin/bash
host=$1
port=$2
starts=$3
end=$4
pass=123456
for slot in `seq ${starts} ${end}` ;do
        echo slot:$sort
        redis-cli -h ${host} -p ${port} -a ${pass} --no-auth-warning cluster addslots ${slot}
done

#爲三個master分配槽位,共16364/3=5,461.333333333333,平均每一個master分配5,461個槽位
[root@centos8 ~]#bash addslot.sh 10.0.0.21  6379  0 5461
[root@centos8 ~]#bash adds1ot.sh 10.0.0.22  6379 5462 10922
[root@centos8 ~]#bash addslot.sh 10.0.0.23  6379 10923 16383

---------------------------------------------------------------------------------------------
root@C8-21 ~]#  redis-cli  -a 123456 --no-auth-warning cluster info 
cluster_state:ok
cluster_slots_assigned:5465
cluster_slots_ok:5465
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:2
cluster_current_epoch:3
cluster_my_epoch:0
cluster_stats_messages_ping_sent:4746
cluster_stats_messages_pong_sent:4013
cluster_stats_messages_meet_sent:1
cluster_stats_messages_fail_sent:4
cluster_stats_messages_update_sent:4
cluster_stats_messages_sent:8768
cluster_stats_messages_ping_received:4009
cluster_stats_messages_pong_received:4181
cluster_stats_messages_meet_received:4
cluster_stats_messages_fail_received:1
cluster_stats_messages_publish_received:2876
cluster_stats_messages_update_received:105
cluster_stats_messages_received:11176

[root@C8-22 ~]# redis-cli  -a 123456 --no-auth-warning cluster info 
cluster_state:ok
cluster_slots_assigned:10924
cluster_slots_ok:10924
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:1
cluster_current_epoch:3
cluster_my_epoch:3
cluster_stats_messages_ping_sent:3541
cluster_stats_messages_pong_sent:3631
cluster_stats_messages_update_sent:757
cluster_stats_messages_sent:7929
cluster_stats_messages_ping_received:3631
cluster_stats_messages_pong_received:3541
cluster_stats_messages_received:7172

[root@C8-23 ~]# redis-cli  -a 123456 --no-auth-warning cluster info
cluster_state:ok
cluster_slots_assigned:10925
cluster_slots_ok:10925
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:1
cluster_current_epoch:3
cluster_my_epoch:3
cluster_stats_messages_ping_sent:5393
cluster_stats_messages_pong_sent:4981
cluster_stats_messages_meet_sent:2
cluster_stats_messages_publish_sent:2869
cluster_stats_messages_update_sent:1
cluster_stats_messages_sent:13246
cluster_stats_messages_ping_received:4978
cluster_stats_messages_pong_received:4828
cluster_stats_messages_meet_received:3
cluster_stats_messages_fail_received:2
cluster_stats_messages_publish_received:2293
cluster_stats_messages_update_received:2
cluster_stats_messages_received:12106
[root@C8-23 ~]# 
------------------------------------------------------------------------------------

#分配槽位後能夠建立key      -c 重定向
[root@C8-88-mariadb-bak ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning set a A
(error) MOVED 15495 10.0.0.98:6379
[root@C8-88-mariadb-bak ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  set a A
OK

#當全部的三個master分配完槽位後,能夠看到下面信息
[root@C8-21 ~]# redis-cli -h 10.0.0.21 -a 123456  --no-auth-warning cluster nodes
92659fe7e61ab39c3db658bed90e534143703c78 10.0.0.35:6379@16379 master - 0 1628351780000 3 connected 5649 5798 15495
185c2ff48708fb65cfbcf445a7a60fc6ca508246 10.0.0.22:6379@16379 slave 715d2c7dded4d1b944a4ff894d205190a2e275c6 0 1628351783544 3 connected
c7f8594a7e02724c159f2e7edc46cfca8b622f68 10.0.0.21:6379@16379 myself,master - 0 1628351781000 0 connected 0-5461
b000b3f13a4a93da220f3f206170db78bf49d04a 10.0.0.23:6379@16379 slave 185c2ff48708fb65cfbcf445a7a60fc6ca508246 0 1628351780521 3 connected
563cebc14be57e76c45ef3b3451218c7646930e4 10.0.0.58:6379@16379 slave c7f8594a7e02724c159f2e7edc46cfca8b622f68 0 1628351783000 3 connected
715d2c7dded4d1b944a4ff894d205190a2e275c6 10.0.0.34:6379@16379 slave 92659fe7e61ab39c3db658bed90e534143703c78 0 1628351782000 3 connected
[root@C8-21 ~]# redis-cli -h 10.0.0.21 -a 123456  --no-auth-warning cluster info
cluster_state:ok
cluster_slots_assigned:5465
cluster_slots_ok:5465
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:2
cluster_current_epoch:3
cluster_my_epoch:0
cluster_stats_messages_ping_sent:5044
cluster_stats_messages_pong_sent:4298
cluster_stats_messages_meet_sent:1
cluster_stats_messages_fail_sent:4
cluster_stats_messages_update_sent:4
cluster_stats_messages_sent:9351
cluster_stats_messages_ping_received:4294
cluster_stats_messages_pong_received:4479
cluster_stats_messages_meet_received:4
cluster_stats_messages_fail_received:1
cluster_stats_messages_publish_received:2876
cluster_stats_messages_update_received:196
cluster_stats_messages_received:11850

指定各個節點的主從關係

#查看各個節點之間的主次關係:
[root@C8-68-DNS ~]# redis-cli -h 10.0.0.68 -a 123456  --no-auth-warning cluster nodes
73d0503e5289e1d975ea453833f37357b6a771cb 10.0.0.158:6379@16379 master - 0 1628381587000 5 connected
8968f3f46e326cb95d1a21b07d8d9c143c679608 10.0.0.138:6379@16379 master - 0 1628381588129 4 connected
46342d277e8f6d769e70e07061bce5ee652869f3 10.0.0.178:6379@16379 master - 0 1628381589138 3 connected
8a4dbebf4675d4433aa6225f63d99faf41703f8b 10.0.0.68:6379@16379 myself,master - 0 1628381588000 2 connected 0-5461
2453a2fa33c90b67bd36407bbc1dbc8fa713992a 10.0.0.88:6379@16379 master - 0 1628381586113 1 connected 5462-10922
95af9d679b1510c654d778a38155cfacbee4331d 10.0.0.98:6379@16379 master - 0 1628381588000 0 connected 10923-16383

[root@C8-68-DNS ~]# redis-cli -a 123456 --no-auth-warning -h 10.0.0.158  cluster replicate  8a4dbebf4675d4433aa6225f63d99faf41703f8b
OK
[root@C8-68-DNS ~]# redis-cli -a 123456 --no-auth-warning -h 10.0.0.138  cluster replicate 2453a2fa33c90b67bd36407bbc1dbc8fa713992a
OK
[root@C8-68-DNS ~]# redis-cli -a 123456 --no-auth-warning -h 10.0.0.178  cluster replicate 95af9d679b1510c654d778a38155cfacbee4331d
OK

#都成爲從節點
10.0.0.158 
10.0.0.138
10.0.0.178 

[root@C8-68-DNS ~]#  redis-cli  -a 123456 --no-auth-warning cluster info 
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:2
cluster_stats_messages_ping_sent:4699
cluster_stats_messages_pong_sent:4487
cluster_stats_messages_meet_sent:9
cluster_stats_messages_sent:9195
cluster_stats_messages_ping_received:4487
cluster_stats_messages_pong_received:4499
cluster_stats_messages_received:8986

#確節點關係之後能夠看到主從信息,例如:
[root@C8-88-mariadb-bak ~]# redis-cli -h 10.0.0.68 -a 123456 --no-auth-warning info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.158,port=6379,state=online,offset=1498,lag=0
master_replid:a8a4a351de058b1c9e878f9acf92d693077a790e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1512
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1512
[root@C8-88-mariadb-bak ~]# redis-cli -h 10.0.0.158 -a 123456 --no-auth-warning info replication
# Replication
role:slave
master_host:10.0.0.68
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:1526
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a8a4a351de058b1c9e878f9acf92d693077a790e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1526
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1526

查看主從節關係及槽位信息

[root@C8-98-slave-DNS ~]# redis-cli -a 123456 -h 10.0.0.98   --no-auth-warning  cluster slots
1) 1) (integer) 10923
   2) (integer) 16383
   3) 1) "10.0.0.98"
      2) (integer) 6379
      3) "95af9d679b1510c654d778a38155cfacbee4331d"
   4) 1) "10.0.0.178"
      2) (integer) 6379
      3) "46342d277e8f6d769e70e07061bce5ee652869f3"
2) 1) (integer) 0
   2) (integer) 5461
   3) 1) "10.0.0.158"
      2) (integer) 6379
      3) "73d0503e5289e1d975ea453833f37357b6a771cb"
   4) 1) "10.0.0.68"
      2) (integer) 6379
      3) "8a4dbebf4675d4433aa6225f63d99faf41703f8b"
3) 1) (integer) 5462
   2) (integer) 10922
   3) 1) "10.0.0.88"
      2) (integer) 6379
      3) "2453a2fa33c90b67bd36407bbc1dbc8fa713992a"
   4) 1) "10.0.0.138"
      2) (integer) 6379
      3) "8968f3f46e326cb95d1a21b07d8d9c143c679608"

或者不寫主機IP
redis-cli -a 123456    --no-auth-warning  cluster slots

驗證redis訪問:

-c 表示以集羣的方式

[root@C8-98-slave-DNS ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -c   -a 123456 -h 10.0.0.68  --no-auth-warning   set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -c   -a 123456 -h 10.0.0.68  --no-auth-warning   set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  set d D
OK
[root@C8-98-slave-DNS ~]# redis-cli  -a 123456 -h 10.0.0.68  --no-auth-warning -c  get d
"D"

實戰案例:基於Redis 5的redis cluster部署

官方文檔: https://redis.io/topics/cluster-tutorial
redis cluster相關命令
範例:查看--cluster 選項幫助

[root@C8-98-slave-DNS ~]# redis-cli  --cluster help
Cluster Manager Commands:
  create         host1:port1 ... hostN:portN
                 --cluster-replicas <arg>
  check          host:port
                 --cluster-search-multiple-owners
  info           host:port
  fix            host:port
                 --cluster-search-multiple-owners
  reshard        host:port
                 --cluster-from <arg>
                 --cluster-to <arg>
                 --cluster-slots <arg>
                 --cluster-yes
                 --cluster-timeout <arg>
                 --cluster-pipeline <arg>
                 --cluster-replace
  rebalance      host:port
                 --cluster-weight <node1=w1...nodeN=wN>
                 --cluster-use-empty-masters
                 --cluster-timeout <arg>
                 --cluster-simulate
                 --cluster-pipeline <arg>
                 --cluster-threshold <arg>
                 --cluster-replace
  add-node       new_host:new_port existing_host:existing_port
                 --cluster-slave
                 --cluster-master-id <arg>
  del-node       host:port node_id
  call           host:port command arg arg .. arg
  set-timeout    host:port milliseconds
  import         host:port
                 --cluster-from <arg>
                 --cluster-copy
                 --cluster-replace
  help           

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

#手動修改配置文件

[root@redis-node1 ~]vim /etc/redis.conf
bind 0.0.0.0
masterauth 123456#建議配置,不然後期的master和s7ave主從複製沒法成功,還需再配置requirepass 123456
cluster-enabled yes #取消此行註釋,必須開啓集羣,開啓後redis進程會有cluster顯示cluster-config-file nodes-6379.conf #取消此行註釋,此爲集羣狀態文件,記錄主從關係及s7ot範圍信息,由redis cluster集羣自動建立和維護
cluster-require-ful7-coverage no#默認值爲yes,設爲no能夠防止一個節點不可用致使整個cluster不可能

#或者執行命令:

#從新安裝redis,修改配置文件
sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf
#重啓服務
#此時的集羣之間是沒有任何關係的
[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456  cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,master - 0 0 0 connected

systemctl restart redis

meet --->設置槽位---->設置主從
如今一條命令搞定:

#注意進程有[cluster]狀態
[root@C8-178-mariadb-slave-1 ~]# ps -ef |grep redis
redis      25848       1  0 09:32 ?        00:00:00 /usr/bin/redis-server 0.0.0.0:6379 [cluster]
root       25863   25024  0 09:42 pts/1    00:00:00 grep --color=auto redis

建立集羣:

1.每一個redis 節點採用相同的硬件配置、相同的密碼、相同的redis版本

⒉.全部redis服務器必須沒有任何數據

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 --cluster create 10.0.0.68:6379 10.0.0.88:6379 10.0.0.98:6379 10.0.0.178:6379 10.0.0.138:6379  10.0.0.168:6379 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.178:6379 to 10.0.0.68:6379
Adding replica 10.0.0.138:6379 to 10.0.0.88:6379
Adding replica 10.0.0.168:6379 to 10.0.0.98:6379
M: a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379
   slots:[0-5460] (5461 slots) master
M: 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379
   slots:[5461-10922] (5462 slots) master
M: 4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379
   slots:[10923-16383] (5461 slots) master
S: 50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379
   replicates a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33
S: d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379
   replicates 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5
S: ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379
   replicates 4f5221ac1cce03a4f57807cb51b09f53ad154f02
Can I set the above configuration? (type 'yes' to accept): yes  #輸入yes 建立槽位
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379     # M 爲master
   slots:[0-5460] (5461 slots) master #當前槽位的起始位置    已經分配到得槽位
   1 additional replica(s)  #分配一個從節點
M: 4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379   # S爲slave
   slots: (0 slots) slave
   replicates a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33
S: ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379
   slots: (0 slots) slave   #沒有分配到槽位
   replicates 4f5221ac1cce03a4f57807cb51b09f53ad154f02  #對應的master的ID
M: 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5
[OK] All nodes agree about slots configuration.  #全部槽位分配完成
>>> Check for open slots... #檢查打開的槽位
>>> Check slots coverage... #檢查槽位的覆蓋的範圍
[OK] All 16384 slots covered.  #全部的槽位分配完成

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379@16379 master - 0 1628389147000 1 connected 0-5460
ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379@16379 slave 4f5221ac1cce03a4f57807cb51b09f53ad154f02 0 1628389148009 3 connected
d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379@16379 slave 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 0 1628389147000 5 connected
4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379@16379 master - 0 1628389144000 3 connected 10923-16383
5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379@16379 master - 0 1628389149016 2 connected 5461-10922
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,slave a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 0 1628389148000 4 connected

查看主從狀態

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456  info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.68
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:448
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a45e1f15dd97baf651b38adad678bc8a62fbea09
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:448
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:448
[root@C8-178-mariadb-slave-1 ~]#

查看指定master節點的slave節點信息

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster info
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:220
cluster_stats_messages_pong_sent:227
cluster_stats_messages_meet_sent:2
cluster_stats_messages_sent:449
cluster_stats_messages_ping_received:224
cluster_stats_messages_pong_received:222
cluster_stats_messages_meet_received:3
cluster_stats_messages_received:449

如下命令查看指定master節點的slave節點信息,其中

a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 爲主節點信息

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379@16379 master - 0 1628391529000 1 connected 0-5460
ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379@16379 slave 4f5221ac1cce03a4f57807cb51b09f53ad154f02 0 1628391531536 3 connected
d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379@16379 slave 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 0 1628391530000 5 connected
4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379@16379 master - 0 1628391530528 3 connected 10923-16383
5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379@16379 master - 0 1628391528512 2 connected 5461-10922
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,slave a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 0 1628391530000 4 connected
[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456   cluster slaves a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
1) "50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 myself,slave a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 0 1628391537000 4 connected"
[root@C8-178-mariadb-slave-1 ~]#

驗證羣集狀態

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 cluster info
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6 #節點數
cluster_size:3       #三個羣集
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:3254
cluster_stats_messages_pong_sent:3248
cluster_stats_messages_meet_sent:2
cluster_stats_messages_sent:6504
cluster_stats_messages_ping_received:3245
cluster_stats_messages_pong_received:3256
cluster_stats_messages_meet_received:3
cluster_stats_messages_received:6504
[root@C8-178-mariadb-slave-1 ~]# 

#查看容易節點的羣集狀態:

[root@C8-178-mariadb-slave-1 ~]# redis-cli -a 123456 --cluster info 10.0.0.168:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.0.0.68:6379 (a0fe49b2...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.88:6379 (5cfc8c2f...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.98:6379 (4f5221ac...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.

查看集羣node對應關係

[root@redis-node1 ~]#redis-cli -a 123456 CLUSTER NODES

驗證集羣寫入key

redis

redis cluster寫入key

#通過算法計算,當前key的槽位須要寫入指定的node
[root@redis-node1 ~]#redis-cli -a 123456 -h 10.0.0.8 SET key1 values1
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
(error)MOVED 9189 10.0.0.18:6379#槽位不在當前node因此沒法寫入
[root@redis-node1 ~]#redis-cli -a 123456 -h 10.0.0.18 SET key1 values1
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
oK
#指定node可寫入
[root@redis-node1 ~]#redis-c1i -a 123456 -h 10.0.0.18 GET key1
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
"values1"
#對應的slave節點能夠KEYS*,但GET key1失敗,能夠到master上執行GET key1
[root@redis-node1 ~]#redis-cli -a 123456 -h 10.0.0.48 KEYS "*"
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
1) "key1"
[root@redis-nodel ~]#redis-cli -a 123456 -h 10.0.0.48 GET key1
warning: using a password with '-a' or '-u' option on the command 1ine interfacemay not be safe.
(error) MOVED 9189 10.0.0.18:6379

redis cluster 計算key 所屬的 slot

[root@C8-178-mariadb-slave-1 ~]# 
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.178 -a 123456 --no-auth-warning cluster keyslot hello
(integer) 866  #查看所屬的槽位
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.178 -a 123456 --no-auth-warning set hello magedu
(error) MOVED 866 10.0.0.68:6379
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.68 -a 123456 --no-auth-warning set hello magedu
OK
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.178 -a 123456 --no-auth-warning cluster keyslot name
(integer) 5798
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.68 -a 123456 --no-auth-warning set name wang
(error) MOVED 5798 10.0.0.88:6379
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.88 -a 123456 --no-auth-warning set name wang
OK
[root@C8-178-mariadb-slave-1 ~]# redis-cli -h 10.0.0.88 -a 123456 --no-auth-warning get name
"wang"

#使用-c 用集羣模式
[root@C8-178-mariadb-slave-1 ~]# redis-cli  -c   -h 10.0.0.88 -a 123456 --no-auth-warning cluster keyslot linux
(integer) 12299
[root@C8-178-mariadb-slave-1 ~]# redis-cli  -c   -h 10.0.0.88 -a 123456 --no-auth-warning set linux love
OK
[root@C8-178-mariadb-slave-1 ~]# redis-cli  -c   -h 10.0.0.88 -a 123456 --no-auth-warning get linux
"love"

模擬master故障,對應的slave節點自動提高爲新master

[root@C8-68-DNS ~]# redis-cli -a 123456 
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> shutdown   #關閉服務
not connected> exit
[root@C8-68-DNS ~]# ss -tnl
State                Recv-Q               Send-Q                             Local Address:Port                              Peer Address:Port               
LISTEN               0                    10                                     127.0.0.1:53                                     0.0.0.0:*                  
LISTEN               0                    128                                      0.0.0.0:22                                     0.0.0.0:*                  
LISTEN               0                    128                                    127.0.0.1:953                                    0.0.0.0:*                  
LISTEN               0                    10                                         [::1]:53                                        [::]:*                  
LISTEN               0                    128                                         [::]:22                                        [::]:*                  
LISTEN               0                    128                                            *:23                                           *:*                  
LISTEN               0                    128                                        [::1]:953                                       [::]:*                  

[root@C8-68-DNS ~]# redis-cli -a 123456 --cluster info 10.0.0.68:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.68:6379: Connection refused
[root@C8-68-DNS ~]# redis-cli -a 123456 --cluster info 10.0.0.88:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.68:6379: Connection refused
10.0.0.88:6379 (5cfc8c2f...) -> 2 keys | 5462 slots | 1 slaves.
10.0.0.178:6379 (50676f5d...) -> 2 keys | 5461 slots | 0 slaves.   #10.0.0.178成爲新的master
10.0.0.98:6379 (4f5221ac...) -> 1 keys | 5461 slots | 1 slaves.
[OK] 5 keys in 3 masters.
0.00 keys per slot on average.

[root@C8-68-DNS ~]# redis-cli -a 123456 --cluster check  10.0.0.88:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.68:6379: Connection refused
10.0.0.88:6379 (5cfc8c2f...) -> 2 keys | 5462 slots | 1 slaves.
10.0.0.178:6379 (50676f5d...) -> 2 keys | 5461 slots | 0 slaves.
10.0.0.98:6379 (4f5221ac...) -> 1 keys | 5461 slots | 1 slaves.
[OK] 5 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.0.88:6379)
M: 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379
   slots:[0-5460] (5461 slots) master
S: ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 4f5221ac1cce03a4f57807cb51b09f53ad154f02
M: 4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

[root@C8-68-DNS ~]# redis-cli -a 123456 -h 10.0.0.178 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:0
master_replid:d5e9c0e26314f0fdf735e655f3342427b506ba3d
master_replid2:a45e1f15dd97baf651b38adad678bc8a62fbea09
master_repl_offset:7696
second_repl_offset:7697
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:7696
#重啓以前的master
[root@C8-68-DNS ~]# systemctl start redis

#查看配置文件,10.0.0.68 自動成爲10.0.0.178的slaves
[root@C8-68-DNS ~]# cat /var/lib/redis/nodes-6379.conf 
d7555b90d3b5ac854e1a227e17b4f43fe6fb78bd 10.0.0.138:6379@16379 slave 5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 0 1628394804924 5 connected
50676f5d541925735eb930dea4f706b5ef5b456c 10.0.0.178:6379@16379 master - 0 1628394804924 7 connected 0-5460
ce459c0f1f09093fe61df351bd7c99cdb60a07bf 10.0.0.168:6379@16379 slave 4f5221ac1cce03a4f57807cb51b09f53ad154f02 1628394804917 1628394804916 6 connected
a0fe49b2146c7b1804b389ebe0fcdf3bf9600d33 10.0.0.68:6379@16379 myself,slave 50676f5d541925735eb930dea4f706b5ef5b456c 0 1628394804916 1 connected
4f5221ac1cce03a4f57807cb51b09f53ad154f02 10.0.0.98:6379@16379 master - 0 1628394804924 3 connected 10923-16383
5cfc8c2fe4616d4bd81cad8f811e18622f7ed7f5 10.0.0.88:6379@16379 master - 1628394804917 1628394804916 2 connected 5461-10922
vars currentEpoch 7 lastVoteEpoch 0
[root@C8-68-DNS ~]# redis-cli -a 123456 -h 10.0.0.178 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.68,port=6379,state=online,offset=7934,lag=0
master_replid:d5e9c0e26314f0fdf735e655f3342427b506ba3d
master_replid2:a45e1f15dd97baf651b38adad678bc8a62fbea09
master_repl_offset:7934
second_repl_offset:7697
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:7934

實戰案例:基於Redis 4的redis cluster部署

準備redis Cluster基本配置
1.每一個redis節點採用相同的硬件配置、相同的密碼、相同的redis版本

2.全部redis服務器必須沒有任何數據

3.準備三臺CentOS7主機,已編譯安裝好redis,各啓動兩個redis實例,分別使用6379和6380端口,從而模擬實現6臺redis實例

[root@C8-98-slave-DNS ~]# cat redis_instll.sh 
#!/bin/bash
#*****************************************************************************
#*******************************************************************************
. /etc/init.d/functions
#VERSION=redis-6.2.5
VERSION=redis-4.0.14
PASSWORD=123456
INSTALL_DIR=/apps/redis
install(){
yum -y install wget make  gcc jemalloc-devel || { action "軟件安裝失敗,檢查網絡配置" false;exit;}
wget https://download.redis.io/releases/${VERSION}.tar.gz  || { action "Redis reload faild" false;exit; }
tar xf ${VERSION}.tar.gz
cd ${VERSION}
make PREFIX=${INSTALL_DIR} install && action "Redis 編譯完成" || { action "Redis 編譯安裝失敗" false;exit; }
ln -s ${INSTALL_DIR}/bin/redis-* /usr/bin/
mkdir -p ${INSTALL_DIR}/{etc,log,data,run}
cp redis.conf ${INSTALL_DIR}/etc/
sed -i  's/bind 127.0.0.1/bind 0.0.0.0/'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/# requirepass/a requirepass $PASSWORD"'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^dir .*/c dir ${INSTALL_DIR}/data/'     ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/logfile .*/c logfile ${INSTALL_DIR}/log/redis-6397.log'  ${INSTALL_DIR}/etc/redis.conf    
sed -i  's/^pidfile .*/c pidfile ${INSTALL_DIR}/run/redis-6393.pid'  ${INSTALL_DIR}/etc/redis.conf
sed -i  's/daemonize .*/c  daemonize  yes'  ${INSTALL_DIR}/etc/redis.conf

if id redis &> /dev/null;then
    action "redis 用戶存在" false
else
    useradd -r -s /sbin/nologin redis
    action "redis 用戶建立成功"
fi

chown -R redis.redis ${INSTALL_DIR}
cat >>/etc/sysctl.conf <<EOF
net.core.somaxconn = 1024
vm.overcommit_memory = 1
EOF
sysctl -p
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >>/etc/rc.d/rc.local 
chmod +x /etc/rc.d/rc.local
/etc/rc.d/rc.local 
cat > /usr/lib/systemd/system/redis6379.service <<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target

[Service]
ExecStart=${INSTALL_DIR}/bin/redis-server ${INSTALL_DIR}/etc/redis.conf  --supervised systemd
ExecStop=/bin/kill -s QUIT \$MAINPID
#Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemct  enable --now redis6379  &>/dev/null && action "Redis 啓動成功,信息以下:" || { action "redis 啓動失敗" false;exit; }
redis-cli -a $PASSWORD INFO  server 2>/dev/null
}
install

[root@C8-98-slave-DNS ~]# sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /apps/redis/etc/redis.conf 

[root@C8-98-slave-DNS ~]# ps -ef |grep redis
root        7909       1  0 14:06 ?        00:00:00 /apps/redis/bin/redis-server 0.0.0.0:6379 [cluster]
root        7915    1672  0 14:06 pts/1    00:00:00 grep --color=auto redis

 /apps/redis/bin/redis-server  /apps/redis/etc/redis.conf  #啓動服務

 #複製 redis-trib.rb
 [root@C8-68-DNS redis-4.0.14]# cp src/redis-trib.rb /usr/bin/

準備redis-trib.rb工具

Redis 3和4版本須要使用到集羣管理工具redis-trib.rb,這個工具是redis官方推出的管理redis集羣的工具,集成在redis的源碼src目錄下,是基於redis提供的集羣命令封裝成簡單、便捷、實用的操做工具,redis-trib.rb是redis做者用ruby開發完成的,centos 7系統yum安裝的ruby存在版本較低問題,以下:

[root@C8-68-DNS redis-4.0.14]# ll /usr/bin/redis-trib.rb 
-rwxr-xr-x 1 root root 65991 Aug  8 14:18 /usr/bin/redis-trib.rb
[root@C8-68-DNS redis-4.0.14]# /usr/bin/redis-trib.rb  #缺乏ruby環境沒法運行rb腳本
/usr/bin/env: ‘ruby’: No such file or directory

#Centos 7帶的ruby版本太低,沒法運行上面ruby腳本,須要安裝2.3以上版本,安裝rubygems依賴ruby自動安裝

[root@C8-68-DNS redis-4.0.14]# yum install rubygems -y
[root@C8-68-DNS redis-4.0.14]# gem install redis     #gem至關於python裏pip和7inux的yum
Fetching: redis-4.4.0.gem (100%)
Successfully installed redis-4.4.0
1 gem installed

[root@C8-68-DNS redis-4.0.14]# yum install gcc openssl-devel zlib-devel -y

解決ruby版本較低問題:

[root@redis-node1 ~]#yum -y insta1l gcc openss7-deve1 zlib-deve1
[root@redis-node1 ~]#wget https:/ /cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.gz
[root@redis-node1 ~]#tar xf ruby-2.5.5.tar.gz[root@redis-node1 ~]#cd ruby-2.5.5
[root@redis-node1 ruby-2.5.5]# . / configure
[root@redis-node1 ruby-2.5.5]#make -j 2 && make insta77
[root@redis-node1 ruby-2.5.5]#which ruby
/usr/ loca1/bin/ ruby
[root@redis-node1 ruby-2.5.5]#ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260)[x86_64-7inux]
[root@redis-node1 ruby-2.5.5]#exit#注意須要從新登陸

redis-trib.rb仍沒法運行錯誤

[root@redis-node1 ~]#redis-trib.rb -hTraceback (most recent ca17 last):
2 : from /usr/bin/redis-trib.rb:25:in '<main>'
1: from /usr/loca1/1ib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in'require '
/usr/loca1/1ib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in require ' :cannot load such file -- redis (LoadError)

解決上述錯誤:

[root@redis-node1 ~]#gem install redis -v 4.1.3 #注意須要從新登陸再執行,不然沒法識別到新ruby版本
Fetching: redi s-4.1.3.gem (100%)successful1y insta1led redi s-4.1.3Parsing documentation for redis-4.1.3
Insta1ling ri documentation for redis-4.1.3
Done insta7ling documentation for redis after 1 seconds1 gem insta7led
#gem uninsta17 redis能夠卸載已安裝好redis模塊

若是沒法在線安裝,能夠下載redis模塊安裝包離線安裝

#https: / /rubygems.org/gems/redis #先下載redis模塊安裝包
[root@redis-node1 ~]#gem instal1 -7 redis-4.1.3.gem #安裝redis模塊

redis-trib.rb命令用法

[root@C8-68-DNS redis-4.0.14]# /usr/bin/redis-trib.rb
Usage: redis-trib <command> <options> <arguments ...>

  create          host1:port1 ... hostN:portN  #建立集羣
                  --replicas <arg><arg>#指定每一個master的副本數量,即對應s1ave數量,通常爲1
  check           host:port #檢查集羣信息
  info            host:port #查看集羣主機信息
  fix             host:port #修復集羣
                  --timeout <arg>
  reshard         host:port  #在線熱遷移集羣指定主機的slots數據
                  --from <arg>
                  --to <arg>
                  --slots <arg>
                  --yes
                  --timeout <arg>
                  --pipeline <arg>
  rebalance       host:port   #平衡集羣中各主機的slot數量
                  --weight <arg>
                  --auto-weights
                  --use-empty-masters
                  --timeout <arg>
                  --simulate
                  --pipeline <arg>
                  --threshold <arg>
  add-node        new_host:new_port existing_host:existing_port  #添加主機到集羣
                  --slave
                  --master-id <arg>
  del-node        host:port node_id   #刪除主機
  set-timeout     host:port milliseconds  #設置節點的超時時間
  call            host:port command arg arg .. arg #在集羣的全部節點上執行命令
  import          host:port  #導入外部的redis服務器的數據到當前的集羣
                  --from <arg>
                  --copy
                  --replace
  help            (show this help)

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
[root@C8-68-DNS redis-4.0.14]#

修改redis登陸的密碼

[root@C8-68-DNS redis-4.0.14]# find / -name "client.rb"
/usr/local/share/gems/gems/redis-4.4.0/lib/redis/client.rb

[root@C8-68-DNS redis-4.0.14]# grep "password: 123456"  /usr/local/share/gems/gems/redis-4.4.0/lib/redis/client.rb
      password: 123456,

建立集羣:

[root@C8-68-DNS redis-4.0.14]# redis-trib.rb create --replicas 1  10.0.0.68:6379 10.0.0.88:6379 10.0.0.98:6379  10.0.0.138:6379 10.0.0.158:6379 10.0.0.168:6379
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
10.0.0.68:6379
10.0.0.88:6379
10.0.0.98:6379
Adding replica 10.0.0.158:6379 to 10.0.0.68:6379
Adding replica 10.0.0.168:6379 to 10.0.0.88:6379
Adding replica 10.0.0.138:6379 to 10.0.0.98:6379
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:0-5460 (5461 slots) master
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:5461-10922 (5462 slots) master
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:10923-16383 (5461 slots) master
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   slots: (0 slots) slave
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

若是有以前的操做致使Redis集羣建立報錯,則執行清空數據和集羣命令:
127.0.0.1:6379> FLUSHALL
127.0.0.1:6379>cluster resetOK

查看redis cluster集羣狀態

自動生成配置文件記錄master/slave對應關係

[root@C8-68-DNS data]# find / -name "nodes-6379.conf"
/root/nodes-6379.conf
[root@C8-68-DNS data]# cat /root/nodes-6379.conf 
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave b8a9fdb19a529d36238eed905bcf7d251e34b059 0 1628407512309 5 connected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628407511000 2 connected 5461-10922
b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379@16379 myself,master - 0 1628407512000 1 connected 0-5460
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628407513000 4 connected
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 master - 0 1628407512000 3 connected 10923-16383
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave 83fb5104b17ab176b08b4679af77548ca9680a0f 0 1628407513318 6 connected
vars currentEpoch 6 lastVoteEpoch 0

查看狀態:

[root@C8-68-DNS data]# redis-trib.rb info 10.0.0.168:6379
10.0.0.98:6379 (8dfe226b...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.88:6379 (83fb5104...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.68:6379 (b8a9fdb1...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
[root@C8-68-DNS data]# 

[root@C8-68-DNS data]# redis-cli -a 123456
Warning: Using a password with '-a' option on the command line interface may not be safe.
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:434
cluster_stats_messages_pong_sent:435
cluster_stats_messages_sent:869
cluster_stats_messages_ping_received:430
cluster_stats_messages_pong_received:434
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:869

[root@C8-68-DNS data]# redis-cli -a 123456 -p 6379 cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave b8a9fdb19a529d36238eed905bcf7d251e34b059 0 1628408002000 5 connected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628408004609 2 connected 5461-10922
b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379@16379 myself,master - 0 1628408002000 1 connected 0-5460
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628408001581 4 connected
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 master - 0 1628408002590 3 connected 10923-16383
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave 83fb5104b17ab176b08b4679af77548ca9680a0f 0 1628408003600 6 connected

[root@C8-68-DNS data]# redis-cli -a 123456 -p 6379 info replication
Warning: Using a password with '-a' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.158,port=6379,state=online,offset=756,lag=1
master_replid:3ce3556a1d59ad1d594da1c6900bf45e9d8d3342
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:756
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:756
[root@C8-68-DNS data]#

Redis cluster集羣節點維護

redis集羣運行以後,不免因爲硬件故障、網絡規劃、業務增加等緣由對已有集羣進行相應的調整,好比:增長Redis node節點、減小節點、節點遷移、更換服務器等。增長節點和刪除節點會涉及到已有的槽位從新分配及數據遷移。

集羣維護之動態擴容
實戰案例:
因公司業務發展迅猛,現有的三主三從的redis cluster架構可能沒法知足現有業務的併發寫入需求,所以公司緊急採購兩臺服務器10.0.0.68,10.0.0.78,須要將其動態添加到集羣當中,但不能影響業務使用和數據丟失。
注意:生產環境通常建議master節點爲奇數個,好比:3,5,7,以防止腦裂現象

添加節點準備

增長Redis node節點,須要與以前的Redis node版本相同、配置一致,而後分別再啓動兩臺Redis

node 要是一主一從

#配置兩個從節點:

sed  -i.bak  -e  '/# cluster-enabled yes/a cluster-enabled yes'  -e '/# cluster-config-file nodes-6379.conf/a  cluster-config-file nodes-6379.conf' -e  '/cluster-require-full-coverage yes/c  cluster-require-full-coverage  no'  -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth .*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/'   /etc/redis.conf

/apps/redis/bin/redis-server /apps/redis/etc/redis.conf

[root@C8-68-DNS ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave,fail 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 1628417548785 1628417548785 4 disconnected
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave,fail b8a9fdb19a529d36238eed905bcf7d251e34b059 1628417548785 1628417548785 5 disconnected
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave,fail 83fb5104b17ab176b08b4679af77548ca9680a0f 1628417548798 1628417548785 6 disconnected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628417790437 2 connected 5461-10922
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 master - 0 1628417792463 3 connected 10923-16383
b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379@16379 myself,master - 0 1628417790000 1 connected 0-5460

添加新的master節點到集羣

使用如下命令添加新節點,要添加的新redis節點IP和端口添加到的已有的集羣中任意節點的IP:端口
add-node new_host:new_port existing_host:existing_port [--slave --master-id<arg>]
#說明:
new_host:new_port #爲新添加的主機的IP和端口
existing_host:existing_port #爲已有的集羣中任意節點的IP和端口

Redis 3/4添加方式:

#把新的Redis節點10.0.0.19 和10.0.0.20 添加到當前Redis集羣當中。
[root@C8-68-DNS ~]# redis-trib.rb add-node 10.0.0.20:6379  10.0.0.68:6379
[root@C8-68-DNS ~]# redis-trib.rb add-node 10.0.0.19:6379  10.0.0.68:6379

Redis 5添加方式:

#將一臺新的主機10.0.0.68加入集羣,如下示例中10.0.0.58能夠是任意存在的集羣節點

[root@redis-node1 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.68:6379  <當前任意集羣節點>:6379

#觀察到該節點已經加入成功,但此節點上沒有s1ot位,也無從節點,並且新的節點是master
[root@redis-node1 ~]#redis-cli -a 123456 --cluster info 10.0.0.8:6379
warning: using a password with '-a' or '-u' option on the command line interfacemay not be safe.
10.0.0.8:6379 (cb028b83...) -> 6672 keys | 5461 slots | 1 slaves.10.0.0.68:6379 (d6e2eca6.. .) -> 0 keys | 0 slots | o s1aves.
10.0.0.48:6379 (d04e524d...) -> 6679 keys | 5462 slots | 1 slaves.10.0.0.28:6379 (d34da866...) -> 6649 keys | 5461 slots | 1 slaves.[OK] 20000 keys in 5 masters.

在新的master上從新分配槽位

新的node節點加到集羣以後,默認是master節點,可是沒有slots,須要從新分配
添加主機以後須要對添加至集羣種的新主機從新分片,不然其沒有分片也就沒法寫入數據。

注意:從新分配槽位須要清空數據,因此須要先備份數據,擴展後再恢復數據
Redis 3/4:

[root@redis-node1 ~]# redis-trib.rb check 10.0.0.67:6379   #當前狀態
[root@redis-node1 ~]# redis-trib.rb reshard <集羣中任意節點>:6379  #從新分片
[root@redis-node1 ~]# redis-trib.rb fix 10.0.0.68:6379#若是遷移失敗使用此命令修復集羣

Redis 5

[root@redis-node1 ~]#redis-cli -a 123456 --cluster reshard  <當前任意集羣節點>:6379
warning: using a password with '-a’ or '-u' option on the command line interfacemay not be safe.
How many slots do you want to move (from 1 to 16384)?4096 #新分配多少個槽位=16384/master個數
what is the receiving node ID? d6e2eca6b338b717923f64866bd31d42e52edc98#新的master的ID
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.Type 'done' once you entered a17 the source nodes IDs.
source node #1: all #將哪些源主機的槽位分配給新的節點,a11是自動在全部的redis node選擇劃分,若是是從redis cluster刪除某個主機能夠使用此方式將指定主機上的槽位所有移動到別的redis主機

Do you want to proceed with the proposed reshard plan (yes/no)?yes #確認分配......
Moving slot 12280 from 10.0.0.28:6379 to 10.0.0.68:6379: .Moving slot 12281 from 10.0.0.28:6379 to 10.0.0.68:6379: .Moving slot 12282 from 10.0.0.28:6379 to 10.0.0.68:6379:Moving slot 12283 from 10.0.0.28:6379 to 10.0.0.68:6379: ..Moving slot 12284 from 10.0.0.28:6379 to 10.0.0.68:6379:Moving slot 12285 from 10.0.0.28:6379 to 10.0.0.68:6379: .Moving slot 12286 from 10.0.0.28:6379 to 10.0.0.68:6379:Moving slot 12287 from 10.0.0.28:6379 to 10.0.0.68:6379: ..
[root@redis-node1 ~]#

#肯定s1ot分配成功
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.8:6379
warning: using a password with '-a’or '-u' option on the command line interfacemay not be safe.
10.0.0.8:6379 (cb028b83...) ->5019 keys | 4096 slots | 1 slaves.10.0.0.68:6379 (d6e2eca6...) -> 4948 keys | 4096 slots | 0 slaves.

爲新的master添加新的slave節點

先加入集羣再修改成slave

須要手動將其指定爲某個master的slave,不然其默認角色爲master。

#加入到集羣
redis-trib.rb add-node 10.0.0.20:6379  10.0.0.68:6379
#登陸到先添加的節點
redis-cli -h 10.0.0.20 -p 6379 -a 123456
#改其爲slave
10.0.0.20:6380> CLUSTER NODES #查看當前集羣節點,找到目標master的ID
10.0.0.20:6380> CLUSTER REPLICATE 886338acd50c3015be68a760502b239f4509881c #將其設置s1ave,命令格式爲cluster replicate MASTERID
10.0.0.78:6380> CLUSTER NODES #再次查看集羣節點狀態,驗證節點是否已經更改成指定master 的

Redis 5添加方式:

#把10.0.0.20:6379添加到集羣中:
[root@redis-node1 ~]#redis-cli -a 123456 --cluster add-node 10.0.0.20:6379  10.0.0.19:6379

驗證

rides 3/4的驗證方法:

[root@C8-68-DNS ~]#  redis-trib.rb   check 10.0.0.68:6379
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)
S: 74e446278d33e4235583f9f64c8c83d69b4d5d66 10.0.0.20:6379
   slots: (0 slots) slave
   replicates 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
M: 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 10.0.0.19:6379
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   1 additional replica(s)
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   slots: (0 slots) slave
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

[root@C8-68-DNS ~]# redis-cli -h 10.0.0.20 -a 123456  cluster info
Warning: Using a password with '-a' option on the command line interface may not be safe.
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:8 #8個節點
cluster_size:4  #4組主從
cluster_current_epoch:7
cluster_my_epoch:7
cluster_stats_messages_ping_sent:6272
cluster_stats_messages_pong_sent:6257
cluster_stats_messages_meet_sent:7
cluster_stats_messages_update_sent:12
cluster_stats_messages_sent:12548
cluster_stats_messages_ping_received:6257
cluster_stats_messages_pong_received:6279
cluster_stats_messages_received:12536

redis 5 的驗證方法:

#驗證是否成功
[root@redis-node1 ~]#redis-cli -a 123456 --cluster check 10.0.0.68:6379

集羣維護之動態縮容

因爲服務器使用年限已經超過三年,已經超過廠商質保期並且硬盤出現異常報警,經運維部架構師提交方案並同開發同事開會商議,決定將現有Redis集羣的8臺主服務器中的master 10.0.0.8和對應的slave 10.0.0.38臨時下線,三臺服務器的併發寫入性能足夠支出將來1-2年的業務需求
刪除節點過程:
添加節點的時候是先添加node節點到集羣,而後分配槽位,刪除節點的操做與添加節點的操做正好相反,是先將被刪除的Redis node上的槽位遷移到集羣中的其餘Redis node節點上,而後再將其刪除,若是一個Redis node節點上的槽位沒有被徹底遷移,刪除該node的時候會提示有數據且沒法刪除。
遷移master的槽位之其餘master

Redis 3/4版本

[root@redis-node1 ~]# redis-trib.rb reshard 10.0.0.8:6379
[root@redis-node1 ~]# redis-trib.rb fix 10.0.0.8:6379 #若是遷移失敗使用此命令修復集羣

移動槽位

[root@C8-68-DNS ~]# redis-trib.rb  reshard 10.0.0.68:6379
>>> Performing Cluster Check (using node 10.0.0.68:6379)
M: b8a9fdb19a529d36238eed905bcf7d251e34b059 10.0.0.68:6379
   slots:1365-5460 (4096 slots) master
   1 additional replica(s)
S: 7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379
   slots: (0 slots) slave
   replicates 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3
M: 83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379
   slots:6827-10922 (4096 slots) master
   1 additional replica(s)
S: 74e446278d33e4235583f9f64c8c83d69b4d5d66 10.0.0.20:6379
   slots: (0 slots) slave
   replicates 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25
M: 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379
   slots:12288-16383 (4096 slots) master
   1 additional replica(s)
M: 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 10.0.0.19:6379
   slots:0-1364,5461-6826,10923-12287 (4096 slots) master
   1 additional replica(s)
S: bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379
   slots: (0 slots) slave
   replicates b8a9fdb19a529d36238eed905bcf7d251e34b059
S: 305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379
   slots: (0 slots) slave
   replicates 83fb5104b17ab176b08b4679af77548ca9680a0f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 1365   #移動多少個槽位
What is the receiving node ID? 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25  #移動槽位的機器ID
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1:b8a9fdb19a529d36238eed905bcf7d251e34b059   #接受槽位的機器的ID
Source node #2:done
Do you want to proceed with the proposed reshard plan (yes/no)? yes
以上的步驟重複,將全部的槽位所有移走

root@C8-68-DNS ~]# redis-cli -a 123456 cluster nodes

redis

#刪除10.0.0.68 這個節點
[root@C8-68-DNS ~]# redis-trib.rb del-node 10.0.0.98:6379 b8a9fdb19a529d36238eed905bcf7d251e34b059
>>> Removing node b8a9fdb19a529d36238eed905bcf7d251e34b059 from cluster 10.0.0.98:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

[root@C8-68-DNS ~]# redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
Could not connect to Redis at 127.0.0.1:6379: Connection refused

#查看如今的節點狀態
[root@C8-68-DNS ~]# redis-cli -a 123456 -h 10.0.0.98  cluster nodes
Warning: Using a password with '-a' option on the command line interface may not be safe.
bde13303ad49e3dd24840ea448f1f34376ce896a 10.0.0.158:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628481507268 9 connected
74e446278d33e4235583f9f64c8c83d69b4d5d66 10.0.0.20:6379@16379 slave 21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 0 1628481508274 7 connected
8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 10.0.0.98:6379@16379 myself,master - 0 1628481506000 9 connected 4095-5460 12288-16383
7685c0716fbaafb028366012ae700b027974cc68 10.0.0.138:6379@16379 slave 8dfe226b3b61fa0d24fe0c1f6691f999a99fa2d3 0 1628481505253 9 connected
21fe3c362aa04f8a15dbb575a2b9a2f60a325a25 10.0.0.19:6379@16379 master - 0 1628481504245 7 connected 0-2729 5461-6826 10923-12287
305f4c6e0c039db0a2f9cdc56474530280141761 10.0.0.168:6379@16379 slave 83fb5104b17ab176b08b4679af77548ca9680a0f 0 1628481506000 8 connected
83fb5104b17ab176b08b4679af77548ca9680a0f 10.0.0.88:6379@16379 master - 0 1628481506261 8 connected 2730-4094 6827-10922
[root@C8-68-DNS ~]#
相關文章
相關標籤/搜索