Redis入門 - 數據類型:3種特殊類型詳解

Redis除了上文中5種基礎數據類型,還有三種特殊的數據類型,分別是 HyperLogLogs(基數統計), Bitmaps (位圖) 和 geospatial (地理位置)。@pdai

HyperLogLogs(基數統計)

Redis 2.8.9 版本更新了 Hyperloglog 數據結構!

  • 什麼是基數?

舉個例子,A = {1, 2, 3, 4, 5}, B = {3, 5, 6, 7, 9};那麼基數(不重複的元素)= 1, 2, 4, 6, 7, 9; (允許容錯,即可以接受一定誤差)

  • HyperLogLogs 基數統計用來解決什麼問題

這個結構可以非常省內存的去統計各種計數,比如註冊 IP 數、每日訪問 IP 數、頁面實時UV、在線用戶數,共同好友數等。

  • 它的優勢體現在哪

一個大型的網站,每天 IP 比如有 100 萬,粗算一個 IP 消耗 15 字節,那麼 100 萬個 IP 就是 15M。而 HyperLogLog 在 Redis 中每個鍵佔用的內容都是 12K,理論存儲近似接近 2^64 個值,不管存儲的內容是什麼,它一個基於基數估算的算法,只能比較準確的估算出基數,可以使用少量固定的內存去存儲並識別集合中的唯一元素。而且這個估算的基數並不一定準確,是一個帶有 0.81% 標準錯誤的近似值(對於可以接受一定容錯的業務場景,比如IP數統計,UV等,是可以忽略不計的)。

  • 相關命令使用
127.0.0.1:6379> pfadd key1 a b c d e f g h i	# 創建第一組元素
(integer) 1
127.0.0.1:6379> pfcount key1					# 統計元素的基數數量
(integer) 9
127.0.0.1:6379> pfadd key2 c j k l m e g a		# 創建第二組元素
(integer) 1
127.0.0.1:6379> pfcount key2
(integer) 8
127.0.0.1:6379> pfmerge key3 key1 key2			# 合併兩組:key1 key2 -> key3 並集
OK
127.0.0.1:6379> pfcount key3
(integer) 13

Bitmap (位存儲)

Bitmap 即位圖數據結構,都是操作二進制位來進行記錄,只有0 和 1 兩個狀態。

  • 用來解決什麼問題

比如:統計用戶信息,活躍,不活躍! 登錄,未登錄! 打卡,不打卡! 兩個狀態的,都可以使用 Bitmaps

如果存儲一年的打卡狀態需要多少內存呢? 365 天 = 365 bit 1字節 = 8bit 46 個字節左右!

  • 相關命令使用

使用bitmap 來記錄 週一到週日的打卡! 週一:1 週二:0 週三:0 週四:1 ......

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 1
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0

查看某一天是否有打卡!

127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 5
(integer) 0

統計操作,統計 打卡的天數!

127.0.0.1:6379> bitcount sign # 統計這周的打卡記錄,就可以看到是否有全勤!
(integer) 3

geospatial (地理位置)

Redis 的 Geo 在 Redis 3.2 版本就推出了! 這個功能可以推算地理位置的信息: 兩地之間的距離, 方圓幾裏的人

geoadd

添加地理位置

127.0.0.1:6379> geoadd china:city 118.76 32.04 manjing 112.55 37.86 taiyuan 123.43 41.80 shenyang
(integer) 3
127.0.0.1:6379> geoadd china:city 144.05 22.52 shengzhen 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 3

規則

兩級無法直接添加,我們一般會下載城市數據(這個網址可以查詢 GEO: http://www.jsons.cn/lngcode)!

  • 有效的經度從-180度到180度。
  • 有效的緯度從-85.05112878度到85.05112878度。
# 當座標位置超出上述指定範圍時,該命令將會返回一個錯誤。
127.0.0.1:6379> geoadd china:city 39.90 116.40 beijin
(error) ERR invalid longitude,latitude pair 39.900000,116.400000

geopos

獲取指定的成員的經度和緯度

127.0.0.1:6379> geopos china:city taiyuan manjing
1) 1) "112.54999905824661255"
   1) "37.86000073876942196"
2) 1) "118.75999957323074341"
   1) "32.03999960287850968"

獲得當前定位, 一定是一個座標值!

geodist

如果不存在, 返回空

單位如下

  • m
  • km
  • mi 英里
  • ft 英尺
127.0.0.1:6379> geodist china:city taiyuan shenyang m
"1026439.1070"
127.0.0.1:6379> geodist china:city taiyuan shenyang km
"1026.4391"

georadius

附近的人 ==> 獲得所有附近的人的地址, 定位, 通過半徑來查詢

獲得指定數量的人

127.0.0.1:6379> georadius china:city 110 30 1000 km			以 100,30 這個座標爲中心, 尋找半徑爲1000km的城市
1) "xian"
2) "hangzhou"
3) "manjing"
4) "taiyuan"
127.0.0.1:6379> georadius china:city 110 30 500 km
1) "xian"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist
1) 1) "xian"
   2) "483.8340"
127.0.0.1:6379> georadius china:city 110 30 1000 km withcoord withdist count 2
1) 1) "xian"
   2) "483.8340"
   3) 1) "108.96000176668167114"
      2) "34.25999964418929977"
2) 1) "manjing"
   2) "864.9816"
   3) 1) "118.75999957323074341"
      2) "32.03999960287850968"

參數 key 經度 緯度 半徑 單位 [顯示結果的經度和緯度] [顯示結果的距離] [顯示的結果的數量]

georadiusbymember

顯示與指定成員一定半徑範圍內的其他成員

127.0.0.1:6379> georadiusbymember china:city taiyuan 1000 km
1) "manjing"
2) "taiyuan"
3) "xian"
127.0.0.1:6379> georadiusbymember china:city taiyuan 1000 km withcoord withdist count 2
1) 1) "taiyuan"
   2) "0.0000"
   3) 1) "112.54999905824661255"
      2) "37.86000073876942196"
2) 1) "xian"
   2) "514.2264"
   3) 1) "108.96000176668167114"
      2) "34.25999964418929977"

參數與 georadius 一樣

geohash(較少使用)

該命令返回11個字符的hash字符串

127.0.0.1:6379> geohash china:city taiyuan shenyang
1) "ww8p3hhqmp0"
2) "wxrvb9qyxk0"

將二維的經緯度轉換爲一維的字符串, 如果兩個字符串越接近, 則距離越近

底層

geo底層的實現原理實際上就是Zset, 我們可以通過Zset命令來操作geo

127.0.0.1:6379> type china:city
zset

查看全部元素 刪除指定的元素

127.0.0.1:6379> zrange china:city 0 -1 withscores
 1) "xian"
 2) "4040115445396757"
 3) "hangzhou"
 4) "4054133997236782"
 5) "manjing"
 6) "4066006694128997"
 7) "taiyuan"
 8) "4068216047500484"
 9) "shenyang"
1)  "4072519231994779"
2)  "shengzhen"
3)  "4154606886655324"
127.0.0.1:6379> zrem china:city manjing
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "xian"
2) "hangzhou"
3) "taiyuan"
4) "shenyang"
5) "shengzhen"

參考文章

知識體系

知識體系

相關文章

首先,我們通過學習Redis的概念基礎,瞭解它適用的場景。

  • Redis入門 - Redis概念和基礎
    • Redis是一種支持key-value等多種數據結構的存儲系統。可用於緩存,事件發佈或訂閱,高速隊列等場景。支持網絡,提供字符串,哈希,列表,隊列,集合結構直接存取,基於內存,可持久化。

其次,這些適用場景都是基於Redis支持的數據類型的,所以我們需要學習它支持的數據類型;同時在redis優化中還需要對底層數據結構瞭解,所以也需要了解一些底層數據結構的設計和實現。

再者,需要學習Redis支持的核心功能,包括持久化,消息,事務,高可用;高可用方面包括,主從,哨兵等;高可拓展方面,比如 分片機制等。

  • Redis進階 - 持久化:RDB和AOF機制詳解
    • 爲了防止數據丟失以及服務重啓時能夠恢復數據,Redis支持數據的持久化,主要分爲兩種方式,分別是RDB和AOF; 當然實際場景下還會使用這兩種的混合模式。
  • Redis進階 - 消息傳遞:發佈訂閱模式詳解
    • Redis 發佈訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。
  • Redis進階 - 事件:Redis事件機制詳解
    • Redis 採用事件驅動機制來處理大量的網絡IO。它並沒有使用 libevent 或者 libev 這樣的成熟開源方案,而是自己實現一個非常簡潔的事件驅動庫 ae_event。
  • Redis進階 - 事務:Redis事務詳解
    • Redis 事務的本質是一組命令的集合。事務支持一次執行多個命令,一個事務中所有命令都會被序列化。在事務執行過程,會按照順序串行化執行隊列中的命令,其他客戶端提交的命令請求不會插入到事務執行命令序列中。
  • Redis進階 - 高可用:主從複製詳解
    • 我們知道要避免單點故障,即保證高可用,便需要冗餘(副本)方式提供集羣服務。而Redis 提供了主從庫模式,以保證數據副本的一致,主從庫之間採用的是讀寫分離的方式。本文主要闡述Redis的主從複製。
  • Redis進階 - 高可用:哨兵機制(Redis Sentinel)詳解
    • 在上文主從複製的基礎上,如果注節點出現故障該怎麼辦呢? 在 Redis 主從集羣中,哨兵機制是實現主從庫自動切換的關鍵機制,它有效地解決了主從複製模式下故障轉移的問題。
  • Redis進階 - 高可拓展:分片技術(Redis Cluster)詳解
    • 前面兩篇文章,主從複製和哨兵機制保障了高可用,就讀寫分離而言雖然slave節點來擴展主從的讀併發能力,但是寫能力和存儲能力是無法進行擴展的,就只能是master節點能夠承載的上限。如果面對海量數據那麼必然需要構建master(主節點分片)之間的集羣,同時必然需要吸收高可用(主從複製和哨兵機制)能力,即每個master分片節點還需要有slave節點,這是分佈式系統中典型的縱向擴展(集羣的分片技術)的體現;所以在Redis 3.0版本中對應的設計就是Redis Cluster。

最後,就是具體的實踐以及實踐中遇到的問題和解決方法了:在不同版本中有不同特性,所以還需要了解版本;以及性能優化,大廠實踐等。

  • Redis進階 - 緩存問題:一致性, 穿擊, 穿透, 雪崩, 污染等
    • Redis最常用的一個場景就是作爲緩存,本文主要探討作爲緩存,在實踐中可能會有哪些問題?比如一致性, 穿擊, 穿透, 雪崩, 污染等
  • Redis進階 - 版本特性: Redis4.0、5.0、6.0特性整理
    • 在學習Redis知識體系時,我們難免會需要查看版本實現之間的差異,本文主要整理Redis較爲新的版本的特性。
  • Redis進階 - 運維監控:Redis的監控詳解
    • Redis實戰中包含開發,集羣 和 運維,Redis用的好不好,如何讓它更好,這是運維要做的;本文主要在 Redis自身狀態及命令可視化監控工具,以及Redis監控體系等方面幫助你構建對redis運維/監控體系的認知,它是性能優化的前提。
  • Redis進階 - 性能調優:Redis性能調優詳解
    • Redis 的性能問題,涉及到的知識點非常廣,幾乎涵蓋了 CPU、內存、網絡、甚至磁盤的方方面面;同時還需要對上文中一些基礎或底層有詳細的瞭解。針對Redis的性能調優,這裏整理分享一篇水滴與銀彈(公衆號)的文章,這篇文章可以幫助你構築Redis性能調優的知識體系。
  • Redis大廠經驗 - 微博:萬億級日訪問量下,Redis在微博的9年優化歷程
    • 再分享一篇微博使用redis的經驗的文章,因爲Redis在微博內部分佈在各個應用場景,比如像現在春晚必爭的“紅包飛”活動,還有像粉絲數、用戶數、閱讀數、轉評贊、評論蓋樓、廣告推薦、負反饋、音樂榜單等等都有用到Redis;我們可以通過大廠使用redis的經驗來強化對redis使用上的認知。

學習資料

除此之外,我還推薦你看下 極客時間 《Redis核心技術與實戰》(作者:蔣德鈞)的相關內容,它是我看到的爲數不多的含有實戰經驗比較多的專欄,部分文章中圖片也來源於這個系列。

本篇文章由一文多發平臺ArtiPub自動發佈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章