網(wǎng)站 ip修改備案流程西安搜建站科技網(wǎng)站
Redis
Redis 是基于鍵值對的非關(guān)系型數(shù)據(jù)庫。Redis 擁有string、hash、list、set、zset等多種數(shù)據(jù)結(jié)構(gòu), redis具有驚人的讀寫性能, 其優(yōu)秀的持久化機(jī)制是的它在斷電和機(jī)械故障時也不會發(fā)生數(shù)據(jù)丟失, 可以用于熱點(diǎn)數(shù)據(jù)存放, 還提供了鍵過期、發(fā)布訂閱、食物、流水線、LUA腳本等多個高級功能。
1 Redis 數(shù)據(jù)結(jié)構(gòu)
-
string
: 最基本數(shù)據(jù)類型, 可以存放入二進(jìn)制、序列化數(shù)據(jù)、JSON對象、圖片等數(shù)據(jù)-
底層實(shí)現(xiàn):
SDS(Simple Dynamic String) - 動態(tài)字符串
可修改字符串, 采用預(yù)分配冗余空間的方式減少內(nèi)存的頻繁分配。與Java中的ArrayList比較類似, 實(shí)質(zhì)上也是在空間不足時觸發(fā)擴(kuò)容機(jī)制, 如果 SDS 值大小< 1M , 則增加一倍;反之如果>1M , 則當(dāng)前空間加1M作為新的空間。
struct sdshdr{//記錄buf數(shù)組中已使用字節(jié)的數(shù)量//等于SDS保存字符串的長度4byteint len;//記錄 buf數(shù)組中未使用字節(jié)的數(shù)量 4 byteint free;//字節(jié)數(shù)組,用于保存字符串字節(jié)\0結(jié)尾的字符串占用了1bytechar buf[]; }
-
-
list
: 字符串列表, 按照插入的順序排序, 元素可以重復(fù), 底層由鏈表
實(shí)現(xiàn)。-
底層實(shí)現(xiàn):
ZIPList| LinkedList(雙向鏈表)
當(dāng)元素字符串的長度小于64字節(jié)而且元素個數(shù)小于512時,采用 zipList;否則采用likedList;
-
ZIPList - 壓縮列表
: 由連續(xù)內(nèi)存塊組成且用于存儲小型有序集合或哈希集合的數(shù)據(jù)結(jié)構(gòu)。主要參數(shù)包括: 整個列表占用字節(jié)數(shù)、偏移量、元素個數(shù)、內(nèi)容列表、結(jié)束標(biāo)志。 優(yōu)點(diǎn): 節(jié)省空間
struct ziplist<T> {int32 zlbytes; // 整個壓縮列表占用字節(jié)數(shù)int32 zltail_offset; // 最后一個元素距離壓縮列表起始位置的偏移量,用于快速定位到最后一個節(jié)點(diǎn)int16 zllength; // 元素個數(shù)T[] entries; // 元素內(nèi)容列表,挨個挨個緊湊存儲int8 zlend; // 標(biāo)志壓縮列表的結(jié)束,值恒為 0xFF }
-
-
-
hash
: string 類型 field 和 value 的集合, 適合存放對象-
底層實(shí)現(xiàn):
ZIPList | HashTable
當(dāng)hash對象的鍵與值的長度都小于64字節(jié)時而且鍵值對的個數(shù)小于512個,采用zipList,其它情況,采用hashTable
-
ZIPLIST: 參考上述
-
HashTable - 哈希表
① 數(shù)組 + 鏈表 ②數(shù)組+紅黑樹(樹化方便查找)
根據(jù)Key value而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)。它通過把關(guān)鍵碼值映射到表中一個位置來訪問記錄(類似索引),以加快查找的速度。這個映射函數(shù)叫做散列函數(shù),存放記錄的數(shù)組叫做散列表。
-
-
-
set
: 無序不重復(fù)的集合-
底層實(shí)現(xiàn):
INTSet | HashTable
當(dāng)保存的元素都是整形數(shù)字,而且元素個數(shù)小于配置范圍的時候,則使用intset,否則使用hash表。
-
INTSet - 整數(shù)集合
可變長度的整型數(shù)組 - 基于整數(shù)數(shù)組來實(shí)現(xiàn),并且具備長度可變、有序等特征, 包含: 編碼方式、長度、內(nèi)容等主要屬性(可以選擇不同位數(shù)的整數(shù)存儲)。
typedef struct intset {uint32_t encoding; /* 編碼方式,支持存放16位、32位、64位整數(shù) */uint32_t length; /* 元素個數(shù) */int8_t contents[]; /* 整數(shù)數(shù)組,保存集合數(shù)據(jù) */ } intset;
-
-
-
zset
: 與 set 一樣都是 String 類型元素的集合, 且不允許重復(fù), 但 zset 每個元素都會關(guān)聯(lián)一個分?jǐn)?shù), Redis通過分?jǐn)?shù)來為集合匯總的成員進(jìn)行從小到大的排序。-
底層實(shí)現(xiàn):
ZIPList| SKIPList
-
ZIPList: 參考上述
-
SKIPList
:一種有序的數(shù)據(jù)結(jié)構(gòu),通過在每個節(jié)點(diǎn)維護(hù)多個指針,從而達(dá)到快速訪問的目的。 優(yōu)點(diǎn): 實(shí)現(xiàn)簡單、內(nèi)存消耗少 缺點(diǎn): 不適合范圍查詢
跳躍表 - 跳躍表節(jié)點(diǎn)結(jié)構(gòu)定義
typedef struct zskiplist{// 表頭節(jié)點(diǎn)和表尾節(jié)點(diǎn)struct zskiplist *header,*tail;// 表節(jié)點(diǎn)個數(shù)unsigned long length;// 表節(jié)點(diǎn)最大層數(shù)int level; }zskiplist;
typedef struct zskiplistNode{// 層struct zskiplistLevel{// 前進(jìn)指針struct zskiplistNode *forward;// 跨度unsigned int span;}level[];// 后退指針struct zskiplistNode *backward;// 分值double score;// 成員對象robj *robj; }zskiplistNode;
-
-
-
四種特殊數(shù)據(jù)類型: 1)bitmap 2)hyperloglog 3)geo 4)stream
1) zset 與 set 的區(qū)別
-
set 無序, zset 有序
-
zset 底層使用壓縮列表和跳躍列表( ziplist & skiplist )
set 使用 INTSet 和 HashTable
2 Key 過期策略
-
定期刪除
-過期 Key 保存在字典, 定期隨機(jī)抽取20個Key, 刪除其中過期的, 如果比例超過1/4, 重復(fù)刪除步驟。
redis 會將每個設(shè)置了過期時間的 key 放入到一個獨(dú)立的字典中,以后會定期遍歷這個字典來刪除到期的 key。
Redis 默認(rèn)會每秒進(jìn)行十次過期掃描(100ms一次),過期掃描不會遍歷過期字典中所有的 key,而是采用了一種簡單的貪心策略。
1.從過期字典中隨機(jī) 20 個 key;
2.刪除這 20 個 key 中已經(jīng)過期的 key;
3.如果過期的 key 比率超過 1/4,那就重復(fù)步驟 1;
redis默認(rèn)是每隔 100ms就隨機(jī)抽取一些設(shè)置了過期時間的key,檢查其是否過期,如果過期就刪除。注意這里是隨機(jī)抽取的。為什么要隨機(jī)呢?你想一想假如 redis 存了幾十萬個 key ,每隔100ms就遍歷所有的設(shè)置過期時間的 key 的話,就會給 CPU 帶來很大的負(fù)載。
-
惰性刪除
-訪問時發(fā)現(xiàn) Key 過期, 直接刪除不返回任何值
在客戶端訪問這個key的時候,redis對key的過期時間進(jìn)行檢查,如果過期了就立即刪除,不會給你返回任何東西。
定期刪除可能會導(dǎo)致很多過期key到了時間并沒有被刪除掉。所以就有了惰性刪除。假如你的過期 key,靠定期刪除沒有被刪除掉,還停留在內(nèi)存里,除非你的系統(tǒng)去查一下那個 key,才會被redis給刪除掉。這就是所謂的惰性刪除,即當(dāng)你主動去查過期的key時,如果發(fā)現(xiàn)key過期了,就立即進(jìn)行刪除,不返回任何東西。
3 內(nèi)存淘汰策略
數(shù)據(jù)的淘汰策略: 當(dāng)Redis中的內(nèi)存不夠用時,此時在向Redis中添加新的key,那么Redis就會按照某一種規(guī)則將內(nèi)存中的數(shù)據(jù)刪除掉,這種數(shù)據(jù)的刪除規(guī)則被稱之為內(nèi)存的淘汰策略。
-
noeviction: 不淘汰任何key,但是內(nèi)存滿時不允許寫入新數(shù)據(jù),默認(rèn)策略。
-
volatile-TTL: 對設(shè)置了TTL的key,比較key的剩余TTL值,TTL越小越先被淘汰。
-
allkeys -RANDOM: 對全體key,隨機(jī)進(jìn)行淘汰。
-
volatile-RANDOM: 對設(shè)置了TTL的key,隨機(jī)進(jìn)行淘汰。
-
alkeys -LRU: 對全體key,基于LRU算法進(jìn)行淘汰
-
volatile-LRU: 對設(shè)置了TTL的key,基于LRU算法進(jìn)行淘汰
-
allkeys -LFU: 對全體key,基于LFU算法進(jìn)行淘汰
-
volatile-LFU: 對設(shè)置了TTL的key,基于LFU算法進(jìn)行淘汰
4 主從同步機(jī)制
-
主從同步
-
全量同步
一般發(fā)生在第一次連接時, 原理為將當(dāng)前數(shù)據(jù)寫入到RDB文件后發(fā)送給從機(jī)讀取到叢機(jī)的內(nèi)存中。
-
增量同步
一般發(fā)生在第一次之后的鏈接時, 主機(jī)同步期間發(fā)生的數(shù)據(jù)變化會以命令的形式寫入緩存中, 當(dāng)校驗(yàn)到正確的從機(jī)ID時獲取從機(jī)的偏移量,然后從偏移量記錄的命令開始將未同步的數(shù)據(jù)操作命令發(fā)送給從機(jī)執(zhí)行, 進(jìn)而完成數(shù)據(jù)同步。
-
updating …