每個程式設計師都應該知道的Redis知識 - String底層原理

2021-01-14 網際網路技術精選

上文我們講述了Redis的數據類型,以及應用場景,文章連結是《每個程式設計師都應該知道的Redis知識》。本文將講述如下內容:

Redis中Srting類型的底層實現原理通過String底層實現原理的學習,我們可以學習到哪些底層優化方法Redis中關於String命令介紹

我們知道Redis是由C語言實現的,在介紹Sring類型的實現之前我們先複習一下C語言的字符串類型。C語言中的字符串是以空字符結尾的字符數組,詳細說明見下圖:

C語言中的字符串

01Redis中Srting類型的底層實現原理

Redis中沒有直接使用C語言的字符串,而是構建了一套自己的抽象類型,名為簡單動態字符串,簡稱SDS。

如果你看Redis源碼會發現這樣一種結構體:

SDS的定義

len 記錄buf數組中已經使用字節的數量,也就是SDS類型所保存的字符串的長度。free 記錄了buf數組中未使用的字節數量buf 是存儲字節的數組,用於保存字符串從上面的結構我們可以看出:

Redis的String類型封裝成SDS結構,體現了用空間換時間的算法思想。犧牲了一些空間,來換取更快的查詢效率。比如說結構體中len的值5表示這個SDS保存了一個五個字節長的字符串,O(1)的時間複雜度就可以查詢出結果。Redis的定位就是資料庫層之上的一層緩存層,所以處處都要考慮高效。其實緩存本身也是用空間換時間思想的體現。解決了C字符串容易緩衝區溢出的問題。因為C字符串不記錄字符串長度,所以通過C語言的 strcat 函數拼接字符串的時候,容易造成拼接後的字符串超過了本身申請的字符串的長度,造成緩衝區溢出。SDS就不會出現這個問題空間預分配:在申請空間的時候預先分配好一定長度的空間。當空間不夠用的時候,通過SDS提供的API可以重新申請一片更大的空間。惰性釋放空間:當申請的空間不再被使用的時候,不是立刻釋放空間,而是在SDS中的free屬性將這些字節的數量記錄下來,等待將來使用二進位安全:封裝後的SDS解決了二進位安全問題,所以在Redis的String類型中可以緩存各種類型數據。SDS的API會以處理二進位的方式來處理SDS存放在buf數組裡的數據,不會對其中的數據做任何限制、過濾、或假設,數據在寫入時是什麼樣的,它被讀取時就是什麼樣的。

總結一下上面所說的,主要是兩個核心思想。第一是SDS這種結構的實現;第二是空間換時間的思想。後面也會有文章專門介紹空間換時間、時間換空間兩種思想的具體應用。

02底層優化方法學習

從上面的介紹我們可以學習到哪些底層優化方法呢?上文反覆提到用空間換時間思想,我想大多數開發人員在實際項目開發中都或多或少地使用過這種思想。Redis、Memcache的設計思路就是這種思想的具體體現。除了Redis,MySQL中也有大量運用,比如說索引就是其中之一。在作業系統、計算機體系結構設計中也存在大量這種設計。

除了空間換時間,內存預分配、惰性釋放也是很好的優化方法。比如說PHP-FPM進程管理方式中的動態方式(Dynamic),啟動的時候預先生成N個Worker進程,當訪問量增加時可以增加Worker進程的數量,當訪問量降下來後再銷毀掉或者保留這些增加的Worker進程,方面後面使用。

除了以上方法,還有很多值得學習和借鑑的方法,在此不再一一列舉。如果這篇文章對你有幫助,歡迎轉發給你的朋友,你們可以一起學習成長。如果有錯誤的地方或者表達不清晰的地方,也歡迎在評論區指出來。大家的支持就是我的動力,希望我們可以一起進步!

03

以下是Redis中String命令的介紹,可以結合前面講的原理來學習這些命令,一定會有不一樣的體會。

相關焦點

  • 新手請進:每個Python程式設計師都應該知道的10個縮寫詞
    學習過程中,我們會逐漸熟悉它的數據結構、控制流、類、函數和其他基本知識。還有一件有趣的事人們不常提起:我們時不時就會遇到Python中的各種首字母縮寫詞。本文將回顧十個這樣的縮寫詞,包括通用的編程原理以及特定的Python編碼,每個詞都有自己有用有趣的方面。1.
  • 國外程式設計師推薦:每個程式設計師都應讀的書
    源於2008年8月4日,StackOverflow 網友 Bert F 發帖提問:哪本最具影響力的書,是每個程式設計師都應該讀的?「如果能時光倒流,回到過去,作為一個開發人員,你可以告訴自己在職業生涯初期應該讀一本, 你會選擇哪本書呢?我希望這個書單列表內容豐富,可以涵蓋很多東西。」
  • 微信附近的人,用redis也能實現?(GEO)
    相信微信附近的人的功能大家都應該用過我可以很隨意的通過我自己的定位能看到我附近的人,並且能看到那個人距離我的距離,大家有沒有思考過這個是怎麼實現的?作為一個程序猿任何問題應該都有一個思考的過程,而不是直接看結論,接下來大家一步一步的思考,直到問題解決。
  • Python使用redis存儲對象
    Python總的對象存儲到redis中默認為字符串,那麼如何存儲對象呢?下面就看看如何直接將Python中對象存儲到redis中先寫個測試redis是否正常連接上import rediscache = redis.StrictRedis('172.20.0.227',6379)
  • 機率大的 Redis 面試題(含答案)|內存|key|原子性|哈希|redis_網易...
    單線程的redis為什麼這麼快redis的數據類型,以及每種數據類型的使用場景,Redis 內部結構redis的過期策略以及內存淘汰機制【~】Redis 為什麼是單線程的,優點如何解決redis的並發競爭key問題Redis 集群方案應該怎麼做?都有哪些方案?有沒有嘗試進行多機redis 的部署?如何保證數據一致的?對於大量的請求怎麼樣處理Redis 常見性能問題和解決方案?
  • 程式設計師必讀源碼,Redis的精緻,在每個數據結構體現得淋漓盡致
    我們知道,在C語言中,是沒有維護字符串數組的長度的,為什麼Redis需要維護這個字符串的長度呢?我們不煩想一個現實的問題,在C語言中,類似'\0'的字符,系統函數讀取到就認為是結束,所以像"abc'\0'dfg"這樣的字符串,在C語言的系統函數只能讀取到abc,如果我們不記錄數組的長度,就有可能讀取到被截斷的數據。所以,Redis的字符串設計,讓Redis的字符串是二進位安全的。
  • Redis RDB與AOF模式下的持久化原理
    前言:在此之前,如果還不了解Redis的,或者不知道怎麼使用Redis,可以參考官網網站:https://redis.io/documentation自行學習,本文主要針對Redis的核心點之一:RDB和AOF持久化模式進行展開。
  • 程式設計師及嵌入式的一些學習建議
    但是又有幾個人能走到設計師、經理的位置,這使得好多想做程式設計師的畢業生很猶豫,不知道到底該不該做程式設計師。其實大部分職業都一樣,有能力的自然會往高處走,沒能力的自然就被淘汰。優勝劣汰的原則大家都知道,幹別的行業三四十歲無所建樹不也玩完嗎?
  • Redis教程:Redis持久化方式
    AOP重寫原理AOF 重寫和 RDB 創建快照一樣,都巧妙地利用了寫時複製機制: redis 執行 fork() ,現在同時擁有父進程和子進程。子進程開始將新 AOF 文件的內容寫入到臨時文件。最重要的事情是了解RDB和AOF持久化方式的不同,讓我們以RDB持久化方式開始:RDB的優缺點優點RDB是一個非常緊湊的文件,它保存了某個時間點得數據集,非常適用於數據集的備份,比如你可以在每個 小時報保存一下過去24小時內的數據,同時每天保存過去30天的數據,這樣即使出了問題你也可以根據需 求恢復到不同版本的數據集.
  • 每個程式設計師都該閱讀的書 - OSCHINA - 中文開源技術交流社區
    國外知名網站stackoverflow上有一個問題調查: 哪本書是對程式設計師最有 影響、每個程式設計師都該閱讀的書? 如果你是個程序猿,你一定有興 趣看看這些書裡你都看過幾本,如果你一本沒看過的話,我也不好說什麼 ,也許你是個天才,但我相信大多數人都知道,你在學校裡根本學不到什 麼真正的工作中需要的知識,我們畢業後能幫助我們在公司中勝任工作的 老師就是這些優秀的書籍,一本好書可以改變一個人的一生。
  • 程式設計師面試通關的 101 道真題
    這是每個程式設計師都需要面對的難關,這是他們邁出學校走向軟體開發的第一重障礙。更糟糕的是,你會發現網際網路上有那麼多人都認為編程面試存在缺陷,程式設計師的招聘過程非常痛苦,但是你不需要特別在意這些觀點,至少在你的職業生涯剛剛起步的時候不應該過度在意別人的言論。他們可能沒有錯,但你羨慕的正是這些人身處的這座圍城。
  • redis cluster 集群管理工具
    前言在redis源碼編譯的時候,在src目錄下會有一個redis-trib.rb的腳本,這個腳本是ruby寫的,用於管理redis cluster。安裝系統依賴包yum -y install epel-release yum -y install ruby rubygem-redis redis-trib.rb/opt/redis/bin/redis-trib.rb
  • 《Python程式設計師面試算法寶典》PDF超清版開源了文末附下載方式
    全面介紹Python程式設計師面試筆試技巧和方法,教你如何以「不變應萬變」。√ 兩萬多行代碼,100多個知識點,全面覆蓋Python程式設計師各類面試題型。√ 15年開發經驗、實戰技巧總結,站在「巨人」的肩膀上,讓學習走捷徑。
  • 大數據必學:redis深入了解 Redis 的持久化機制(RDB、AOF)
    因為 redis是一個內存資料庫,所有數據都存儲在內存中,而且內存中的數據非常容易丟失,所以 redis的數據持久化就變得非常重要, redis提供了兩種數據持久化方法,分別用於 RDB和 AOF,而 redis默認用於 RDB的數據持久化方法。
  • redis cluster 之master 選舉過程
    在redis 3.0版本後,官方推出了redis cluster 分布式解決方案,當一個redis節點掛了可以快速地切換到另一個節點。當遇到單機內存、並發等瓶頸時,可以採用分布式方案要解決問題.redis-cluster架構中,被設計成共有16384(2的14次方)個hash slot。每個master分得一部分slot,其算法為:hash_slot = crc16(key) mod 16384 ,這就找到對應slot。群集至少需要3主3從,且每個實例使用不同的配置文件。
  • 程式設計師要不要學習算法、數據結構、計算機原理等等基礎知識?
    程式設計師要不要學諸如算法、數據結構、網絡編程、計算機原理等等基礎課程?一直是碼農界經久不衰的話題。
  • 詳解Redis中兩種持久化機制RDB和AOF(面試常問,工作常用)
    redis是一個內存資料庫,數據保存在內存中,但是我們都知道內存的數據變化是很快的,也容易發生丟失。幸好Redis還為我們提供了持久化的機制,分別是RDB(Redis DataBase)和AOF(Append Only File)。在這裡假設你已經了解了redis的基礎語法,某字母網站都有很好的教程,可以去看。基本使用的文章就不寫了,都是一些常用的命令。
  • 提升java編程性能優化知識 程式設計師必看這幾點
    每個人在學習的路上都有自己的方法。對於學習java的學子也是如此,那麼java程式設計師如何提高編程性能呢,有哪些小知識或者技巧呢,怎麼樣才能在編程性能優化方面有所提升呢?  提升java編程性能優化知識 程式設計師必看這幾點  控制資源的使用,通過線程同步來控制資源的並發訪問;  控制實例的產生,以達到節約資源的目的;  控制數據共享,在不建立直接關聯的條件下
  • gtoken v1.1.0 發布,gf 的 token 插件,加入 Redis 緩存支持
    gtoken此版本主要加入了緩存redis支持,便於項目集群部署介紹基於gf框架的token插件,通過服務端驗證方式實現token認證; 支持單機gcache和集群gredis