日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【缓存中间件】redis 支持的数据类型

發(fā)布時(shí)間:2024/1/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【缓存中间件】redis 支持的数据类型 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 前言
  • 一、字符串
  • 二、哈希
  • 三、 列表
  • 四、集合
  • 五、有序集合
  • 六、位圖 Redis Bitmap
  • 七、基數(shù)統(tǒng)計(jì) HyperLogLog
  • 八、Geo 地理位置
  • 九、Streams 流
  • 應(yīng)用場景總結(jié)

前言

Redis 數(shù)據(jù)庫支持的數(shù)據(jù)類型。

  • 最基本的5種
    • 字符串(string)
    • 哈希(hash)
    • 列表(list)
    • 集合(set)
    • 有序集合(sorted set)
  • 新版本
    • 位圖 BitMap(2.2)
    • 基數(shù)統(tǒng)計(jì) ( HyperLogLog) # 2.8.9新增
    • Geo:地理位置信息儲(chǔ)存起來, 并對(duì)這些信息進(jìn)行操作 # 3.2新增
    • 流(Stream)# 5.0新增

一、字符串

String 是一組字節(jié)。在 Redis 數(shù)據(jù)庫中,字符串是二進(jìn)制安全的。這意味著它們具有已知長度,并且不受任何特殊終止字符的影響。可以在一個(gè)字符串中存儲(chǔ)最多 512 兆字節(jié)的內(nèi)容。


使用 SET 命令在 name 鍵中存儲(chǔ)字符串 redis.com.cn,然后使用 GET 命令查詢 name。

SET name "abc" OK GET name "abc"

在上面的例子中,SET 和 GET 是 Redis 命令,name 是 Redis 中使用的 key,abc 是存儲(chǔ)在 Redis 中的字符串值。

二、哈希

哈希是鍵值對(duì)的集合。在 Redis 中,哈希是字符串字段和字符串值之間的映射。因此,它們適合表示對(duì)象。


讓我們存儲(chǔ)一個(gè)用戶的對(duì)象,其中包含用戶的基本信息。

HMSET user:1 username ajeet password javatpoint alexa 2000 OK HGETALL user:1 "username" "ajeet" "password" "javatpoint" "alexa" "2000"

這里,HMSET 和 HGETALL 是 Redis 的命令,而 user:1 是鍵。

每個(gè)哈希可以存儲(chǔ)多達(dá) 2的32– 次方 1 個(gè)字段-值對(duì)。

三、 列表

Redis 列表定義為字符串列表,按插入順序排序。可以將元素添加到 Redis 列表的頭部或尾部。

lpush javatpoint java (integer) 1 lpush javatpoint java (integer) 1 lpush javatpoint java (integer) 1 lpush javatpoint java (integer) 1 lrange javatpoint 0 10 "cassandra" "mongodb" "sql" "java"

列表的最大長度為 232 – 1 個(gè)元素(超過 40 億個(gè)元素)。

四、集合

集合(set)是 Redis 數(shù)據(jù)庫中的無序字符串集合。在 Redis 中,添加,刪除和查找的時(shí)間復(fù)雜度是 O(1)。

sadd tutoriallist redis (integer) 1 redis 127.0.0.1:6379> sadd tutoriallist sql (integer) 1 redis 127.0.0.1:6379> sadd tutoriallist postgresql (integer) 1 redis 127.0.0.1:6379> sadd tutoriallist postgresql (integer) 0 redis 127.0.0.1:6379> sadd tutoriallist postgresql (integer) 0 redis 127.0.0.1:6379> smembers tutoriallist 1) "redis" 2) "postgresql" 3) "sql"

在上面的示例中,您可以看到 postgresql 被添加了三次,但由于該集的唯一屬性,它只添加一次。

集合中的最大成員數(shù)為 232-1 個(gè)元素(超過 40 億個(gè)元素)。

五、有序集合

Redis 有序集合類似于 Redis 集合,也是一組非重復(fù)的字符串集合。但是,排序集的每個(gè)成員都與一個(gè)分?jǐn)?shù)相關(guān)聯(lián),該分?jǐn)?shù)用于獲取從最小到最高分?jǐn)?shù)的有序排序集。雖然成員是獨(dú)特的,但可以重復(fù)分?jǐn)?shù)。

redis 127.0.0.1:6379> zadd tutoriallist 0 redis (integer) 1 redis 127.0.0.1:6379> zadd tutoriallist 0 sql (integer) 1 redis 127.0.0.1:6379> zadd tutoriallist 0 postgresql (integer) 1 redis 127.0.0.1:6379> zadd tutoriallist 0 postgresql (integer) 0 redis 127.0.0.1:6379> zadd tutoriallist 0 postgresql (integer) 0 redis 127.0.0.1:6379> ZRANGEBYSCORE tutoriallist 0 10 1) "postgresql" 2) "redis" 3) "sql"

六、位圖 Redis Bitmap

Redis Bitmap 通過類似 map 結(jié)構(gòu)存放 0 或 1 ( bit 位 ) 作為值。

Redis Bitmap 可以用來統(tǒng)計(jì)狀態(tài),如日活是否瀏覽過某個(gè)東西。

Redis setbit 命令
Redis setbit 命令用于設(shè)置或者清除一個(gè) bit 位。

*Redis setbit 命令語法格式

SETBIT key offset value

*范例

127.0.0.1:6379> setbit aaa:001 10001 1 # 返回操作之前的數(shù)值 (integer) 0 127.0.0.1:6379> setbit aaa:001 10002 2 # 如果值不是0或1就報(bào)錯(cuò) (error) ERR bit is not an integer or out of range 127.0.0.1:6379> setbit aaa:001 10002 0 (integer) 0 127.0.0.1:6379> setbit aaa:001 10003 1 (integer) 0

七、基數(shù)統(tǒng)計(jì) HyperLogLog

Redis HyperLogLog 可以接受多個(gè)元素作為輸入,并給出輸入元素的基數(shù)估算值

  • 基數(shù)
    集合中不同元素的數(shù)量,比如 {‘a(chǎn)pple’, ‘banana’, ‘cherry’, ‘banana’, ‘a(chǎn)pple’} 的基數(shù)就是 3

  • 估算值
    算法給出的基數(shù)并不是精確的,可能會(huì)比實(shí)際稍微多一些或者稍微少一些,但會(huì)控制在合 理的范圍之內(nèi)

HyperLogLog 的優(yōu)點(diǎn)是:即使輸入元素的數(shù)量或者體積非常非常大,計(jì)算基數(shù)所需的空間總是固定的、并且是很小的。

在 Redis 里面,每個(gè) HyperLogLog 鍵只需要花費(fèi) 12 KB 內(nèi)存,就可以計(jì)算接近 264 個(gè)不同元素的基數(shù)。

這和計(jì)算基數(shù)時(shí),元素越多耗費(fèi)內(nèi)存就越多的集合形成鮮明對(duì)比。

因?yàn)?HyperLogLog 只會(huì)根據(jù)輸入元素來計(jì)算基數(shù),而不會(huì)儲(chǔ)存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個(gè)元素。

  • Redis PFADD 命令
    Redis PFADD 命令將元素添加至 HyperLogLog

    Redis PFADD 命令語法格式
    PFADD key element [element …]

  • 范例

127.0.0.1:6379> PFADD unique::ip::counter '192.168.0.1' (integer) 1 127.0.0.1:6379> PFADD unique::ip::counter '127.0.0.1' (integer) 1 127.0.0.1:6379> PFADD unique::ip::counter '255.255.255.255' (integer) 1 127.0.0.1:6379> PFCOUNT unique::ip::counter (integer) 3

八、Geo 地理位置

Redis 的 GEO 特性在 Redis 3.2 版本中推出, 這個(gè)功能可以將用戶給定的地理位置信息儲(chǔ)存起來, 并對(duì)這些信息進(jìn)行操作。GEO的數(shù)據(jù)結(jié)構(gòu)總共有六個(gè)命令:geoadd、geopos、geodist、georadius、georadiusbymember、gethash,GEO使用的是國際通用坐標(biāo)系WGS-84。

  • GEOADD:添加地理位置
  • GEOPOS:查詢地理位置(經(jīng)緯度),返回?cái)?shù)組
  • GEODIST:計(jì)算兩位位置間的距離
  • GEORADIUS:以給定的經(jīng)緯度為中心, 返回鍵包含的位置元素當(dāng)中, 與中心的距離不超過給定最大距離的所有位置元素。
  • GEORADIUSBYMEMBER:以給定的地理位置為中心, 返回鍵包含的位置元素當(dāng)中, 與中心的距離不超過給定最大距離的所有位置元素。
  • 127.0.0.1:6379> geoadd kcityGeo 116.405285 39.904989 "beijing" (integer) 1 127.0.0.1:6379> geoadd kcityGeo 121.472644 31.231706 "shanghai" (integer) 1 127.0.0.1:6379> geodist kcityGeo beijing shanghai km "1067.5980" 127.0.0.1:6379> geopos kcityGeo beijing 1) 1) "116.40528291463851929"2) "39.9049884229125027" 127.0.0.1:6379> geohash kcityGeo beijing 1) "wx4g0b7xrt0" 127.0.0.1:6379> georadiusbymember kcityGeo beijing 1200 km withdist withcoord asc count 5 1) 1) "beijing"2) "0.0000"3) 1) "116.40528291463851929"2) "39.9049884229125027" 2) 1) "shanghai"2) "1067.5980"3) 1) "121.47264629602432251"2) "31.23170490709807012"
    • 內(nèi)部編碼
      但是,需要說明的是,Geo本身不是一種數(shù)據(jù)結(jié)構(gòu),它本質(zhì)上還是借助于Sorted Set(ZSET),并且使用GeoHash技術(shù)進(jìn)行填充。Redis中將經(jīng)緯度使用52位的整數(shù)進(jìn)行編碼,放進(jìn)zset中,score就是GeoHash的52位整數(shù)值。在使用Redis進(jìn)行Geo查詢時(shí),其內(nèi)部對(duì)應(yīng)的操作其實(shí)就是zset(skiplist)的操作。通過zset的score進(jìn)行排序就可以得到坐標(biāo)附近的其它元素,通過將score還原成坐標(biāo)值就可以得到元素的原始坐標(biāo)。

    總之,Redis中處理這些地理位置坐標(biāo)點(diǎn)的思想是:二維平面坐標(biāo)點(diǎn) --> 一維整數(shù)編碼值 --> zset(score為編碼值) --> zrangebyrank(獲取score相近的元素)、zrangebyscore --> 通過score(整數(shù)編碼值)反解坐標(biāo)點(diǎn) --> 附近點(diǎn)的地理位置坐標(biāo)。

    • 應(yīng)用場景
      • 比如現(xiàn)在比較火的直播業(yè)務(wù),我們需要檢索附近的主播,那么GEO就可以很好的實(shí)現(xiàn)這個(gè)功能。
        一是主播開播的時(shí)候?qū)懭胫鞑d的經(jīng)緯度,
        二是主播關(guān)播的時(shí)候刪除主播Id元素,這樣就維護(hù)了一個(gè)具有位置信息的在線主播集合提供給線上檢索。
      • 滴滴叫車:
        • 記錄車位置:GEOADD cars:locations 116.034579 39.030452 33
        • 用戶讀取附近的車:GEORADIUS cars:locations 116.054579 39.030452 5 km ASC COUNT 10

    九、Streams 流

    這是Redis5.0引入的全新數(shù)據(jù)結(jié)構(gòu),用一句話概括Streams就是Redis實(shí)現(xiàn)的內(nèi)存版kafka。支持多播的可持久化的消息隊(duì)列,用于實(shí)現(xiàn)發(fā)布訂閱功能,借鑒了 kafka 的設(shè)計(jì)。Redis Stream的結(jié)構(gòu)有一個(gè)消息鏈表,將所有加入的消息都串起來,每個(gè)消息都有一個(gè)唯一的ID和對(duì)應(yīng)的內(nèi)容。消息是持久化的,Redis重啟后,內(nèi)容還在。

    每個(gè)Stream都有唯一的名稱,它就是Redis的key,在我們首次使用xadd指令追加消息時(shí)自動(dòng)創(chuàng)建。

    每個(gè)Stream都可以掛多個(gè)消費(fèi)組,每個(gè)消費(fèi)組會(huì)有個(gè)游標(biāo)last_delivered_id在Stream數(shù)組之上往前移動(dòng),表示當(dāng)前消費(fèi)組已經(jīng)消費(fèi)到哪條消息了。每個(gè)消費(fèi)組都有一個(gè)Stream內(nèi)唯一的名稱,消費(fèi)組不會(huì)自動(dòng)創(chuàng)建,它需要單獨(dú)的指令xgroup create進(jìn)行創(chuàng)建,需要指定從Stream的某個(gè)消息ID開始消費(fèi),這個(gè)ID用來初始化last_delivered_id變量。

    每個(gè)消費(fèi)組(Consumer Group)的狀態(tài)都是獨(dú)立的,相互不受影響。也就是說同一份Stream內(nèi)部的消息會(huì)被每個(gè)消費(fèi)組都消費(fèi)到。

    同一個(gè)消費(fèi)組(Consumer Group)可以掛接多個(gè)消費(fèi)者(Consumer),這些消費(fèi)者之間是競爭關(guān)系,任意一個(gè)消費(fèi)者讀取了消息都會(huì)使游標(biāo)last_delivered_id往前移動(dòng)。每個(gè)消費(fèi)者者有一個(gè)組內(nèi)唯一名稱。

    消費(fèi)者(Consumer)內(nèi)部會(huì)有個(gè)狀態(tài)變量pending_ids,它記錄了當(dāng)前已經(jīng)被客戶端讀取的消息,但是還沒有ack。如果客戶端沒有ack,這個(gè)變量里面的消息ID會(huì)越來越多,一旦某個(gè)消息被ack,它就開始減少。這個(gè)pending_ids變量在Redis官方被稱之為PEL,也就是Pending Entries List,這是一個(gè)很核心的數(shù)據(jù)結(jié)構(gòu),它用來確保客戶端至少消費(fèi)了消息一次,而不會(huì)在網(wǎng)絡(luò)傳輸?shù)闹型緛G失了沒處理。

    • 消息ID:消息ID的形式是timestampInMillis-sequence,例如1527846880572-5,它表示當(dāng)前的消息在毫米時(shí)間戳1527846880572時(shí)產(chǎn)生,并且是該毫秒內(nèi)產(chǎn)生的第5條消息。消息ID可以由服務(wù)器自動(dòng)生成,也可以由客戶端自己指定,但是形式必須是整數(shù)-整數(shù),而且必須是后面加入的消息的ID要大于前面的消息ID。
    • 消息內(nèi)容:消息內(nèi)容就是鍵值對(duì),形如hash結(jié)構(gòu)的鍵值對(duì),這沒什么特別之處。
    127.0.0.1:6379> XADD mystream * field1 value1 field2 value2 field3 value3 "1588491680862-0" 127.0.0.1:6379> XADD mystream * username lisi age 18 "1588491854070-0" 127.0.0.1:6379> xlen mystream (integer) 2 127.0.0.1:6379> XADD mystream * username lisi age 18 "1588491861215-0" 127.0.0.1:6379> xrange mystream - + 1) 1) "1588491680862-0"2) 1) "field1"2) "value1"3) "field2"4) "value2"5) "field3"6) "value3" 2) 1) "1588491854070-0"2) 1) "username"2) "lisi"3) "age"4) "18" 3) 1) "1588491861215-0"2) 1) "username"2) "lisi"3) "age"4) "18" 127.0.0.1:6379> xdel mystream 1588491854070-0 (integer) 1 127.0.0.1:6379> xrange mystream - + 1) 1) "1588491680862-0"2) 1) "field1"2) "value1"3) "field2"4) "value2"5) "field3"6) "value3" 2) 1) "1588491861215-0"2) 1) "username"2) "lisi"3) "age"4) "18" 127.0.0.1:6379> xlen mystream (integer) 2

    內(nèi)部編碼
    streams底層的數(shù)據(jù)結(jié)構(gòu)是radix tree:Radix Tree(基數(shù)樹) 事實(shí)上就幾乎相同是傳統(tǒng)的二叉樹。僅僅是在尋找方式上,以一個(gè)unsigned int類型數(shù)為例,利用這個(gè)數(shù)的每個(gè)比特位作為樹節(jié)點(diǎn)的推斷。能夠這樣說,比方一個(gè)數(shù)10001010101010110101010,那么依照Radix 樹的插入就是在根節(jié)點(diǎn),假設(shè)遇到0,就指向左節(jié)點(diǎn),假設(shè)遇到1就指向右節(jié)點(diǎn),在插入過程中構(gòu)造樹節(jié)點(diǎn),在刪除過程中刪除樹節(jié)點(diǎn)。如下是一個(gè)保存了7個(gè)單詞的Radix Tree:

    應(yīng)用場景總結(jié)

    實(shí)際上,所謂的應(yīng)用場景,其實(shí)就是合理的利用Redis本身的數(shù)據(jù)結(jié)構(gòu)的特性來完成相關(guān)業(yè)務(wù)功能,可參考我我之前寫的文章:學(xué)了redis不會(huì)實(shí)戰(zhàn)?看這篇就夠了

    總結(jié)

    以上是生活随笔為你收集整理的【缓存中间件】redis 支持的数据类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。