redis解析c語言,redis基於什麼語言

本文目錄一覽:

Redis — 八種數據類型(基本命令)

String、Hash、List、Set和Zset。

等同於java中的, MapString,String string 是redis裡面的最基本的數據類型,一個key對應一個value。

應用場景 :String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類,如用戶信息,登錄信息和配置信息等;

實現方式 :String在redis內部存儲默認就是一個字符串,被redisObject所引用,當遇到incr、decr等操作(自增自減等原子操作)時會轉成數值型進行計算,此時redisObject的encoding字段為int。

Redis雖然是用C語言寫的,但卻沒有直接用C語言的字符串,而是自己實現了一套字符串。目的就是為了提升速度,提升性能。 Redis構建了一個叫做簡單動態字符串(Simple Dynamic String),簡稱SDS。

Redis的字符串也會遵守C語言的字符串的實現規則,即 最後一個字符為空字符。然而這個空字符不會被計算在len裡頭。

Redis動態擴展步驟:

Redis字符串的性能優勢

常用命令 :set/get/decr/incr/mget等,具體如下;

ps:計數器(字符串的內容為整數的時候可以使用),如 set number 1。

補充:

等同於java中的: MapString,MapString,String ,redis的hash是一個string類型的field和value的映射表, 特別適合存儲對象。 在redis中,hash因為是一個集合,所以有兩層。第一層是key:hash集合value,第二層是hashkey:string value。所以判斷是否採用hash的時候可以參照有兩層key的設計來做參考。並且注意的是, 設置過期時間只能在第一層的key上面設置。

應用場景 :我們要存儲一個用戶信息對象數據,其中包括用戶ID、用戶姓名、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日;

實現方式 :Redis的Hash實際是內部存儲的Value為一個HashMap,並提供了直接存取這個Map成員的接口。如,Key是用戶ID, value是一個Map。 這個Map的key是成員的屬性名,value是屬性值 。這樣對數據的修改和存取都可以直接通過其內部Map的Key(Redis里稱內部Map的key為field), 也就是通過 key(用戶ID) + field(屬性標籤) 就可以操作對應屬性數據。 當前HashMap的實現有兩種方式 :當HashMap的成員比較少時Redis為了節省內存會採用類似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,這時對應的value的redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時redisObject的encoding字段為int。

常用命令 :hget/hset/hgetall等,具體如下:

等同於java中的 MapString,ListString ,list 底層是一個鏈表,在redis中,插入list中的值,只需要找到list的key即可,而不需要像hash一樣插入兩層的key。 list是一種有序的、可重複的集合。

應用場景 :Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現;

實現方式 :Redis list的實現為一個 雙向鏈表 ,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括 發送緩衝隊列 等也都是用的這個數據結構。

常用命令 :lpush/rpush/lpop/rpop/lrange等,具體如下:

性能總結 :

它是一個字符串鏈表,left、right都可以插入添加。

等同於java中的 MapString,SetString ,Set 是一種無序的,不能重複的集合。並且在redis中,只有一個key它的底層由hashTable實現的,天生去重。

應用場景 :Redis set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動去重的,當你需要存儲一個列表數據,又不希望出現重複數據時,set是一個很好的選擇,並且 set提供了判斷某個成員是否在一個set集合內的重要接口 ,這個也是list所不能提供的;如保存一些標籤的名字。標籤的名字不可以重複,順序是可以無序的。

實現方式 :set 的內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。

常用命令 :sadd/spop/smembers/sunion等,具體如下:

ZSet(Sorted Set:有序集合) 每個元素都會關聯一個double類型的分數score,分數允許重複,集合元素按照score排序( 當score相同的時候,會按照被插入的鍵的字典順序進行排序 ),還可以通過 score 的範圍來獲取元素的列表。

應用場景 :Redis sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以 通過用戶額外提供一個優先級(score)的參數來為成員排序,並且是插入有序的,即自動排序。 當你需要一個有序的並且不重複的集合列表,那麼可以選擇sorted set數據結構,比如twitter 的public timeline可以以發表時間作為score來存儲,這樣獲取時就是自動按時間排好序的。

底層實現 : zset 是 Redis 提供的一個非常特別的數據結構,常用作排行榜等功能,以用戶 id 為 value ,關注時間或者分數作為 score 進行排序。實現機制分別是 zipList 和 skipList 。規則如下:

zipList:滿足以下兩個條件

skipList:不滿足以上兩個條件時使用跳錶、組合了hash和skipList

為什麼用skiplist不用平衡樹?

主要從內存佔用、對範圍查找的支持和實現難易程度這三方面總結的原因。

拓展:mysql為什麼不用跳錶?

常用命令 :zadd/zrange/zrem/zcard等;

官網地址:

可以用來推算兩地之間的距離,方圓半徑內的人。

關於經度緯度的限制:

一般我們使用Hyperloglog做基數統計。

什麼是基數?就是一個集合中不重複的數的個數。

集合A:{1,3,5,7,9,7}

集合B:{1,3,5,7,9}

AB集合的基數都是5

應用:統計網站的訪問量(一個人訪問網站很多次仍然算作一次)。

優點:佔用的內存是固定的,找2^64次方個數的基數,只需要12KB內存。

缺點:有0.81%的錯誤率,可以忽略不計

概述: bitmap 存儲的是連續的二進制數字(0 和 1),通過 bitmap, 只需要一個 bit 位來表示某個元素對應的值或者狀態,key 就是對應元素本身 。 我們知道 8 個 bit 可以組成一個 byte,所以 bitmap 本身會極大的節省儲存空間。

應用場景: 適合需要保存狀態信息(比如是否簽到、是否登錄…)並需要進一步對這些信息進行分析的場景。比如用戶簽到情況、活躍用戶情況、用戶行為統計(比如是否點贊過某個視頻)。

針對上面提到的一些場景,這裡進行進一步說明。

使用場景一:用戶行為分析 很多網站為了分析你的喜好,需要研究你點贊過的內容。

使用場景二:統計活躍用戶

使用時間作為 key,然後用戶 ID 為 offset,如果當日活躍過就設置為 1

那麼我該如果計算某幾天/月/年的活躍用戶呢(暫且約定,統計時間內只有有一天在線就稱為活躍),有請下一個 redis 的命令

使用場景三:用戶在線狀態

對於獲取或者統計用戶在線狀態,使用 bitmap 是一個節約空間效率又高的一種方法。

只需要一個 key,然後用戶 ID 為 offset,如果在線就設置為 1,不在線就設置為 0。

補充 :

巨人的肩膀:

redis是使用c語言開發的么

Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫。

詳解Redis 主從複製及主從複製原理

Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工作由VMware主持。從2013年5月開始,Redis的開發由Pivotal贊助。

概述

在現有企業中80%公司大部分使用的是redis單機服務,在實際的場景當中單一節點的redis容易面臨風險。

2、容量瓶頸。 當我們有需求需要擴容 Redis 內存時,從 16G 的內存升到 64G,單機肯定是滿足不了。當然,你可以重新買個 128G 的新機器。

解決辦法

要實現分布式數據庫的更大的存儲容量和承受高並發訪問量,我們會將原來集中式數據庫的數據分別存儲到其他多個網絡節點上。

Redis 為了解決這個單一節點的問題,也會把數據複製多個副本部署到其他節點上進行複製,實現 Redis的高可用,實現對數據的冗餘備份,從而保證數據和服務的高可用。

主從複製

什麼是主從複製

主從複製,是指將一台Redis服務器的數據,複製到其他的Redis服務器。前者稱為主節點(master),後者稱為從節點(slave),數據的複製是單向的,只能由主節點到從節點。

默認情況下,每台Redis服務器都是主節點;且一個主節點可以有多個從節點(或沒有從節點),但一個從節點只能有一個主節點。

主從複製的作用

1、數據冗餘: 主從複製實現了數據的熱備份,是持久化之外的一種數據冗餘方式。

2、故障恢復: 當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗餘。

3、負載均衡: 在主從複製的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫Redis數據時應用連接主節點,讀Redis數據時應用連接從節點),分擔服務器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis服務器的並發量。

4、讀寫分離: 可以用於實現讀寫分離,主庫寫、從庫讀,讀寫分離不僅可以提高服務器的負載能力,同時可根據需求的變化,改變從庫的數量。

5、高可用基石: 除了上述作用以外,主從複製還是哨兵和集群能夠實施的基礎,因此說主從複製是Redis高可用的基礎。

主從複製啟用

從節點開啟主從複製,有3種方式:

1、配置文件: 在從服務器的配置文件中加入 slaveofmasteripmasterport。

2、啟動命令: redis-server啟動命令後加入 –slaveofmasteripmasterport。

3、客戶端命令: Redis服務器啟動後,直接通過客戶端執行命令 slaveofmasteripmasterport,則該Redis實例成為從節點。

通過 info replication 命令可以看到複製的一些信息。

主從複製原理

主從複製過程大體可以分為3個階段:連接建立階段(即準備階段)、數據同步階段、命令傳播階段。

在從節點執行 slaveof 命令後,複製過程便開始運作,下面圖示可以看出複製過程大致分為6個過程。

主從配置之後的日誌記錄也可以看出這個流程。

1、保存主節點(master)信息

執行 slaveof 後 Redis 會打印如下日誌:

2、從節點與主節點建立網絡連接

從節點(slave)內部通過每秒運行的定時任務維護複製相關邏輯,當定時任務發現存在新的主節點後,會嘗試與該節點建立網絡連接。

從節點與主節點建立網絡連接。

從節點會建立一個 socket 套接字,從節點建立了一個端口為51234的套接字,專門用於接受主節點發送的複製命令。從節點連接成功後打印如下日誌:

如果從節點無法建立連接,定時任務會無限重試直到連接成功或者執行 slaveofnoone 取消複製。

關於連接失敗,可以在從節點執行 info replication 查看 master_link_down_since_seconds 指標,它會記錄與主節點連接失敗的系統時間。從節點連接主節點失敗時也會每秒打印如下日誌,方便發現問題:

3、發送 ping 命令

連接建立成功後從節點發送 ping 請求進行首次通信, ping 請求主要目的如下:

如果發送 ping 命令後,從節點沒有收到主節點的 pong 回復或者超時,比如網絡超時或者主節點正在阻塞無法響應命令,從節點會斷開複製連接,下次定時任務會發起重連。

從節點發送的 ping 命令成功返回,Redis 打印如下日誌,並繼續後續複製流程:

4、權限驗證

如果主節點設置了 requirepass 參數,則需要密碼驗證,從節點必須配置 masterauth 參數保證與主節點相同的密碼才能通過驗證。如果驗證失敗複製將終止,從節點重新發起複制流程。

5、同步數據集

主從複製連接正常通信後,對於首次建立複製的場景,主節點會把持有的數據全部發送給從節點,這部分操作是耗時最長的步驟。

6、命令持續複製

當主節點把當前的數據同步給從節點後,便完成了複製的建立流程。接下來主節點會持續地把寫命令發送給從節點,保證主從數據一致性。

作者:LoyaltyLu

鏈接:

4、Redis高性能的根本原理

內存的讀寫速度很快

Epoll 模型

常用的五大Redis的數據結構,及他們各自的底層實現結構

string hash list set sortset(zset)

string 的底層實現是 簡單動態字符串(SDS -simple dynamic string)

hash 的底層實現是 hash表 或則 壓縮列表(ziplist)

list 的底層實現是 雙向列表(quicklist) 或者 壓縮列表

set 的底層實現是 hash表(hashtable) 或者 整數數組

sortset(zset) 的底層實現是 壓縮列表 或者 跳錶

各個數據結構的底層實現概覽

value是 string 類型的時候分為三種情況

(1)、當設置的值是整數類型的時候,redis底層會將 string 類型轉化為 int 來存儲

(2)、設置的值小於等於44個字節的時候,使用的編碼是 embstr

(3)、設置的值大於44個字節的時候,使用的編碼是 raw

redis是用C語言編寫的,在C語言中 string 類型是用字符數組 char[] 來實現的。redis實現字符串的底層並沒有直接使用C語言中的字符數組的形式,而是進行了改造,構造出了一種SDS的數據結構

list的底層使用 快速雙向鏈表quicklist 或者 壓縮鏈表ziplist 來實現的。

list的底層並沒有使用傳統的雙向鏈表的結構是因為

(1)、雙向鏈表需要有一個 前指針 和 後指針 ,每個指針佔用的空間分別都是8byte, 佔用內存 比較多

(2)、雙向鏈表所通用的一個問題是會形成很多的 內存碎片

壓縮鏈表 ziplist 結構是

快速雙向鏈表 quicklist 結構

hash的底層實現為 hashtable 或者 ziplist 。

hashtable的底層實現

當數據量比較小或者單個元素的時候,底層使用的是ziplist存儲,具體可以通過配置來制定

1、 hashtable 是無序的 ziplist 是有序的

2、在能使用 hash 的情況下優先使用 hash ,不要使用 String ,因為使用太多的 String ,則會創建出過多的 key ,當 key 大量的時候,就會容易發生 hash碰撞 ,所以就需要頻繁的 rehash ,每次 rehash 就會創建2倍的內存,造成內存浪費

hash的底層實現為 整數數組intset 或者 hashtable 。

當set都為整數的時候,set的底層實現都是使用 intset 結構實現

如果set中存在字符串的值,則使用 hashtable 來實現

intset 是有序的, hashtable 是無序的

sortset 底層使用 壓縮列表ziplist 或 跳錶skiplist 的結構實現

當數據量小的情況下,使用 ziplist 實現,當數據量大的情況下使用 ziplist 實現,具體可以通過配置設置

默認設置下的底層結構

skiplist 的底層實現

查找對應元素的時候,先從最高的索引層找,例如找c 150,則先從L1找,L1的指針指向b,查看b120小於150,則繼續往後找,b的指針指向null,則向下一層找,向下一層b的指針指向c,查看c的score為150,所以找到對應的元素c

1、

什麼是redis呢,求通俗解釋

Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工作由VMware主持。

redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set –有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。

Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關係數據庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便。[1]

Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。這使得Redis可執行單層樹複製。從盤可以有意無意的對數據進行寫操作。由於完全實現了發布/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發布記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/231405.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-11 01:05
下一篇 2024-12-11 01:05

相關推薦

  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演着非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29
  • Python語言由荷蘭人為中心的全能編程開發工程師

    Python語言是一種高級語言,很多編程開發工程師都喜歡使用Python語言進行開發。Python語言的創始人是荷蘭人Guido van Rossum,他在1989年聖誕節期間開始…

    編程 2025-04-28
  • Python語言設計基礎第2版PDF

    Python語言設計基礎第2版PDF是一本介紹Python編程語言的經典教材。本篇文章將從多個方面對該教材進行詳細的闡述和介紹。 一、基礎知識 本教材中介紹了Python編程語言的…

    編程 2025-04-28
  • Python語言實現人名最多數統計

    本文將從幾個方面詳細介紹Python語言實現人名最多數統計的方法和應用。 一、Python實現人名最多數統計的基礎 1、首先,我們需要了解Python語言的一些基礎知識,如列表、字…

    編程 2025-04-28
  • Python作為中心語言,在編程中取代C語言的優勢和挑戰

    Python一直以其簡單易懂的語法和高效的編碼環境而著名。然而,它最近的發展趨勢表明Python的使用範圍已經從腳本語言擴展到了從Web應用到機器學習等廣泛的開發領域。與此同時,C…

    編程 2025-04-28
  • Python基礎語言

    Python作為一種高級編程語言擁有簡潔優雅的語法。在本文中,我們將從多個方面探究Python基礎語言的特點以及使用技巧。 一、數據類型 Python基礎數據類型包括整數、浮點數、…

    編程 2025-04-28

發表回復

登錄後才能評論