天天看點

Redis詳解(二)

一、redis認證

二、redis事務

三、Connection&server相關指令

四、Redis的釋出與訂閱//充當mq的功能

五、Redis持久化

六、redis複制

七、master-slave實作

八、sentinal哨兵

九、redis限制

十、redis性能測試

redis認證:

    vim /etc/redis.conf 

        requirepass redispass //密碼

    [root@node1 ~]# systemctl restart redis

    [root@node1 ~]# redis-cli -h 192.168.4.106

    192.168.4.106:6379> select 0

    (error) NOAUTH Authentication required.

    192.168.4.106:6379> auth redispass

    OK

    OK    

清空資料庫

    flushdb:清空目前庫

    flushall:清空所有庫

1.MULTI用來組裝一個事務;

2.EXEC用來執行一個事務;

3.DISCARD用來取消一個事務;

4.WATCH用來監視一些key,一旦這些key在事務執行之前被改變,則取消事務的執行。

我們來看一個MULTI和EXEC的例子:

RDBMS的事務:一組相關操作,是原子性的:滿足ACID :原子性(Atomicity)、一緻性(Consistency)、隔離性(Isolation)、持久性(Durability)

redis的事務:可以将多個指令綁定在一起,順序執行。通過multi,exec,watch等指令實作事務功能;

    在事務執行過程中,redis不會中斷目前事務去執行其他client的指令。

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set ip 192.168.0.1

QUEUED

127.0.0.1:6379> set port 800 //放到隊列中

127.0.0.1:6379> exec //一起執行

1) OK

2) OK

watch:在事務執行過程中,施加樂觀鎖 //不支援復原

    在exec之前,監視 指定的資料key是否在 multi和exec之間發生修改操作,有變動則不予執行事務

    事務中關聯的 鍵 的監視操作。    

    //樂觀鎖,隻是看他是否被修該,一旦被修改了,就不予執行。在事務過程中仍然可以被修改

redis不支援復原操作,這是和mysql事務最大的差別

    事務有10個操作,第5個指令錯誤。redis事務會忽略第5個錯誤,執行到最後。

    redis目标:簡單、高效

    redis的原子性:事務隊列中的任務,要麼全部執行,要麼全都不執行

    redis的一緻性:在檢查入隊時的一緻性,例如輸入為錯誤指令 //文法級别

    redis的隔離性:單線程,在執行事務中,不會執行其他操作,但是可以接受使用者請求到queue中

    redis的持久性:依賴于server是否啟用持久化功能 

        rdb或者aof //快照和追加到檔案    

示例:樂觀鎖

<code>終端1:            </code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>watch</code> <code>ip </code>

<code>    </code><code>OK</code>

<code>    </code><code>127.0.0.1:6379&gt; multi</code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>set</code> <code>ip 10.0.0.1</code>

<code>    </code><code>QUEUED</code>

<code>    </code><code>127.0.0.1:6379&gt; get ip</code>

<code>終端2:</code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>set</code> <code>ip 172.16.100.1</code>

<code>    </code><code>"172.16.100.1"</code>

<code>終端1:        </code>

<code>    </code><code>127.0.0.1:6379&gt; </code><code>exec</code>

<code>    </code><code>(nil)  </code><code>//</code><code>事務執行失敗</code>

<code>    </code> 

<code>redis的一緻性************        </code>

<code>127.0.0.1:6379&gt; multi</code>

<code>OK</code>

<code>127.0.0.1:6379&gt; </code><code>set</code> <code>jsidfjd</code>

<code>(error) ERR wrong number of arguments </code><code>for</code> <code>'set'</code> <code>command</code>

<code>127.0.0.1:6379&gt; </code><code>exec</code>

<code>(error) EXECABORT Transaction discarded because of previous errors.</code>

<code>redis的原子性************</code>

<code>127.0.0.1:6379&gt; </code><code>set</code> <code>ip 10.0.0.1</code>

<code>QUEUED</code>

<code>127.0.0.1:6379&gt; </code><code>set</code> <code>aa</code>

<code>127.0.0.1:6379&gt; </code><code>exec</code>    <code>//</code><code>因為有文法錯誤,是以都沒有執行</code>

help @connections

<code>    </code><code>auth:</code>

<code>    </code><code>ping</code><code>: 驗證伺服器是否線上</code>

<code>    </code><code>echo</code> <code>“hello redis"</code>

<code>    </code><code>quit:</code>

<code>    </code><code>select</code><code>:選擇指定的DB</code>

help @server 

<code>    </code><code>bgsave:異步存儲資料到disk</code>

<code>    </code><code>client setname: 為連接配接設定名字 </code><code>//</code><code>隻能為自己修改名字</code>

<code>    </code><code>client getname :擷取目前用戶端的連結名</code>

<code>    </code><code>client </code><code>kill</code> <code>ip:port </code><code>//kill</code> <code>client的一個連接配接</code>

<code>    </code><code>client list :檢視連結</code>

<code>    </code><code>config get  </code><code>//redis</code><code>的多數配置都可以在運作時修改</code>

<code>    </code><code>config </code><code>set</code> <code>//</code><code>配置</code><code>file</code><code>中的參數 ,可以在記憶體中修改</code>

<code>    </code><code>config rewrite </code><code>//</code><code>在記憶體中修改的操作,寫入到配置檔案</code>

<code>    </code><code>info </code><code>//</code><code>伺服器的所有統計資料</code>

<code>    </code><code>info Memory </code><code>//</code><code>指定隻看記憶體資訊</code>

<code>    </code><code>info Cluster </code><code>//</code><code>擷取指定section的内容</code>

<code>    </code><code>config resetstat </code><code>//</code><code>重置info的所有資料</code>

<code>    </code><code>dbsize:    限制所有的鍵的數量</code>

<code>    </code><code>bgsave: </code><code>//</code>

<code>    </code><code>save:</code>

<code>    </code><code>lastsave:擷取最近一次成功儲存到disk的 timestamp</code>

<code>    </code><code>monitor:實時監控接受到的請求</code>

<code>    </code><code>shutdown</code> <code>[nosave</code><code>/save</code> <code>]:同步所有資料到disk後,關閉</code>

<code>    </code><code>slaveof :配置主從</code>

<code>    </code><code>slowlog:管理慢查詢日志</code>

<code>    </code><code>sync</code><code>:複制功能的内建指令 </code><code>//</code><code>同步master</code>

<code>    </code><code>time</code><code>:擷取目前server時間</code>

釋出與訂閱:釋出者在訂閱者訂閱之前的釋出資料預設是收取不到的

redis的釋出與訂閱功能:(publish/subscribe)

    生産者把資訊釋出在指定頻道上,訂閱者從指定的頻道去訂閱自己關注的資訊即可

    SUBSCRIBE:訂閱一個或多個 隊列/頻道 

    unsubscribe 退訂此前訂閱的頻道

    psubscribe "new.i[to]" //訂閱2個頻道

        psubscribe "new.*" //也可以

示例:釋出與訂閱

<code>終端1:</code>

<code>    </code><code>127.0.0.1:6379&gt; SUBSCRIBE news  </code><code>//</code><code>可以同時訂閱多個channel</code>

<code>    </code><code>Reading messages... (press Ctrl-C to quit)</code>

<code>    </code><code>1) </code><code>"subscribe"</code>

<code>    </code><code>2) </code><code>"news"</code>

<code>    </code><code>3) (integer) 1</code>

<code>    </code><code>127.0.0.1:6379&gt; PUBLISH news hello</code>

<code>    </code><code>(integer) 1</code>

<code>    </code><code>1) </code><code>"message"</code>

<code>    </code><code>2) </code><code>"news"</code>  <code>//</code><code>頻道名</code>

<code>    </code><code>3) </code><code>"hello"</code>     <code>//</code><code>内容</code>

五、Redis持久化    

redis如何實作持久化

    redis預設工作在記憶體中

持久化

    SAVE:将資料同步儲存到磁盤;

    BGSAVE:将資料異步儲存到磁盤;

    LASTSAVE:傳回上次成功将資料儲存到磁盤的 UNIX 時戳;

    SHUNDOWN:将資料同步儲存到磁盤,然後關閉服務。

持久化:RDB和AOF

RDB:snapshot,二進制格式,預設機制

    按事先定制的政策,周期性的将資料儲存到disk中;資料檔案預設為dump.rdb

    用戶端也可使用save或bgsave密令啟動快照儲存機制。

        save:異步方式實作,在主線程中儲存快照:在save過程中,其他所有client請求都是block的

            完整寫入記憶體資料到disk,而不是增量的同步

        bgsave:異步background save,不會阻塞client請求,使用一個新的程序

AOF:append only file,把每個 寫指令 追加到檔案尾部。

    假如incr指令,執行100次,預設需要記錄100次

    附加日志類型的持久化存儲:問題:檔案會變的越來越大,

    但是redis能夠合并aof的持久化檔案,bgrewriteaof 指令來實作。

    例如 set count=100,直接修改aof檔案,用來節約空間

127.0.0.1:6379&gt; dir //擷取備份目錄

==============================================================================    

    記錄每一次寫操作至指定的檔案尾部實作持久化,當redis重新開機時,可重新執行檔案中的指令在記憶體中重建資料庫

        BGREWRITEAOF:aof檔案重寫,

    不會讀取正在使用的AOF檔案,而通過将記憶體中的資料以指令的方式儲存到臨時檔案中,完成後替換原有的AOF檔案來實作。

Redis在實作RDB模式時的實作方式:

    redis調用fork建立一個子程序,父程序繼續處理client的請求,子程序負責将記憶體中的内容快照 到disk 中。

    linux有COW(copy on write)機制,子程序和父程序會共享相同的實體頁面,

    當父程序要寫請求時,os會為父程序建立一個副本,是以子程序所實作的儲存,一定是時間點一緻的資料。核心的特性。

        當子程序快照寫入完成後,os會用副本覆寫源檔案。然後子程序退出

    不足:一定會有一部分資料丢失,rdb儲存的時間點之後的時間點會丢失

    RDB:

        SAVE 900 1 

        SAVE 300 10

        SAVE 60 10000 //周期性的工作機制。

        SAVE "" //關閉RDB功能

        stop-writes-on-bgsave-error yes //在持久化時

        rdbcompression yes //壓縮rdb檔案

        rdbchecksum yes//對rdb的鏡像檔案進行校驗

        dbfilename dump.rdb 

        dir /var/lib/redis 

            //redis-cli&gt; config get dir //可以擷取配置

redis在實作AOF模式時的實作方式

    每一個指令發出後,直接追加到append到檔案中 

    重建過程:redis父程序調用fork,啟動一個子程序,子程序根據記憶體中現有的檔案的資料,在臨時檔案中,寫入一個資料庫重建的指令。

        父程序繼續處理client請求,client新的請求除了把指令寫入到檔案中,還要把新的指令緩存起來,放到緩存隊列中,後續執行。

    當子程序把快照内容寫入到新的AOF檔案後,通知父程序,父程序會用新的AOF替換老的AOF檔案,并把這個操作啟動之後,新收到的請求指令,追加到新的AOF檔案中

    預設每秒鐘fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中)

    1.redis主程序fork一個子程序

    2.子程序根據redis記憶體中的資料建立資料庫重建指令序列于臨時檔案中

    3.父程序繼續接受用戶端請求,并且會把這些請求中的寫操作繼續追加到原來的AOF檔案;額外地,這些新的寫請求還會被放置于一個緩沖隊列中

    4.子程序重寫完成後通知父程序,父程序把緩沖中的指令寫到臨時檔案中

    5.父程序用臨時檔案替換老的aof檔案

AOF方式的另一個好處,我們通過一個“場景再現”來說明。某同學在操作redis時,不小心執行了FLUSHALL,導緻redis記憶體中的資料全部被清空了,這是很悲劇的事情。不過這也不是世界末日,隻要redis配置了AOF持久化方式,且AOF檔案還沒有被重寫(rewrite),我們就可以用最快的速度暫停redis并編輯AOF檔案,将最後一行的FLUSHALL指令删除,然後重新開機redis,就可以恢複redis的所有資料到FLUSHALL之前的狀态了。是不是很神奇,這就是AOF持久化方式的好處之一。但是如果AOF檔案已經被重寫了,那就無法通過這種方法來恢複資料了。    

但AOF方式也同樣存在缺陷,比如在同樣資料規模的情況下,AOF檔案要比RDB檔案的體積大。而且,AOF方式的恢複速度也要慢于RDB方式。

如果在追加日志時,恰好遇到磁盤空間滿、inode滿或斷電等情況導緻日志寫入不完整,也沒有關系,redis提供了redis-check-aof工具,可以用來進行日志修複。    

    appendonly no //預設是關閉的

    appendfilename "appendonly.aof" //追加到哪個檔案

    # appendfsync always //每次收到寫請求,就執行操作

    appendfsync everysec //每s一次

    # appendfsync no //append的功能自行不會觸發寫操作,所有寫操作都是送出給OS,由OS自行決定如何寫。

            //由核心決定如何進行寫操作

    no-appendfsync-on-rewrite no //yes:表示,對重寫操作,對新寫入的操作,不做fsync,而是暫存到隊列中

    auto-aof-rewrite-percentage 100 //本次重新的aof檔案是上次重新檔案的2倍時,執行重寫。

        (目前寫入日志檔案的大小超過上一次rewrite之後的檔案大小的百分之100時就是2倍時觸發Rewrite)

    auto-aof-rewrite-min-size 64mb //剛開始的時候,1個1s後,4個大于1的2倍,會發起重寫操作,顯然不合理,要設定最小aof檔案大小

    aof-load-truncated yes        //

可以同時啟動RDB和AOF,

注意:持久本身不能取代備份,還應該指定備份政策,對redis資料庫及逆行定期備份

假如同時啟用AOF和RDB    

    兩個同時滿足,需要重寫

        bgsave和rewrite不會同時執行,redis隻會讓一個執行,為了避免過大的磁盤IO,逐個執行

RDB,簡而言之,就是在不同的時間點,将redis存儲的資料生成快照并存儲到磁盤等媒體上;

AOF,則是換了一個角度來實作持久化,那就是将redis執行過的所有寫指令記錄下來,在下次redis重新啟動時,隻要把這些寫指令從前到後再重複執行一遍,就可以實作資料恢複了。

其實RDB和AOF兩種方式也可以同時使用,在這種情況下,如果redis重新開機的話,則會優先采用AOF方式來進行資料恢複,這是因為AOF方式的資料恢複完整度更高。

如果你沒有資料持久化的需求,也完全可以關閉RDB和AOF方式,這樣的話,redis将變成一個純記憶體資料庫,就像memcache一樣。

特點:    

    一個master可以有多個slave,一個slave也可以有自己的slave

    支援鍊式複制功能:

    master以非阻塞方式同步資料至slave//master會繼續接受一個或多個slave的同步請求

<code>slaveof &lt;masterip&gt; &lt;masterport&gt;</code>

<code>masterauth &lt;master-password&gt;  </code><code>//</code><code>主redis設定了驗證密碼的話(使用requirepass來設定)</code>

<code>slave-</code><code>read</code><code>-only </code><code>yes</code>

<code>repl-</code><code>ping</code><code>-slave-period 10  </code><code>//slave</code><code>預設每10s向master發送</code><code>ping</code><code>包</code>

<code>repl-timeout 60  </code><code>//</code><code>設定</code><code>ping</code><code>逾時時間,確定這個時限比repl-</code><code>ping</code><code>-slave-period的值要大,否則每次主redis都會認為從redis逾時。</code>

<code>repl-disable-tcp-nodelay no  </code><code>//</code><code>主從同步時是否禁用TCP_NODELAY。開啟:主redis會使用更少的TCP包和更少的帶寬來向從redis傳輸資料。但是這可能會增加一些同步的延遲,大概會達到40毫秒左右。如果你關閉了TCP_NODELAY,那麼資料同步的延遲時間會降低,但是會消耗更多的帶寬</code>

<code>repl-backlog-size 1mb </code><code>//</code><code>同步隊列長度。隊列長度(backlog)是主redis中的一個緩沖區,在與從redis斷開連接配接期間,主redis會用這個緩沖區來緩存應該發給從redis的資料。這樣的話,當從redis重新連接配接上之後,就不必重新全量同步資料,隻需要同步這部分增量資料即可。</code>

<code>repl-backlog-ttl 3600 </code><code>//</code><code>如果主redis等了一段時間之後,還是無法連接配接到從redis,那麼緩沖隊列中的資料将被清理掉。我們可以設定主redis要等待的時間長度。如果設定為0,則表示永遠不清理。預設是1個小時。</code>

<code>slave-priority 100 </code><code>//redis</code><code>優先級,在主redis持續工作不正常的情況,優先級高的從redis将會更新為主redis。而編号越小,優先級越高。比如一個主redis有三個從redis,優先級編号分别為10、100、25,那麼編号為10的從redis将會被首先選中更新為主redis。當優先級被設定為0時,這個從redis将永遠也不會被選中。預設的優先級為100。</code>

<code>min-slaves-to-write 3 </code><code>//redis</code><code>提供了可以讓master停止寫入的方式,如果配置了min-slaves-to-write,健康的slave的個數小于N,mater就禁止寫入。master最少得有多少個健康的slave存活才能執行寫指令。這個配置雖然不能保證N個slave都一定能接收到master的寫操作,但是能避免沒有足夠健康的slave的時候,master不能寫入來避免資料丢失。設定為0是關閉該功能。</code>

<code>min-slaves-max-lag 10 </code><code>//</code><code>#延遲小于min-slaves-max-lag秒的slave才認為是健康的slave。</code>

<code>slave-serve-stale-data </code><code>yes</code>    <code>//</code><code>聯系不到master之後,仍然使用過期資料</code>

<code>repl-diskless-</code><code>sync</code> <code>no </code><code>//</code><code>當硬碟太慢的時候,啟用該值 </code>

<code>repl-diskless-</code><code>sync</code><code>-delay 5 </code><code>//</code><code>延遲操作時間</code>

當從redis失去了與主redis的連接配接,或者主從同步正在進行中時,redis該如何處理外部發來的通路請求呢?這裡,從redis可以有兩種選擇:

    第一種選擇:如果slave-serve-stale-data設定為yes(預設),則從redis仍會繼續響應用戶端的讀寫請求。

    第二種選擇:如果slave-serve-stale-data設定為no,則從redis會對用戶端的請求傳回“SYNC with master in progress”,當然也有例外,當用戶端發來INFO請求和SLAVEOF請求,從redis還是會進行處理。

    你可以控制一個從redis是否可以接受寫請求。将資料直接寫入從redis,一般隻适用于那些生命周期非常短的資料,因為在主從同步時,這些臨時資料就會被清理掉。自從redis2.6版本之後,預設從redis為隻讀。

隻讀的從redis并不适合直接暴露給不可信的用戶端。為了盡量降低風險,可以使用rename-command指令來将一些可能有破壞力的指令重命名,避免外部直接調用。比如:

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

主從情況下的timeout:

1.以從redis的角度來看,當有大規模IO傳輸時。

2.以從redis的角度來看,當資料傳輸或PING時,主redis逾時

3.以主redis的角度來看,在回複從redis的PING時,從redis逾時    

MONITOR:實時轉儲收到的請求; //master和slave之間進行的ping-pong也可以看到

    192.168.4.106 server

    192.168.4.109 slave

server: 

    bind 0.0.0.0 

    service redis resart //沒有認證密碼

slave:    

    service redis resart     

<code>[root@node2 ~]</code><code># redis-cli -h 192.168.4.109</code>

<code>192.168.4.109:6379&gt; SLAVEOF 192.168.4.106 6379</code>

<code>OK Already connected to specified master</code>

<code>192.168.4.109:6379&gt; get ip</code>

<code>"172.16.100.1"</code>

<code>192.168.4.109:6379&gt; config get slaveof</code>

<code>1) </code><code>"slaveof"</code>

<code>2) </code><code>"192.168.4.106 6379"</code>    

<code>192.168.4.109:6379&gt; key * </code><code>//</code><code>檢視所有的key</code>

<code>192.168.4.109:6379&gt; config </code><code>set</code> <code>masterauth </code><code>"redispass"</code> <code>//slave</code><code>通過auth進行認證</code>

<code>    </code><code>注意:可以在同一個主機上啟動多個redis,使用不同的端口接口</code>

<code>    </code><code>如果主redis設定了驗證密碼的話(使用requirepass來設定),則在從redis的配置中要使用masterauth來設定校驗密碼,否則的話,主redis會拒絕從redis的通路請求。</code>

<code>192.168.4.106:6379&gt; info Replication</code>

<code># Replication</code>

<code>role:master</code>

<code>connected_slaves:1</code>

<code>slave0:ip=192.168.4.109,port=6379,state=online,offset=575,lag=1</code>

<code>master_repl_offset:589</code>

<code>repl_backlog_active:1</code>

<code>repl_backlog_size:1048576</code>

<code>repl_backlog_first_byte_offset:2</code>

<code>repl_backlog_histlen:588</code>

<code>//</code><code>預設slaveof 之後,slave将變成隻讀</code>

主從架構問題:主故障,從不會執行寫操作

redis引入了sentinel哨兵機制。監控整個主從架構。

    [監控主機] //sentinel會在主node挂的時候,選取一個從作為主node

[master]    

-----------------------

[s1]    [s2]    [s3]

前端代理會向sentinal發起查詢請求,擷取新的master node

萬一sentinal故障:或者sentinal聯系不到master,是以sentinal可以做叢集,例如3個sentinal節點,避免誤判

sentinal隻監控主的,從master擷取從的配置資訊,一旦主故障,則選一個從為主

sentinal:

    用于管理多個redis伺服器實作HA

        監控

        通知

        自動故障轉移

        流言協定[sentinal之間接受master是否下線的消息],投票協定[決定是否執行故障遷移,以及選取哪一個為主master]

redis-server --sentinal 在啟動的時候,指定sentinal可以自己成為sentinal 伺服器

    redis-sentinal /path/to/file.conf  //專用指令,配置檔案

sentinal啟動:

    1.sentinal初始化自身伺服器,運作redis-server中專用于sentinal功能的代碼

    2.初始化sentinal狀态,根據給定的配置檔案,初始化監控的master伺服器清單

    3.建立連向master的連接配接

專用配置檔案:

/etc/redis-sentinal.conf 專用配置檔案

port 26379     

(1)sentinel monitor mymaster 127.0.0.1 6379 2 //監控的主節點

    mymaster是自己取名,master-name,可以不是主機名,随意

    2:quorum 法定票數,至少2票,才可以啟動叢集

    //該條目可以出現多個

(2)sentinel down-after-milliseconds mymaster 30000

    master多少時間聯系不到後為 down 離線

(3)sentinel parallel-syncs mymaster 1

    剛設定為新master時,允許同時多少個slave發起同步請求

(4)sentinel failover-timeout mymaster 18000

    故障轉移的逾時時間。在3min内不能把該slave提升為master,則故障轉移失敗

(5)logfile /var/log/redis/sentinel.log    

setinal隻需要知道master節點,從node,sentinal會從主node擷取的

主觀下線:一個sentinal發現master找不到了,認為其down了

客觀下線: 所有sentinal都認為該master down,

    sentinal會每隔1s 探測 ping(pong)

常用指令:

    sentinal masters

    sentinal slaves master_name

    sentinal get-master-addr-by-namne master_name

    sentinal reset //清除所有狀态

    sentinal failover master_name //強制故障轉移

實作:

    啟動三個redis

    1主,2從,1個sentinal,讓主的下線然後檢視效果 //取消認證功能

[root@node1 lib]# mkdir /etc/redis

[root@node1 lib]# cp /etc/redis.conf /etc/redis

[root@node1 lib]# cd /etc/redis

[root@node1 redis]# cp redis.conf redis.conf.2

[root@node1 redis]# cp redis.conf redis.conf.3

[root@node1 redis]# mkdir -pv /redis/{db1,db2,db3}

[root@node1 redis]# chown -R redis.redis /redis/

<code>(1)預設</code>

<code>    </code><code>vim redis.conf </code>

<code>bind 0.0.0.0</code>

<code>port 6379</code>

<code>logfile </code><code>/var/log/redis/redis</code><code>.log</code>

<code>pidfile </code><code>/var/run/redis/redis</code><code>.pid</code>

<code>daemonize </code><code>yes</code> <code>//</code><code>能夠在背景運作</code>

<code>protected-mode no</code>

<code>(2)vim redis.conf.2</code>

<code>port 6380</code>

<code>pidfile </code><code>/var/run/redis/redis2</code><code>.pid</code>

<code>logfile </code><code>/var/log/redis/redis2</code><code>.log    </code>

<code>dir</code> <code>/redis/db2</code>

<code>daemonize </code><code>yes</code>

<code>(3)    vim redis.conf.3</code>

<code>port 6381</code>

<code>pidfile </code><code>/var/run/redis/redis3</code><code>.pid</code>

<code>logfile </code><code>/var/log/redis/redis3</code><code>.log    </code>

<code>dir</code> <code>/redis/db3</code>

<code>[root@node1 redis]</code><code># redis-server /etc/redis/redis.conf</code>

<code>[root@node1 redis]</code><code># redis-server /etc/redis/redis.conf.2</code>

<code>[root@node1 redis]</code><code># redis-server /etc/redis/redis.conf.3    </code>

<code>[root@node1 redis]</code><code># ss -tunl |grep -E "6379|6380|6381"</code>

<code>tcp    LISTEN     0      128       *:6379                  *:*                  </code>

<code>tcp    LISTEN     0      128       *:6380                  *:*                  </code>

<code>tcp    LISTEN     0      128       *:6381                  *:*       </code>

<code>6379為主,其他都是從</code>

三個終端:

1.6379

[root@node2 ~]# redis-cli -h 192.168.4.106 -p 6379

192.168.4.106:6379&gt; config set requirepass masterpass

192.168.4.106:6379&gt; config set masterauth mastermaster

//在mater上set 添加新值,slave會立即看到

2.6380

[root@node2 ~]# redis-cli -h 192.168.4.106 -p 6380

192.168.4.106:6380&gt; slaveof 192.168.4.106 6379

192.168.4.106:6380&gt; config set masterauth masterpas //和master的requirepass一緻

192.168.4.106:6380&gt; keys *

1) "port"

2) "ip"

3) "mm"

4) "kk"

5) "nn"

3.6381

[root@node2 ~]# redis-cli -h 192.168.4.106 -p 6381

192.168.4.106:6381&gt; slaveof 192.168.4.106 6379

192.168.4.106:6381&gt; config set masterauth masterpass

192.168.4.106:6381&gt; info Replication    

192.168.4.106:6380&gt; keys *    

啟動sentinal配置,隻啟動一個sentinal

192.168.4.109:

[root@node2 ~]# cp /etc/redis-sentinel.conf /etc/redis/

[root@node2 ~]# cd /etc/redis/

[root@node2 redis]# vim redis-sentinel.conf

1.port :目前Sentinel服務運作的端口

2.dir : Sentinel服務運作時使用的臨時檔案夾

3.sentinel monitor master001 192.168.110.101 6379 2:Sentinel去監視一個名為master001的主redis執行個體,這個主執行個體的IP位址為本機位址192.168.110.101,端口号為6379,而将這個主執行個體判斷為失效至少需要2個 Sentinel程序的同意,隻要同意Sentinel的數量不達标,自動failover就不會執行

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

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

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

7.sentinel notification-script &lt;master-name&gt; &lt;script-path&gt;:指定sentinel檢測到該監控的redis執行個體指向的執行個體異常時,調用的報警腳本。該配置項可選,但是很常用     

[root@node2 redis]# egrep -v "^#|^$" redis-sentinel.conf 

sentinel monitor mymaster 192.168.4.106 6380 1 //有1個哨兵認為其故障,就确定故障

sentinel down-after-milliseconds mymaster 3000

sentinel failover-timeout mymaster 18000

sentinel auth-pass mymaster redispass

logfile "/var/log/redis/sentinel.log"

protected-mode no

daemonize yes     

sentinel auth-pass mymaster redispass //密碼,沒有密碼,是以沒有使用

# Generated by CONFIG REWRITE

sentinel known-slave mymaster 192.168.2.103 6380

sentinel known-slave mymaster 192.168.2.103 6381  //生成的

[root@node2 redis]# redis-sentinel /etc/redis/redis-sentinel.conf    

[root@node2 ~]# redis-cli -h 192.168.4.109 -p 26379    

sentinel masters //檢視master所在的node

sentinel slaves mymaster //檢視從s

kill 主node程序 6379

info //檢視新的master 變為 6380

sentinel master //可以看到

在 6381上

    info replication //檢視master

重新啟動master //6379

26379:info 端口仍然為6380

    sentinel slaves mymaster //原主依然為從

maxclients 10000 //如果達到了此限制,redis會拒絕新請求,并發出“max number of clients reached”回應。

maxmemory &lt;bytes&gt; //一旦到達記憶體使用上限,redis将會試圖移除内部資料,移除規則可以通過maxmemory-policy來指定。

    如果你的redis是主redis(說明你的redis有從redis),那麼在設定記憶體使用上限時,需要在系統中留出一些記憶體空間給同步隊列緩存,隻有在你設定的是“不移除”的情況下,才不用考慮這個因素。

對于記憶體移除規則來說,redis提供了多達6種的移除規則。他們是:

1.volatile-lru:使用LRU算法移除過期集合中的key

2.allkeys-lru:使用LRU算法移除key

3.volatile-random:在過期集合中移除随機的key

4.allkeys-random:移除随機的key

5.volatile-ttl:移除那些TTL值最小的key,即那些最近才過期的key。

6.noeviction:不進行移除。針對寫操作,隻是傳回錯誤資訊。

無論使用上述哪一種移除規則,如果沒有合适的key可以移除的話,redis都會針對寫請求傳回錯誤資訊。

LRU算法和最小TTL算法都并非是精确的算法,而是估算值。是以你可以設定樣本的大小。假如redis預設會檢查三個key并選擇其中LRU的那個,那麼你可以改變這個key樣本的數量。

maxmemory-samples 3

<code>info memory: </code><code>//</code><code>實際占用記憶體</code>

<code>    </code><code>used_memory:13490096 </code><code>//</code><code>資料占用了多少記憶體(位元組)</code>

<code>    </code><code>used_memory_human:12.87M </code><code>//</code><code>資料占用了多少記憶體(帶機關的,可讀性好)</code>

<code>    </code><code>used_memory_rss:13490096  </code><code>//redis</code><code>占用了多少記憶體,常駐記憶體集</code>

<code>    </code><code>used_memory_peak:15301192 </code><code>//</code><code>占用記憶體的峰值(位元組)</code>

<code>    </code><code>used_memory_peak_human:14.59M </code><code>//</code><code>占用記憶體的峰值(帶機關的,可讀性好)</code>

<code>    </code><code>used_memory_lua:31744  </code><code>//lua</code><code>引擎所占用的記憶體大小(位元組)</code>

<code>    </code><code>mem_fragmentation_ratio:1.00  </code><code>//</code><code>記憶體碎片率</code>

<code>    </code><code>mem_allocator:libc </code><code>//redis</code><code>記憶體配置設定器版本,在編譯時指定的。有libc、jemalloc、tcmalloc這3種。</code>

redis-benchmark [option] [option value]

$ redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

100個并發連接配接,100000個請求,檢測host為localhost 端口為6379的redis伺服器性能

<code>-h      指定伺服器主機名        127.0.0.1</code>

<code>-p      指定伺服器端口  6379</code>

<code>-s      指定伺服器 socket</code>

<code>-c      指定并發連接配接數  50</code>

<code>-n      指定請求數      10000</code>

<code>-d      以位元組的形式指定 SET</code><code>/GET</code> <code>值的資料大小   2</code>

<code>-k      1=keep alive 0=reconnect        1</code>

<code>-r      SET</code><code>/GET/INCR</code> <code>使用随機 key, SADD 使用随機值</code>

<code>-P      通過管道傳輸 &lt;numreq&gt; 請求      1</code>

<code>-q      強制退出 redis。僅顯示 query</code><code>/sec</code> <code>值</code>

<code>--csv   以 CSV 格式輸出</code>

<code>-l      生成循環,永久執行測試</code>

<code>-t      僅運作以逗号分隔的測試指令清單。</code>

<code>-I      Idle 模式。僅打開 N 個 idle 連接配接并等待。</code>

參考:

https://piaosanlang.gitbooks.io/redis/content/happy/section2.html

https://www.cnblogs.com/wyy123/p/6078593.html

https://yq.aliyun.com/articles/226052    

http://www.cnblogs.com/hjfeng1988/p/6144352.html

http://chong-zh.iteye.com/blog/2175166

本文轉自MT_IT51CTO部落格,原文連結:http://blog.51cto.com/hmtk520/2056357,如需轉載請自行聯系原作者