中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

本地dedecms網(wǎng)站網(wǎng)絡(luò)培訓(xùn)

本地dedecms網(wǎng)站,網(wǎng)絡(luò)培訓(xùn),別樣海外購怎么開店,中高端網(wǎng)站開發(fā)基本結(jié)構(gòu)圖 key和value指向的是redisObject對象 type:標(biāo)識該對象用的是什么類型(String、List Redis數(shù)據(jù)結(jié)構(gòu) SDS SDS有4個(gè)屬性: len:記錄了字符串長度,因此獲取字符串長度的時(shí)候時(shí)間復(fù)雜度O(1&#xff…

基本結(jié)構(gòu)圖

key和value指向的是redisObject對象

type:標(biāo)識該對象用的是什么類型(String、List

Redis數(shù)據(jù)結(jié)構(gòu)

SDS

SDS有4個(gè)屬性:

  • len:記錄了字符串長度,因此獲取字符串長度的時(shí)候時(shí)間復(fù)雜度O(1)
  • alloc:分配給字符數(shù)組的空間長度。這樣在修改字符串的時(shí)候,只需要alloc-len來判斷剩余空間大小,可以用來判斷空間是否滿足修改條件,如果不滿足就會將SDS擴(kuò)容。因此不會出現(xiàn)C語言的緩沖區(qū)溢出問題
  • flags:用來表示不同類型的SDS,表示len和alloc的類型不同,進(jìn)而保存的SDS分配給字節(jié)數(shù)組的大小不同。
  • buf[]:字節(jié)數(shù)組,用來保存實(shí)際數(shù)據(jù)。不僅可以保存文本數(shù)據(jù),還可以保存二進(jìn)制數(shù)據(jù)。

Redis底層由C語言實(shí)現(xiàn),那么SDS與C語言字符串對比:

  • O(1)獲得字符串長度:因?yàn)镾DS有l(wèi)en屬性
  • 二進(jìn)制安全:SDS不僅可以保存文本數(shù)據(jù),還能保存二進(jìn)制數(shù)據(jù)。SDS的使用len屬性來判斷是否遍歷完成,不會管'\0'的字符
  • 不會發(fā)生緩沖區(qū)溢出:通過alloc-len來判斷剩余空間大小,可以用來判斷空間是否滿足修改條件,如果不滿足就會將SDS擴(kuò)容。因此不會出現(xiàn)C語言的緩沖區(qū)溢出問題

擴(kuò)容機(jī)制:

  • 如果所需的SDS長度小于1MB,則翻倍 + 1
  • 如果所需的SDS長度超過1MB,最后的擴(kuò)容大小應(yīng)該是newlen + 1MB + 1?

壓縮列表

ZipList分為這幾個(gè)部分:

  • zlbytes:整個(gè)壓縮列表占用內(nèi)存字節(jié)數(shù)
  • zltail:壓縮表尾部節(jié)點(diǎn)距離起始地址多少個(gè)字節(jié),也就是列表尾的便宜量
  • zllen:entry節(jié)點(diǎn)的個(gè)數(shù)
  • entry部分:存儲數(shù)據(jù)的部分
  • zlend:壓縮列表的結(jié)束點(diǎn),固定在0xFF

entry的構(gòu)成:

  • prevlen:前一個(gè)節(jié)點(diǎn)的長度,目的是實(shí)現(xiàn)從后往前遍歷
  • encoding:記錄當(dāng)前節(jié)點(diǎn)實(shí)際的類型和長度,類型主要是字符串和整數(shù)
  • data:記錄當(dāng)前節(jié)點(diǎn)的實(shí)際存儲數(shù)據(jù),類型和長度由encoding決定

prevlen屬性的大小:

  • 如果前一個(gè)節(jié)點(diǎn)的長度小于254字節(jié),那么prevlen屬性需要1字節(jié)
  • 如果前一個(gè)節(jié)點(diǎn)的長度大于等于254字節(jié),那么prevlen屬性需要5字節(jié)

encoding屬性的大小:

  • 如果當(dāng)前數(shù)據(jù)是整數(shù),需要1字節(jié)
  • 如果當(dāng)前的數(shù)據(jù)是字符串,會根據(jù)需要使用1、2、5字節(jié)的空間

連續(xù)更新問題:

  • 壓縮列表新增某一個(gè)元素或者修改某一個(gè)元素,如果空間不夠,壓縮列表占用的內(nèi)存空間需要重新分配。當(dāng)更新的元素較大,會導(dǎo)致后續(xù)的prevlen也都要重新分配,從而引起連鎖更新的問題

quicklist

在 Redis 3.0 之前,List 對象的底層數(shù)據(jù)結(jié)構(gòu)是雙向鏈表或者壓縮列表。然后在 Redis 3.2 的時(shí)候,List 對象的底層改由 quicklist 數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)。

quicklist就是雙向鏈表+壓縮列表的組合,quicklist鏈表中的每一個(gè)節(jié)點(diǎn)是一個(gè)壓縮列表。

解決連鎖更新:

  • 通過控制鏈表節(jié)點(diǎn)中的壓縮列表的大小或者元素個(gè)數(shù),來規(guī)避連鎖更新的問題。因?yàn)閴嚎s列表元素越小,連鎖更新帶來的影響就越小,從而性能提升

哈希表

dictht有這幾個(gè)屬性:

  • dictEntry **table:數(shù)組的每一個(gè)元素是指向哈希表節(jié)點(diǎn)的指針
  • size:哈希表大小
  • sizemask:掩碼,用于計(jì)算索引值
  • used:哈希表已有的entry個(gè)數(shù)

哈希沖突:
當(dāng)兩個(gè)key不同,但是索引值相同,就會發(fā)生沖突

解決辦法是采用拉鏈法:

  • 被分配到同一個(gè)哈希桶上的多個(gè)節(jié)點(diǎn)用一個(gè)單項(xiàng)鏈表連接起來
  • 但是也有缺點(diǎn),當(dāng)鏈表長度過長的時(shí)候,查詢效率很低。

解決辦法是rehash,分為三步:

  1. 給哈希表2分配空間,一般比哈希表1大一倍
  2. 將哈希表1數(shù)據(jù)遷移到哈希表2
  3. 遷移完成后,哈希表1的空間釋放,并把哈希表2設(shè)置為哈希表1,然后在新哈希表2創(chuàng)建出一個(gè)空白的哈希表,為下次rehash做準(zhǔn)備

?但是也有問題,遷移的過程很耗時(shí)間,因此采用了漸進(jìn)式rehash:

  1. 給哈希表2分配空間,一般比哈希表1大一倍
  2. 在rehash期間,每次哈希表元素新增、刪除、查找的時(shí)候,Redis會執(zhí)行對應(yīng)的操作外,還會將哈希表1中索引位置上的所有dictEntry遷移到哈希表2
  3. 遷移完成后,哈希表1的空間釋放,并把哈希表2設(shè)置為哈希表1,然后在新哈希表2創(chuàng)建出一個(gè)空白的哈希表,為下次rehash做準(zhǔn)備

rehash觸發(fā)條件:

  • 負(fù)載因子 = 哈希表已保存的節(jié)點(diǎn)數(shù)量 / 哈希表大小
  • 當(dāng)負(fù)載因子大于等于1,并且redis沒有進(jìn)行RDB快照和AOF重寫的時(shí)候,進(jìn)行rehash
  • 當(dāng)負(fù)載因子大于等于5,說明哈希沖突非常嚴(yán)重,不管也沒用RDB快照和AOF重寫,都會強(qiáng)制執(zhí)行rehash

整數(shù)集合

intset有這幾個(gè)屬性:

  • encoding:編碼方式,比如?INTSET_ENC_INT16,那么contents就是一個(gè)int16_t類型的數(shù)組
  • length:集合包含的元素?cái)?shù)量
  • contents:雖然被聲明為?int8_t 類型,但是實(shí)際上是由保存的數(shù)據(jù)大小由encoding決定

升級規(guī)則:

  • 當(dāng)我們將一個(gè)新元素加入集合中,如果新元素的類型(int32_t)比現(xiàn)有元素的類型(int16_t)都要長,需要擴(kuò)寬contents數(shù)組的大小。
  • 在原本的數(shù)組上,將每個(gè)元素按間隔類型分割,比如如果encoding屬性值為INTSET_ENC_INT16,那么間隔就是16位。
  • 比如現(xiàn)在有3個(gè)類型為int16_t的元素,每個(gè)都是16位長度,然后往整數(shù)集合里面加入一個(gè)新元素65535,這個(gè)新元素類型用int32_t保存,然后對contents擴(kuò)容,會在原本的空間的大小之上多出80位(4 * 32 - 3 * 16 = 80),這樣就能保證可以存下4個(gè)int32_t的元素
  • 然后從后往前依次填充,最終再把65535這個(gè)元素放到最后。

整數(shù)集合升級的好處:

  • 如果讓一個(gè)數(shù)組保存int16_t、int32_t、int64_t的元素,最好的方式就是用int64_t類型,但是會造成空間的浪費(fèi)。
  • 整數(shù)升級保證了我們只需要int64_t類型的元素再進(jìn)行擴(kuò)容,因此可以節(jié)約資源內(nèi)存
  • 另外,整數(shù)集合不支持降級?

跳表

跳表是在鏈表的基礎(chǔ)上改進(jìn)過來的,是一個(gè)多層有序鏈表。

跳表zskiplist有以下屬性:

  • 跳表的頭尾節(jié)點(diǎn)head,tail
  • 跳表的長度length
  • 跳表的最大層數(shù)level

跳表節(jié)點(diǎn)zskiplistNode有以下幾個(gè)屬性:

  • ele:SDS結(jié)構(gòu)存儲數(shù)據(jù)
  • score:節(jié)點(diǎn)的分?jǐn)?shù),浮點(diǎn)型
  • backward:指向上一個(gè)節(jié)點(diǎn)的回退指針,支持從表尾向表頭遍歷,也就是ZREVRANGE命令
  • level:是個(gè)zskiplistLevel數(shù)組,zskiplistLevel包含了兩個(gè)字段,一個(gè)是forward,指向下一層能調(diào)到哪個(gè)節(jié)點(diǎn),span記錄了距離下個(gè)節(jié)點(diǎn)的步數(shù)。數(shù)據(jù)結(jié)構(gòu)就表示每個(gè)節(jié)點(diǎn)是個(gè)多層結(jié)構(gòu)

跳表節(jié)點(diǎn)層數(shù)設(shè)置:

  • 跳表的相鄰兩層的節(jié)點(diǎn)數(shù)量最理想的比例是 2:1,查找復(fù)雜度可以降低到 O(logN)。?
  • Redis在創(chuàng)建節(jié)點(diǎn)的時(shí)候,會生成范圍為[0, 1]的隨機(jī)數(shù),如果這個(gè)隨機(jī)數(shù)小于0.25(相當(dāng)于概率25%),那么層數(shù)就增加一層。然后繼續(xù)生成下一個(gè)隨機(jī)數(shù),直到隨機(jī)數(shù)的結(jié)構(gòu)大于0.25就結(jié)束
  • 這樣的做法,相當(dāng)于每增加一層的概率不超過 25%,層數(shù)越高,概率越低,層高最大限制是 64。

為什么用跳表而不用平衡樹??

  • 從內(nèi)存占用上,跳表比平衡樹更靈活:平衡樹每個(gè)節(jié)點(diǎn)包含2個(gè)指針,跳表每個(gè)節(jié)點(diǎn)包含的指針數(shù)目為1/(1-p),在redis中p=0.25,平均每個(gè)節(jié)點(diǎn)包含1.33個(gè)指針,內(nèi)存占用更少
  • 在做范圍查詢的時(shí)候,跳表比平衡樹操作更簡單:在平衡樹中我們找到特定范圍的最小值后,還需要以中序遍歷的順序?qū)ふ移渌怀^大值的節(jié)點(diǎn),所以中序遍歷不容易實(shí)現(xiàn)。而跳表就很簡單,只需要找到最小值后,對第一層的節(jié)點(diǎn)進(jìn)行若干步的遍歷即可
  • 在算法實(shí)現(xiàn)難度上,跳表更簡單。平衡樹的插入和刪除操作可能引發(fā)子樹的調(diào)整,子樹邏輯復(fù)雜。而跳表的插入和刪除只需要修改相鄰的節(jié)點(diǎn),操作簡單又迅速。

listpack

quicklist并沒有完全解決連鎖更新問題,因?yàn)閝uicklist還是使用了壓縮列表來保存元素,于是有了listpack

listpack結(jié)構(gòu):

  • listpack頭包含兩個(gè)屬性,分別記錄了listpack總字節(jié)數(shù)和元素?cái)?shù)量。然后listpack也有一個(gè)結(jié)尾標(biāo)識。listpack entry是listpack的節(jié)點(diǎn)

listpack entry:

  • encoding:定于元素的編碼類型,會對不同長度的整數(shù)和字符串進(jìn)行編碼
  • data:實(shí)際存放的數(shù)據(jù)
  • len:encdong+data的總長度

將prevlen改成len之后能不能從后往前遍歷?

  • 答案是可以。lpDecodeBacklen函數(shù)已經(jīng)實(shí)現(xiàn)了?

Redis數(shù)據(jù)對象有哪些

概述

常見的對象有以下五種:

  • String:二進(jìn)制安全的,特性是可以包含任何數(shù)據(jù)比如一個(gè)序列化的對象,一個(gè)鍵最大能存儲512M。適用于簡短的字符場景。底層數(shù)據(jù)結(jié)構(gòu)采用的是SDS或者INT編碼
  • Hash:鍵值對數(shù)據(jù)結(jié)構(gòu),相當(dāng)于編程語言的Map。適用于存儲、讀取、修改用戶屬性。底層數(shù)據(jù)結(jié)構(gòu)是哈希表或者壓縮列表
  • Set:包含字符串的無序集合,增刪查找快。使用于最新消息排行榜,消息隊(duì)列。底層數(shù)據(jù)結(jié)構(gòu)是哈希表或者整數(shù)集合
  • Sort Set: 將Set集合加一個(gè)權(quán)重參數(shù)score,元素按照score排序。特性是在插入元素的時(shí)候自然排序。適用于排行榜、帶權(quán)重的消息隊(duì)列。底層數(shù)據(jù)結(jié)構(gòu)是跳表或者壓縮列表

String

字符串對象的內(nèi)部編碼(encoding)有 3 種 :int、raw和 embstr。

  • int:如果一個(gè)字符串對象保存的是整數(shù)值,并且這個(gè)整數(shù)值可以用long類型表示,那么這個(gè)字符串對象會被保存在redisObject對象的prt中,同時(shí)將encoding設(shè)置成int
  • embstr:如果一個(gè)字符串對象保存的是字符串,并且這個(gè)字符串對象小于等于32字節(jié)。那么字符串對象將用SDS表示,同時(shí)encoding設(shè)置成embstr
  • raw:如果一個(gè)字符串對象保存的是字符串,并且這個(gè)字符串對象大于32字節(jié)。那么字符串對象將用SDS表示,同時(shí)encoding設(shè)置成raw

embstr和raw都會用SDS來保存值,但不同之處在于embstr會通過一次內(nèi)存分配函數(shù)來分配一塊連續(xù)的內(nèi)存空間來保存redisObject和SDS。而raw編碼會調(diào)用兩次內(nèi)存分配函數(shù)分別分配redisObject和SDS。

embstr相比raw好處:

  • embstr編碼創(chuàng)建字符串對象只用調(diào)用一次內(nèi)存分配函數(shù),而raw編碼需要兩次
  • 釋放embstr編碼的字符串對象同樣也只需要調(diào)用一次內(nèi)存釋放函數(shù)
  • 因?yàn)閑mbstr編碼的字符串對象的所有數(shù)據(jù)都保存在一塊連續(xù)的內(nèi)存空間,可以更好的利用cpu緩存提升性能

但embstr也有缺點(diǎn):

  • 如果字符串的長度需要重新分配空間時(shí),整個(gè)redisObject和sds都需要重新分配空間,所以embstr編碼的字符串對象實(shí)際上是只讀的。redis沒有為embstr編碼的字符串對象編寫任何修改的程序。當(dāng)我們對embstr編碼的字符串對象執(zhí)行修改的命令,實(shí)際上是先將編碼從embstr轉(zhuǎn)換成raw,再做修改。?

List

底層是雙向鏈表和壓縮列表

  • 如果列表中的元素小于512個(gè),列表每個(gè)元素的值都小于64字節(jié),redis會用壓縮列表存儲
  • 否則用雙向鏈表

在redis3.2之后,使用quicklist作為底層數(shù)據(jù)結(jié)構(gòu)

Hash

  • 如果哈希類型元素個(gè)數(shù)小于512個(gè),并且所有值小于64字節(jié),Redis會用壓縮列表底層數(shù)據(jù)結(jié)構(gòu)?
  • 否則用哈希表

?在redis7.0,壓縮列表結(jié)構(gòu)被拋棄,使用listpack

Set

  • 如果集合中的元素都是整數(shù)且元素個(gè)數(shù)小于512使用整數(shù)集合
  • 否則用哈希表

Zset

  • 如果有序集合元素小于128個(gè),并且每個(gè)元素大小小于64字節(jié),使用壓縮列表
  • 否則用跳表

Redis7.0已經(jīng)將壓縮列表廢棄使用listpack?

http://www.risenshineclean.com/news/6759.html

相關(guān)文章:

  • 廣州企業(yè)網(wǎng)站建設(shè)費(fèi)用武漢百度seo排名
  • 網(wǎng)站建設(shè) 后臺北京谷歌seo
  • 網(wǎng)站查詢域名ip解析免費(fèi)推廣app平臺有哪些
  • 成都網(wǎng)站建設(shè)培訓(xùn)班公關(guān)公司提供的服務(wù)有哪些
  • 國外做詳情頁網(wǎng)站營銷推廣手段有什么
  • 研究網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷方式對比分析
  • 偷dede網(wǎng)站模板網(wǎng)站seo優(yōu)化技巧
  • 河北pc端網(wǎng)站建設(shè)知乎怎么申請關(guān)鍵詞推廣
  • 貴州省網(wǎng)站建設(shè)選哪家廣州seo網(wǎng)站服務(wù)公司
  • 商城網(wǎng)站建設(shè)浩森宇特營銷策略怎么寫范文
  • cc域名注冊搜索優(yōu)化整站優(yōu)化
  • 淄博網(wǎng)站建設(shè)程序競價(jià)運(yùn)營是做什么的
  • 網(wǎng)站優(yōu)化具體是怎么做的seo外鏈工具
  • 廣東官網(wǎng)網(wǎng)站建設(shè)品牌網(wǎng)絡(luò)媒體軟文案例
  • 求推薦公司網(wǎng)站建設(shè)品牌推廣思路
  • wordpress小程序調(diào)用數(shù)據(jù)庫字段長沙優(yōu)化網(wǎng)站推廣
  • 網(wǎng)站建設(shè)需要什么教材網(wǎng)絡(luò)營銷策略實(shí)施的步驟
  • 做網(wǎng)站備案需要什么百度推廣的廣告真實(shí)可信嗎
  • 自己做網(wǎng)站花多少錢域名是什么 有什么用
  • 河北省建設(shè)機(jī)械協(xié)會是真的網(wǎng)站嗎聊城seo
  • 營銷類網(wǎng)站建設(shè)百度刷排名優(yōu)化軟件
  • 網(wǎng)站開發(fā)軟件最流行蘇州搜索引擎優(yōu)化
  • 哪個(gè)網(wǎng)站是做包裝材料珍珠棉包管seo推廣一個(gè)月見效
  • 公司網(wǎng)站不續(xù)費(fèi)能打開網(wǎng)頁嗎seo研究所
  • 對手網(wǎng)站分析如何修改百度上面的門店號碼
  • 后海做網(wǎng)站公司湖南百度推廣代理商
  • 福州外文網(wǎng)站建設(shè)seo網(wǎng)站優(yōu)化知識
  • 沈陽房地產(chǎn)網(wǎng)站開發(fā)西點(diǎn)培訓(xùn)班一般要多少學(xué)費(fèi)
  • 東莞市建設(shè)局網(wǎng)站首頁營銷策略怎么寫
  • 做京東網(wǎng)站需要哪些手續(xù)重慶網(wǎng)站建設(shè)公司