摘要:它是內(nèi)存存儲的數(shù)據(jù)結(jié)構(gòu)服務(wù)器,可用作數(shù)據(jù)庫高速緩存和消息隊(duì)列代理。支持字符串哈希表列表集合有序集合位圖等數(shù)據(jù)類型。最為常用的數(shù)據(jù)類型。類型經(jīng)常會被用于消息隊(duì)列的服務(wù),以完成多程序之間的消息交換。應(yīng)用場景實(shí)現(xiàn)最新消息排行等功能,還有消息隊(duì)列。
前言
redis是一個開源的使用ANSI C語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存、亦可持久化的日志型、key-value數(shù)據(jù)庫,并提供多種語言的API。
它是內(nèi)存存儲的數(shù)據(jù)結(jié)構(gòu)服務(wù)器,可用作數(shù)據(jù)庫、高速緩存和消息隊(duì)列代理。
通過數(shù)據(jù)全部in-momery的方式保證高速訪問,同時提供數(shù)據(jù)落地的功能,這是redis最主要的適用場景。
reids內(nèi)置復(fù)制、Lua腳本、LRU收回、事物以及不同級別磁盤持久化功能,同時通過redis Sentinel提供高可用,通過Redis Cluster提供自動分區(qū)。
redis支持字符串、哈希表、列表、集合、有序集合、位圖、hyperloglogs等數(shù)據(jù)類型。
redis最為常用的數(shù)據(jù)類型:stirng、hash、list、set、sorted set、pub/sub、transactions。
String類型string類型就是簡單的key-value類型,value不僅僅是string,也可以是數(shù)字。
常用命令:set、get、decr、incr、mget等。
除了提供與memcached一樣的get、set、incr、decr 等操作外,redis還提供了下面的一些操作:
(1)獲取字符串長度; (2)往字符串a(chǎn)ppend內(nèi)容; (3)設(shè)置和獲取字符串的某一段內(nèi)容; (4)設(shè)置及獲取字符串的某一位(bit); (5)批量設(shè)置一系列字符串的內(nèi)容;Hash類型
hash特別適合用于存儲對象。
常用命令:hget、hset、hgetall等。
應(yīng)用場景:存儲一些結(jié)構(gòu)化的數(shù)據(jù),比如用戶的昵稱、年齡、性別、積分等,存儲一個用戶信息對象數(shù)據(jù)。
我們舉個簡單的實(shí)例來描述下Hash的應(yīng)用場景,比如我們存儲一個用戶信息對象數(shù)據(jù),包含以下信息:
(1)用戶id為查找的key; (2)存儲的value包括姓名、年齡、生日等信息
實(shí)例解析:
(1)key是用戶id,value是一個Map。 (2)這個Map的key是成員的屬性名,value是屬性值; (3)這樣對數(shù)據(jù)的修改和存取都可以直接通過其內(nèi)部的Map的key(redis里稱內(nèi)部Map的key為field),也就是key(用戶名id)+field(屬性名)就可以操作對應(yīng)屬性數(shù)據(jù)了。
注意:
(1)redis提供了接口(hgetall)可以直接取到全部的屬性數(shù)據(jù),但是如果內(nèi)部Map的成員很多,那么涉及到遍歷整個Map的操作。 (2)由于redis單線程模型的緣故,這個遍歷操作可能會比較耗時,而令其他客戶端的請求完全響應(yīng)不到,這點(diǎn)需要注意。List類型
list類型實(shí)質(zhì)是一個每個元素都是string類型的雙向鏈表,這使得list既可以用作棧,也可以用作隊(duì)列。
list類型經(jīng)常會被用于消息隊(duì)列的服務(wù),以完成多程序之間的消息交換。
常用命令:lpush、rpush、lpop、rpop、lrange等。
lpush是插入到鏈表的左邊,也就是頭部;rpush是插入到鏈表的右邊,也就是尾部;lrange(key,start,end)返回指定區(qū)間內(nèi)的元素,從頭部(左端)start開始到尾部(右端)區(qū)間內(nèi)。
應(yīng)用場景:實(shí)現(xiàn)最新消息排行等功能,還有消息隊(duì)列。
簡單消息隊(duì)列舉例分析:
(1)假設(shè)一個應(yīng)用程序執(zhí)行l(wèi)push向鏈表中添加新的元素,我們通常將這樣的程序稱之為“生產(chǎn)者(producer)”; (2)而另外一個應(yīng)用程序正在執(zhí)行rpop操作從鏈表中取出元素,我們稱這樣的程序?yàn)椤跋M(fèi)者(consumer)”; (3)在消費(fèi)者消費(fèi)消息的過程中,需要不停調(diào)用rpop查看list中是否有待處理消息。每調(diào)用一次都會發(fā)起一次鏈接,造成不必要的浪費(fèi)。 (4)另外,如果生產(chǎn)者速度大于消費(fèi)者速度,消息隊(duì)列長度會一直增大,時間久了會占用大量內(nèi)存空間; (5)所以,可以使用brpop命令,這個命令只有在有元素時返回,沒有則會阻塞直到超時返回null。Set類型
set類型是string類型的無序集合。
set集合的概念就是一堆不重復(fù)值的組合。
set元素最大可以包含(2的32次方-1)個元素。
set內(nèi)部實(shí)現(xiàn)是一個value永遠(yuǎn)為null的HashMap。
set對外提供的功能與list類似是一個列表的功能,特殊之處在于set時可以自動排重的。
常用命令:sadd、spop、smembers、sunion等。
當(dāng)你需要存儲一個列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時,set是一個很好的選擇。
并且set提供了判斷某個成員是否在一個set集合內(nèi)的重要接口,這個是list不能提供的。
利用set數(shù)據(jù)結(jié)構(gòu),可以存儲一些集合性的數(shù)據(jù),比如在微博應(yīng)用中,可以將一個用戶所有的關(guān)注人存在一個集合中,將其所有粉絲存在一個集合。
redis還為集合提供了求交集、并集、差集等操作,可以非常方便的實(shí)現(xiàn)如共同關(guān)注、共同喜好、二度好友等功能。
Zset類型和set一樣,sorted set也是stirng類型元素的集合。不同的是每個元素都會關(guān)聯(lián)一個double類型的score,元素順序由score決定。
sorted set是插入有序的,即自動排序。
常用命令:zadd、zrange、zrem、zcard等。
zRange(key,start,end)返回指定范圍內(nèi)的score從低到高順序的所有元素;zRevRange(key,start,end)返回key對應(yīng)的有序集合中指定區(qū)間的按照score從高到低的順序的所有元素。
當(dāng)你需要一個有序的并且不重復(fù)的集合列表時,那么可以選擇sorted set數(shù)據(jù)結(jié)構(gòu)。
應(yīng)用舉例:
(1)例如存儲全班同學(xué)的成績,其集合value可以是同學(xué)的學(xué)號,而score就可以是成績。 (2)排行榜應(yīng)用,根據(jù)得分列出topN的用戶等。pub/sub
subscribe、unsubscribe和publish三個命令實(shí)現(xiàn)了發(fā)布與訂閱泛型。
發(fā)送者(發(fā)送信息的客戶端)不是直接將信息發(fā)給特定的接收者(接受信息的客戶端),而是將信息發(fā)給頻道(channel),然后由頻道將信息轉(zhuǎn)發(fā)給所有對這個頻道感興趣的訂閱者。
發(fā)送者無需知道任何關(guān)于訂閱者的信息,而訂閱者也無需知道是哪個客戶端給它發(fā)送信息,它只要關(guān)注自己感興趣的頻道即可。
發(fā)布/訂閱在redis中,被設(shè)計(jì)的非常輕量級和簡潔,它做到了消息的發(fā)布和訂閱的基本能力;但是尚未提供關(guān)于消息持久化等各種企業(yè)級的特性。
一個redis client發(fā)布消息,其他多個redis client訂閱消息,發(fā)布的消息即發(fā)即失,redis不會持久保存發(fā)布的消息;消息訂閱者也只能得到訂閱后的消息,通道中此前的消息無從獲得。
消息發(fā)布者,即publish客戶端,無需獨(dú)占鏈接,你可以在publish消息的同時,使用同一個redis-client鏈接進(jìn)行其他操作(如incr等);
消息訂閱者,即subscribe客戶端,需要獨(dú)占鏈接,即進(jìn)行subscribe期間,redis-client無法穿插其他操作。
此時client以阻塞的方式等待publish端的消息,因此subscribe需要使用多帶帶的鏈接,甚至需要在額外的線程中使用。
tcp默認(rèn)連接時間固定,如果在這世間內(nèi)sub端沒有接收到pub端消息,或pub端沒有消息產(chǎn)生,sub端的連接都會強(qiáng)制回收。
這就需要特殊手段解決,用定時器來模擬pub和sub之間的保活機(jī)制,定時器時間不能超過tcp最大連接時間。
一旦subscribe端斷開鏈接,將會失去部分消息,即鏈接失效期間的消息將會被丟失,所以,這里需要考慮redis的list來持久化;
如果你非常關(guān)注每個消息,那么你應(yīng)該基于redis做一些額外的補(bǔ)充工作,如果你希望訂閱是持久的,那么如下設(shè)計(jì)思路可以借鑒:
(1)subscribe端:首先向一個set集合中增加“訂閱者id”,此set集合保存了“活躍訂閱”者;訂閱者id標(biāo)記每個唯一的訂閱者,此set為“活躍訂閱者集合”。 (2)subscribe端開啟訂閱操作,并基于redis創(chuàng)建一個以訂閱者id為key的list數(shù)據(jù)結(jié)構(gòu),此list中存儲了所有的尚未消費(fèi)的消息,此list稱為“訂閱者消息隊(duì)列”; (3)publish端:每發(fā)布一條消息之后,publish端都需要遍歷活躍訂閱者集合,并依次向每個“訂閱者消息隊(duì)列”尾部追加此次發(fā)布的消息; (4)到此為止,我們基本可以保證,發(fā)布的每一條消息,都會持久的保存在每個“訂閱者消息隊(duì)列”中; (5)subscribe端,每接收到一個訂閱消息,在消費(fèi)周后,必須刪除自己的“訂閱者消息隊(duì)列”頭部的一條消息; (6)subscribe端啟動時,如果發(fā)現(xiàn)自己的“訂閱者消息隊(duì)列”中有殘存記錄,那么將會首先消費(fèi)這些消息,然后再去訂閱。
以上方法可以保證成功到達(dá)的消息必消費(fèi)不丟失
transactionsredis事務(wù)可以一次執(zhí)行多個命令。
一個事務(wù)從開始到執(zhí)行會經(jīng)歷三個階段:
(1)開始事務(wù) (2)命令入隊(duì) (3)執(zhí)行事務(wù)
事務(wù)是一個多帶帶的隔離操作:事務(wù)中的所有命令都會序列化、按順序執(zhí)行。
事務(wù)在執(zhí)行的過程中,不會被其他客戶端發(fā)送來的命令請求所打斷。
單個redis命令的執(zhí)行時原子性的,但redis沒有在事務(wù)上增加任何維持原子性的機(jī)制,所以redis事務(wù)的執(zhí)行并不是原子性的。
事務(wù)可以理解為一個打包的批量執(zhí)行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會導(dǎo)致前面已做指令的回滾,也不會造成后續(xù)的指令不做。
multi、exec、discard和watch命令是redis事務(wù)的基礎(chǔ)。
multi:
(1)multi命令用于開啟一個事務(wù),它總是返回ok。 (2)multi命令執(zhí)行之后,客戶端可以繼續(xù)向服務(wù)器發(fā)送任意多條命令; (3)這些命令不會立即被執(zhí)行,而是被放到一個隊(duì)列中; (4)當(dāng)exec命令被調(diào)用時,所有隊(duì)列中的命令才會被執(zhí)行。
exec:
(1)exec命令負(fù)責(zé)觸發(fā)并執(zhí)行事務(wù)中的所有命令; (2)如果客戶端在使用multi開啟了一個事務(wù)后,卻因?yàn)閿嗑€而沒有成功執(zhí)行exec命令,那么事務(wù)中所有的命令都不會被執(zhí)行。 (3)另一方面,如果客戶端成功在開啟事務(wù)之后執(zhí)行exec命令,那么事務(wù)中的所有命令都會被執(zhí)行。
discard:
(1)通過調(diào)用discard,客戶端可以清空事務(wù)隊(duì)列,并放棄執(zhí)行事務(wù)。
watch:
(1)watch命令可以為redis事務(wù)提供check-and-set (CAS)行為。 (2)watch使得exec命令有條件的執(zhí)行:事務(wù)只能在所有被監(jiān)控健都沒有被修改的前提下執(zhí)行,如果這個前提不能滿足,事務(wù)就不會執(zhí)行。 (3)如果你用watch監(jiān)視來一個帶過期時間的健,那么即使這個健過期了,事務(wù)仍然可以執(zhí)行。 (4)watch可以被調(diào)用多次,對健的監(jiān)視從watch被執(zhí)行之后就生效,直到調(diào)用exec為止。 (5)當(dāng)exec被調(diào)用時,不管事務(wù)是否被成功執(zhí)行,對所有健的監(jiān)視都會被取消。 (6)當(dāng)客戶端斷開鏈接時,該客戶端對健的監(jiān)視也會被取消。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/62032.html
摘要:它是內(nèi)存存儲的數(shù)據(jù)結(jié)構(gòu)服務(wù)器,可用作數(shù)據(jù)庫高速緩存和消息隊(duì)列代理。支持字符串哈希表列表集合有序集合位圖等數(shù)據(jù)類型。最為常用的數(shù)據(jù)類型。類型經(jīng)常會被用于消息隊(duì)列的服務(wù),以完成多程序之間的消息交換。應(yīng)用場景實(shí)現(xiàn)最新消息排行等功能,還有消息隊(duì)列。 前言 redis是一個開源的使用ANSI C語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存、亦可持久化的日志型、key-value數(shù)據(jù)庫,并提供多種語言的API...
摘要:它是內(nèi)存存儲的數(shù)據(jù)結(jié)構(gòu)服務(wù)器,可用作數(shù)據(jù)庫高速緩存和消息隊(duì)列代理。支持字符串哈希表列表集合有序集合位圖等數(shù)據(jù)類型。最為常用的數(shù)據(jù)類型。類型經(jīng)常會被用于消息隊(duì)列的服務(wù),以完成多程序之間的消息交換。應(yīng)用場景實(shí)現(xiàn)最新消息排行等功能,還有消息隊(duì)列。 前言 redis是一個開源的使用ANSI C語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存、亦可持久化的日志型、key-value數(shù)據(jù)庫,并提供多種語言的API...
摘要:時間年月日星期日說明本文部分內(nèi)容均來自慕課網(wǎng)。當(dāng)對應(yīng)的鏈表存在時,從左側(cè)插入數(shù)據(jù)。從右側(cè)插入數(shù)據(jù)。當(dāng)系統(tǒng)在定時持久化之前出現(xiàn)宕機(jī),還未來得及往硬盤寫入數(shù)據(jù),那數(shù)據(jù)就丟失了。當(dāng)數(shù)據(jù)集過大時,可能會導(dǎo)致服務(wù)器停止幾百毫秒甚至是秒鐘。 時間:2017年05月21日星期日說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:無個人學(xué)習(xí)源碼:https:...
閱讀 2452·2021-11-22 09:34
閱讀 3063·2021-10-25 09:43
閱讀 1975·2021-10-11 10:59
閱讀 3361·2021-09-22 15:13
閱讀 2323·2021-09-04 16:40
閱讀 418·2019-08-30 15:53
閱讀 3186·2019-08-30 11:13
閱讀 2602·2019-08-29 17:30