Redis數(shù)據(jù)結(jié)構(gòu)實(shí)戰(zhàn)演練,看看微博、微信、購(gòu)物車(chē)、抽獎(jiǎng)小程序是如何使用的?

大家都知道,現(xiàn)在只要是個(gè)系統(tǒng)就會(huì)有緩存的存在,而且?guī)缀跛械南到y(tǒng)都離不開(kāi)Redis,可見(jiàn)Redis在現(xiàn)在系統(tǒng)的重要性。

所以,今天我們就來(lái)聊一下Redis,當(dāng)然主要聊聊Redis在不同業(yè)務(wù)場(chǎng)景下的使用。

接下來(lái),我們先從緩存的世界開(kāi)始,一步步揭開(kāi)Redis的神秘面紗。

1. 緩存發(fā)展史&緩存分類(lèi)

1.1 大型網(wǎng)站中緩存的使用

file

訪(fǎng)問(wèn)量越大,響應(yīng)力越差,用戶(hù)體驗(yàn)越差

引入緩存、示意圖如下:

file

高性能

假如用戶(hù)第一次訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)中的某些數(shù)據(jù)的話(huà),這個(gè)過(guò)程是比較慢,畢竟是從硬盤(pán)中讀取的。但是,如果說(shuō),用戶(hù)訪(fǎng)問(wèn)的數(shù)據(jù)屬于高頻數(shù)據(jù)并且不會(huì)經(jīng)常改變的話(huà),那么我們就可以很放心地將該用戶(hù)訪(fǎng)問(wèn)的數(shù)據(jù)存在緩存中。

這樣有什么好處呢? 那就是保證用戶(hù)下一次再訪(fǎng)問(wèn)這些數(shù)據(jù)的時(shí)候就可以直接從緩存中獲取了。操作緩存就是直接操作內(nèi)存,所以速度相當(dāng)快。

不過(guò),要保持?jǐn)?shù)據(jù)庫(kù)和緩存中的數(shù)據(jù)的一致性。 如果數(shù)據(jù)庫(kù)中的對(duì)應(yīng)數(shù)據(jù)改變的之后,同步改變緩存中相應(yīng)的數(shù)據(jù)即可!

高并發(fā):

一般像 MySQL 這類(lèi)的數(shù)據(jù)庫(kù)的 QPS 大概都在 1w 左右(4 核 8g) ,但是使用 Redis 緩存之后很容易達(dá)到 10w+,甚至最高能達(dá)到 30w+(就單機(jī) redis 的情況,redis 集群的話(huà)會(huì)更高)。

QPS(Query Per Second):服務(wù)器每秒可以執(zhí)行的查詢(xún)次數(shù);

所以,直接操作緩存能夠承受的數(shù)據(jù)庫(kù)請(qǐng)求數(shù)量是遠(yuǎn)遠(yuǎn)大于直接訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的,所以我們可以考慮把數(shù)據(jù)庫(kù)中的部分?jǐn)?shù)據(jù)轉(zhuǎn)移到緩存中去,這樣用戶(hù)的一部分請(qǐng)求會(huì)直接到緩存這里而不用經(jīng)過(guò)數(shù)據(jù)庫(kù)。進(jìn)而,我們也就提高的系統(tǒng)整體的并發(fā)。

1.2 常見(jiàn)緩存的分類(lèi)

分布式緩存

分布式緩存主要解決的是單機(jī)緩存的容量受服務(wù)器限制并且無(wú)法保存通用的信息。因?yàn)椋镜鼐彺嬷辉诋?dāng)前服務(wù)里有效,比如如果你部署了兩個(gè)相同的服務(wù),他們兩者之間的緩存數(shù)據(jù)是無(wú)法共同的。

具有緩存功能的中間件:Redis、Memcache、Tair(阿里 、美團(tuán))等等

1.3 分布式緩存選型方案對(duì)比

Memcache和Redis區(qū)別

共同點(diǎn)

  1. 都是基于內(nèi)存的數(shù)據(jù)庫(kù),一般都用來(lái)當(dāng)做緩存使用。
  2. 都有過(guò)期策略。
  3. 兩者的性能都非常高。

區(qū)別

  1. Redis 支持更豐富的數(shù)據(jù)類(lèi)型(支持更復(fù)雜的應(yīng)用場(chǎng)景)。Redis 不僅僅支持簡(jiǎn)單的 k/v 類(lèi)型的數(shù)據(jù),同時(shí)還提供 list,set,zset,hash 等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。Memcached 只支持最簡(jiǎn)單的 k/v 數(shù)據(jù)類(lèi)型。
  2. Redis 支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤(pán)中,重啟的時(shí)候可以再次加載進(jìn)行使用,而 Memecache 把數(shù)據(jù)全部存在內(nèi)存之中。
  3. Redis 有災(zāi)難恢復(fù)機(jī)制。 因?yàn)榭梢园丫彺嬷械臄?shù)據(jù)持久化到磁盤(pán)上。
  4. Memcached 沒(méi)有原生的集群模式,需要依靠客戶(hù)端來(lái)實(shí)現(xiàn)往集群中分片寫(xiě)入數(shù)據(jù);但是 Redis 目前是原生支持 cluster 模式的.
  5. Memcached 是多線(xiàn)程,非阻塞 IO 復(fù)用的網(wǎng)絡(luò)模型;Redis 使用單線(xiàn)程的多路 IO 復(fù)用模型。 (Redis 6.0 引入了多線(xiàn)程 IO )

相信看了上面的對(duì)比之后,我們已經(jīng)沒(méi)有什么理由可以選擇使用 Memcached 來(lái)作為自己項(xiàng)目的分布式緩存了。

2. Redis概述&安裝配置

2.1 概述

官網(wǎng):https://redis.io

中文官網(wǎng)地址:http://www.redis.cn

file

簡(jiǎn)單來(lái)說(shuō) Redis 就是一個(gè)使用 C 語(yǔ)言開(kāi)發(fā)的數(shù)據(jù)庫(kù),不過(guò)與傳統(tǒng)數(shù)據(jù)庫(kù)不同的是 Redis 的數(shù)據(jù)是存在內(nèi)存中的 ,也就是它是內(nèi)存數(shù)據(jù)庫(kù),所以讀寫(xiě)速度非常快,因此 Redis 被廣泛應(yīng)用于緩存方向。

另外,Redis 除了做緩存之外,Redis 也經(jīng)常用來(lái)做分布式鎖,甚至是消息隊(duì)列。

Redis 提供了多種數(shù)據(jù)類(lèi)型來(lái)支持不同的業(yè)務(wù)場(chǎng)景。Redis 還支持事務(wù) 、持久化、Lua 腳本、多種集群方案。

Redis應(yīng)用場(chǎng)景

  • 緩存使用,減輕DB壓力
  • DB使用,用于臨時(shí)存儲(chǔ)數(shù)據(jù)(字典表,購(gòu)買(mǎi)記錄)
  • 解決分布式場(chǎng)景下Session分離問(wèn)題(登錄信息)
  • 任務(wù)隊(duì)列(秒殺、搶紅包等等) 樂(lè)觀(guān)鎖
  • 應(yīng)用排行榜 zset
  • 簽到 bitmap
  • 分布式鎖
  • 冷熱數(shù)據(jù)交換

2.3 安裝&配置

官網(wǎng):https://redis.io/download

file

Redis沒(méi)有官方的windows版本,所以建議在linux系統(tǒng)上去運(yùn)行

選擇下載穩(wěn)定版本、不穩(wěn)定版本可以嘗鮮、但是不推薦在生產(chǎn)環(huán)境中使用

安裝

第一步:安裝 C 語(yǔ)言需要的 GCC 環(huán)境

yum install -y gcc-c++
yum install -y wget

第二步:下載并解壓縮 Redis 源碼壓縮包

# 下載
wget https://download.redis.io/releases/redis-6.2.4.tar.gz
mkdir /usr/local/redis
    tar -zxvf redis-6.2.4.tar.gz -C /usr/local/redis
file

第三步:編譯 Redis 源碼,進(jìn)入 redis-6.2.4 目錄,執(zhí)行編譯命令,進(jìn)行安裝

cd  /usr/local/redis/redis-6.2.4/src
make && make install

執(zhí)行完畢后安裝成功!

啟動(dòng)

前端啟動(dòng)
  • 啟動(dòng)命令: redis-server ,直接運(yùn)行 bin/redis-server 將以前端模式啟動(dòng)
  • 關(guān)閉命令: ctrl+c
  • 啟動(dòng)缺點(diǎn):客戶(hù)端窗口關(guān)閉則 redis-server 程序結(jié)束,不推薦使用此方法
  • 啟動(dòng)圖例:
file
后端啟動(dòng)(守護(hù)進(jìn)程啟動(dòng))
  • 第一步:拷貝 redis-6.2.4/redis.conf 配置文件到 Redis 安裝目錄的 bin 目錄
cp redis.conf /usr/local/redis
  • 第二步:修改 redis.conf
vim redis.conf
  • 第三步:修改 redis.conf

(1)修改daemonize no ---> daemonize yes,目的是為了讓redis啟動(dòng)在linux后臺(tái)運(yùn)行

file

(2)修改redis的工作目錄:(名稱(chēng)隨意)

file
  • 第四步:?jiǎn)?dòng)服務(wù)
.redis-server redis.conf
file

查看進(jìn)程

file
  • 后端啟動(dòng)的關(guān)閉方式
.redis-cli shutdown

命令說(shuō)明

redis-server :?jiǎn)?dòng) redis 服務(wù)

redis-cli :進(jìn)入 redis 命令客戶(hù)端

redis-benchmark : 性能測(cè)試的工具

redis-check-aof : aof 文件進(jìn)行檢查的工具

redis-check-dump : rdb 文件進(jìn)行檢查的工具

redis-sentinel : 啟動(dòng)哨兵監(jiān)控服務(wù)

Redis命令行客戶(hù)端

  • 命令格式
.redis-cli -h 127.0.0.1 -p 6379
  • 參數(shù)說(shuō)明
-h:redis服務(wù)器的ip地址
-p:redis實(shí)例的端口號(hào)
  • 默認(rèn)方式:如果不指定主機(jī)和端口也可以 默認(rèn)主機(jī)地址是127.0.0.1 默認(rèn)端口是6379
.redis-cli

2.4 ui

命令行已經(jīng)足夠強(qiáng)大,尤其是高版本,強(qiáng)大到懷疑人生

但是!它并不友好,業(yè)界有很多ui可供使用,典型的:Another Redis Desktop Manager

1)開(kāi)源

源碼地址:https://gitee.com/qishibo/AnotherRedisDesktopManager

編譯包下載:https://github.com/qishibo/AnotherRedisDesktopManager/releases

2)支持多平臺(tái)

Windows

Linux

Mac

3)基本使用

創(chuàng)建連接:

file

主頁(yè)監(jiān)控:

file

基本操作:

file

命令行:

file

3. 數(shù)據(jù)類(lèi)型選擇&應(yīng)用場(chǎng)景

file

Redis的Key的設(shè)計(jì)

1、key名設(shè)計(jì)

可讀性和可管理性

以業(yè)務(wù)名(或數(shù)據(jù)庫(kù)名)為前綴(防止key沖突),用冒號(hào)分隔,比如 業(yè)務(wù)名:表名:id

file

簡(jiǎn)潔性

保證語(yǔ)義的前提下,控制key的長(zhǎng)度,當(dāng)key較多時(shí),內(nèi)存占用也不容忽視,例如:

file

不要包含特殊字符

反例:包含空格、換行、單雙引號(hào)以及其他轉(zhuǎn)義字符

string字符串類(lèi)型

  1. 介紹 :string 數(shù)據(jù)結(jié)構(gòu)是簡(jiǎn)單的 key-value 類(lèi)型。雖然 Redis 是用 C 語(yǔ)言寫(xiě)的,但是 Redis 并沒(méi)有使用 C 的字符串表示,而是自己構(gòu)建了一種 簡(jiǎn)單動(dòng)態(tài)字符串(simple dynamic string,SDS)。相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本數(shù)據(jù)還可以保存二進(jìn)制數(shù)據(jù),并且獲取字符串長(zhǎng)度復(fù)雜度為 O(1)(C 字符串為 O(N)),除此之外,Redis 的 SDS API 是安全的,不會(huì)造成緩沖區(qū)溢出。
  2. 常用命令: set,get,strlen,exists,decr,incr,setex 等等。
  3. 應(yīng)用場(chǎng)景 :一般常用在需要計(jì)數(shù)的場(chǎng)景,比如用戶(hù)的訪(fǎng)問(wèn)次數(shù)、熱點(diǎn)文章的點(diǎn)贊轉(zhuǎn)發(fā)數(shù)量等等。
  • 單值緩存

    SET <font color='red'>key </font> <font color='blue'>value</font>

    GET <font color='red'>key </font>


  • 對(duì)象緩存

    MSET user:1:name zimu user:1:balance 1888

    MGET user:1:name user:1:balance

file

  • 分布式鎖(「SET if Not eXists」)

    SETNX <font color='red'>product:10001</font> true // 返回1代表獲取鎖成功

    SETNX <font color='red'>product:10001</font> false // 返回0代表獲取鎖失敗

    .......執(zhí)行業(yè)務(wù)操作

    DEL <font color='red'>product:10001</font> // 執(zhí)行完業(yè)務(wù) 釋放鎖

    SET <font color='red'>product:10001</font> true ex 10 nx // 防止程序意外終止導(dǎo)致死鎖


  • 計(jì)數(shù)器

    INCR article:readcount:101

file

hash類(lèi)型(散列表)

file
  1. 介紹 :hash 類(lèi)似于 JDK1.8 前的 HashMap,內(nèi)部實(shí)現(xiàn)也差不多(數(shù)組 + 鏈表)。不過(guò),Redis 的 hash 做了更多優(yōu)化。另外,hash 是一個(gè) string 類(lèi)型的 field 和 value 的映射表,特別適合用于存儲(chǔ)對(duì)象,后續(xù)操作的時(shí)候,你可以直接僅僅修改這個(gè)對(duì)象中的某個(gè)字段的值。 比如我們可以 hash 數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)用戶(hù)信息,商品信息等等。
  2. 常用命令: hset,hmset,hexists,hget,hgetall,hkeys,hvals 等。
  3. 應(yīng)用場(chǎng)景: 系統(tǒng)中對(duì)象數(shù)據(jù)的存儲(chǔ)。
  • 對(duì)象緩存

    HMSET user {userId}:username zhangfei {userId}:password 123456

    HMSET user 1:username zhangfei 1:password 123456

    HMGET user 1:username 1:password

  • 電商購(gòu)物車(chē)
file
  • 購(gòu)物車(chē)操作

    1)添加商品 ---> hset cart:1001 10088 1

    1. 增加數(shù)量 ---> hincrby cart:1001 10088 1

    3) 商品總數(shù) ---> hlen cart:1001

    4) 刪除商品---> hdel cart:1001 10088

    5)獲取購(gòu)物車(chē)所有商品---> hgetall cart:1001

優(yōu)點(diǎn):

1)同類(lèi)數(shù)據(jù)歸類(lèi)整合儲(chǔ)存,方便數(shù)據(jù)管理

2)相比String操作消耗內(nèi)存和cpu更小

3)相比String儲(chǔ)存 更節(jié)省空間

缺點(diǎn):

1)過(guò)期功能不能使用在field上,只能用在key上

2)Redis集群架構(gòu)下不適合大規(guī)模使用

file

list列表類(lèi)型

  1. 介紹list 即是 鏈表。鏈表是一種非常常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),特點(diǎn)是易于數(shù)據(jù)元素的插入和刪除并且且可以靈活調(diào)整鏈表長(zhǎng)度,但是鏈表的隨機(jī)訪(fǎng)問(wèn)困難。許多高級(jí)編程語(yǔ)言都內(nèi)置了鏈表的實(shí)現(xiàn)比如 Java 中的 LinkedList,但是 C 語(yǔ)言并沒(méi)有實(shí)現(xiàn)鏈表,所以 Redis 實(shí)現(xiàn)了自己的鏈表數(shù)據(jù)結(jié)構(gòu)。Redis 的 list 的實(shí)現(xiàn)為一個(gè) 雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過(guò)帶來(lái)了部分額外的內(nèi)存開(kāi)銷(xiāo)。
  2. 常用命令: rpush,lpop,lpush,rpop,lrange、llen 等。
  3. 應(yīng)用場(chǎng)景: 發(fā)布與訂閱或者說(shuō)消息隊(duì)列、慢查詢(xún)。
file
  • 常用數(shù)據(jù)結(jié)構(gòu)

    Stack(棧)= LPUSH(左邊放) + LPOP(左邊取) --> FILO

    Quece(隊(duì)列)= LPUSH(左邊放) + RPOP右邊取)

    BLocking MQ(阻塞隊(duì)列)= LPUSH(左邊放) + BRPOP(右邊阻塞取:沒(méi)有數(shù)據(jù)就阻塞!)

  • 微博、朋友圈、公眾號(hào)等,關(guān)注的文章列表展示
file

子慕老師關(guān)注了北京本地寶 ,京城美味君等公眾號(hào),這些訂閱號(hào)發(fā)布消息時(shí),通過(guò)推或拉的方式把消息LPUSH放入redis中屬于小明的list中。其中key為msg:{小明_ID}。當(dāng)小明要獲取大V們發(fā)的消息時(shí),使用LRANGE 命令從隊(duì)列中獲取指定個(gè)數(shù)的訂閱號(hào)信息

1)京城美味君發(fā)動(dòng)態(tài),消息ID為10001

LPUSH msg:{zimu-ID} 10001

2)北京本地寶發(fā)動(dòng)態(tài),消息ID為10002

LPUSH msg:{zimu-ID} 10002

3)查看最新訂閱號(hào)消息

LRANGE msg:{zimu-ID} 0 4

set集合類(lèi)型

  1. 介紹 : set 類(lèi)似于 Java 中的 HashSet 。Redis 中的 set 類(lèi)型是一種無(wú)序集合,集合中的元素沒(méi)有先后順序。當(dāng)你需要存儲(chǔ)一個(gè)列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時(shí),set 是一個(gè)很好的選擇,并且 set 提供了判斷某個(gè)成員是否在一個(gè) set 集合內(nèi)的重要接口,這個(gè)也是 list 所不能提供的。可以基于 set 輕易實(shí)現(xiàn)交集、并集、差集的操作。比如:你可以將一個(gè)用戶(hù)所有的關(guān)注人存在一個(gè)集合中,將其所有粉絲存在一個(gè)集合。Redis 可以非常方便的實(shí)現(xiàn)如共同關(guān)注、共同粉絲、共同喜好等功能。這個(gè)過(guò)程也就是求交集的過(guò)程。
  2. 常用命令: sadd,spop,smembers,sismember,scard,sinterstore,sunion 等。
  3. 應(yīng)用場(chǎng)景: 需要存放的數(shù)據(jù)不能重復(fù)以及需要獲取多個(gè)數(shù)據(jù)源交集和并集等場(chǎng)景
  • 微信抽獎(jiǎng)小程序
file

1)點(diǎn)擊 參與抽獎(jiǎng) 加入集合

SADD key {userID}

2)查看排行榜

SMEMBERS key

3)抽取count名中獎(jiǎng)?wù)?/p>

SRANDMEMBER key [count] / SPOP key [count]

  • 集合操作實(shí)現(xiàn)微博、微信關(guān)注模型
file

首先了解一下set的集合操作,假如有三個(gè)集合

file

交集為:SINTER set1 set2 set3 ==> { c }

并集為:SUNION set1 set2 set3 ==> { a,b,c,d,e }

差集為:SDIFF set1 set2 set3 ==> { a }

差集計(jì)算方式:set1 - (set2并set3) = {a、b、c} - {b、c、d、e} = {a} 只保留a中單獨(dú)存在的元素

共同關(guān)注A的人:可以用交集來(lái)實(shí)現(xiàn)
我可能認(rèn)識(shí)的人:可以使用差集來(lái)實(shí)現(xiàn),把我關(guān)注的人求差集

sortedset有序集合類(lèi)型

  1. 介紹: 和 set 相比,sorted set 增加了一個(gè)權(quán)重參數(shù) score,使得集合中的元素能夠按 score 進(jìn)行有序排列,還可以通過(guò) score 的范圍來(lái)獲取元素的列表。有點(diǎn)像是 Java 中 HashMap 和 TreeSet 的結(jié)合體。

  2. 常用命令: zadd,zcard,zscore,zrange,zrevrange,zrem 等。

  3. 應(yīng)用場(chǎng)景: 需要對(duì)數(shù)據(jù)根據(jù)某個(gè)權(quán)重進(jìn)行排序的場(chǎng)景。比如在直播系統(tǒng)中,實(shí)時(shí)排行信息包含直播間在線(xiàn)用戶(hù)列表,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息。

file
  • Zset集合操作實(shí)現(xiàn)排行榜
file
  1. 點(diǎn)擊新聞,為其分值+1

ZINCRBY hotNews:20210707 1 iphone13或有日落金玫瑰金

2)展示當(dāng)日排行前10

ZREVRANGE hotNews:20210707 0 ,9 WITHSCORES

bitmap位圖 類(lèi)型

  1. 介紹 : bitmap 存儲(chǔ)的是連續(xù)的二進(jìn)制數(shù)字(0 和 1),通過(guò) bitmap, 只需要一個(gè) bit 位來(lái)表示某個(gè)元素對(duì)應(yīng)的值或者狀態(tài),key 就是對(duì)應(yīng)元素本身 。我們知道 8 個(gè) bit 可以組成一個(gè) byte,所以 bitmap 本身會(huì)極大的節(jié)省儲(chǔ)存空間。
file
  1. 常用命令: setbitgetbitbitcountbitop

  2. 應(yīng)用場(chǎng)景: 適合需要保存狀態(tài)信息(比如是否簽到、是否登錄...)并需要進(jìn)一步對(duì)這些信息進(jìn)行分析的場(chǎng)景。比如用戶(hù)簽到情況、活躍用戶(hù)情況、用戶(hù)行為統(tǒng)計(jì)(比如是否點(diǎn)贊過(guò)某個(gè)視頻)。

# SETBIT 會(huì)返回之前位的值(默認(rèn)是 0)這里會(huì)生成 7 個(gè)位
127.0.0.1:6379> setbit mykey 7 1
(integer) 0
127.0.0.1:6379> setbit mykey 7 0
(integer) 1
127.0.0.1:6379> getbit mykey 7
(integer) 0
127.0.0.1:6379> setbit mykey 6 1
(integer) 0
127.0.0.1:6379> setbit mykey 8 1
(integer) 0
# 通過(guò) bitcount 統(tǒng)計(jì)被被設(shè)置為 1 的位的數(shù)量。
127.0.0.1:6379> bitcount mykey
(integer) 2Copy to clipboardErrorCopied

針對(duì)上面提到的一些場(chǎng)景,這里進(jìn)行進(jìn)一步說(shuō)明。

使用場(chǎng)景一:用戶(hù)行為分析 很多網(wǎng)站為了分析你的喜好,需要研究你點(diǎn)贊過(guò)的內(nèi)容。

# 記錄你喜歡過(guò) 001 號(hào)小姐姐
127.0.0.1:6379> setbit beauty_girl_001 uid 1

使用場(chǎng)景二:統(tǒng)計(jì)活躍用戶(hù)

面試題:現(xiàn)在系統(tǒng)有億級(jí)的活躍用戶(hù),為了增強(qiáng)用戶(hù)粘性,該如何實(shí)現(xiàn)簽到、日活統(tǒng)計(jì)?

使用時(shí)間作為 key,然后用戶(hù) ID 為 offset,如果當(dāng)日活躍過(guò)就設(shè)置為 1

那么我該如果計(jì)算某幾天/月/年的活躍用戶(hù)呢(暫且約定,統(tǒng)計(jì)時(shí)間內(nèi)只有有一天在線(xiàn)就稱(chēng)為活躍),有請(qǐng)下一個(gè) redis 的命令

# 對(duì)一個(gè)或多個(gè)保存二進(jìn)制位的字符串 key 進(jìn)行位元操作,并將結(jié)果保存到 destkey 上。
# BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 這四種操作中的任意一種參數(shù)
BITOP operation destkey key [key ...]

初始化數(shù)據(jù):

127.0.0.1:6379> setbit 20210308 1 1
(integer) 0
127.0.0.1:6379> setbit 20210308 2 1
(integer) 0
127.0.0.1:6379> setbit 20210309 1 1
(integer) 0

統(tǒng)計(jì) 20210308~20210309 總活躍用戶(hù)數(shù): 1

127.0.0.1:6379> bitop and desk1 20210308 20210309
(integer) 1
127.0.0.1:6379> bitcount desk1
(integer) 1

統(tǒng)計(jì) 20210308~20210309 在線(xiàn)活躍用戶(hù)數(shù): 2

127.0.0.1:6379> bitop or desk2 20210308 20210309
(integer) 1
127.0.0.1:6379> bitcount desk2
(integer) 2

geo地理位置類(lèi)型

概述

Redis 3.2 中增加了對(duì)GEO類(lèi)型的支持。GEO,Geographic,地理信息的縮寫(xiě)。該類(lèi)型,就是元素的2維坐標(biāo),在地圖上就是經(jīng)緯度。redis基于該類(lèi)型,提供了經(jīng)緯度設(shè)置,查詢(xún),范圍查詢(xún),距離查詢(xún),經(jīng)緯度Hash等常見(jiàn)操作

應(yīng)用場(chǎng)景:附近的人、搖一搖、附近的車(chē)、附近銀行站點(diǎn)查詢(xún)

file

環(huán)境要求

  1. redis版本需要3.2及以上
  2. 如果使用jedis操作redis,需要jedis版本為2.9及以上
  3. 如果使用spring data redis操作redis,需要spring data redis版本為1.8.0及以上

redis GEO常用命令

Tips:
在學(xué)習(xí)geo命令時(shí)會(huì)使用到經(jīng)緯度坐標(biāo)信息,可以在百度地圖的拾取坐標(biāo)系統(tǒng)中獲取測(cè)試坐標(biāo)信息,網(wǎng)址:http://api.map.baidu.com/lbsapi/getpoint/index.html

1. geoadd命令

為了進(jìn)行地理位置相關(guān)操作, 我們首先需要將具體的地理位置記錄起來(lái), 這一點(diǎn)可以通過(guò)執(zhí)行 geoadd 命令來(lái)完成, 該命令的基本格式如下:

GEOADD location-set longitude latitude name [longitude latitude name ...]

此命令用于添加位置信息到集合中

以下代碼展示了如何通過(guò) GEOADD 命令, 將武漢、襄陽(yáng)、宜昌、枝江、咸寧等數(shù)個(gè)湖北省的市添加到位置集合 hubeiCities 集合里面

此處添加武漢的坐標(biāo)信息到hubeiCities集合中

geoadd hubeiCities 114.32538 30.534535 wuhan

此處添加襄陽(yáng)、枝江、咸寧的坐標(biāo)信息到hubeiCities集合中

geoadd hubeiCities 112.161882 32.064505 xiangyang 111.305197 30.708127 yichang 111.583717 30.463363 zhijiang 114.295174 29.885892 xianning

2. geopos命令

此命令用于根據(jù)輸入的位置名稱(chēng)獲取位置的坐標(biāo)信息,基本語(yǔ)法如下

GEOPOS location-set name [name ...]

案例:查詢(xún)襄陽(yáng)市的位置信息

geopos hubeiCities xiangyang
--結(jié)果如下【1為經(jīng)度 2為緯度】
1) "112.16188341379165649"
2) "32.06450528704699821"

也可以一次查詢(xún)多個(gè)位置的經(jīng)緯度

geopos hubeiCities xiangyang wuhan
--襄陽(yáng)的經(jīng)緯度
1) 1) "112.16188341379165649"
   2) "32.06450528704699821"
--武漢的經(jīng)緯度
2) 1) "114.32538002729415894"
   2) "30.53453492166421057"

3. geodist命令

此命令用于計(jì)算兩個(gè)位置之間的距離,基本語(yǔ)法如下:

GEODIST location-set location-x location-y [unit]

可選參數(shù) unit 用于指定計(jì)算距離時(shí)的單位, 它的值可以是以下單位的其中一個(gè):

m 表示單位為米。
km 表示單位為千米。
mi 表示單位為英里。
ft 表示單位為英尺。

案例:分別以默認(rèn)距離單位和指定距離單位計(jì)算襄陽(yáng)和武漢的距離

--不指定距離單位
127.0.0.1:6381> geodist hubeiCities xiangyang wuhan
"266889.7642"
--指定距離單位km
127.0.0.1:6381> geodist hubeiCities xiangyang wuhan km
"266.8898"

4. georadius命令和georadiusbymember命令

這兩個(gè)命令都可以用于獲取指定范圍內(nèi)的元素,也即查找特定范圍之內(nèi)的其他存在的地點(diǎn)。比如找出地點(diǎn)A范圍200米之內(nèi)的所有地點(diǎn),找出地點(diǎn)B范圍50公里之內(nèi)的所有地點(diǎn)等等。

這兩個(gè)命令的作用一樣, 只是指定中心點(diǎn)的方式不同: georadius 使用用戶(hù)給定的經(jīng)緯度作為計(jì)算范圍時(shí)的中心點(diǎn), 而 georadiusbymember 則使用儲(chǔ)存在位置集合里面的某個(gè)地點(diǎn)作為中心點(diǎn)。

以下是這兩個(gè)命令的基本語(yǔ)法

GEORADIUS location-set longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]

GEORADIUSBYMEMBER location-set location radius m|km|ft|mi [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]

這兩個(gè)命令的各個(gè)參數(shù)的意義如下:

m|km|ft|mi 指定的是計(jì)算范圍時(shí)的單位;

如果給定了WITHCOORD,那么在返回匹配的位置時(shí)會(huì)將位置的經(jīng)緯度一并返回;

如果給定了WITHDIST , 那么在返回匹配的位置時(shí)會(huì)將位置與中心點(diǎn)之間的距離一并返回;

在默認(rèn)情況下, GEORADIUS 和 GEORADIUSBYMEMBER 的結(jié)果是未排序的, ASC 可以讓查找結(jié)果根據(jù)距離從近到遠(yuǎn)排序, 而 DESC 則可以讓查找結(jié)果根據(jù)從遠(yuǎn)到近排序;

COUNT參數(shù)用于指定要返回的結(jié)果數(shù)量。

下面通過(guò)案例分別演示georadius命令和georadiusbymember命令

GEORADIUS案例:
在hubeiCities位置集合中查找距離經(jīng)緯度為112.927076 28.235653(長(zhǎng)沙)500km以?xún)?nèi)的位置信息,查找結(jié)果中應(yīng)包含不超過(guò)5個(gè)位置的坐標(biāo)信息,距離信息,并按距離由近到遠(yuǎn)排序。
查詢(xún)代碼如下:

127.0.0.1:6381> georadius hubeiCities 112.927076 28.235653 500 km withcoord withdist asc count 5
-- 咸寧  距離目標(biāo)位置226.67公里  
1) 1) "xianning"
   2) "226.6716"
   3) 1) "114.29517298936843872"
      2) "29.88589217282589772"
-- 枝江  距離目標(biāo)位置279.91公里
2) 1) "zhijiang"
   2) "279.9154"
   3) 1) "111.58371716737747192"
      2) "30.46336248623112652"
-- 武漢  距離目標(biāo)位置289.38公里
3) 1) "wuhan"
   2) "289.3798"
   3) 1) "114.32538002729415894"
      2) "30.53453492166421057"
-- 宜昌  距離目標(biāo)位置316.68公里
4) 1) "yichang"
   2) "316.6777"
   3) 1) "111.30519658327102661"
      2) "30.70812783498269738"
-- 襄陽(yáng)  距離目標(biāo)位置432.18公里
5) 1) "xiangyang"
   2) "432.1767"
   3) 1) "112.16188341379165649"
      2) "32.06450528704699821"

GEORADIUSBYMEMBER案例:
在hubeiCities位置集合中查找距離襄陽(yáng)200km以?xún)?nèi)的位置信息【這里指定的目標(biāo)位置只能是hubeiCities中存在的位置,而不能指定位置坐標(biāo)】,查找結(jié)果中應(yīng)包含不超過(guò)2個(gè)位置的坐標(biāo)信息,距離信息,并按距離由遠(yuǎn)到近排序。
查詢(xún)代碼如下:

127.0.0.1:6381> georadiusbymember hubeiCities xiangyang 200 km withcoord withdist desc count 2
-- 枝江  距襄陽(yáng)186.38km
1) 1) "zhijiang"
   2) "186.3784"
   3) 1) "111.58371716737747192"
      2) "30.46336248623112652"
-- 宜昌  距襄陽(yáng)171.40km
2) 1) "yichang"
   2) "171.3950"
   3) 1) "111.30519658327102661"
      2) "30.70812783498269738"

好了,今天就先嘮到這里,真是越來(lái)越體會(huì)到了 碼字不易的深刻內(nèi)涵,一不小心,碼了6000+字,有點(diǎn)累了

大家如果覺(jué)得有幫助,就請(qǐng)給個(gè) 點(diǎn)贊、 評(píng)論、 轉(zhuǎn)發(fā),順手來(lái)個(gè)一鍵三連,哈哈哈

你們的支持是我最大的動(dòng)力。

加油 打工人!!!

往日文章,大家自行飲用。

往期干貨:

本文由育博學(xué)谷狂野架構(gòu)師發(fā)布
如果本文對(duì)您有幫助,歡迎關(guān)注和點(diǎn)贊;如果您有任何建議也可留言評(píng)論或私信,您的支持是我堅(jiān)持創(chuàng)作的動(dòng)力
轉(zhuǎn)載請(qǐng)注明出處!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容