日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

Redis:相关知识点纵观

發(fā)布時(shí)間:2025/3/21 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis:相关知识点纵观 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這篇文章先簡(jiǎn)單的介紹一下redis有什么相關(guān)知識(shí)點(diǎn),然后再?gòu)慕酉氯サ囊恍┪恼聦?duì)一些重要的知識(shí)點(diǎn)進(jìn)行總結(jié)。

一、Redis 是什么

Redis 是速度非常快的非關(guān)系型(NoSQL)內(nèi)存鍵值數(shù)據(jù)庫(kù),可以存儲(chǔ)鍵和五種不同類(lèi)型的值之間的映射。

五種類(lèi)型數(shù)據(jù)類(lèi)型為:字符串、列表、集合、有序集合、散列表。

Redis 支持很多特性,例如將內(nèi)存中的數(shù)據(jù)持久化到硬盤(pán)中,使用復(fù)制來(lái)擴(kuò)展讀性能,使用分片來(lái)擴(kuò)展寫(xiě)性能。

?

二、五種基本類(lèi)型

數(shù)據(jù)類(lèi)型

可以存儲(chǔ)的值

操作

STRING

字符串、整數(shù)或者浮點(diǎn)數(shù)

對(duì)整個(gè)字符串或者字符串的其中一部分執(zhí)行操作
對(duì)整數(shù)和浮點(diǎn)數(shù)執(zhí)行自增或者自減操作

LIST

鏈表

從兩端壓入或者彈出元素
讀取單個(gè)或者多個(gè)元素
進(jìn)行修剪,只保留一個(gè)范圍內(nèi)的元素

SET

無(wú)序集合

添加、獲取、移除單個(gè)元素
檢查一個(gè)元素是否存在于集合中
計(jì)算交集、并集、差集
從集合里面隨機(jī)獲取元素

HASH

包含鍵值對(duì)的無(wú)序散列表

添加、獲取、移除單個(gè)鍵值對(duì)
獲取所有鍵值對(duì)
檢查某個(gè)鍵是否存在

ZSET

有序集合

添加、獲取、刪除元素
根據(jù)分值范圍或者成員來(lái)獲取元素
計(jì)算一個(gè)鍵的排名

?

三、鍵的過(guò)期時(shí)間

Redis 可以為每個(gè)鍵設(shè)置過(guò)期時(shí)間,當(dāng)鍵過(guò)期時(shí),會(huì)自動(dòng)刪除該鍵。

對(duì)于散列表這種容器,只能為整個(gè)鍵設(shè)置過(guò)期時(shí)間(整個(gè)散列表),而不能為鍵里面的單個(gè)元素設(shè)置過(guò)期時(shí)間。

過(guò)期時(shí)間對(duì)于清理緩存數(shù)據(jù)非常有用。

四、發(fā)布與訂閱

發(fā)布與訂閱實(shí)際上是觀察者模式,訂閱者訂閱了頻道之后,發(fā)布者向頻道發(fā)送字符串消息會(huì)被所有訂閱者接收到。

發(fā)布與訂閱有一些問(wèn)題,很少使用它,而是使用替代的解決方案。問(wèn)題如下:

  • 如果訂閱者讀取消息的速度很慢,會(huì)使得消息不斷積壓在發(fā)布者的輸出緩存區(qū)中,造成內(nèi)存占用過(guò)多;
  • 如果訂閱者在執(zhí)行訂閱的過(guò)程中網(wǎng)絡(luò)出現(xiàn)問(wèn)題,那么就會(huì)丟失斷線期間發(fā)送的所有消息。
  • 五、事務(wù)

    Redis 最簡(jiǎn)單的事務(wù)實(shí)現(xiàn)方式是使用 MULTI EXEC 命令將事務(wù)操作包圍起來(lái)。

    MULTI EXEC 中的操作將會(huì)一次性發(fā)送給服務(wù)器,而不是一條一條發(fā)送,這種方式稱(chēng)為流水線,它可以減少客戶(hù)端與服務(wù)器之間的網(wǎng)絡(luò)通信次數(shù)從而提升性能。

    六、持久化

    Redis 是內(nèi)存型數(shù)據(jù)庫(kù),為了保證數(shù)據(jù)在斷電后不會(huì)丟失,需要將內(nèi)存中的數(shù)據(jù)持久化到硬盤(pán)上。

    1. 快照持久化

    將某個(gè)時(shí)間點(diǎn)的所有數(shù)據(jù)都存放到硬盤(pán)上。

    可以將快照復(fù)制到其它服務(wù)器從而創(chuàng)建具有相同數(shù)據(jù)的服務(wù)器副本。

    如果系統(tǒng)發(fā)生故障,將會(huì)丟失最后一次創(chuàng)建快照之后的數(shù)據(jù)。并且如果數(shù)據(jù)量很大,保存快照的時(shí)間也會(huì)很長(zhǎng)。

    2. AOF 持久化

    AOF 持久化將寫(xiě)命令添加到 AOF 文件(Append Only File)的末尾。

    對(duì)硬盤(pán)的文件進(jìn)行寫(xiě)入時(shí),寫(xiě)入的內(nèi)容首先會(huì)被存儲(chǔ)到緩沖區(qū),然后由操作系統(tǒng)決定什么時(shí)候?qū)⒃搩?nèi)容同步到硬盤(pán),用戶(hù)可以調(diào)用file.flush() 方法請(qǐng)求操作系統(tǒng)盡快將緩沖區(qū)存儲(chǔ)的數(shù)據(jù)同步到硬盤(pán)。因此將寫(xiě)命令添加到 AOF 文件時(shí),要根據(jù)需求來(lái)保證何時(shí)將添加的數(shù)據(jù)同步到硬盤(pán)上,有以下同步選項(xiàng):

    選項(xiàng)

    同步頻率

    always

    每個(gè)寫(xiě)命令都同步

    everysec

    每秒同步一次

    no

    讓操作系統(tǒng)來(lái)決定何時(shí)同步

    always 選項(xiàng)會(huì)嚴(yán)重減低服務(wù)器的性能;everysec 選項(xiàng)比較合適,可以保證系統(tǒng)奔潰時(shí)只會(huì)丟失一秒左右的數(shù)據(jù),并且 Redis 每秒執(zhí)行一次同步對(duì)服務(wù)器性能幾乎沒(méi)有任何影響;no 選項(xiàng)并不能給服務(wù)器性能帶來(lái)多大的提升,而且也會(huì)增加系統(tǒng)奔潰時(shí)數(shù)據(jù)丟失的數(shù)量。

    隨著服務(wù)器寫(xiě)請(qǐng)求的增多,AOF 文件會(huì)越來(lái)越大;Redis 提供了一種將 AOF 重寫(xiě)的特性,能夠去除 AOF 文件中的冗余寫(xiě)命令。

    七、復(fù)制

    通過(guò)使用 slaveofhost port 命令來(lái)讓一個(gè)服務(wù)器成為另一個(gè)服務(wù)器的從服務(wù)器。

    一個(gè)從服務(wù)器只能有一個(gè)主服務(wù)器,并且不支持主主復(fù)制。

    從服務(wù)器連接主服務(wù)器的過(guò)程

    1.?????主服務(wù)器創(chuàng)建快照文件,發(fā)送給從服務(wù)器,并在發(fā)送期間使用緩沖區(qū)記錄執(zhí)行的寫(xiě)命令??煺瘴募l(fā)送完畢之后,開(kāi)始向從服務(wù)器發(fā)送存儲(chǔ)在緩沖區(qū)中的寫(xiě)命令;

    2.?????從服務(wù)器丟棄所有舊數(shù)據(jù),載入主服務(wù)器發(fā)來(lái)的快照文件,之后從服務(wù)器開(kāi)始接受主服務(wù)器發(fā)來(lái)的寫(xiě)命令;

    3.?????主服務(wù)器每執(zhí)行一次寫(xiě)命令,就向從服務(wù)器發(fā)送相同的寫(xiě)命令。

    主從鏈

    隨著負(fù)載不斷上升,主服務(wù)器可能無(wú)法很快地更新所有從服務(wù)器,或者重新連接和重新同步從服務(wù)器將導(dǎo)致系統(tǒng)超載。為了解決這個(gè)問(wèn)題,可以創(chuàng)建一個(gè)中間層來(lái)分擔(dān)主服務(wù)器的復(fù)制工作。中間層的服務(wù)器是最上層服務(wù)器的從服務(wù)器,又是最下層服務(wù)器的主服務(wù)器。

    八、處理故障

    要用到持久化文件來(lái)恢復(fù)服務(wù)器的數(shù)據(jù)。

    持久化文件可能因?yàn)榉?wù)器出錯(cuò)也有錯(cuò)誤,因此要先對(duì)持久化文件進(jìn)行驗(yàn)證和修復(fù)。對(duì) AOF 文件就行驗(yàn)證和修復(fù)很容易,修復(fù)操作將第一個(gè)出錯(cuò)命令和其后的所有命令都刪除;但是只能驗(yàn)證快照文件,無(wú)法對(duì)快照文件進(jìn)行修復(fù),因?yàn)榭煺瘴募M(jìn)行了壓縮,出現(xiàn)在快照文件中間的錯(cuò)誤可能會(huì)導(dǎo)致整個(gè)快照文件的剩余部分無(wú)法讀取。

    當(dāng)主服務(wù)器出現(xiàn)故障時(shí),Redis 常用的做法是新開(kāi)一臺(tái)服務(wù)器作為主服務(wù)器,具體步驟如下:假設(shè) A 為主服務(wù)器,B 為從服務(wù)器,當(dāng) A 出現(xiàn)故障時(shí),讓 B 生成一個(gè)快照文件,將快照文件發(fā)送給 C,并讓 C 恢復(fù)快照文件的數(shù)據(jù)。最后,讓 B 成為 C 的從服務(wù)器。

    九、分片

    Redis 中的分片類(lèi)似于 MySQL 的分表操作,分片是將數(shù)據(jù)劃分為多個(gè)部分的方法,對(duì)數(shù)據(jù)的劃分可以基于鍵包含的 ID、基于鍵的哈希值,或者基于以上兩者的某種組合。通過(guò)對(duì)數(shù)據(jù)進(jìn)行分片,用戶(hù)可以將數(shù)據(jù)存儲(chǔ)到多臺(tái)機(jī)器里面,也可以從多臺(tái)機(jī)器里面獲取數(shù)據(jù),這種方法在解決某些問(wèn)題時(shí)可以獲得線性級(jí)別的性能提升。

    假設(shè)有 4 個(gè) Reids 實(shí)例 R0R1R2R3,還有很多表示用戶(hù)的鍵 user:1user:2... 等等,有不同的方式來(lái)選擇一個(gè)指定的鍵存儲(chǔ)在哪個(gè)實(shí)例中。最簡(jiǎn)單的方式是范圍分片,例如用戶(hù) id 0~1000 的存儲(chǔ)到實(shí)例 R0 中,用戶(hù) id 1001~2000 的存儲(chǔ)到實(shí)例 R1 中,等等。但是這樣需要維護(hù)一張映射范圍表,維護(hù)操作代價(jià)很高。還有一種方式是哈希分片,使用 CRC32 哈希函數(shù)將鍵轉(zhuǎn)換為一個(gè)數(shù)字,再對(duì)實(shí)例數(shù)量求模就能知道應(yīng)該存儲(chǔ)的實(shí)例。

    1. 客戶(hù)端分片

    客戶(hù)端使用一致性哈希等算法決定鍵應(yīng)當(dāng)分布到哪個(gè)節(jié)點(diǎn)。

    2. 代理分片

    將客戶(hù)端請(qǐng)求發(fā)送到代理上,由代理轉(zhuǎn)發(fā)請(qǐng)求到正確的節(jié)點(diǎn)上。

    3. 服務(wù)器分片

    Redis Cluster。

    十、事件

    事件類(lèi)型

    1. 文件事件

    服務(wù)器有許多套接字,事件產(chǎn)生時(shí)會(huì)對(duì)這些套接字進(jìn)行操作,服務(wù)器通過(guò)監(jiān)聽(tīng)套接字來(lái)處理事件。常見(jiàn)的文件事件有:客戶(hù)端的連接事件;客戶(hù)端的命令請(qǐng)求事件;服務(wù)器向客戶(hù)端返回命令結(jié)果的事件;

    2. 時(shí)間事件

    又分為兩類(lèi):定時(shí)事件是讓一段程序在指定的時(shí)間之內(nèi)執(zhí)行一次;周期性時(shí)間是讓一段程序每隔指定時(shí)間就執(zhí)行一次。

    事件的調(diào)度與執(zhí)行

    服務(wù)器需要不斷監(jiān)聽(tīng)文件事件的套接字才能得到待處理的文件事件,但是不能監(jiān)聽(tīng)太久,否則時(shí)間事件無(wú)法在規(guī)定的時(shí)間內(nèi)執(zhí)行,因此監(jiān)聽(tīng)時(shí)間應(yīng)該根據(jù)距離現(xiàn)在最近的時(shí)間事件來(lái)決定。

    事件調(diào)度與執(zhí)行由aeProcessEvents 函數(shù)負(fù)責(zé),偽代碼如下:

    defaeProcessEvents(): ? ??? # 獲取到達(dá)時(shí)間離當(dāng)前時(shí)間最接近的時(shí)間事件 ??? time_event = aeSearchNearestTimer() ? ??? # 計(jì)算最接近的時(shí)間事件距離到達(dá)還有多少毫秒 ??? remaind_ms = time_event.when - unix_ts_now() ? ??? # 如果事件已到達(dá),那么 remaind_ms 的值可能為負(fù)數(shù),將它設(shè)為 0 ??? if remaind_ms <0: ??????? remaind_ms =0 ? ??? # 根據(jù) remaind_ms 的值,創(chuàng)建 timeval ??? timeval = create_timeval_with_ms(remaind_ms) ? ??? # 阻塞并等待文件事件產(chǎn)生,最大阻塞時(shí)間由傳入的 timeval 決定 ??? aeApiPoll(timeval) ? ??? # 處理所有已產(chǎn)生的文件事件 ??? procesFileEvents() ? ??? # 處理所有已到達(dá)的時(shí)間事件 ??? processTimeEvents()

    aeProcessEvents 函數(shù)置于一個(gè)循環(huán)里面,加上初始化和清理函數(shù),就構(gòu)成了 Redis 服務(wù)器的主函數(shù),偽代碼如下:

    defmain(): ? ??? # 初始化服務(wù)器 ??? init_server() ? ??? # 一直處理事件,直到服務(wù)器關(guān)閉為止 ??? while server_is_not_shutdown(): ??????? aeProcessEvents() ? ??? # 服務(wù)器關(guān)閉,執(zhí)行清理操作 ??? clean_server()

    從事件處理的角度來(lái)看,服務(wù)器運(yùn)行流程如下:

    ?

    十一、Redis Memcached 的區(qū)別

    兩者都是非關(guān)系型內(nèi)存鍵值數(shù)據(jù)庫(kù)。有以下主要不同:

    數(shù)據(jù)類(lèi)型

    Memcached 僅支持字符串類(lèi)型,而 Redis 支持五種不同種類(lèi)的數(shù)據(jù)類(lèi)型,使得它可以更靈活地解決問(wèn)題。

    數(shù)據(jù)持久化

    Redis 支持兩種持久化策略:RDB 快照和 AOF 日志,而 Memcached 不支持持久化。

    分布式

    Memcached 不支持分布式,只能通過(guò)在客戶(hù)端使用像一致性哈希這樣的分布式算法來(lái)實(shí)現(xiàn)分布式存儲(chǔ),這種方式在存儲(chǔ)和查詢(xún)時(shí)都需要先在客戶(hù)端計(jì)算一次數(shù)據(jù)所在的節(jié)點(diǎn)。

    Redis Cluster 實(shí)現(xiàn)了分布式的支持。

    內(nèi)存管理機(jī)制

    Redis 中,并不是所有數(shù)據(jù)都一直存儲(chǔ)在內(nèi)存中,可以將一些很久沒(méi)用的 value 交換到磁盤(pán)。而 Memcached 的數(shù)據(jù)則會(huì)一直在內(nèi)存中。

    Memcached 將內(nèi)存分割成特定長(zhǎng)度的塊來(lái)存儲(chǔ)數(shù)據(jù),以完全解決內(nèi)存碎片的問(wèn)題,但是這種方式會(huì)使得內(nèi)存的利用率不高,例如塊的大小為 128 bytes,只存儲(chǔ) 100 bytes 的數(shù)據(jù),那么剩下的 28 bytes 就浪費(fèi)掉了。

    十二、Redis 適用場(chǎng)景

    緩存

    s使用 Redis 作為緩存,將熱點(diǎn)數(shù)據(jù)放到內(nèi)存中。

    消息隊(duì)列

    Redis List 類(lèi)型是雙向鏈表,很適合用于消息隊(duì)列。

    計(jì)數(shù)器

    Redis 這種內(nèi)存數(shù)據(jù)庫(kù)才能支持計(jì)數(shù)器的頻繁讀寫(xiě)操作。

    好友關(guān)系

    使用 set 類(lèi)型的交集很容易就可以知道兩個(gè)用戶(hù)的共同好友。

    十三、數(shù)據(jù)淘汰策略

    可以設(shè)置內(nèi)存最大使用量,當(dāng)內(nèi)存使用量超過(guò)時(shí)施行淘汰策略,具體有 6 種淘汰策略。

    策略

    描述

    volatile-lru

    從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰

    volatile-ttl

    從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集中挑選將要過(guò)期的數(shù)據(jù)淘汰

    volatile-random

    從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰

    allkeys-lru

    從所有數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰

    allkeys-random

    從所有數(shù)據(jù)集中任意選擇數(shù)據(jù)進(jìn)行淘汰

    no-envicition

    禁止驅(qū)逐數(shù)據(jù)

    如果使用 Redis 來(lái)緩存數(shù)據(jù)時(shí),要保證所有數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù),可以將內(nèi)存最大使用量設(shè)置為熱點(diǎn)數(shù)據(jù)占用的內(nèi)存量,然后啟用allkeys-lru 淘汰策略,將最近最少使用的數(shù)據(jù)淘汰。

    十四、一個(gè)簡(jiǎn)單的論壇系統(tǒng)分析

    該論壇系統(tǒng)功能如下:

    • 可以發(fā)布文章;
    • 可以對(duì)文章進(jìn)行點(diǎn)贊;
    • 在首頁(yè)可以按文章的發(fā)布時(shí)間或者文章的點(diǎn)贊數(shù)進(jìn)行排序顯示;

    文章信息

    文章包括標(biāo)題、作者、贊數(shù)等信息,在關(guān)系型數(shù)據(jù)庫(kù)中很容易構(gòu)建一張表來(lái)存儲(chǔ)這些信息,在 Redis 中可以使用 HASH 來(lái)存儲(chǔ)每種信息以及其對(duì)應(yīng)的值的映射。

    Redis 沒(méi)有關(guān)系型數(shù)據(jù)庫(kù)中的表這一概念來(lái)將同類(lèi)型的數(shù)據(jù)存放在一起,而是使用命名空間的方式來(lái)實(shí)現(xiàn)這一功能。鍵名的前面部分存儲(chǔ)命名空間,后面部分的內(nèi)容存儲(chǔ) ID,通常使用 : 來(lái)進(jìn)行分隔。例如下面的 HASH 的鍵名為 article:92617,其中 article 為命名空間,ID 92617。

    ?

    點(diǎn)贊功能

    當(dāng)有用戶(hù)為一篇文章點(diǎn)贊時(shí),除了要對(duì)該文章的 votes 字段進(jìn)行加 1 操作,還必須記錄該用戶(hù)已經(jīng)對(duì)該文章進(jìn)行了點(diǎn)贊,防止用戶(hù)點(diǎn)贊次數(shù)超過(guò) 1??梢越⑽恼碌囊淹镀庇脩?hù)集合來(lái)進(jìn)行記錄。

    為了節(jié)約內(nèi)存,規(guī)定一篇文章發(fā)布滿一周之后,就不能再對(duì)它進(jìn)行投票,而文章的已投票集合也會(huì)被刪除,可以為文章的已投票集合設(shè)置一個(gè)一周的過(guò)期時(shí)間就能實(shí)現(xiàn)這個(gè)規(guī)定。

    ?

    ?

    對(duì)文章進(jìn)行排序

    為了按發(fā)布時(shí)間和點(diǎn)贊數(shù)進(jìn)行排序,可以建立一個(gè)文章發(fā)布時(shí)間的有序集合和一個(gè)文章點(diǎn)贊數(shù)的有序集合。(下圖中的 score 就是這里所說(shuō)的點(diǎn)贊數(shù);下面所示的有序集合分值并不直接是時(shí)間和點(diǎn)贊數(shù),而是根據(jù)時(shí)間和點(diǎn)贊數(shù)間接計(jì)算出來(lái)的)

    總結(jié)

    以上是生活随笔為你收集整理的Redis:相关知识点纵观的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。