redis資料庫理解

2021-07-08 22:22:01 字數 4536 閱讀 2313

1. redis

是什麼

這個問題的結果影響了我們怎麼用

redis

。如果你認為

redis

是乙個key value store,

那可能會用它來代替

mysql

;如果認為它是乙個可以持久化的

cache,

可能只是它儲存一些頻繁訪問的臨時資料。

redis

是remote dictionary server

的縮寫,在

redis

在官方**的的副標題是

a persistent key-value database with built-innet inte***ce written in ansi-c for posix systems

,這個定義偏向

key value store

。還有一些看法則認為

redis

是乙個memory database

,因為它的高效能都是基於記憶體操作的基礎。另外一些人則認為

redis

是乙個data structure server

,因為redis

支援複雜的資料特性,比如

list, set

等。對redis

的作用的不同解讀決定了你對

redis

的使用方式。

網際網路資料目前基本使用兩種方式來儲存,關聯式資料庫或者

key value

。但是這些網際網路業務本身並不屬於這兩種資料型別,比如使用者在社會化平台中的關係,它是乙個

list

,如果要用關聯式資料庫儲存就需要轉換成一種多行記錄的形式,這種形式存在很多冗餘資料,每一行需要儲存一些重複資訊。如果用

key value

儲存則修改和刪除比較麻煩,需要將全部資料讀出再寫入。

redis

在記憶體中設計了各種資料型別,讓業務能夠高速原子的訪問這些資料結構,並且不需要關心持久儲存的問題,從架構上解決了前面兩種儲存需要走一些彎路的問題。

2. redis

不可能比

memcache快

很多開發者都認為

redis

不可能比

memcached

快,memcached

完全基於記憶體,而

redis

具有持久化儲存特性,即使是非同步的,

redis

也不可能比

memcached

快。但是測試結果基本是

redis

佔絕對優勢。一直在思考這個原因,目前想到的原因有這幾方面。

libevent

。和memcached

不同,redis

並沒有選擇

libevent

。libevent

為了迎合通用性造成**龐大(目前

redis

**還不到

libevent

的1/3)

及犧牲了在特定平台的不少效能。

redis

用libevent

中兩個檔案修改實現了自己的

epoll eventloop(4)

。業界不少開發者也建議

redis

使用另外乙個

libevent

高效能替代

libev

,但是作者還是堅持

redis

應該小巧並去依賴的思路。乙個印象深刻的細節是編譯

redis

之前並不需要執行

./configure

。cas

問題。cas

是memcached

中比較方便的一種防止競爭修改資源的方法。

cas實現需要為每個

cache key

設定乙個隱藏的

cas token

,cas

相當value

版本號,每次

set會

token

需要遞增,因此帶來

cpu和記憶體的雙重開銷,雖然這些開銷很小,但是到單機

10g+ cache

以及qps

上萬之後這些開銷就會給雙方相對帶來一些細微效能差別

(5)。

3. 單台

redis

的存放資料必須比物理記憶體小

redis

的資料全部放在記憶體帶來了高速的效能,但是也帶來一些不合理之處。比如乙個中型**有

100萬註冊使用者,如果這些資料要用

redis

來儲存,記憶體的容量必須能夠容納這

100萬使用者。但是業務實際情況是

100萬使用者只有

5萬活躍使用者,

1周來訪問過

1次的也只有

15萬使用者,因此全部

100萬使用者的資料都放在記憶體有不合理之處,

ram需要為冷資料買單。

這跟作業系統非常相似,作業系統所有應用訪問的資料都在記憶體,但是如果物理記憶體容納不下新的資料,作業系統會智慧型將部分長期沒有訪問的資料交換到磁碟,為新的應用留出空間。現代作業系統給應用提供的並不是物理記憶體,而是虛擬記憶體

(virtualmemory)

的概念。

基於相同的考慮,

redis 2.0

也增加了

vm特性。讓

redis

資料容量突破了物理記憶體的限制。並實現了資料冷熱分離。

4. redis的vm

實現是重複造輪子

redis的vm

依照之前的

epoll

實現思路依舊是自己實現。但是在前面作業系統的介紹提到

os也可以自動幫程式實現冷熱資料分離,

redis

只需要os

申請一塊大記憶體,

os會自動將熱資料放入物理記憶體,冷資料交換到硬碟,另外乙個知名的

「理解了現代作業系統

(3)」

的varnish

就是這樣實現,也取得了非常成功的效果。 作者

antirez

在解釋為什麼要自己實現

vm中提到幾個原因

(6)。主要os的

vm換入換出是基於

page

概念,比如

os vm1

個page

是4k, 4k

中只要還有乙個元素即使只有

1個位元組被訪問,這個頁也不會被

swap,

換入也同樣道理,讀到乙個位元組可能會換入

4k無用的記憶體。而

redis

自己實現則可以達到控制換入的粒度。另外訪問作業系統

swap

記憶體區域時

block

程序,也是導致

redis

要自己實現

vm原因之一。

5. 用get/set

方式使用

redis

作為乙個

key value

存在,很多開發者自然的使用

set/get

方式來使用

redis

,實際上這並不是最優化的使用方法。尤其在未啟用

vm情況下,

redis

全部資料需要放入記憶體,節約記憶體尤其重要。

假如乙個

key-value

單元需要最小占用

512位元組,即使只存乙個位元組也佔了

512位元組。這時候就有乙個設計模式,可以把

key復用,幾個

key-value

放入乙個

key中,

value

再作為乙個

set存入,這樣同樣

512位元組就會存放

10-100

倍的容量。

這就是為了節約記憶體,建議使用

hashset

而不是set/get

的方式來使用

redis

,詳細方法見參考文獻

(7)。

6. 使用aof

代替snapshot

redis

有兩種儲存方式,預設是

snapshot

方式,實現方法是定時將記憶體的快照

(snapshot)

持久化到硬碟,這種方法缺點是持久化之後如果出現

crash

則會丟失一段資料。因此在完美主義者的推動下作者增加了

aof方式。

aof即

,在寫入記憶體資料的同時將操作命令儲存到日誌檔案,在乙個併發更改上萬的系統中,命令日誌是乙個非常龐大的資料,管理維護成本非常高,恢復重建時間會非常長,這樣導致失去

aof高可用性本意。另外更重要的是

redis

是乙個記憶體資料結構模型,所有的優勢都是建立在對記憶體複雜資料結構高效的原子操作上,這樣就看出

aof是乙個非常不協調的部分。 其實

aof目的主要是資料可靠性及高可用性,在

redis

中有另外一種方法來達到目的:

replication

。由於redis

的高效能,複製基本沒有延遲。這樣達到了防止單點故障及實現了高可用。

Redis 資料庫理解

在實際專案中redis常被應用於做快取,分布式鎖 訊息佇列等。但是在搭建配置好redis伺服器後很多朋友應該會發現和有這樣的疑問,為什麼redis預設建立了16個資料庫 db0 db15 redis是乙個字典結構的儲存伺服器,乙個redis例項提供了多個用來儲存資料的字典,客戶端可以指定將資料儲存在...

Redis更新快取同步資料庫的理解

問題 當資料庫有資料更新時,怎樣保證redis快取中的資料與資料庫資料一致?redis更新的正確方法 原文 快取更新的套路 看到好些人在寫更新快取資料 時,先刪除快取,然後再更新資料庫,而後續的操作會把資料再裝載的快取中。然而,這個是邏輯是錯誤的。試想,兩個併發操作,乙個是更新操作,另乙個是查詢操作...

Redis資料庫(初級)

redis是乙個開源的非關係型資料庫,它採用c語言編寫,是乙個key value儲存系統,它儲存的value型別很多,包括string 字串 list 鍊錶 set 集合 zset 有序集合 hash 雜湊 比如,我們插入一條資料,如下 python view plain copy import r...