Redis 特殊数据类型 :Geospatial、Hyperloglog、Bitmap
文章目錄
- Geospatial(地理空間)
- 介紹
- 用法
- Hyperloglog(基數統計)
- 介紹
- 用法
- Bitmap(位圖)
- 介紹
- 用法
Geospatial(地理空間)
在使用一些小程序的時候,里面通常都會通過定位使用者的位置,來顯示附近的人、外賣距離、剩余路徑等功能,在Redis3.2中也引入了推算地理信息的數據結構,即Geospatial
介紹
把某個具體的位置信息(經度,緯度,名稱)添加到指定的key中,數據將會用一個sorted set存儲,以便稍后能使用 GEORADIUS和 GEORADIUSBYMEMBER命令來根據半徑來查詢位置信息。
這個命令(指GEOADD)的參數使用標準的x,y形式,所以經度(longitude)必須放在緯度(latitude)之前,對于可被索引的坐標位置是有一定限制條件的:非常靠近極點的位置是不能被索引的, 在EPSG:900913 / EPSG:3785 / OSGEO:41001指定如下:
- 有效的經度是-180度到180度
- 有效的緯度是-85.05112878度到85.05112878度
上面是官方文檔的描述,其實Geo并沒有我們想象中的復雜,它的本質就是一個Zset,通過將坐標以Geohash的方式進行處理,將經度緯度錯位后形成一個52位整數,所以我們同樣能夠使用Zset提供的接口來操作Geo。
用法
| GEOADD key 經度 緯度 地點名稱 | 將指定的地理空間位置(經度、緯度、名稱)添加到指定的key中 |
| GEODIST key 地點1 地點2 | 返回兩個給定位置之間的距離 |
| GEOPOS key 地點 | 從key里返回所有給定位置元素的位置(經度和緯度) |
| GEOHASH key 地點 | 返回一個或多個位置元素的 Geohash 表示 |
| GEORADIUS key 經度 緯度 半徑 | 以給定的經緯度為中心, 找出某一半徑內的元素 |
| GEORADIUSBYMEMBER key 地點 半徑 | 找出位于指定范圍內的元素,中心點是由給定的位置元素決定 |
Zset的接口同樣適用于Geo,因此需要刪除、查詢全部時就可以使用Zset的接口。
下面示范一下這些命令的使用方式
# 為了方便示范,下面加入一些城市的地理信息——GEOADD 127.0.0.1:6379> GEOADD CHINA 108.94683 34.29296 "xian" (integer) 1 127.0.0.1:6379> GEOADD CHINA 116.405285 39.904989 "beijing" (integer) 1 127.0.0.1:6379> GEOADD CHINA 121.472644 31.231706 "shanghai" (integer) 1 127.0.0.1:6379> GEOADD CHINA 113.280637 23.125178 "guangzhou" (integer) 1 127.0.0.1:6379> GEOADD CHINA 114.085947 22.547 "shenzhen" (integer) 1 127.0.0.1:6379> GEOADD CHINA 110.33119 20.031971 "hainan" (integer) 1# 獲取北京和上海的距離——GEODIST 127.0.0.1:6379> GEODIST CHINA beijing shanghai km "1067.5980"# 獲取西安的坐標——GEOPOS 127.0.0.1:6379> GEOPOS CHINA xian 1) 1) "108.94683212041854858"2) "34.29296115814533863"# 以經度120 緯度35位置為中心,獲取半徑1000千米內的城市——GEORADIUS 127.0.0.1:6379> GEORADIUS CHINA 120 35 1000 km 1) "beijing" 2) "shanghai"# 獲取在廣州半徑500千米內的城市——GEORADIUSBYMEMBER 127.0.0.1:6379> GEORADIUSBYMEMBER CHINA guangzhou 500 km 1) "shenzhen" 2) "guangzhou" 3) "hainan"# 將廣州和深圳的坐標轉換為11為的GEO哈希值——GEOHASH 127.0.0.1:6379> GEOHASH CHINA guangzhou shenzhen 1) "ws0e9cb3yj0" 2) "ws10k0dcg10"Hyperloglog(基數統計)
在我們為網站統計訪問量、日活量時,由于我們統計的是用戶數量而非訪問次數,因此即使一個用戶多次訪問也只會統計一次,這種不重復的數據通常被稱為基數。
在傳統的做法中,我們通常會采用set來保存用戶的ID來進行計數,因為其本身存在著去重的功能,但是由于我們所需要的是對用戶進行計數,如果通過將所有用戶的ID保存的方法來完成,當用戶量大的時候就會對內存產生巨大的壓力,并且效率也大大降低。
為了解決這個問題,Redis在2.8.9版本添加了HyperLogLog結構。
介紹
Redis HyperLogLog是用來做基數統計的算法,HyperLogLog的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定的、并且是很小的。
在Redis 里面,每個HyperLogLog鍵只需要花費12KB內存,就可以計算接近2^64個不同元素的基數。這和計算基數時,元素越多耗費內存就越多的集合形成鮮明對比。
但是,由于HyperLogLog使用的是概率算法,通過存儲元素的hash值的第一個1的位置,來計算元素數量,所以HyperLogLog 不會存儲元素本身,在數據量大的時候也可能會存在一定的誤差。但是在基數統計這一方面,它的效果是其他結構無法比擬的。
用法
| PFADD key value | 添加指定的值到Hyperloglog中 |
| PFCONUT key | 返回給定Hyperloglog的基數估算值 |
| PFMERGE destkey sourcekey | 將目標Hyperloglog合并到源Hyperloglog中 |
使用示范
127.0.0.1:6379> PFADD NUMS1 1 2 3 4 #向NUMS1插入1-4 (integer) 1 127.0.0.1:6379> PFADD NUMS1 1 #數據已存在,不再插入 (integer) 0 127.0.0.1:6379> PFCOUNT NUMS1 #查看當前基數數量 (integer) 4127.0.0.1:6379> PFADD NUMS2 3 4 5 6 #向NUMS2插入3-6 (integer) 1 127.0.0.1:6379> PFMERGE NUMS1 NUMS2 #將NUMS2合并到NUMS1中 OK 127.0.0.1:6379> PFCOUNT NUMS1 #此時NUMS1中記錄了1-6,六個元素 (integer) 6Bitmap(位圖)
介紹
位圖其實就是哈希的變形,他通過哈希映射來處理數據,位圖本身并不存儲數據,而是存儲標記。通過一個比特位,即0/1來標記一個數據的兩種狀態
位圖通常情況下用在數據量龐大,且數據不重復的情景下標記某個數據的兩種狀態。 我們可以使用位圖來記錄當前用戶的登陸情況、或者實現打卡、簽到等功能。
用法
| GETBIT key offset value(0/1) | 設置Bitmap中偏移量為offset的位置的值 |
| SETBIT key offset value | 返回Bitmap中偏移量為offset的位置的值 |
| BITCOUNT key | 計算位圖中有多少個1 |
總結
以上是生活随笔為你收集整理的Redis 特殊数据类型 :Geospatial、Hyperloglog、Bitmap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx 反向代理、动静分离、负载均衡
- 下一篇: Redis 过期键删除策略、内存淘汰机制