首頁 >後端開發 >php教程 >redis資料型態有哪些? redis各資料型態的總結

redis資料型態有哪些? redis各資料型態的總結

不言
不言原創
2018-09-13 17:20:386830瀏覽

本篇文章帶給大家的內容是關於redis資料型態有哪些? redis各資料類型的總結,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

前言

  1. redis是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體、亦可持久化的日誌型、key-value資料庫,並提供多種語言的API。

  2. 它是記憶體儲存的資料結構伺服器,可用作資料庫、快取和訊息佇列代理程式。

  3. 透過資料全部in-momery的方式保證高速訪問,同時提供資料落地的功能,這是redis最主要的適用場景。

  4. reids內建複製、Lua腳本、LRU收回、事物以及不同層級磁碟持久化功能,同時透過redis Sentinel提供高可用,透過Redis Cluster提供自動分割。

  5. redis支援字串、雜湊表、列表、集合、有序集合、位圖、hyperloglogs等資料類型。

  6. redis最常用的資料類型:stirng、hash、list、set、sorted set、pub/sub、transactions。

String類型

  1. string類型就是簡單的key-value類型,value不只是string,也可以是數字。

  2. 常用指令:set、get、decr、incr、mget等。

  3. 除了提供與memcached一樣的get、set、incr、decr 等操作外,redis還提供了下面的一些操作:

(1)取得字串長度;
(2)往字串append內容;
(3)設定和取得字串的某一段內容;
(4)設定及取得字串的某一位元(bit);
(5)批次設定一系列字串的內容;

Hash類型

  1. hash特別適合用於儲存物件。

  2. 常用指令:hget、hset、hgetall等。

  3. 應用程式場景:儲存一些結構化的數據,例如使用者的暱稱、年齡、性別、積分等,儲存一個使用者資訊物件資料。

  4. 我們舉個簡單的實例來描述下Hash的應用場景,例如我們儲存一個使用者資訊物件數據,包含以下資訊:

(1)用戶id為查找的key;
(2)儲存的value包括姓名、年齡、生日等資訊

1、實例解析:

(1)key是使用者id,value是一個Map。
(2)這個Map的key是成員的屬性名,value是屬性值;
(3)這樣資料的修改和存取都可以直接透過其內部的Map的key(redis裡稱內部Map的key為field),也就是key(用戶名id) field(屬性名)就可以操作對應屬性資料了。

2、注意:

(1)redis提供了介面(hgetall)可以直接取到全部的屬性數據,但是如果內部Map的成員很多,那麼涉及到遍歷整個Map的操作。
(2)由於redis單執行緒模型的緣故,這個遍歷操作可能會比較耗時,而令其他客戶端的請求完全回應不到,這點需要注意。

List類型

  1. list類型實質是一個每個元素都是string類型的雙向鍊錶,這使得list既可以用作棧,也可以用作隊列。

  2. list類型經常會被用於訊息佇列的服務,以完成多程式之間的訊息交換。

  3. 常用指令:lpush、rpush、lpop、rpop、lrange等。

  4. 應用程式場景:實作最新訊息排行等功能,還有訊息佇列。

  5. 簡單訊息佇列舉例分析:

(1)假設一個應用程式執行lpush向鍊錶中新增新的元素,我們通常將這樣的程式稱為「生產者(producer)」;
(2)而另外一個應用程式正在執行rpop操作從鍊錶中取出元素,我們稱這樣的程式為「消費者(consumer)」;
(3)在消費者消費訊息的過程中,需要不停呼叫rpop來查看list中是否有待處理訊息。每調用一次都會發起一次鏈接,造成不必要的浪費。
(4)另外,如果生產者速度大於消費者速度,訊息佇列長度會一直增大,時間久了會佔用大量記憶體空間;
(5)所以,可以使用brpop指令,這個指令只有在有元素時返回,沒有則會阻塞直到超時返回null。

Set類型

  1. set類型是string類型的無序集合。

  2. set集合的概念就是一堆不重複值的組合。

  3. set元素最大可以包含(2的32次方-1)個元素。

  4. set內部實作是value永遠是null的HashMap。

  5. set對外提供的功能與list類似是一個清單的功能,特殊之處在於set時可以自動排重的。

  6. 常用指令:sadd、spop、smembers、sunion等。

  7. 當你需要儲存一個清單數據,又不希望出現重複數據時,set是一個很好的選擇。

  8. 並且set提供了判斷某個成員是否在一個set集合內的重要接口,這個是list不能提供的。

  9. 利用set資料結構,可以儲存一些集合性的數據,例如在微博應用中,可以將一個用戶所有的關注人存在一個集合中,將其所有粉絲存在一個集合。

  10. redis也為集合提供了求交集、並集、差集等操作,可以非常方便的實現如共同關注、共同喜好、二度好友等功能。

Zset類型

  1. 和set一樣,sorted set也是stirng類型元素的集合。不同的是每個元素都會關聯一個double類型的score,元素順序由score決定。

  2. sorted set是插入有序的,即自動排序。

  3. 常用指令:zadd、zrange、zrem、zcard等。

  4. 當你需要一個有順序的並且不重複的集合清單時,那麼可以選擇sorted set資料結構。

  5. 應用範例:

(1)例如儲存全班同學的成績,其集合value可以是同學的學號,而score就可以是成績。
(2)排行榜應用,依分數列出topN的使用者等。

pub/sub

  1. subscribe、unsubscribe和publish三個指令實作了發布與訂閱泛型。

  2. 發送者(發送訊息的客戶端)不是直接將訊息發給特定的接收者(接受訊息的客戶端),而是將訊息發給頻道(channel),然後由頻道將訊息轉發給所有對這個頻道感興趣的訂閱者。

  3. 發送者無需知道任何關於訂閱者的信息,而訂閱者也無需知道是哪個客戶端給它發送信息,它只要關注自己感興趣的頻道即可。

  4. 發布/訂閱在redis中,被設計的非常輕量級和簡潔,它做到了消息的發布和訂閱的基本能力;但是尚未提供關於消息持久化等各種企業級的特性。

  5. 一個redis client發佈訊息,其他多個redis client訂閱訊息,發佈的訊息即發即失,redis不會持久保存發佈的訊息;訊息訂閱者也只能得到訂閱後的消息,通道中先前的消息無從獲得。

  6. 訊息發布者,即publish客戶端,無需獨佔鏈接,你可以在publish訊息的同時,使用同一個redis-client鏈接進行其他操作(如incr等);

  7. 訊息訂閱者,即subscribe客戶端,需要獨佔鏈接,即進行subscribe期間,redis-client無法穿插其他操作。

  8. 此時client以阻塞的方式等待publish端的消息,因此subscribe需要使用單獨的鏈接,甚至需要在額外的線程中使用。

  9. tcp預設連線時間固定,如果在這世間內sub端沒有接收到pub端訊息,或是pub端沒有訊息產生,sub端的連線都會強制回收。

  10. 這就需要特殊手段解決,用計時器來模擬pub和sub之間的保活機制,定時器時間不能超過tcp最大連接時間。

  11. 一旦subscribe端斷開鏈接,將會失去部分訊息,即連結失效期間的訊息將會被遺失,所以,這裡需要考慮redis的list來持久化;

  12. 如果你非常關注每個訊息,那麼你應該基於redis做一些額外的補充工作,如果你希望訂閱是持久的,那麼如下設計思路可以藉鑑:

(1)subscribe端:首先向一個set集合中增加“訂閱者id”,此set集合保存了“活躍訂閱”者;訂閱者id標記每個唯一的訂閱者,此set為「活躍訂閱者集合」。
(2)subscribe端開啟訂閱操作,並基於redis創建一個以訂閱者id為key的list資料結構,此list中儲存了所有的尚未消費的消息,此list稱為“訂閱者訊息佇列” ;
(3)publish端:每發布一則訊息之後,publish端都需要遍歷活躍訂閱者集合,並依序向每個「訂閱者訊息佇列」尾部追加此次發布的訊息;
(4 )到此為止,我們基本上可以保證,發布的每一則訊息,都會持久的保存在每個「訂閱者訊息佇列」中;
(5)subscribe端,每接收到一個訂閱訊息,在消費週後,必須刪除自己的「訂閱者訊息佇列」頭部的一條訊息;
(6)subscribe端啟動時,如果發現自己的「訂閱者訊息佇列」中有殘存記錄,那麼將會先消費這些訊息,然後再去訂閱。

  1. 以上方法可以保證成功到達的訊息必消費不遺失

#transactions

  1. ##redis事務可以一次執行多個命令。

  2. 一個交易從開始到執行會經歷三個階段:

(1)開始交易

(2)命令入隊
(3)執行交易

交易是一個單獨的隔離操作:事務中的所有命令都會序列化、依序執行。

事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。

單一redis指令的執行時原子性的,但redis沒有在事務上增加任何維持原子性的機制,所以redis事務的執行並不是原子性的。

交易可以理解為一個打包的批次執行腳本,但批次指令並非原子化的操作,中間某指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做。

multi、exec、discard和watch指令是redis事務的基礎。

multi:

(1)multi指令用來開啟一個事務,它總是傳回ok。
(2)multi指令執行之後,客戶端可以繼續向伺服器發送任意多條指令;
(3)這些指令不會立即被執行,而是被放到一個佇列中;
( 4)當exec指令被呼叫時,所有佇列中的指令才會被執行。

exec:

(1)exec指令負責觸發並執行交易中的所有指令;
(2)如果客戶端在使用multi開啟了一個事務後,卻因為斷線而沒有成功執行exec指令,那麼事務中所有的指令都不會被執行。
(3)另一方面,如果客戶端成功在開啟交易之後執行exec指令,那麼交易中的所有指令都會被執行。

discard:

(1)透過呼叫discard,客戶端可以清空交易佇列,並放棄執行交易。

watch:

(1)watch指令可以為redis交易提供check-and-set (CAS)行為。
(2)watch使得exec指令有條件的執行:交易只能在所有被監控健都沒有被修改的前提下執行,如果這個前提不能滿足,事務就不會執行。
(3)如果你用watch監視來一個帶過期時間的健,那麼即使這個健過期了,事務仍然可以執行。
(4)watch可以被呼叫多次,對健的監視從watch被執行之後就生效,直到呼叫exec為止。
(5)當exec被呼叫時,不管交易是否成功執行,對所有健的監視都會被取消。
(6)當客戶端斷開連結時,該客戶端對健的監視也會被取消。

相關建議:

Redis資料類型--string

Redis基本資料型別與相關運算

以上是redis資料型態有哪些? redis各資料型態的總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn