Redis那些你不經(jīng)常使用的數(shù)據(jù)結(jié)構(gòu)
如果你了解過redis,或者使用過它,那么一定知道它的5種常用數(shù)據(jù)結(jié)構(gòu),而且如果你面試有被問過redis的話,那么這5種基本數(shù)據(jù)結(jié)構(gòu)也一定會被問到,不過,我們今天不討論這些,我們討論下除此之外的數(shù)據(jù)結(jié)構(gòu),也許平時你沒有使用過,也許你也沒有了解過,不過這不重要,重要的是它們是非??傄臄?shù)據(jù)結(jié)構(gòu),在解決特定問題的時候很好用。
Btimap
理論上來說,bitmap并不屬于一種特殊的數(shù)據(jù)結(jié)構(gòu),從本質(zhì)上來說,它也是一種string類型數(shù)據(jù)結(jié)構(gòu),只不過存儲的值為bit,也就是我們常說的二進制010101這樣的數(shù)據(jù)。


這樣的數(shù)據(jù)結(jié)構(gòu)可以幫助我們使用很少的存儲空間,就可以完成很高效的數(shù)據(jù)查詢。
比如我們有這樣的需求,我們想要統(tǒng)計每一天的用戶簽到人數(shù),常規(guī)的做法就是將數(shù)據(jù)放到set集合里面,然后對數(shù)據(jù)求和即可,然而如果數(shù)據(jù)量非常大的時候,這樣會浪費很大的存儲空間,而bitmap完美解決了這樣的問題。首先我們可以將每天的日期作為key,然后簽到的人的id轉(zhuǎn)換成bit值存儲,也就說如果它簽到了,那么對應位置的值為1,否則為0,這樣就可以通過一個key:value對來統(tǒng)計簽到人數(shù)。需要說明的是,對于位操作,redis有bitcout來快速統(tǒng)計總和。
HyeprLogLog
從名字我們可以看出來,它有兩個log,也就是說它通過兩次取對數(shù)的操作節(jié)省了存儲空間。需要說明的一點,這是一個概率數(shù)據(jù)結(jié)構(gòu),也就說它只能計算出大概率數(shù)值,并不能精確地得到精準數(shù)值,不過在大數(shù)據(jù)問題中,能夠用最少的代價得到一個大致精確地值就是我們追求的。

在redis里面,每個hyperloglog鍵只需要花費12kb大小空間,就可以存儲2^64個元素,這大大節(jié)省了內(nèi)存的存儲空間。
hyperloglog的數(shù)學原理就是基于伯努利過程,是在同樣的條件下重復地、相互獨立地進行的一種隨機試驗。
對于一個數(shù)據(jù)我們通過計算它的hash值得到二進制01值,然后進行分桶操作,再然后在每個桶中再進行位置的計算,因為通過兩次的操作就可以讓存儲的數(shù)據(jù)成指數(shù)增加,而反過來也就說當我們要存儲一定的數(shù)據(jù),只需要取兩次對數(shù)的位數(shù)的bit就可以存下,所以這也是hyperloglog的名字由來。
有了hyerploglog,還是統(tǒng)計上面的簽到的話,我們的存儲空間就大大減小了,當然了這是以犧牲一定的精準度為代價的。
Stream
我們都知道在redis中,我們可以通過list來實現(xiàn)消息隊列的功能,但是那只是簡單地實現(xiàn),它缺少持久化的功能,缺少數(shù)據(jù)復制的功能,而Steam就是為了解決這個問題而產(chǎn)生的。

當你覺得rabbitmq過于龐大的時候,那么redis的stream數(shù)據(jù)結(jié)構(gòu)可以很好地幫助你實現(xiàn)消息隊列的幾乎全部功能,但是如果你的項目夠大,還是請使用正常的消息隊列。
GEO
計算2個點的距離我們很容易計算出來,但是如果計算2個地理經(jīng)緯度坐標點的距離就會變得復雜,如果計算多個點呢?問題就會變得更加復雜,不過這些計算問題,在redis都可以通過GEO來簡單實現(xiàn)。

GEO主要是用于存儲指定的地理空間位置,可以將一個或多個經(jīng)度(longitude)、緯度(latitude)、位置名稱(member)添加到指定的 key 中。在使用地圖的時候,我們經(jīng)常需要計算得到當前位置一定范圍內(nèi)餐館,或者影院等建筑物的信息,而通過GEO我們就可以很方便地實現(xiàn)這個功能。
在redis中,通過georadiusbymember這個函數(shù),我們就可以方便地計算出周圍點的信息。
總結(jié)
相比較string,list,set,sort set, hash這5種結(jié)構(gòu),你會發(fā)現(xiàn)上面介紹的數(shù)據(jù)結(jié)構(gòu)使用場景很單一,或者說它們的存在主要是為了解決某些特定問題而存在的。
沒有哪種數(shù)據(jù)結(jié)構(gòu)更好的說法,每一種數(shù)據(jù)結(jié)構(gòu)都有它自己的應用場景,否則它也不會被創(chuàng)造出來。