Redis原理及應用

2021-09-11 22:50:49 字數 3461 閱讀 2361

redis是目前最火爆的記憶體資料庫之一,通過在記憶體中讀寫資料,大大提高了讀寫速度,可以說redis是實現高併發服務不可或缺的一部分。通常我們使用redis時,會接觸到5種資料型別(字串、雜湊、列表、集合、有序集合),豐富的型別可以協助我們實現各種業務場景需求。知其然知其所以然,進一步了解redis的記憶體模型及相關持久化,事物,鎖的實現方式和原理可以進一步讓我們深入理解redis,在使用時選擇最佳的實現方式,在遇到問題時也能有分析解決的思路;

先介紹一下redis對外提供支援的資料型別, string, list, hash, set, sorted-set;

字串是最常用且簡單的型別,redis中key是字串型別的,如果value也用字串,這樣我們可以做到乙個字串到另乙個字串的對映,這個在快取html頁面,或者將乙個大物件序列化為字串,都是非常有用的;

list即一系列有序的物件,通常有arrays和linked-list兩種實現方式,且兩者相關屬性有所不同;redis中的list是基於linked-list實現的,這樣就保證了即使在有百萬條資料的list中,在頭部或者尾部插入一條新記錄也會在很短的時間內完成,相對應的缺點就是當按照陣列索引去訪問元素時,就會隨著lists的增大而效率變低;但是為什麼這樣實現的原因還是在於為資料庫提供較高的插入效率是至關重要的;如果需要快速訪問乙個大list裡面中間的元素時,可以考慮使用下文會提及的有序集合;

應用場景

儲存乙個使用者最後一次發布的微博內容

應用消費者-生產者模式,實現對一類訊息進行生產消費的訊息佇列緩衝器;

hashes是乙個鍵值(key=>value)對集合,很多場景下都可能會用到它。

應用場景

快取使用者資訊,假如username全域性唯一,就可以用hashes儲存所有使用者資訊,username作為hashes的key,這樣在獲取使用者資訊或重新整理緩使用者資訊時只操作某乙個使用者,而不影響其他的使用者,減少網路請求資料量;

無序的字串集合(不重複),底層是通過hash表實現,對value計算hash可以實現快速判重;

有序的字串集合(不重複),內部使用hashmap和跳躍表(skiplist)來保證資料的儲存和有序,hashmap裡放的是成員到score的對映,而跳躍表裡存放的是所有的成員,排序依據是hashmap裡存的score,使用跳躍表的結構可以獲得比較高的查詢效率,並且在實現上比較簡單。

上面我們羅列了redis對外提供可直接使用的幾種資料型別,接下來我們了解一下redis的記憶體模型,即在redis內部是如何實現豐富的資料型別及相關操作;

在客戶端通過redis-cli連線伺服器後,通過info命令檢視記憶體使用情況: info memory

redis作為記憶體資料庫,在記憶體中儲存的內容主要是資料(鍵值對);通過前面的敘述可以知道,除了資料以外,redis的其他部分也會占用記憶體。

1、資料

作為資料庫,資料是最主要的部分;這部分占用的記憶體會統計在used_memory中。

redis使用鍵值對儲存資料,其中的值(物件)包括5種型別,即字串、雜湊、列表、集合、有序集合。這5種型別是redis對外提供的,實際上,在redis內部,每種型別可能有2種或更多的內部編碼實現;此外,redis在儲存物件時,並不是直接將資料扔進記憶體,而是會對物件進行各種包裝:如redisobject、sds等;這篇文章後面將重點介紹redis中資料儲存的細節。

2、程序本身執行需要的記憶體

redis主程序本身執行肯定需要占用記憶體,如**、常量池等等;這部分記憶體大約幾兆,在大多數生產環境中與redis資料占用的記憶體相比可以忽略。這部分記憶體不是由jemalloc分配,因此不會統計在used_memory中。

補充說明:除了主程序外,redis建立的子程序執行也會占用記憶體,如redis執行aof、rdb重寫時建立的子程序。當然,這部分記憶體不屬於redis程序,也不會統計在used_memory和used_memory_rss中。

3、緩衝記憶體

緩衝記憶體包括客戶端緩衝區、複製積壓緩衝區、aof緩衝區等;其中,客戶端緩衝儲存客戶端連線的輸入輸出緩衝;複製積壓緩衝用於部分複製功能;aof緩衝區用於在進行aof重寫時,儲存最近的寫入命令。在了解相應功能之前,不需要知道這些緩衝的細節;這部分記憶體由jemalloc分配,因此會統計在used_memory中。

4、記憶體碎片

記憶體碎片是redis在分配、**物理記憶體過程中產生的。例如,如果對資料的更改頻繁,而且資料之間的大小相差很大,可能導致redis釋放的空間在物理記憶體中並沒有釋放,但redis又無法有效利用,這就形成了記憶體碎片。記憶體碎片不會統計在used_memory中。

記憶體碎片的產生與對資料進行的操作、資料的特點等都有關;此外,與使用的記憶體分配器也有關係:如果記憶體分配器設計合理,可以盡可能的減少記憶體碎片的產生。後面將要說到的jemalloc便在控制記憶體碎片方面做的很好。

如果redis伺服器中的記憶體碎片已經很大,可以通過安全重啟的方式減小記憶體碎片:因為重啟之後,redis重新從備份檔案中讀取資料,在記憶體中進行重排,為每個資料重新選擇合適的記憶體單元,減小記憶體碎片。

1. 顯示最新的發布記錄

在乙個論壇的首頁,展示最新發布的20片帖子,我們在每一篇帖子發布後,將帖子的簡要資訊及id儲存在redis-list裡面,用lpush的命令,這樣保證了從左至右就是按照帖子的發布時間倒序排列的;這樣無論取最新20,50,100都可以用命令lrange來讀取,或者用命令ltrim對list進行削整,儲存最新的帖子,淘汰較早的帖子

lpush post "生活大**大結局"

lpush post "華為備胎晶元轉正"

lpush post "滴滴**違規單車"

lpush post "合照殺手王祖賢"

lpush post "evil genius 戰隊勇奪ti5冠軍"

lrange post 0 2

-------

1) "evil genius 戰隊勇奪ti5冠軍"

2) "合照殺手王祖賢"

3) "滴滴**違規單車"

-------

llen post

(integer) 5

ltrim post 0 2

llen post

(integer) 3

2. 天梯分數高手排行榜(維護乙個有序佇列)
zadd ranking 9987 "miracle"

zadd ranking 9762 "天命"

zadd ranking 9521 "高手墳墓"

zadd ranking 9785 "ramzes666"

zadd ranking 9589 "中華小當家"

zadd ranking 9129 "fly"

zadd ranking 9899 "arteezy"

// 降序輸出天梯排名前五(降序)

zrevrange ranking 0

// 公升序輸出

zrange ranking 0 4

注意: 這裡放進set中的值key不是分數而是內容, 所以當我們放入已經存在的值時, 會觸發重新排序;

阿里雲redis開發規範

redis原理及使用

從原理,部分原始碼,demo使用加深理解 原始碼 原始碼 注釋 一 資料結構 6種 sds簡單動態字串 sds資料結構與c字串的區別 c字串是字元 空 如abcd 0 sds是len總長度 buf陣列 free未使用的長度鍊錶 字典 跳躍表 整數集合 壓縮列表 二 資料型別 5種 鍵值對來快取或儲存...

redis簡介及應用

一.mysql事務 原子性 乙個事務是不可分割的整體,執行操作時就是一起做,或者一起都不做 一致性 意思是張三給李四轉了100元,李四就必須加100元 隔離性 意思是寫資料是隔離開 永續性 意思是資料庫的改變不能返回,改了就改了 redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執...

Redis應用及安裝

redis聽到最多的一句話就是redis的使用難嗎?不難,redis用好容易嗎?不容易,有時候覺得這句話說的挺好,但又是讓讀者挺心裡咯噔一下的,還不如不說!redis是乙個開源 bsd許可 的記憶體資料結構儲存,用作資料庫,快取和訊息 它支援資料結構,如字串,雜湊,列表,集合,具有範圍查詢的排序集,...