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

歡迎訪問 生活随笔!

生活随笔

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

数据库

redis(9)--数据库

發(fā)布時(shí)間:2024/4/13 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis(9)--数据库 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

?

服務(wù)器中的數(shù)據(jù)庫(kù)

redisServer結(jié)構(gòu)

redisDB結(jié)構(gòu)

切換數(shù)據(jù)庫(kù)

數(shù)據(jù)庫(kù)鍵空間

設(shè)置鍵的生存時(shí)間或過期時(shí)間

過期鍵判定

過期鍵刪除策略

過期鍵刪除的三種可能策略:

三種策略比較

Redis 的過期鍵刪除策略

惰性刪除策略實(shí)現(xiàn)

定期刪除策略實(shí)現(xiàn)

AOF 、RDB 和復(fù)制功能對(duì)過期鍵的處理

數(shù)據(jù)庫(kù)通知


服務(wù)器中的數(shù)據(jù)庫(kù)

redisServer結(jié)構(gòu)

struct redisServer

{

???? //數(shù)組,保存所有數(shù)據(jù)庫(kù)

????? redisDb *db;

???? //數(shù)據(jù)庫(kù)數(shù)據(jù)量

????? int dbnum;

}

redisDB結(jié)構(gòu)

typedef struct redisDb {// 保存著數(shù)據(jù)庫(kù)以整數(shù)表示的號(hào)碼int id;// 保存著數(shù)據(jù)庫(kù)中的所有鍵值對(duì)數(shù)據(jù)// 這個(gè)屬性也被稱為鍵空間(key space)dict *dict;// 保存著鍵的過期信息dict *expires;// 實(shí)現(xiàn)列表阻塞原語,如 BLPOP// 在列表類型一章有詳細(xì)的討論dict *blocking_keys;dict *ready_keys;// 用于實(shí)現(xiàn) WATCH 命令// 在事務(wù)章節(jié)有詳細(xì)的討論dict *watched_keys;} redisDb;


切換數(shù)據(jù)庫(kù)

每個(gè)Redis客戶端都有自己的目標(biāo)數(shù)據(jù)庫(kù),每當(dāng)客戶端執(zhí)行數(shù)據(jù)庫(kù)讀寫命名時(shí),目標(biāo)數(shù)據(jù)庫(kù)成為這些命令的操作的對(duì)象。

默認(rèn)情況下,Redis客戶端的目錄數(shù)據(jù)庫(kù)為0號(hào)數(shù)據(jù)庫(kù),可以通過select命令切換目標(biāo)數(shù)據(jù)庫(kù)。

select 2

在服務(wù)器內(nèi)部,客戶端狀態(tài)redisClient結(jié)構(gòu)的db屬性,記錄了客戶端當(dāng)前的目標(biāo)數(shù)據(jù)庫(kù)

typedef struct redisClient{

//記錄客戶端當(dāng)前正使用的數(shù)據(jù)庫(kù),指向redisServer中redisDb中的一個(gè)。

redisDb *db;

}? redisClient

到目前為止,redis仍沒有可以返回客戶端目標(biāo)數(shù)據(jù)庫(kù)的命令。在執(zhí)行像Flushdb等危險(xiǎn)操作時(shí),先執(zhí)行select命令,顯示切換到目標(biāo)數(shù)據(jù)庫(kù)。

數(shù)據(jù)庫(kù)鍵空間

為 Redis 是一個(gè)鍵值對(duì)數(shù)據(jù)庫(kù)(key-value pairs database), 所以它的數(shù)據(jù)庫(kù)本身也是一個(gè)字典(俗稱 key space):

  • 字典的鍵是一個(gè)字符串對(duì)象。
  • 字典的值則可以是包括字符串、列表、哈希表、集合或有序集在內(nèi)的任意一種 Redis 類型對(duì)象。

在 redisDb 結(jié)構(gòu)的 dict 屬性中,保存著數(shù)據(jù)庫(kù)的所有鍵值對(duì)數(shù)據(jù)。

數(shù)據(jù)庫(kù)鍵空間示例

因?yàn)閿?shù)據(jù)庫(kù)本身是一個(gè)字典, 所以對(duì)數(shù)據(jù)庫(kù)的操作基本上都是對(duì)字典的操作, 加上以下一些維護(hù)操作

  • 更新鍵的命中率和不命中率,這個(gè)值可以用 INFO 命令查看;
  • 更新鍵的 LRU 時(shí)間,這個(gè)值可以用 OBJECT 命令來查看;
  • 刪除過期鍵(稍后會(huì)詳細(xì)說明);
  • 如果鍵被修改了的話,那么將鍵設(shè)為臟(用于事務(wù)監(jiān)視),并將服務(wù)器設(shè)為臟(等待 RDB 保存);
  • 將對(duì)鍵的修改發(fā)送到 AOF 文件和附屬節(jié)點(diǎn),保持?jǐn)?shù)據(jù)庫(kù)狀態(tài)的一致;

除了上面展示鍵值操作之外,還有很多針對(duì)數(shù)據(jù)庫(kù)本身的命令,也是通過對(duì)鍵空間進(jìn)行處理來完成的:

  • FLUSHDB 命令:刪除鍵空間中的所有鍵值對(duì)。
  • RANDOMKEY 命令:從鍵空間中隨機(jī)返回一個(gè)鍵。
  • DBSIZE 命令:返回鍵空間中鍵值對(duì)的數(shù)量。
  • EXISTS 命令:檢查給定鍵是否存在于鍵空間中。
  • RENAME 命令:在鍵空間中,對(duì)給定鍵進(jìn)行改名。

設(shè)置鍵的生存時(shí)間或過期時(shí)間

在數(shù)據(jù)庫(kù)中, 所有鍵的過期時(shí)間都被保存在 redisDb 結(jié)構(gòu)的 expires 字典里:

帶有過期時(shí)間的數(shù)據(jù)庫(kù)

在實(shí)際中, 鍵空間字典的鍵和過期時(shí)間字典的鍵都指向同一個(gè)字符串對(duì)象, 所以不會(huì)浪費(fèi)任何空間。

過期時(shí)間涉及命令包括:

  • expire
  • expireat
  • pexpire
  • pexpireat
  • persist
  • ttl
  • pttl

過期鍵判定

通過 expires 字典, 可以用以下步驟檢查某個(gè)鍵是否過期:

  • 檢查鍵是否存在于 expires 字典:如果存在,那么取出鍵的過期時(shí)間;
  • 檢查當(dāng)前 UNIX 時(shí)間戳是否大于鍵的過期時(shí)間:如果是的話,那么鍵已經(jīng)過期;否則,鍵未過期。

  • 過期鍵刪除策略

    過期鍵刪除的三種可能策略:

  • 定時(shí)刪除:在設(shè)置鍵的過期時(shí)間時(shí),創(chuàng)建一個(gè)定時(shí)事件,當(dāng)過期時(shí)間到達(dá)時(shí),由事件處理器自動(dòng)執(zhí)行鍵的刪除操作。
  • 惰性刪除:放任鍵過期不管,但是在每次從 dict 字典中取出鍵值時(shí),要檢查鍵是否過期,如果過期的話,就刪除它,并返回空;如果沒過期,就返回鍵值。
  • 定期刪除:每隔一段時(shí)間,對(duì) expires 字典進(jìn)行檢查,刪除里面的過期鍵。
  • 三種策略比較

    策略優(yōu)點(diǎn)缺點(diǎn)說明
    定時(shí)刪除內(nèi)存友好可能占用大量CPU目前 Redis 事件處理器對(duì)時(shí)間事件的實(shí)現(xiàn)方式 —— 無序鏈表, 查找一個(gè)時(shí)間復(fù)雜度為 O(N)—— 并不適合用來處理大量時(shí)間事件。
    惰性刪除CPU友好占用內(nèi)存如果長(zhǎng)時(shí)間沒有訪問,不會(huì)被刪除
    定期刪除折中折中定期刪除,限制操作時(shí)長(zhǎng)和頻率,減少CPU占用時(shí)間,減少內(nèi)存占用

    ?

    Redis 的過期鍵刪除策略

    Redis 使用的過期鍵刪除策略是惰性刪除加上定期刪除, 這兩個(gè)策略相互配合,可以很好地在合理利用 CPU 時(shí)間和節(jié)約內(nèi)存空間之間取得平衡。

    惰性刪除策略實(shí)現(xiàn)

    定期刪除策略實(shí)現(xiàn)

    對(duì)過期鍵的定期刪除由 redis.c/activeExpireCycle 函執(zhí)行: 每當(dāng) Redis 的例行處理程序 serverCron 執(zhí)行時(shí), activeExpireCycle 都會(huì)被調(diào)用 —— 這個(gè)函數(shù)在規(guī)定的時(shí)間限制內(nèi), 盡可能地遍歷各個(gè)數(shù)據(jù)庫(kù)的 expires 字典, 隨機(jī)地檢查一部分鍵的過期時(shí)間, 并刪除其中的過期鍵。

    整個(gè)過程可以用偽代碼描述如下:

    def activeExpireCycle():# 遍歷數(shù)據(jù)庫(kù)(不一定能全部都遍歷完,看時(shí)間是否足夠)for db in server.db:# MAX_KEY_PER_DB 是一個(gè) DB 最大能處理的 key 個(gè)數(shù)# 它保證時(shí)間不會(huì)全部用在個(gè)別的 DB 上(避免饑餓)i = 0while (i < MAX_KEY_PER_DB):# 數(shù)據(jù)庫(kù)為空,跳出 while ,處理下個(gè) DBif db.is_empty(): break# 隨機(jī)取出一個(gè)帶 TTL 的鍵key_with_ttl = db.expires.get_random_key()# 檢查鍵是否過期,如果是的話,將它刪除if is_expired(key_with_ttl):db.deleteExpiredKey(key_with_ttl)# 當(dāng)執(zhí)行時(shí)間到達(dá)上限,函數(shù)就返回,不再繼續(xù)# 這確保刪除操作不會(huì)占用太多的 CPU 時(shí)間if reach_time_limit(): returni += 1

    ?

    AOF 、RDB 和復(fù)制功能對(duì)過期鍵的處理

    • 生成RDB文件

    過期鍵不會(huì)寫入到新創(chuàng)建的RDB文件

    • 載入RDB文件

    主服務(wù)器模式運(yùn)行,過期鍵忽略。

    從服務(wù)器模式運(yùn)行,過期鍵保留。——主從同步時(shí)會(huì)刪除。

    • AOF寫入

    過期鍵被刪除后,向AOF追加DEL命令。

    • AOF重寫

    過期鍵忽略

    • 復(fù)制

    主服務(wù)器刪除一個(gè)過期鍵,會(huì)向從服務(wù)器發(fā)送DEL命令

    從服務(wù)器執(zhí)行讀取命令時(shí),不會(huì)刪除過期鍵。——所有從服務(wù)器讀取命令,可能返回不一致信息

    從服務(wù)器只有接收到主服務(wù)器的DEL命令,才會(huì)刪除過期鍵。


    數(shù)據(jù)庫(kù)通知

    數(shù)據(jù)庫(kù)通知是Redis2.8版本新增加的功能,可以讓客戶端通過訂閱,獲知數(shù)據(jù)庫(kù)中鍵的變化

    參考SUBSCRIBE 命令。

    ?

    總結(jié)

    以上是生活随笔為你收集整理的redis(9)--数据库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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