精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

淺析Redis的5種基本數據類型

汽車玩家 ? 來源:IT知識課堂 ? 作者:IT知識課堂 ? 2020-05-05 23:44 ? 次閱讀

面試官: 我看你簡歷上說在你的項目中使用了 Redis,并使用它做了緩存,你能給我介紹一下 Redis 的五種基本數據類型嗎?

于是說道:emmm,Redis 中有 string字符串,hash哈希,list列表,set無序集合,zset有序集合,這五種數據類型。

面試官:除了這五種基本數據類型你還了解過其他 Redis 提供的額外的數據類型嗎?你說你用 Redis 做了緩存,比如我現在查詢用戶用一個本來就不會存在的 ID 去調你接口,這樣的緩存穿透如何防范呢?

沒辦法了硬著頭皮往上懟:emm, 有了解過 bitMap,緩存穿透我沒接觸過。

面試官:那你有使用過 bitMap 實現什么功能么?

面試者心里想:完了完了,這場涼了,都怪 FrancisQ ,回去找他算賬。

心里已經涼涼:沒有。。。

寫在前面的話

其實 FrancisQ 只是一個沒有參加面試過的小白,在讀大三,想明年暑期實習,所以在學習之余會寫一些文章進行分享并自我總結(不為賺錢),如果覺得 FrancisQ 寫的還不錯的話,給我點個贊哦 (#^.^#),其實我只是想早日到 LV4。當然我還有分享其他文章比如 SSM框架的原理解析和實現 ,MySQL 等等,如果感興趣的也可以關注我。

當然各位大佬有實習崗位的可以幫幫我哈,哈哈哈。

多余的話不多說,今天給大家帶來的是 Redis 中的四種特殊的數據結構 bitmap,hyperLogLog,bloomFilter,GeoHash 。這四種數據結構其實有點類似于算法層面了,比如 GeoHash 其實就是一個 zset,bitmap 就是 string,只是使用的方法不同導致了更多的功能。

BloomFilter

介紹以及場景使用

對 BloomFilter 不熟悉的話,對下面的圖片大家肯定很熟悉吧?別告訴我你只玩過王者農藥。

BloomFilter 中文名就是布隆過濾器,作為過濾器,有沒有感覺很像 LOL 中布隆的 E技能(堅不可摧) ?

布隆過濾器是一個叫 布隆 的人提出來的,它是通過一個大型位數組和幾個不同的hash函數來實現的,我們可以把布隆過濾器理解為一個不精確的set。我們都知道 set 可以去重,使用 set 可以幫我們判斷集合中是否已經存在某些元素并且或者幫我們實現去重功能。

但是,set 提供精確的去重功能的同時也給我們帶來了一個更大的問題——空間消耗。

比如這個時候我們進行網頁爬蟲,需要對爬過的 url 進行去重以避免爬到已經爬過的網站,如果我們使用 set 那么也就意味著我們需要將所有爬過的 url 放入集合中,假設一個 url 64字節,那么一億個 url 意味著我們需要占用 6GB,十億就是 60GB 左右。

請注意,是內存。

比如這個時候我們要進行垃圾郵件或者垃圾短信的過濾,我們需要從數十億個垃圾郵件列表或者垃圾電話列表中進行判斷此時的郵件或者短信是否是垃圾的。如果我們此時使用 set 那么占用空間不用我多說了,也是百GB級別的。

上面的面試中我提到了緩存穿透,用戶故意請求數據庫本來就不存在的(比如ID = -1),這個時候如果不做處理那么肯定會穿透緩存去查詢數據庫,一個查詢還好,如果幾千,幾萬個同時進來呢?你的數據庫頂得住嗎?那么此時我們使用 set 進行處理,占用那么多內存空間,你覺得值得嗎???或者說,還有沒有更好的方法了?

上面所講的三個典型場景,網站去重,垃圾郵件過濾,緩存穿透,這三個只要使用 BloomFilter 就能完美解決。

你有沒有發現,上面三個場景其實對精度要求都不是很高,尤其是垃圾郵件過濾,其實偶爾收到幾個垃圾郵件也無所謂的。像緩存穿透,也正好符合了 BloomFilter 的一個特性他說有的不一定有,他說沒有的肯定沒有,我說你這個 ID 在數據庫不存在那就真的不存在,老子把你過濾了就是這么自信,怎么,你打我???

原理探究

聊了這么久的概念和應用場景,是不是還對 BloomFilter 怎么能進行去重的還是一臉懵逼? 下面我們就聊一聊 BloomFilter 的實現原理。首先給大家放一張結構圖。

淺析Redis的5種基本數據類型

其中 F、G、H 是幾種無偏 Hash 函數,底下是一個大型的位數組,當我們向 BloomFilter 添加數據的時候,它首先會將我們的數據(key)做幾次hash運算(這里就是FGH),每個hash運算都會得到一個不用的位數組索引下標,此時我們就將算出的幾個下標的位置的值改成1就行。如果判斷元素是否存在,只要判斷所在的所有索引下標的值都是1就行了。

其實你也發現了,在 BloomFilter 中會出現不同key所算出的下標重復了,如上圖所示,這就是誤差的來源( 你可以配置初始大小和錯誤率來控制誤差 )也是他說有的不一定有,他說沒有的肯定沒有這一特性的根本原因,因為如果全是0或者存在0那么肯定不存在,如果全是1也有可能是別的幾個key給放進去的1。

基本使用

因為 BloomFilter 是 Redis 的擴展模塊,所以需要額外下載,你可以使用 Docker 進行拉取。安裝步驟我不做詳細解釋,你可以到它的github上學習怎么安裝

安裝完之后我們就可以愉快的使用啦。

bf.add key element 添加

bf.exists key element 判斷是否存在

bf.madd key element1 element2 ... 批量添加

bf.mexists key element1 element2 ... 批量判斷

命令很簡單,你可以自己去嘗試。

HyperLogLog

介紹以及場景使用

在 Redis 中還有一個會存在誤差的數據結構 HyperLogLog。

我們首先思考一個場景,當老板讓我們計算頁面的 UV 我們該怎么辦?

如果訪問量不大使用 set 進行用戶去重完全可以,但是訪問量如果有幾百萬,幾千萬,那么就會又遇到上面提到的浪費空間的問題。如果我們這個時候有一個能進行去重且能進行計數的數據結構就好了。

這個時候 HyperLogLog 就閃亮登場了!它能提供不精確的去重計數方案(誤差值在 0.81% 左右),不精確就不精確哇,UV 要你多精確?0.81%我們也能接受。最重要的是 HyperLogLog 只占用12KB的內存。

使用方法和場景實踐

pfadd key element 添加

pfcount key 計算

pfmerge destkey sourcekey1 sourcekey2 ... 合并

命令都是 pf 開頭是因為這是一個名叫 Philippe Flajolet 的教授發明的。

可以看到就這三個基本命令,很簡單很容易掌握。那我們來動手實踐一下吧。

淺析Redis的5種基本數據類型

BitMap

介紹和使用場景

首先我們再來思考一個比較有意思的場景,老板想讓你統計一年內多個用戶之間他們同時在線的天數,這個時候你怎么辦?

你可能會想到使用 hash 存儲,這太浪費空間了,有沒有更好的辦法呢?答案是有的,Redis 中使用了 bitmap位圖。

淺析Redis的5種基本數據類型

我們知道,字符串中一個字符是使用8個比特來表示的(如上圖),在 Redis 中 bitmap 底層就是 string,也可以說 string 底層就是 bitmap。

如果有了這個我們是不是可以用來計算一個用戶在指定時間內簽到的次數?也就是一個位置代表一天,0代表未簽到,1代表簽到,在上圖中,該用戶在八天內簽到了四次。

Redis 中的 bitmap 還提供了多個 bitmap 進行與,或,異或運算的命令,當然還有單個 bitmap 的 非 運算。這是不是給你提供了一點思路對于我們一開始的需求呢?

基本命令使用

setbit key index 0/1 設置某位的值

getbit key index 獲取某位的值

bitcount key start end 獲取指定范圍內為1的數量

需要注意的是,這里的start 和 end是指的字符位置不是比特位置!!!包括下面的 bitpos 也是

bitpos key bit start end 獲取第一個值為bit的從start到end字符索引范圍的位置

bitop and/or/xor/not destkey key1 key2 對多個 bitmap 進行邏輯運算。

對于bitmap還有一個好玩的指令就是 bitfield ,這里我不做過多介紹,感興趣的同學自己可以了解一下。

動手實踐

我們首先來實現一下統計用戶簽到次數的功能。

淺析Redis的5種基本數據類型

還記得我們一開始的問題嗎?統計一年內多個用戶之間他們同時在線的天數,我們有了 bitmap 還怕什么。

淺析Redis的5種基本數據類型

GeoHash

介紹和場景運用

GeoHash 常用來計算附近的人,附近的商店。

試想一下如果我們使用 關系數據庫 來存儲某個元素的地址 (id,經度,緯度) 。這個時候我們該如何計算附近的人?難道我們要遍歷所有元素位置并做距離計算?這顯然不可能。

當然你可以使用劃分區域并使用 SQL 語句圈出區域,然后建立雙向復合索引來提升性能,但是數據庫的并發能力畢竟有限,我們能不能使用 Redis 來做呢?

答案是可以的,Redis 中使用了 GeoHash 提供了很好的解決方案。具體原理是將地球看成一個平面,并把二維坐標映射成一維(精度損失的原因)。如果對其中的算法感興趣你可以自己額外去了解,篇幅有限不做過多說明。

基本命令和使用實戰

geoadd key longitude latitude element(后面可配置多個三元組) 添加元素

geodist key element1 element2 unit 計算兩個元素的距離

geopos key element [element] 獲取元素的位置

geohash key element 獲取元素hash

georadiusbymember key element distanceValue unit count countValue ASC/DESC [withdist] [withhash] [withcoord] 獲取元素附近的元素 可附加后面選項[距離][hash][坐標]

georadius key longitude latitude distanceValue unit count countValue ASC/DESC [withdist] [withhash] [withcoord] 和上面一樣只是元素改成了指定坐標值

淺析Redis的5種基本數據類型

總結

這篇文章中我想大家介紹了 Redis 另外的四種特殊數據結構,他們分別是 BloomFilter,HyperLogLog,BitMap還有GeoHash。并且我還想你們介紹了如何使用他們,他們的運用場景有哪些,希望對你們有幫助。

非常感謝你能看到這里,如果喜歡或者對你有幫助別忘了點贊哦。你也可以關注我,我會經常做些學習分享給大家。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內存
    +關注

    關注

    8

    文章

    2999

    瀏覽量

    73882
  • Redis
    +關注

    關注

    0

    文章

    371

    瀏覽量

    10846
收藏 人收藏

    評論

    相關推薦

    AIC23采集到的數據是應該用什么數據類型來接收?int還是unsigned int?

    AIC23采集到的數據是應該用什么數據類型來接收,int還是unsigned int? 這個采集到的數字是什么含義呢?代表的是聲音信號的幅值? while(!MCBSP_rrdy(hMcbsp
    發表于 10-18 06:56

    labview數據類型的取值范圍是多少

    LabVIEW的數據類型豐富多樣,涵蓋了整數、小數(浮點數)、復數等多種類型,每種類型都有其特定的取值范圍。以下是對LabVIEW中常見數據類型取值范圍的說明: 整數
    的頭像 發表于 09-04 17:33 ?748次閱讀

    常見的遙感數據類型有哪些

    遙感技術是一通過遙感器在遠離目標的位置獲取目標地物的電磁波信息,并進行分析的技術。遙感數據類型繁多,涵蓋了從可見光到紅外、微波等多個波段,以及不同的數據格式和分辨率。 光學遙感數據
    的頭像 發表于 09-04 14:30 ?1127次閱讀

    技術干貨驛站 ▏深入理解C語言:基本數據類型和變量

    在C語言中,數據類型和變量是編程的基礎,也是理解更復雜概念的關鍵。數據類型決定了變量的內存分配、存儲范圍和操作方式,而變量則是存儲數據的容器。本篇文章將從基本數據類型和變量兩個方面,帶
    的頭像 發表于 07-26 17:53 ?1933次閱讀
    技術干貨驛站 ▏深入理解C語言:基<b class='flag-5'>本數據類型</b>和變量

    C語言數據類型有哪些

    在 C 語言中,數據類型指的是用于聲明不同類型的變量或函數的一個廣泛的系統。變量的類型決定了變量存儲占用的空間,以及如何解釋存儲的位模式。
    發表于 03-20 10:56 ?439次閱讀
    C語言<b class='flag-5'>數據類型</b>有哪些

    plc數據類型怎么理解和應用

    PLC(可編程邏輯控制器)是一工業自動化設備,用于控制機械和工業過程。在PLC編程中,數據類型是非常重要的概念,因為它決定了程序中數據的存儲和處理方式。正確理解和應用PLC數據類型
    的頭像 發表于 12-19 11:39 ?4013次閱讀

    oracle的數據類型有哪些

    。 一、數值類型 NUMBER:數值類型是Oracle中最常用的數據類型之一。它用于存儲整數或帶有小數點的數字。NUMBER類型可以指定精度(precision)和標度(scale),
    的頭像 發表于 12-05 16:45 ?2296次閱讀

    byte屬于java基本類型

    是的,byte屬于Java的基本數據類型之一。Java中共有8本數據類型,分別是byte、short、int、long、float、double、char和boolean。byte類型
    的頭像 發表于 12-05 10:40 ?826次閱讀

    redis是關系型數據庫嗎

    Redis不是關系型數據庫,它是一基于鍵值對的NoSQL數據庫。在本文中,我將對Redis進行詳細介紹,包括其特點、用途、常見命令和應用場
    的頭像 發表于 12-05 10:32 ?1496次閱讀

    redis數據結構的底層實現

    Redis是一內存鍵值數據庫,常用于緩存、消息隊列、實時數據分析等場景。它的高性能得益于其精心設計的數據結構和底層實現。本文將詳細介紹
    的頭像 發表于 12-05 10:14 ?590次閱讀

    redis的主要方法

    ,包括字符串操作、哈希操作、列表操作、集合操作以及有序集合操作等,同時還會對每個方法進行實例演示。 一、字符串操作 Redis的字符串是最基本的數據類型,可以存儲任意類型數據,包括二
    的頭像 發表于 12-05 09:59 ?783次閱讀

    php的數據類型主要有哪幾種

    PHP是一類型編程語言,它支持多種數據類型。以下是PHP的主要數據類型: 字符串(String): 表示文本數據,可以使用單引號或雙引號
    的頭像 發表于 12-04 16:05 ?688次閱讀

    javascript的typeof返回哪些數據類型?

    JavaScript的typeof操作符用于確定一個值的數據類型,可能的返回值包括以下幾種: "undefined":當一個變量被聲明但未被賦值時,其類型為undefined。 "boolean
    的頭像 發表于 12-03 11:41 ?761次閱讀

    javascript的基本數據類型有哪些

    JavaScript 是一動態的、面向對象的編程語言,廣泛應用于 Web 開發中。在 JavaScript 中,有七本數據類型(Primitive Types),它們分別是 Undefined
    的頭像 發表于 12-03 11:17 ?732次閱讀

    Java各種類的區別

    了8基本類型:byte、short、int、long、float、double、char和boolean。這些基本類型都有對應的包裝類,用于將基本數據類型轉化為對象。 包裝類: 包裝
    的頭像 發表于 12-03 11:08 ?7644次閱讀