尚矽谷Redis學習總結
簡單介紹
Redis:開源、免費、非關係型資料庫、K-V資料庫、記憶體資料庫,支援持久化、事務和備份,叢集(支援16個庫)等高可用功能。並且效能極高(可以達到100000+的QPS),易擴充套件,豐富的資料型別,所有操作都是單執行緒,原子性的。
NOSQL:非關係型資料庫,資料與資料之間沒有關聯關係。就是為了解決大規模資料集合多重資料種類帶來的挑戰,尤其是大資料應用難題
型別
-
鍵值(key-value)儲存資料庫
-
列儲存資料庫:鍵仍然存在,但是指向了多個列,HBase (eg:部落格平臺(標籤和文章),日誌)
-
文件型資料庫 MongoDb (eg:淘寶商品的評價)
-
圖形資料庫 Neo4j (eg:好友列表)
擴充套件:
MongoDB是一個基於分散式檔案儲存的資料庫。有C++語言編寫。旨在為WEB應用提供可擴充套件的高效能資料儲存解決方案。
MongoDB是一個介於關係型資料庫和非關係型資料庫之間的產品,是非關係資料庫當中功能最豐富,最像關係型資料庫的。
文件(document)是MongoDB中資料的基本單元,非常類似於關係型資料庫系統中的行(但是比行要複雜的多); 集合(collection)就是一組文件,如果說MongoDB中的文件類似於關係型資料庫中的行,那麼集合就如同表;
使用場景:
-
資料模型比較簡單
-
需要靈活更強的IT系統
-
對資料庫效能要求比較高
-
不需要高度的資料一致性
-
對於給定的key,比較容易映射覆雜值的環境
SQL:關係型資料庫,表與表之間建立關聯關係
redis的安裝
#拉取映象
docker pull redis
#掛載資料卷並執行容器
docker run -p 6379:6379 --name redis -v /root/redis/data:/data -v /root/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis redis-server /usr/local/etc/redis/redis.conf --appendonly yes --requirepass "xxx"
為什麼使用NOSQL
單機 MySQL 的美好時代
在90年代,一個網站的訪問量一般都不大,用單個數據庫完全可以輕鬆應付。 在那個時候,更多的都是靜態網頁,動態互動型別的網站不多。
DAL : Data Access Layer(資料訪問層 – Hibernate,MyBatis)
上述架構下,我們來看看資料儲存的瓶頸
是什麼?
資料量的總大小一個機器放不下時。
資料的索引(B+ Tree)一個機器的記憶體放不下時。
訪問量(讀寫混合)一個例項不能承受。
如果滿足了上述1 or 3個時,只能對資料庫的整體架構進行重構。
Memcached(快取)+MySQL+垂直拆分
後來,隨著訪問量的上升,幾乎大部分使用MySQL架構的網站在資料庫上都開始出現了效能問題,web程式不再僅僅專注在功能上,同時也在追求效能。程式設計師們開始大量的使用快取技術來緩解資料庫的壓力,優化資料庫的結構和索引。開始比較流行的是通過檔案快取來緩解資料庫壓力,但是當訪問量繼續增大的時候,多臺web機器通過檔案快取不能共享,大量的小檔案快取也帶了了比較高的IO壓力。在這個時候,Memcached就自然的成為一個非常時尚的技術產品。
Memcached作為一個獨立的分散式的快取伺服器,為多個web伺服器提供了一個共享的高效能快取服務,在Memcached伺服器上,又發展了根據hash演算法來進行多臺Memcached快取服務的擴充套件,然後又出現了一致性hash來解決增加或減少快取伺服器導致重新hash帶來的大量快取失效的弊端。
Mysql主從讀寫分離
由於資料庫的寫入壓力增加,Memcached只能緩解資料庫的讀取壓力。讀寫集中在一個數據庫上讓資料庫不堪重負,大部分網站開始使用主從複製技術來達到讀寫分離,以提高讀寫效能和讀庫的可擴充套件性。Mysql的master-slave模式成為這個時候的網站標配了。
分庫分表+水平拆分+mysql叢集
在Memcached的快取記憶體,MySQL的主從複製,讀寫分離的基礎之上,這時MySQL主庫的寫壓力開始出現瓶頸,而資料量的持續猛增,由於MyISAM在寫資料的時候會使用表鎖,在高併發寫資料的情況下會出現嚴重的鎖問題,大量的高併發MySQL應用開始使用InnoDB引擎代替MyISAM。
ps:這就是為什麼 MySQL 在 5.6 版本之後使用 InnoDB 做為預設儲存引擎的原因 – MyISAM 寫會鎖表,InnoDB 有行鎖,,並且是事務優先,發生衝突的機率低,併發效能高。
注意鎖的幾個概念:行鎖和表鎖,讀鎖和寫鎖,樂觀鎖和悲觀鎖,還有一個間隙鎖
詳情請看鎖的介紹
四種NoSQL對比
3V+3高
大資料時代的3V 網際網路需求的3高 海量Volumn 3v 多樣Variety 實時Velocity 高併發 3高 高可用 高效能ACID
事務是由一組SQL語句組成的邏輯處理單元,事務具有4屬性,通常稱為事務的ACID屬性。
-
原子性
(Actomicity):事務是一個原子操作單元,其對資料的修改,要麼全都執行,要麼全都不執行。 -
一致性
(Consistent):在事務開始和完成時,資料都必須保持一致狀態。這意味著所有相關的資料規則都必須應用於事務的修改,以操持完整性;事務結束時,所有的內部資料結構(如B樹索引或雙向連結串列)也都必須是正確的。eg:有3個人進行轉賬操作,為了保證一致性(即3個人 的賬號金額總數不變),那在我寫程式碼的時候,如果寫了程式碼:A=A-5000;此時資料時不一致的。那就必須要寫上,B=B+5000,或者是C=C+5000,這樣的程式碼才能保證了資料庫的一致性狀態。
-
隔離性
(Isolation):資料庫系統提供一定的隔離機制,保證事務在不受外部併發操作影響的“獨立”環境執行。這意味著事務處理過程中的中間狀態對外部是不可見的,反之亦然。具體看下面的幾個隔離級別和併發問題。 -
永續性
(Durable):事務完成之後,它對於資料的修改是永久性的,即使出現系統故障也能夠保持
CAP
C:consistency,資料在多個副本中能保持一致的狀態。
A:Availability,整個系統在任何時刻都能提供可用的服務,通常達到99.99%四個九可以稱為高可用
P:Partition tolerance,分割槽容錯性,在分散式中,由於網路的原因無法避免有時候出現數據不一致的情況,系統如果不能在時限內達成資料一致性,就意味著發生了分割槽的情況,必須就當前操作在C和A之間做出選擇,換句話說,系統可以跨網路分割槽線性的伸縮和擴充套件。
CAP理論的核心:一個分散式系統不可能同時
很好的滿足一致性,可用性和分割槽容錯性這三個需求,最多隻能同時較好的滿足兩個
。
-
CA:單點叢集,滿足一致性,可用性的系統,通常在可擴充套件上不太強大。應用:傳統的Oracle資料庫
-
CP:滿足一致性,分割槽容錯性的系統,通常效能不是特別高。應用:Redis,MongoDB,銀行
-
AP:滿足可用性,分割槽容錯性,通常可能對一致性要求低一些。應用:大多數網站架構的選擇
CAP理論就是說在分散式儲存系統中,最多隻能實現上面的兩個。而由於當前的網路硬體肯定會出現延遲丟包等問題。所以
分割槽容忍性是我們必須需要實現的
所以我們只能在一致性和高可用之間進行權衡,沒有NoSQL系統能同時保證三點。為什麼呢?
為何CAP三者不可兼得
現在我們就來證明一下,為什麼不能同時滿足三個特性?
假設有兩臺伺服器,一臺放著應用A和資料庫V,一臺放著應用B和資料庫V,他們之間的網路可以互通,也就相當於分散式系統的兩個部分。
在滿足一致性的時候,兩臺伺服器 N1和N2,一開始兩臺伺服器的資料是一樣的,DB0=DB0。在滿足可用性的時候,使用者不管是請求N1或者N2,都會得到立即響應。在滿足分割槽容錯性的情況下,N1和N2有任何一方宕機,或者網路不通的時候,都不會影響N1和N2彼此之間的正常運作。
當用戶通過N1中的A應用請求資料更新到伺服器DB0後,這時N1中的伺服器DB0變為DB1,通過分散式系統的資料同步更新操作,N2伺服器中的資料庫V0也更新為了DB1,這時,使用者通過B向資料庫發起請求得到的資料就是即時更新後的資料DB1。
上面是正常運作的情況,但分散式系統中,最大的問題就是網路傳輸問題,現在假設一種極端情況,N1和N2之間的網路斷開了,但我們仍要支援這種網路異常,也就是滿足分割槽容錯性,那麼這樣能不能同時滿足一致性和可用性呢?
假設N1和N2之間通訊的時候網路突然出現故障,有使用者向N1傳送資料更新請求,那N1中的資料DB0將被更新為DB1,由於網路是斷開的,N2中的資料庫仍舊是DB0;
如果這個時候,有使用者向N2傳送資料讀取請求,由於資料還沒有進行同步,應用程式沒辦法立即給使用者返回最新的資料DB1,怎麼辦呢?有二種選擇,第一,犧牲資料一致性,響應舊的資料DB0給使用者;第二,犧牲可用性,阻塞等待,直到網路連線恢復,資料更新操作完成之後,再給使用者響應最新的資料DB1。
上面的過程比較簡單,但也說明了要滿足分割槽容錯性的分散式系統,只能在一致性和可用性兩者中,選擇其中一個。也就是說分散式系統不可能同時滿足三個特性。這就需要我們在搭建系統時進行取捨了。
Base
Base就是為了解決關係型資料庫強一致性引起的問題而引起的可用性降低而提出的解決方案。
Base其實是下面三個術語的縮寫:
-
基本可用(Basically Available)
-
軟狀態(Soft state)狀態可以有一段時間不同步
-
最終一致(Eventually consistent)最終資料是一致的就可以了,而不是時時保持強一致
它的思想是通過讓系統放鬆對某一時刻資料一致性的要求來換取系統整體伸縮性和效能上改觀。為什麼這麼說呢,緣由就在於大型系統往往由於地域分佈和極高效能的要求,不可能採用分散式事務來完成這些指標,要想獲得這些指標,我們必須採用另外一種方式來完成,這裡BASE就是解決這個問題的辦法。
以案例轉賬為例,我們把使用者A給使用者B轉賬分成四個階段,第一個階段使用者A準備轉賬,第二個階段從使用者A賬戶扣減餘額,第三個階段對使用者B增加餘額,第四個階段完成轉賬。系統需要記錄操作過程中每一步驟的狀態,一旦系統出現故障,系統能夠自動發現沒有完成的任務,然後,根據任務所處的狀態,繼續執行任務,最終完成任務,達到一致的最終狀態。
在實際應用中,上面這個過程通常是通過持久化執行任務的狀態和環境資訊,一旦出現問題,定時任務會撈取未執行完的任務,繼續未執行完的任務,直到執行完成為止,或者取消已經完成的部分操作回到原始狀態。這種方法在任務完成每個階段的時候,都要更新資料庫中任務的狀態,這在大規模高併發系統中不會有太好的效能,一個更好的辦法是用Write-Ahead Log(寫前日誌),這和資料庫的Bin Log(操作日誌)相似,在做每一個操作步驟,都先寫入日誌,如果操作遇到問題而停止的時候,可以讀取日誌按照步驟進行恢復,並且繼續執行未完成的工作,最後達到一致。寫前日誌可以利用機械硬碟的追加寫而達到較好效能,因此,這是一種專業化的實現方式,多數業務繫系統還是使用資料庫記錄的欄位來記錄任務的執行狀態,也就是記錄中間的“軟狀態”,一個任務的狀態流轉一般可以通過資料庫的行級鎖來實現,這比使用Write-Ahead Log實現更簡單、更快速。
分散式和叢集
分散式:不同的多臺伺服器上面部署不同的服務模組(工程)
叢集:不同的多臺伺服器上面部署相同的服務模組。通過分散式排程軟體進行統一的排程,對外提供服務和訪問。
Redis的資料型別
Redis五種資料型別:string、hash、list、set、zset
公用命令
del key
dump key:序列化給定key,返回被序列化的值
exists key:檢查key是否存在
expire key second:為key設定過期時間,以秒計算,可以不寫second,預設為秒
ttl key:返回key剩餘時間,-1為永久,-2為失效
persist key:移除key的過期時間,key將持久儲存
keys pattern:查詢所有符號給定模式的key eg:keys *
randomkey:隨機返回一個key
rename key newkey:修改key的名稱
move key db:移動key至指定資料庫中 eg:move a 1
type key:返回key所儲存的值的型別
expirekey second的使用場景: 1、限時的優惠活動 2、網站資料快取 3、手機驗證碼 4、限制網站訪客頻率
key的命名建議
key不要太長,儘量不要超過1024位元組。不僅消耗記憶體,也會降低查詢的效率
key不要太短,太短可讀性會降低
在一個專案中,key最好使用統一的命名模式,如user:123:password
key區分大小寫
String
string型別是二進位制安全的,redis的string可以包含任何資料,如影象、序列化物件。一個鍵最多能儲存512MB。
二進位制安全是指,在傳輸資料的時候,能保證二進位制資料的資訊保安,也就是不會被篡改、破譯;如果被攻擊,能夠及時檢測出來
set key_name value:命令不區分大小寫,但是key_name區分大小寫
setnx key value:當key不存在時設定key的值。(SET if Not eXists),分散式鎖的問題
setex:建立一個key,並且設定他的過期時間
get key_name
getrange key start end:獲取key中字串的子字串,從start開始,end結束
setrange key offset value:設定從offset往後的值
mget key1 [key2 …]:獲取多個key
getset key_name value:返回key的舊值,並設定key的值。當key不存在,返回nil
strlen key:返回key所儲存的字串的長度
incr key_name :INCR命令key中儲存的值+1,如果不存在key,則key中的值話先被初始化為0再加1
INCRBY KEY_NAME 增量
DECR KEY_NAME:key中的值自減一
DECRBY KEY_NAME
append key_name value:字串拼接,追加至末尾,如果不存在,為其賦值
String應用場景: 1、String通常用於儲存單個字串或JSON字串資料 2、因為String是二進位制安全的,所以可以把保密要求高的圖片檔案內容作為字串來儲存 3、計數器:常規Key-Value快取應用,如微博數、粉絲數。INCR本身就具有原子性特性,所以不會有執行緒安全問題
hash
Redis hash是一個string型別的field和value的對映表,hash特別適用於儲存物件。每個hash可以儲存232-1(40億左右)鍵值對。可以看成KEY和VALUE的MAP容器。相比於JSON,hash佔用很少的記憶體空間。
常用命令
hset key_name field value:為指定的key設定field和value
hmset key field value[field1,value1]
hsetnx:當不存在才建立該field
hget key field
hmget key field[field1]
hgetall key:返回hash表中所有欄位和值
hkeys key:獲取hash表所有欄位
hvals key:獲取hash表所有值
hlen key:獲取hash表中的欄位數量
hdel key field [field1]:刪除一個或多個hash表的欄位
hexists:在key裡面是否存在指定的field
hincrby key field increment:增加某個field的值
應用場景
Hash的應用場景,通常用來儲存一個使用者資訊的物件資料。
相比於儲存物件的string型別的json串,json串修改單個屬性需要將整個值取出來。而hash不需要。
相比於多個key-value儲存物件,hash節省了很多記憶體空間
如果hash的屬性值被刪除完,那麼hash的key也會被redis刪除
list
類似於Java中的LinkedList。
常用命令
lpush key value1 [value2]:從左側插入,右邊的先出,相當於一個棧
eg:lpush list 1 2 3 lrange list 0 -1 輸出:3 2 1
rpush key value1 [value2]: 從右側插入,左邊的先出
eg:rpush list 1 2 3 lrange list 0 -1 輸出:1 2 3
lpushx key value:從左側插入值,如果list不存在,則不操作
rpushx key value:從右側插入值,如果list不存在,則不操作
llen key:獲取列表長度
lindex key index:獲取指定索引的元素,從零開始
lrange key start stop:獲取列表指定範圍的元素
lpop key :從左側移除第一個元素
prop key:移除列表最後一個元素
irem:刪除指定個數的同一元素
eg:irem list 2 3 刪掉了集合中的兩個三
blpop key [key1] timeout:移除並獲取列表第一個元素,如果列表沒有元素會阻塞列表到等待超時或發現可彈出元素為止
brpop key [key1] timeout:移除並獲取列表最後一個元素,如果列表沒有元素會阻塞列表到等待超時或發現可彈出元素為止
ltrim key start stop :對列表進行修改,讓列表只保留指定區間的元素,不在指定區間的元素就會被刪除
eg:list1中元素1 2 3 4 5 ltrim list1 2 3 list1剩餘元素:3 4
lset key index value :指定索引的值
linsert key before|after world value:在列表元素前或則後插入元素
應用場景
對資料大的集合資料刪減
列表顯示、關注列表、粉絲列表、留言評價...分頁、熱點新聞等
任務佇列 list通常用來實現一個訊息佇列,而且可以確保先後順序,不必像MySQL那樣通過order by來排序
補充:
rpoplpush list1 list2 移除list1最後一個元素,並將該元素新增到list2並返回此元素 用此命令可以實現訂單下單流程、使用者系統登入註冊簡訊等。
效能總結
它是一個字串連結串列,left、right都可以插入新增; 如果鍵不存在,建立新的連結串列; 如果鍵已存在,新增內容; 如果值全移除,對應的鍵也就消失了。 連結串列的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了。
set
唯一、無序
sadd key value1[value2]:向集合新增成員
scard key:返回集合成員數
smembers key:返回集合中所有成員
sismember key member:判斷memeber元素是否是集合key成員的成員
srandmember key [count]:返回集合中一個或多個隨機數
srem key member1 [member2]:移除集合中一個或多個成員
spop key:移除並返回集合中的一個隨機元素
smove source destination member:將member元素從source集合移動到destination集合
sdiff key1 [key2]:返回給定的第一個集合和其他集合的差集(即在key1中的值而在其他key中找不到)
sdiffstore destination key1[key2]:返回給定的第一個集合與其他的集合的差集並存儲在destination中
eg:set1:1 2 3 set2:3 4 5 6 sdiffstore set3 set1 set2 smembers set3 result:1 2
sinter key1 [key2]:返回所有集合的交集
sunion key1 [key2]:返回所有集合的並集
對兩個集合間的資料[計算]進行交集、並集、差集運算 1、以非常方便的實現如共同關注、共同喜好、二度好友等功能。對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給客戶端還是儲存到一個新的集合中。 2、利用唯一性,可以統計訪問網站的所有獨立 IP
zset
有序且不重複。每個元素都會關聯一個double型別的分數,Redis通過分數進行從小到大的排序。分數可以重複
zadd key score1 memeber1
zcard key :獲取集合中的元素數量
zcount key min max 計算在有序集合中指定區間分數的成員數
zcount key min max 計算在有序集合中指定區間分數的成員數
zrange key start stop 指定輸出索引範圍內的成員
zrangebyscore key min max 指定輸出score區間內的成員
zrank key member:返回有序集合指定成員的索引
zrevrange key start stop :返回有序集中指定區間內的成員,通過索引,分數從高到底
zrem key member [member …] 移除有序集合中的一個或多個成員
zremrangebyrank key start stop 移除有序集合中給定的索引區間的所有成員(第一名是0)(低到高排序)
zremrangebyscore key min max 移除有序集合中給定的分數區間的所有成員
常用於排行榜:
如推特可以以發表時間作為score來儲存
儲存成績
還可以用zset來做帶權重的佇列,讓重要的任務先執行
解析配置檔案
#是否在後臺執行;no:不是後臺執行
daemonize yes
#是否開啟保護模式,預設開啟。要是配置裡沒有指定bind和密碼。開啟該引數後,redis只會本地進行訪問,拒絕外部訪問。
protected-mode yes
#redis的程序檔案
pidfile /var/run/redis/redis-server.pid
#redis監聽的埠號。
port 6379
#此引數確定了TCP連線中已完成佇列(完成三次握手之後)的長度, 當然此值必須不大於Linux系統定義的/proc/sys/net/core/somaxconn值,預設是511,而Linux的預設引數值是128。當系統併發量大並且客戶端速度緩慢的時候,可以將這二個引數一起參考設定。該核心引數預設值一般是128,對於負載很大的服務程式來說大大的不夠。一般會將它修改為2048或者更大。在/etc/sysctl.conf中新增:net.core.somaxconn = 2048,然後在終端中執行sysctl -p。
tcp-backlog 511
#指定 redis 只接收來自於該 IP 地址的請求,如果不進行設定,那麼將處理所有請求
#bind 127.0.0.1
#bind 0.0.0.0
#配置unix socket來讓redis支援監聽本地連線。
# unixsocket /var/run/redis/redis.sock
#配置unix socket使用檔案的許可權
# unixsocketperm 700
# 此引數為設定客戶端空閒超過timeout,服務端會斷開連線,為0則服務端不會主動斷開連線,不能小於0。
timeout 0
#tcp keepalive引數。如果設定不為0,就使用配置tcp的SO_KEEPALIVE值,使用keepalive有兩個好處:檢測掛掉的對端。降低中間裝置出問題而導致網路看似連線卻已經與對端埠的問題。在Linux核心中,設定了keepalive,redis會定時給對端傳送ack。檢測到對端關閉需要兩倍的設定值。
tcp-keepalive 0
#指定了服務端日誌的級別。級別包括:debug(很多資訊,方便開發、測試),verbose(許多有用的資訊,但是沒有debug級別資訊多),notice(適當的日誌級別,適合生產環境),warn(只有非常重要的資訊)
loglevel notice
#指定了記錄日誌的檔案。空字串的話,日誌會列印到標準輸出裝置。後臺執行的redis標準輸出是/dev/null。
logfile /var/log/redis/redis-server.log
#是否開啟記錄syslog功能
# syslog-enabled no
#syslog的識別符號。
# syslog-ident redis
#日誌的來源、裝置
# syslog-facility local0
#資料庫的數量,預設使用的資料庫是DB 0。可以通過SELECT命令選擇一個db
databases 16
# redis是基於記憶體的資料庫,可以通過設定該值定期寫入磁碟。
# 註釋掉“save”這一行配置項就可以讓儲存資料庫功能失效
# 900秒(15分鐘)內至少1個key值改變(則進行資料庫儲存--持久化)
# 300秒(5分鐘)內至少10個key值改變(則進行資料庫儲存--持久化)
# 60秒(1分鐘)內至少10000個key值改變(則進行資料庫儲存--持久化)
save 900 1
save 300 10
save 60 10000
#當RDB持久化出現錯誤後,是否依然進行繼續進行工作,yes:不能進行工作,no:可以繼續進行工作,可以通過info中的rdb_last_bgsave_status瞭解RDB持久化是否有錯誤
stop-writes-on-bgsave-error yes
#使用壓縮rdb檔案,rdb檔案壓縮使用LZF壓縮演算法,yes:壓縮,但是需要一些cpu的消耗。no:不壓縮,需要更多的磁碟空間
rdbcompression yes
#是否校驗rdb檔案。從rdb格式的第五個版本開始,在rdb檔案的末尾會帶上CRC64的校驗和。這跟有利於檔案的容錯性,但是在儲存rdb檔案的時候,會有大概10%的效能損耗,所以如果你追求高效能,可以關閉該配置。
rdbchecksum yes
#rdb檔案的名稱
dbfilename dump.rdb
#資料目錄,資料庫的寫入會在這個目錄。rdb、aof檔案也會寫在這個目錄
dir /data
############### 主從複製 ###############
#複製選項,slave複製對應的master。
# slaveof <masterip> <masterport>
#如果master設定了requirepass,那麼slave要連上master,需要有master的密碼才行。masterauth就是用來配置master的密碼,這樣可以在連上master後進行認證。
# masterauth <master-password>
#當從庫同主機失去連線或者複製正在進行,從機庫有兩種執行方式:1) 如果slave-serve-stale-data設定為yes(預設設定),從庫會繼續響應客戶端的請求。2) 如果slave-serve-stale-data設定為no,除去INFO和SLAVOF命令之外的任何請求都會返回一個錯誤”SYNC with master in progress”。
slave-serve-stale-data yes
#作為從伺服器,預設情況下是隻讀的(yes),可以修改成NO,用於寫(不建議)。
slave-read-only yes
#是否使用socket方式複製資料。目前redis複製提供兩種方式,disk和socket。如果新的slave連上來或者重連的slave無法部分同步,就會執行全量同步,master會生成rdb檔案。有2種方式:disk方式是master建立一個新的程序把rdb檔案儲存到磁碟,再把磁碟上的rdb檔案傳遞給slave。socket是master建立一個新的程序,直接把rdb檔案以socket的方式發給slave。disk方式的時候,當一個rdb儲存的過程中,多個slave都能共享這個rdb檔案。socket的方式就的一個個slave順序複製。在磁碟速度緩慢,網速快的情況下推薦用socket方式。
repl-diskless-sync no
#diskless複製的延遲時間,防止設定為0。一旦複製開始,節點不會再接收新slave的複製請求直到下一個rdb傳輸。所以最好等待一段時間,等更多的slave連上來。
repl-diskless-sync-delay 5
#slave根據指定的時間間隔向伺服器傳送ping請求。時間間隔可以通過 repl_ping_slave_period 來設定,預設10秒。
# repl-ping-slave-period 10
#複製連線超時時間。master和slave都有超時時間的設定。master檢測到slave上次傳送的時間超過repl-timeout,即認為slave離線,清除該slave資訊。slave檢測到上次和master互動的時間超過repl-timeout,則認為master離線。需要注意的是repl-timeout需要設定一個比repl-ping-slave-period更大的值,不然會經常檢測到超時。
# repl-timeout 60
#是否禁止複製tcp連結的tcp nodelay引數,可傳遞yes或者no。預設是no,即使用tcp nodelay。如果master設定了yes來禁止tcp nodelay設定,在把資料複製給slave的時候,會減少包的數量和更小的網路頻寬。但是這也可能帶來資料的延遲。預設我們推薦更小的延遲,但是在資料量傳輸很大的場景下,建議選擇yes。
repl-disable-tcp-nodelay no
#複製緩衝區大小,這是一個環形複製緩衝區,用來儲存最新複製的命令。這樣在slave離線的時候,不需要完全複製master的資料,如果可以執行部分同步,只需要把緩衝區的部分資料複製給slave,就能恢復正常複製狀態。緩衝區的大小越大,slave離線的時間可以更長,複製緩衝區只有在有slave連線的時候才分配記憶體。沒有slave的一段時間,記憶體會被釋放出來,預設1m。
# repl-backlog-size 5mb
#master沒有slave一段時間會釋放複製緩衝區的記憶體,repl-backlog-ttl用來設定該時間長度。單位為秒。
# repl-backlog-ttl 3600
#當master不可用,Sentinel會根據slave的優先順序選舉一個master。最低的優先順序的slave,當選master。而配置成0,永遠不會被選舉。
slave-priority 100
#redis提供了可以讓master停止寫入的方式,如果配置了min-slaves-to-write,健康的slave的個數小於N,mater就禁止寫入。master最少得有多少個健康的slave存活才能執行寫命令。這個配置雖然不能保證N個slave都一定能接收到master的寫操作,但是能避免沒有足夠健康的slave的時候,master不能寫入來避免資料丟失。設定為0是關閉該功能。
# min-slaves-to-write 3
#延遲小於min-slaves-max-lag秒的slave才認為是健康的slave。
# min-slaves-max-lag 10
# 設定1或另一個設定為0禁用這個特性。
# Setting one or the other to 0 disables the feature.
# By default min-slaves-to-write is set to 0 (feature disabled) and
# min-slaves-max-lag is set to 10.
############### 安全相關 ###############
#requirepass配置可以讓使用者使用AUTH命令來認證密碼,才能使用其他命令。這讓redis可以使用在不受信任的網路中。為了保持向後的相容性,可以註釋該命令,因為大部分使用者也不需要認證。使用requirepass的時候需要注意,因為redis太快了,每秒可以認證15w次密碼,簡單的密碼很容易被攻破,所以最好使用一個更復雜的密碼。注意只有密碼沒有使用者名稱。
# requirepass foobared
#把危險的命令給修改成其他名稱。比如CONFIG命令可以重新命名為一個很難被猜到的命令,這樣使用者不能使用,而內部工具還能接著使用。
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#設定成一個空的值,可以禁止一個命令
# rename-command CONFIG ""
############### 程序限制相關 ###############
# 設定能連上redis的最大客戶端連線數量。預設是10000個客戶端連線。由於redis不區分連線是客戶端連線還是內部開啟檔案或者和slave連線等,所以maxclients最小建議設定到32。如果超過了maxclients,redis會給新的連線傳送’max number of clients reached’,並關閉連線。
# maxclients 10000
#redis配置的最大記憶體容量。當記憶體滿了,需要配合maxmemory-policy策略進行處理。注意slave的輸出緩衝區是不計算在maxmemory內的。所以為了防止主機記憶體使用完,建議設定的maxmemory需要更小一些。
# maxmemory <bytes>
#記憶體容量超過maxmemory後的處理策略。
#volatile-lru:利用LRU演算法移除設定過過期時間的key。
#volatile-random:隨機移除設定過過期時間的key。
#volatile-ttl:移除即將過期的key,根據最近過期時間來刪除(輔以TTL)
#allkeys-lru:利用LRU演算法移除任何key。