1、redis兩種存儲機制(持久化) Redis的存儲機制分為:Snapshot和AOF 都先將記憶體存儲在記憶體中。 (1)Snapshot當數據累計到一定的閾值,就會觸發dump將數據一次性寫入到數據文件RDB文件。批量數據存儲,寫入頻率低,效率也高。但是安全性小,redis宕機,沒有寫入的數據會造 ...
1、redis兩種存儲機制(持久化)
Redis的存儲機制分為:Snapshot和AOF 都先將記憶體存儲在記憶體中。
(1)Snapshot當數據累計到一定的閾值,就會觸發dump將數據一次性寫入到數據文件RDB文件。批量數據存儲,寫入頻率低,效率也高。但是安全性小,redis宕機,沒有寫入的數據會造成丟失。
(2)AOF採用日誌追加的方式來持久化數據,調用fsync來完成對本次寫操作的日誌記錄。調用fsync追加日誌文件的頻率可以更改,always每次記錄都添加進來,everysecond每秒添加一次。rewrite這個日誌的概念:根據合理的配置觸發rewrite操作,將日誌文件中所有數據都重新寫在新的文件中,對於同個key的多次操作,保留最終的值得那次操作在日誌文件中。縮小了日誌文件大小。
2、redis的記憶體優化
(1)string和數字,redis能識別出一個數字,並按數字存儲,節省存儲空間。redis內部有一個數字池,預設10000,數字在這個池中就只需要一個簡單的索引引用進來就可以,不需要把重覆的數字分開存。
(2)複雜類型的存儲優化,map,list,set這些大小不固定的集合類。redis會判斷這裡存儲的entry數量,不多則採用緊湊格式來存儲數據,這裡不做解釋。
3、講講redis中的hash數據類型
比起String數據類型,這個更適合存儲對象,避免了序列化和反序列化
hash是一個string 類型的field和value的映射表。
hash特別適合存儲對象。相對於將對象的每個欄位存成單個string 類型。一個對象存儲在hash類型中會占用更少的記憶體,並且可以更方便的存取整個對象。
Redis的Hash數據類型的value內部是一個HashMap,如果該Map的成員比較少,則會採用一維數組的方式來緊湊存儲該MAP,省去了大量指針的記憶體開銷。
採用key—field—value的方式。一個key可對應多個field,一個field對應一個value。這裡同時需要註意,Redis提供了介面(hgetall)可以直接取到全部的屬性數據,但是如果內部Map的成員很多,那麼涉及到遍歷整個內部Map的操作,由於Redis單線程模型的緣故,這個遍歷操作可能會比較耗時,而令其它客戶端的請求完全不響應,這點需要格外註意
建議使用對象類別和ID構成鍵名,使用欄位表示對象屬性,欄位值存儲屬性值。
4、redis集群
如果redis只是單例的話,萬一掛了,數據丟失。而且當數據量很大的時候,集群可以保證高可用。它可以把多個redis實例整合在一起,形成一個集群,也就是將數據分散到集群的多台機器上。但是該怎麼分散呢,一個Key只能被分配到一臺機器上,集群是如何實現把數據分配到不同的節點呢?我們在查詢數據時,數據在任意一個節點中,我們如何保證成功存取呢?
如圖是redis集群架構圖,藍色的是redis伺服器節點,綠色的是客戶端。每個節點通過二進位協議進行通信,每個節點也保存著所有集群的信息。節點之間相互ping對方,如果ping不通,說明對方節點掛了,由於每個節點會有一個副本slave,主從備份保證了後臺的穩定性。
客戶端可以與任何一個節點通信,對其存取和其他操作。由於數據被分配在不同的節點中,集群是如何找到數據在哪兒呢?redis 集群有一個16384長度的插槽。slot。編號分別是0,1,2,……16383,16384.每個節點都會負責一些插槽。集群維護這節點到插槽的映射。是由長度為16384,類型為節點的數組實現的。槽編碼就是數組的下標。數組的內容就是節點。所以這樣很快的能知道哪些槽是由哪些節點負責的。對於master節點來說,維護一個16384/8位元組的位序列,比如對於編號為1的槽,Master只要判斷序列的第二位(索引從0開始)是不是為1即可。
redis的數據是key-value存儲的。不同的key的數據如何對應到slot呢。有一個鍵空間分佈的演算法 HASH_SLOT=CRC16(key)mod16384 這樣就可以算出當前key被存在哪個slot里。
5、分片
分片不變的是鍵對於槽的映射,改變的是槽對於節點的映射。