redis設計與實現 二

Redis設計與實現閱讀總結(二)單機數據庫
書的重點內容逐漸到了,我們的寫作方式也該換一下了,不會像(一)一樣流水賬式了的解釋幾種數據結構了

在第一篇文章中,我簡略的解釋下有關的數據結構,現在我們開始想想如何實現

先提幾個問題

如何實現多數據庫
redis數據是存在內存中的,但是這樣數據存在丟失的風險,那我們怎樣化解決這個問題
redis服務器和多個客戶端的交互是怎樣實現的呢

在我看來,該書第二部分<單機數據庫的實現>就是圍繞上面的幾個問題,來用列舉式行文寫下相應部分知識點的。

服務器中的多數據庫

看到這個多字,其實我們很容易就想到用鏈表的方式去儲存

一個服務器,先假設是一個簡單的struct結構來維護的,我們想在其中實現多數據庫,自然想到,在其中添加一個鍵值對,而這個值我們使用一個鏈表

這個鏈表中存放一個又一個的指針,每個指針指向一個struct結構(維護着數據庫結構的struct)

好,這樣,我們就簡單的實現這個多。

然後我們再去實現單數據庫

服務器中的多數據庫

每個數據庫中那有該如何存放數據呢

由於redis是kv數據庫,數據都是以kv形式存在的,那我們完全就可以用字典去實現

鍵值對中的值可以是(一)中的多種形式,那麼,

下圖的形式就能得出了

到了這裏後,書上將過期問題在後續進行了說明。

過期問題

書籍主要是解釋了 列舉式解釋了相關命令

我覺得比較重要是redis的過期鍵刪除策略

一個經典的問題是:如果一個鍵過期了,那麼它什麼時候會被刪除呢?

這個問題有三種可能的答案,它們分別代表了三種不同的刪除策略:

定時刪除:在設置鍵的過期時間的同時,創建一個定時器(timer),讓定時器在鍵的過期時間來臨時,立即執行對鍵的刪除操作。
優點:對內存是最友好的:通過使用定時器,定時刪除策略可以保證過期鍵會儘可能快地被刪除,並釋放過期鍵所佔用的內存。
缺點:它對CPU時間是最不友好的:在過期鍵比較多的情況下,刪除過期鍵這一行爲可能會佔用相當一部分CPU時間 | 創建一個定時器需要用到Redis服務器中的時間事件,而當前時間事件的實現方式——無序鏈表,查找一個事件的時間複雜度爲O(N)
惰性刪除:放任鍵過期不管,但是每次從鍵空間中獲取鍵時,都檢查取得的鍵是否過期,如果過期的話,就刪除該鍵;如果沒有過期,就返回該鍵。
對CPU時間來說是最友好的。 這個策略不會在刪除其他無關的過期鍵上花費任何CPU時間
它對內存是最不友好的:如果一個鍵已經過期,而這個鍵又仍然保留在數據庫中,那麼只要這個過期鍵不被刪除,它所佔用的內存就不會釋放
定期刪除:每隔一段時間,程序就對數據庫進行一次檢查,刪除裏面的過期鍵。至於要刪除多少過期鍵,以及要檢查多少個數據庫,則由算法決定
定期刪除策略是前兩種策略的一種整合和折中
定期刪除策略的難點是確定刪除操作執行的時長和頻率。

上面大概性的介紹了數據庫的存儲實現,但是現在數據仍然保持在內存中的,但是這樣數據存在丟失的風險,這個時候我們應該設計持久化的策略了。

Redis的持久化

Redis 分別提供了 RDB 和 AOF 兩種持久化機制:

RDB 將數據庫的快照(snapshot)以二進制的方式保存到磁盤中。

AOF 則以協議文本的方式,將所有對數據庫進行過寫入的命令(及其參數)記錄到 AOF 文件,以此達到記錄數據庫狀態的目的

我們繼續想第三個問題,客戶端和服務器是如何交互的?

Redis客戶端和服務器的交互

關於這一點,書上用了三個章節來講解。

分別是 服務器事件,客戶端,服務器

Redis的事件處理器是單線程的,但並不意味着Redis就是單線程的!

I/O多路服用程序

Redis的事件處理機制是I/O多路複用的。多個文件事件可能併發的出現,但是I/O多路複用程序會將所有的產生的套接字放到一個隊列裏。

以有序,同步的方式,I/O多路複用程序向文件事件分派器傳送套接字,當一個套接字處理完,纔會傳送下一個。

I/O多路複用程序底層有多種實現可以選擇,epoll,select,evport,kqueue.

文件事件處理器

連接應答處理器
爲了對連接服務器的客戶端進行應答,服務器爲套接字連接進行應答的處理器
命令處理器
命令回覆處理器

後面主要就是 服務器和客戶端的通信協議部分,這部分我不準備講解,也不是什麼特別重要和難點的部分,就略過了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章