Redis(一):基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)

Redis 有 5 種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),分別為:string (字符串)矿瘦、list (列表)、set (集合)愿卒、hash (哈希) 和 zset (有序集合)缚去。

image

1、String 字符串

字符串 string 是 Redis 最簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)琼开。Redis 所有的數(shù)據(jù)結(jié)構(gòu)都是以唯一的 key 字符串作為名稱(chēng)易结,然后通過(guò)這個(gè)唯一 key 值來(lái)獲取相應(yīng)的 value 數(shù)據(jù)。不同類(lèi)型的數(shù)據(jù)結(jié)構(gòu)的差異就在于 value 的結(jié)構(gòu)不一樣。字符串結(jié)構(gòu)使用非常廣泛衬衬,一個(gè)常見(jiàn)的用途就是緩存用戶信息买猖。我們將用戶信息結(jié)構(gòu)體使用 JSON 序列化成字符串,然后將序列化后的字符串塞進(jìn) Redis 來(lái)緩存滋尉。同樣玉控,取用戶信息會(huì)經(jīng)過(guò)一次反序列化的過(guò)程。

鍵值對(duì)命令:

image

批量鍵值對(duì)命令:可以批量對(duì)多個(gè)字符串進(jìn)行讀寫(xiě)狮惜,節(jié)省網(wǎng)絡(luò)耗時(shí)開(kāi)銷(xiāo)

image

過(guò)期和 set 命令擴(kuò)展:可以對(duì) key 設(shè)置過(guò)期時(shí)間高诺,到點(diǎn)自動(dòng)刪除,這個(gè)功能常用來(lái)控制緩存的失效時(shí)間

image

原子計(jì)數(shù):如果 value 值是一個(gè)整數(shù)碾篡,還可以對(duì)它進(jìn)行自增操作虱而。自增是有范圍的,它的范圍是 signed long 的最大最小值开泽,超過(guò)了這個(gè)值牡拇,Redis 會(huì)報(bào)錯(cuò)

image

2、list(列表)

Redis的列表相當(dāng)于java中的LinkedList穆律,是鏈表而不是數(shù)組惠呼,這意味著list的插入和刪除操作非常快峦耘,時(shí)間復(fù)雜度為O(1)剔蹋,但是索引定位很慢,時(shí)間復(fù)雜度為O(n)辅髓,當(dāng)列表彈出了最后一個(gè)元素以后泣崩,該數(shù)據(jù)結(jié)構(gòu)自動(dòng)被刪除,內(nèi)存被回收洛口;
Redis的列表結(jié)構(gòu)常用來(lái)做異步隊(duì)列使用矫付,將需要延后處理的任務(wù)結(jié)構(gòu)體序列化為字符串塞進(jìn)Redis的列表,另一個(gè)線程從這個(gè)列表中輪詢數(shù)據(jù)進(jìn)行處理绍弟;

右邊進(jìn)左邊出:隊(duì)列

圖片.png

右邊進(jìn)右邊出:棧

image

3技即、hash(字典)

Redis的字典相當(dāng)于Java中的HashMap,是無(wú)序字典樟遣,內(nèi)部實(shí)現(xiàn)結(jié)構(gòu)上同Java的HashMap也是一致的而叼,是數(shù)據(jù)+鏈表二維結(jié)構(gòu)的,第一維hash的數(shù)組位置碰撞時(shí)豹悬,就會(huì)將碰撞的元素使用鏈表串接起來(lái)葵陵;
hash結(jié)構(gòu)也可以用來(lái)存儲(chǔ)用戶信息,不同于字符串String需要一次性全部序列化整個(gè)對(duì)象瞻佛,hash結(jié)構(gòu)可以對(duì)用戶結(jié)構(gòu)中的每個(gè)字段單獨(dú)存儲(chǔ)脱篙,這樣當(dāng)我們需要獲取用戶信息時(shí)娇钱,可以進(jìn)行部分獲取,而以整個(gè)字符串的形式去保存用戶信息的話绊困,就只能一次性全部讀取文搂,這樣就會(huì)比較浪費(fèi)網(wǎng)絡(luò)流量;
hash也有缺點(diǎn)秤朗,就是hash結(jié)構(gòu)的存儲(chǔ)消耗要高于單個(gè)字符串煤蹭。

image

4、Set(集合)

Redis的集合相當(dāng)于Java中的HashSet取视,內(nèi)部的鍵值對(duì)是無(wú)序的唯一的(無(wú)序是指不是按照插入數(shù)據(jù)順序排序硝皂,而是按照字典序排序),內(nèi)部實(shí)現(xiàn)相當(dāng)于一個(gè)特殊的字典(hash)作谭,字典中所有的value都是一個(gè)值NULL稽物,當(dāng)集合中最后一個(gè)元素移除之后,數(shù)據(jù)結(jié)構(gòu)自動(dòng)刪除折欠,內(nèi)存被回收贝或。

image

5、zset(有序集合)

zset類(lèi)似于java的SortedSet和HashMap的結(jié)合體怨酝,一方面它是一個(gè)set傀缩,保證了內(nèi)存value的唯一性,另一方面它可以給每個(gè)value賦予一個(gè)score农猬,代表這個(gè)value排序權(quán)重。
zset可以用來(lái)存粉絲列表售淡,value值是粉絲的用戶ID斤葱,score的關(guān)注事件,可以可以對(duì)粉絲列表按關(guān)注時(shí)間進(jìn)行排序揖闸;
zset還可以用來(lái)存儲(chǔ)學(xué)生的成績(jī)揍堕,value值是學(xué)生ID,score是他的成績(jī)汤纸,我們可以對(duì)成績(jī)按分?jǐn)?shù)進(jìn)行排序就可以得到他的名次

image

6衩茸、高級(jí)命令

  • keys:全量遍歷鍵,用來(lái)列出所有滿足正則字符串規(guī)則的key贮泞,當(dāng)redis數(shù)據(jù)量比較大時(shí)楞慈,性能比較差,要避免使用
image
  • scan:漸進(jìn)式遍歷鍵啃擦,scan參數(shù)提供了三個(gè)參數(shù)囊蓝,第一個(gè)是cursor整數(shù)值,第二個(gè)是key的正則模式令蛉,第三個(gè)是遍歷的limit hint聚霜;
    第一次遍歷時(shí),cursor值為0,然后將返回結(jié)果中第一個(gè)整數(shù)值作為下一次遍歷的cursor蝎宇,一直遍歷到返回的cursor值為0時(shí)結(jié)束
image
image

Redis存儲(chǔ)鍵值對(duì)實(shí)際使用的是hashtable的數(shù)據(jù)結(jié)構(gòu)

image
  • info:查看redis服務(wù)運(yùn)行信息弟劲,分為9大塊,每個(gè)塊都有非常多的參數(shù)姥芥,這9個(gè)塊分別是:
    1兔乞、Server 服務(wù)器運(yùn)行的環(huán)境參數(shù)
    2、Clients 客戶端相關(guān)信息
    3撇眯、Memory 服務(wù)器運(yùn)行內(nèi)存統(tǒng)計(jì)數(shù)據(jù)
    4报嵌、Persistence 持久化信息
    5、Stats 通用統(tǒng)計(jì)數(shù)據(jù)
    6熊榛、Replication 主從復(fù)制相關(guān)信息
    7锚国、CPU CPU 使用情況
    8、Cluster 集群信息
    9玄坦、KeySpace 鍵值對(duì)統(tǒng)計(jì)數(shù)量信息
image

7血筑、核心原理

1、Redis的單線程和高性能

  • Redis為什么這么快煎楣,尤其是其采用單線程
    因?yàn)樗乃械臄?shù)據(jù)都在內(nèi)存中豺总,所有的運(yùn)算都是內(nèi)存級(jí)別的運(yùn)算,而且單線程避免了多線程的切換性能損耗問(wèn)題择懂;
    而且正因?yàn)镽edis是單線程喻喳,所以要小心使用Redis指令,對(duì)于那些耗時(shí)的指令(比如keys),一定要謹(jǐn)慎使用困曙,一步小心就可能會(huì)導(dǎo)致Redis卡頓表伦;

  • Redis單線程處理多個(gè)并發(fā)客戶端連接:IO多路復(fù)用
    Redis的IO多路復(fù)用:redis利用epoll來(lái)實(shí)現(xiàn)IO多路復(fù)用,將連接信息和事件放到隊(duì)列中慷丽,依次放到文件事件分派器蹦哼,事件分派器將事件分發(fā)給事件處理器。
    Nginx也是采用IO多路復(fù)用原理解決C10k問(wèn)題

image

2要糊、持久化

  • RDB快照(snapshot)
    在默認(rèn)情況下纲熏,Redis將數(shù)據(jù)庫(kù)快照保存在名字為dump.rdb的二進(jìn)制文件中。
    可以對(duì)Redis進(jìn)行設(shè)置锄俄,讓它在“N秒內(nèi)數(shù)據(jù)集中至少有M個(gè)改的”這個(gè)條件被滿足時(shí)局劲,自動(dòng)保存一次數(shù)據(jù)集。
//在滿足“60s內(nèi)至少有1000個(gè)鍵被改動(dòng)”這一條件時(shí)珊膜,自動(dòng)保存一次數(shù)據(jù)集
save 60 100

  • AOF(append-only file)
    快照功能并不是非常耐久(durable):如果Redis因?yàn)槟承┰蚨斐晒收贤C(jī)容握,那么服務(wù)器將丟失最近寫(xiě)入、且仍未保存到快照中的哪些數(shù)據(jù)车柠。
    從1.1版本開(kāi)始剔氏,Redis增加了一種完全耐久的持久化方式塑猖,AOF持久化,將修改的每一條指令記錄進(jìn)文件谈跛,就是說(shuō)羊苟,每當(dāng)Redis執(zhí)行一個(gè)改變數(shù)據(jù)集的命令時(shí)(比如SET),這個(gè)命令就會(huì)被追加到AOF文件的末尾感憾,這樣的話蜡励,當(dāng)Redis重新啟動(dòng)時(shí),程序就可以通過(guò)重新執(zhí)行AOF文件中的命令來(lái)達(dá)到重建數(shù)據(jù)集的目的阻桅。
//通過(guò)修改配置文件來(lái)打開(kāi)AOF功能
appendonly yes

可以配置 Redis 多久才將數(shù)據(jù) fsync 到磁盤(pán)一次凉倚,有三個(gè)選項(xiàng):
1、每次有新命令追加到 AOF 文件時(shí)就執(zhí)行一次 fsync :非常慢嫂沉,也非常安全稽寒。
2、每秒 fsync 一次:足夠快(和使用 RDB 持久化差不多)趟章,并且在故障時(shí)只會(huì)丟失 1 秒鐘的數(shù)據(jù)杏糙。
3、從不 fsync :將數(shù)據(jù)交給操作系統(tǒng)來(lái)處理蚓土。更快宏侍,也更不安全的選擇。
推薦(并且也是默認(rèn))的措施為每秒 fsync 一次蜀漆, 這種 fsync 策略可以兼顧速度和安全性谅河。

  • RDB vs AOF
    如果你非常關(guān)心你的數(shù)據(jù), 但仍然可以承受數(shù)分鐘以內(nèi)的數(shù)據(jù)丟失确丢, 那么你可以只使用 RDB 持久化旧蛾。
    有很多用戶都只使用 AOF 持久化, 但我們并不推薦這種方式: 因?yàn)槎〞r(shí)生成 RDB 快照(snapshot)非常便于進(jìn)行數(shù)據(jù)庫(kù)備份蠕嫁, 并且 RDB 恢復(fù)數(shù)據(jù)集的速度也要比 AOF 恢復(fù)的速度要快。

  • Redis 4.0 混合持久化
    重啟 Redis 時(shí)毯盈,我們很少使用 rdb 來(lái)恢復(fù)內(nèi)存狀態(tài)剃毒,因?yàn)闀?huì)丟失大量數(shù)據(jù)。我們通常使用 AOF 日志重放搂赋,但是重放 AOF 日志性能相對(duì) rdb 來(lái)說(shuō)要慢很多赘阀,這樣在 Redis 實(shí)例很大的情況下,啟動(dòng)需要花費(fèi)很長(zhǎng)的時(shí)間脑奠。 Redis 4.0 為了解決這個(gè)問(wèn)題基公,帶來(lái)了一個(gè)新的持久化選項(xiàng)——混合持久化。AOF在重寫(xiě)(aof文件里可能有太多沒(méi)用指令宋欺,所以aof會(huì)定期根據(jù)內(nèi)存的最新數(shù)據(jù)生成aof文件)時(shí)將 rdb文件的內(nèi)容和增量的 AOF 日志文件存在一起轰豆,AOF根據(jù)配置規(guī)則在后臺(tái)自動(dòng)重寫(xiě)胰伍,也可以人為執(zhí)行命令bgrewriteaof重寫(xiě)AOF。這里的 AOF 日志不再是全量的日志酸休,而是自持久化開(kāi)始到持久化結(jié)束的這段時(shí)間發(fā)生的增量 AOF 日志骂租,通常這部分 AOF 日志很小。 于是在 Redis 重啟的時(shí)候斑司,可以先加載 rdb 的內(nèi)容渗饮,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重啟效率因此大幅得到提升宿刮。

//開(kāi)啟混合持久化:
aof-use-rdb-preamble yes  

混合持久化aof文件結(jié)構(gòu)

image

3互站、緩存淘汰策略
當(dāng) Redis 內(nèi)存超出物理內(nèi)存限制時(shí),內(nèi)存的數(shù)據(jù)會(huì)開(kāi)始和磁盤(pán)產(chǎn)生頻繁的交換 (swap)僵缺。交換會(huì)讓 Redis 的性能急劇下降胡桃,對(duì)于訪問(wèn)量比較頻繁的 Redis 來(lái)說(shuō),這樣龜速的存取效率基本上等于不可用谤饭。
在生產(chǎn)環(huán)境中我們是不允許 Redis 出現(xiàn)交換行為的标捺,為了限制最大使用內(nèi)存,Redis 提供了配置參數(shù) maxmemory 來(lái)限制內(nèi)存超出期望大小揉抵。
當(dāng)實(shí)際內(nèi)存超出 maxmemory 時(shí)亡容,Redis 提供了幾種可選策略 (maxmemory-policy) 來(lái)讓用戶自己決定該如何騰出新的空間以繼續(xù)提供讀寫(xiě)服務(wù)。

  • noeviction:不會(huì)繼續(xù)服務(wù)寫(xiě)請(qǐng)求 (DEL 請(qǐng)求可以繼續(xù)服務(wù))冤今,讀請(qǐng)求可以繼續(xù)進(jìn)行闺兢。這樣可以保證不會(huì)丟失數(shù)據(jù),但是會(huì)讓線上的業(yè)務(wù)不能持續(xù)進(jìn)行戏罢。這是默認(rèn)的淘汰策略屋谭。
  • volatile-lru:嘗試淘汰設(shè)置了過(guò)期時(shí)間的 key,最少使用的 key 優(yōu)先被淘汰龟糕。沒(méi)有設(shè)置過(guò)期時(shí)間的 key 不會(huì)被淘汰桐磁,這樣可以保證需要持久化的數(shù)據(jù)不會(huì)突然丟失。
  • volatile-ttl:跟上面一樣讲岁,除了淘汰的策略不是 LRU我擂,而是 key 的剩余壽命 ttl 的值,ttl 越小越優(yōu)先被淘汰缓艳。
  • volatile-random:跟上面一樣校摩,不過(guò)淘汰的 key 是過(guò)期 key 集合中隨機(jī)的 key。
  • allkeys-lru:區(qū)別于 volatile-lru阶淘,這個(gè)策略要淘汰的 key 對(duì)象是全體的 key 集合衙吩,而不只是過(guò)期的 key 集合。這意味著沒(méi)有設(shè)置過(guò)期時(shí)間的 key 也會(huì)被淘汰溪窒。
  • allkeys-random:跟上面一樣坤塞,不過(guò)淘汰的策略是隨機(jī)的 key冯勉。

volatile-xxx 策略只會(huì)針對(duì)帶過(guò)期時(shí)間的 key 進(jìn)行淘汰,allkeys-xxx 策略會(huì)對(duì)所有的 key 進(jìn)行淘汰尺锚。如果你只是拿 Redis 做緩存珠闰,那應(yīng)該使用 allkeys-xxx,客戶端寫(xiě)緩存時(shí)不必?cái)y帶過(guò)期時(shí)間瘫辩。如果你還想同時(shí)使用 Redis 的持久化功能伏嗜,那就使用 volatile-xxx 策略,這樣可以保留沒(méi)有設(shè)置過(guò)期時(shí)間的 key伐厌,它們是永久的 key 不會(huì)被 LRU 算法淘汰

8承绸、腦圖

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市挣轨,隨后出現(xiàn)的幾起案子军熏,更是在濱河造成了極大的恐慌,老刑警劉巖卷扮,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荡澎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡晤锹,警方通過(guò)查閱死者的電腦和手機(jī)摩幔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鞭铆,“玉大人或衡,你說(shuō)我怎么就攤上這事〕邓欤” “怎么了封断?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)舶担。 經(jīng)常有香客問(wèn)我坡疼,道長(zhǎng),這世上最難降的妖魔是什么衣陶? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任回梧,我火速辦了婚禮,結(jié)果婚禮上祖搓,老公的妹妹穿的比我還像新娘。我一直安慰自己湖苞,他們只是感情好拯欧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著财骨,像睡著了一般镐作。 火紅的嫁衣襯著肌膚如雪藏姐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天该贾,我揣著相機(jī)與錄音羔杨,去河邊找鬼。 笑死杨蛋,一個(gè)胖子當(dāng)著我的面吹牛兜材,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逞力,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼曙寡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了寇荧?” 一聲冷哼從身側(cè)響起举庶,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揩抡,沒(méi)想到半個(gè)月后户侥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡峦嗤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年蕊唐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寻仗。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刃泌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出署尤,到底是詐尸還是另有隱情耙替,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布曹体,位于F島的核電站俗扇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏箕别。R本人自食惡果不足惜铜幽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望串稀。 院中可真熱鬧除抛,春花似錦、人聲如沸母截。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至喘漏,卻和暖如春护蝶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背翩迈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工持灰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人负饲。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓堤魁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親绽族。 傳聞我的和親對(duì)象是個(gè)殘疾皇子姨涡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Redis 有 5 種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),分別為:string (字符串)吧慢、list (列表)涛漂、set (集合)、has...
    雪飄千里閱讀 600評(píng)論 0 2
  • 原帖地址:http://www.reibang.com/p/2f14bc570563 redis概述 Redis...
    onlyHalfSoul閱讀 2,168評(píng)論 0 28
  • 一检诗、Redis高可用概述 在介紹Redis高可用之前匈仗,先說(shuō)明一下在Redis的語(yǔ)境中高可用的含義。 我們知道逢慌,在w...
    空語(yǔ)閱讀 1,597評(píng)論 0 2
  • Redis是啥 Redis是一個(gè)開(kāi)源的key-value存儲(chǔ)系統(tǒng)悠轩,由于擁有豐富的數(shù)據(jù)結(jié)構(gòu),又被其作者戲稱(chēng)為數(shù)據(jù)結(jié)構(gòu)...
    一凡呀閱讀 1,173評(píng)論 0 5
  • 1.1 資料 攻泼,最好的入門(mén)小冊(cè)子火架,可以先于一切文檔之前看,免費(fèi)忙菠。 作者Antirez的博客何鸡,Antirez維護(hù)的R...
    JefferyLcm閱讀 17,056評(píng)論 1 51