1、同步錯誤。不停重試一直不成功
Full resync from master: e51165e2868c541e28134a287f9bfe36372bae34:80575961684 MASTER <-> SLAVE sync: receiving 3320957238 bytes from master I/O error trying to sync with MASTER: connection lost
原因:
client-output-buffer-limit 這個參數對slave 同步時候所用的buffer做限制了
默認值是這個 client-output-buffer-limit slave 256mb 64mb 60(這是說負責發數據給slave的client,如果buffer超過256m或者連續60秒超過64m,就會被立刻強行關閉!!! Traffic大的話一定要設大一點。否則就會出現一個很悲劇循環,Master傳輸一個大的RDB給Slave,Slave努力的裝載,但還沒裝載 完,Master對client的緩存滿了,再來一次
output buffer是Redis為client分配的緩沖區(這里的"client"可能是真正的client,也可能是slave或monitor),若為某個客戶端分配的output buffer超過了預留大小,Redis可能會根據配置策略關閉與該端的連接。 例如,若Redis被用作message queue,訂購消息的consumer處理速度跟不上發布消息的producer時,就會發生對應的output buffer超限的情況。 該配置項格式如下: client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds> <class>:目前支持3種客戶端:1) normal => normal clients; 2) slave clients and MONITOR clients; 3) pubsub => clients subcribed to at least one pubsub channel or pattern <hard limit>:若output buffer大小超過該值,Redis會立即關閉與對應client的連接 <soft limit> <soft seconds>:若output buffer大小超過soft limit且這種情況的持續時間超過soft seconds,則Redis會關閉與對應client的連接。 默認的配置如下: client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60
解決:
config set client-output-buffer-limit 'slave 536870912 134217728 120'
參考:http://devopsh.com/289.html
備注:感覺這個參數只針對運行中的redis,如果是重啟slave,這時候會拷貝文件同步成功。由於redis屬於弱一致性,而且完全同步的時候從庫不能訪問,所以,不建議主從服務器跨機房,這樣同步時間會很長。導致從庫不能訪問的時間很長
另外一個可能配置是:Redis復制超時的默認值是60秒(見redis.conf文件的repl-timeout指令,或使用redis-cli運行“config get repl-timeout”)。
- 低速存儲器:如果主服務器或從服務器是基於低速存儲器的,如果是主服務器將導致后台進程花費很多時間;如果是服務器磁盤讀寫數據時間將延長。
- 大數據集:更大的數據集將需要更長的存儲時間和傳輸時間。
- 網絡性能:當主服務器和從服務器的網絡鏈路有限制帶寬和高延遲時,這會直接影響數據傳輸傳輸速率。
我們可以通過將復制超時設置為更合適的值來修正這個問題。首先是一個可接受復制數據庫的的估計時間。第一步,檢查Redis通過BGSAVE指令和檢查相關行(如“Background saving started by pid nnn ”表示進程開始,“ Background saving terminated with success”表示進程結束)的日志文檔執行后台進程所花的時間。然后,測量CN將主服務器上的結果RDB文件拷貝到從服務器硬盤所需的時間。最后,測量從硬盤加載數據實際消耗的時間(如重啟Redis,在日志文件中尋找“DB loaded from disk”行)。這些方法可以大致估計復制超時值,保險起見,我們可能需要在上面加上10~20%。
config set client-output-buffer-limit 'slave 536870912 134217728 300' config set repl-timeout '300'
2、由於Redis的單線程模型,理論上每個redis實例只會用到一個CPU, 也就是說可以在一台多核的服務器上部署多個實例(實際就是這么做的)。但是Redis的AOF重寫是通過fork出一個Redis進程來實現的,所以有經驗的Redis開發和運維人員會告訴你,在一台服務器上要預留一半的內存(防止出現AOF重寫集中發生,出現swap和OOM)。
還有一個可能是組合字符串,使用hmset或者hmget命令,同時操作多個key,超過redis硬編碼的1G限制
MSET key field value [field value ...] 同時將多個 field-value (域-值)對設置到哈希表 key 中。
http://redisdoc.com/hash/hmset.html
Query buffer hard limit Every client is also subject to a query buffer limit. This is a non-configurable hard limit that will close the connection when the client query buffer (that is the buffer we use to accumulate commands from the client) reaches 1 GB, and is actually only an extreme limit to avoid a server crash in case of client or server software bugs.
http://redis.io/topics/clients
3、查看連接占用內存
redis-cli -a 密碼 -h 127.0.0.1 -p 6379 client list redis-cli -a 密碼 -h 127.0.0.1 -p 6379 client list | grep -v "omem=0"
各項信息: addr: 客戶端的TCP地址,包括IP和端口 fd: 客戶端連接 socket 對應的文件描述符句柄號 name: 連接的名字,默認為空,可以通過 CLIENT SETNAME 設置 age: 客戶端存活的秒數 idle: 客戶端空閑的秒數 flags: 客戶端的類型 (N 表示普通客戶端,更多類型見 http://redis.io/commands/client-list) omem: 輸出緩沖區的大小 cmd: 最后執行的命令名稱
如果看到cmd=monitor
說明是監控進程緩存了很多內存。關閉監控。
http://www.open-open.com/lib/view/open1454502890526.html
4、maxclients
客戶端的並發連接數,默認10000。當redis實例無法更改系統fd限制時,會以系統限制數n減去32作為Redis支持的最大連接數(減32是因為Redis保留32個fd供內部邏輯使用)。當達到Redis支持的最大連接數后,新連接會被close,對應的client會收到"max number of clients reached"的出錯提示。
5、
redis的數據持久化有兩種方案:
1 寫aof文件
2 寫快照rdb文件
如果兩種同時打開,redis啟動后會優先嘗試從aof文件中恢復數據。另外如果做主從,redis以slave會向master拉aof文件來實現主從同步的目的。
在redis中執行的命令,會被寫入aof文件,並且在master中執行的命令,會將aof文件同步到slave(准確的說是由slave向master發送sync命令拉aof文件)。
假如公共數據存儲在0庫,那cache就存儲在1庫。我向master執行
select 0
flushdb
select 1
flushdb
接下來問題就來了,由於master的cache分區1庫中一條數據都沒有。所以這條flushdb實際並不會寫入本機aof文件,更不會被同步到各個slave。
解決方案嘛也很簡單:
A 修改為統一向master寫數據
B 晚上腳本在master上清理cache分區時,先隨便set一個key,然后再執行flushdb