這篇文章主要講解了“redis中的Redis Streams有什么作用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Redis中的Redis Streams有什么作用”吧!
成都創(chuàng)新互聯公司是一家專業(yè)提供云州企業(yè)網站建設,專注與成都網站設計、成都做網站、H5場景定制、小程序制作等業(yè)務。10年已為云州眾多企業(yè)、政府機構等服務。創(chuàng)新互聯專業(yè)網站制作公司優(yōu)惠進行中。
如果你想記錄一系列的結構化數據,并且確定數據庫是足夠大的,你可能會說:我們以追加寫入的方式打開一個文件,每一行記錄是一個CSV數據項:
time=1553096724033,cpu_temp=23.4,load=2.3
time=1553096725029,cpu_temp=23.2,load=2.1
這看起來很簡單,然后人們一直這樣做了好多年,并且一直持續(xù)著:如果你知道你在做什么,那么這將成為一種固定的模式。如果同樣的事情發(fā)生在內存中會怎樣呢?內存的順序寫入能力更強,并且會自動移除掉CSV文件的一些限制:
很難批量查詢
太多的冗余信息:每個條目的時間幾乎相同,字段也相同。但是移除字段會降低靈活性,就不能再增加別的字段了
每個條目的偏移量都是它在文件中的字節(jié)偏移量,而如果我們修改了文件結構,那么這些偏移量就會失效。所以這里缺少一個唯一標識的ID。
不能刪除條目,只能標記無效。如果不重寫日志的話,又沒有垃圾回收,重寫日志經常會因為各種原因出錯,所以最好不要重寫。
不過使用這樣的CSV條目也有一些好處:沒有固定格式,字段可以改變,生成比較容易,而且存儲格式比較緊湊。我們保留了其優(yōu)點,去掉了限制,于是設計出了像Redis Sorted Set這樣的混合數據結構——Redis Streams。他們看起來像基本數據結構一樣,但是為了得到這樣的效果,內部是有多種表現形式的。
Redis Streams是一種通過基數樹連接的增量壓縮的宏節(jié)點。(好難理解的概念,把原話貼出來:Redis Streams are represented as delta-compressed macro nodes that are linked together by a radix tree)。它的作用是,快速查找一個隨機項,獲取范圍值,刪除舊值來創(chuàng)建一個有大小上限的流。對程序員來說,我們的接口和CSV文件很相似:
1> XADD mystream * cpu-temp 23.4 load 2.3
2"1553097561402-0"
3> XADD mystream * cpu-temp 23.2 load 2.1
4"1553097568315-0"
通過這個例子可以看到,XADD命令自動生成并返回了一個entry ID。它是單調遞增的,并且有兩部分組成,<時間>-<數量>,時間是毫秒級,而數量則是同一毫秒生成的entry數量遞增。
所以第一個從上面所說的"追加寫入CSV"文件抽象出來概念就是,如果用星號作為XADD命令的ID參數,就從服務器獲取了一個entry ID。這個ID不僅僅是entry的唯一標識,也和entry加入流的時間有關。XRANGE命令可以批量獲取或獲取單個數據項。
1> XRANGE mystream 1553097561402-0 1553097561402-0
21) 1) "1553097561402-0"
3 2) 1) "cpu-temp"
4 2) "23.4"
5 3) "load"
6 4) "2.3"
在這個例子中,為了得到單個數據項,我用了相同的ID作為起始和結束值。然而我可以獲取任意范圍的數據項,并且用COUNT參數限制結果的數量。我也可以將起止參數都設置為時間戳,獲取一段時間內的數據項。
1> XRANGE mystream 1553097560000 1553097570000
21) 1) "1553097561402-0"
3 2) 1) "cpu-temp"
4 2) "23.4"
5 3) "load"
6 4) "2.3"
72) 1) "1553097568315-0"
8 2) 1) "cpu-temp"
9 2) "23.2"
10 3) "load"
11 4) "2.1"
篇幅原因,我們不再展示更多的Streams API了。我們有相關的文檔,感興趣的同學可以去閱讀。目前為止,我們只需要關注基本使用方法:XADD用來增加數據,XRANGE(或XREAD)用來讀取數據。我們來看一下我為什么說Streams是一個強大的數據結構。
前幾天我和一個最近在學習Redis的朋友一起建模一個應用程序:這是一個用來追蹤當地網球場、球員和比賽的app。很明顯,球員是一個小的模型,在Redis中只需要用一個hash就足夠了,key的形式可以是player:
1> XADD club:1234.matches * player-a 1 player-b 2 winner 1
2"1553254144387-0"
通過這樣簡單的操作,我們就可以獲得如下的信息:
一場比賽的唯一標識:流里的ID
不需要創(chuàng)建一個表示比賽的對象
分頁查詢比賽情況,或者查看某場比賽是否在指定時間就進行
在Streams出現之前,我們需要創(chuàng)建一個Sorted Set,分數是時間。Sorted Set的元素是比賽的ID(存在一個Hash里)。這不僅是增加了工作量,而且還造成了更多的內存浪費,比你想象的要多得多。
現在看起來Streams像是一個追加模式的,以時間為分數,元素是小型Hash的Sorted Set。簡而言之,這是Rediscover建模環(huán)境中的一次革命。
上面的例子不僅僅是固化模式的問題,相比舊有的Sorted Set+ Hash的模式,Streams對內存的節(jié)省做了很好的優(yōu)化,然而這一點是不容易被發(fā)現的。
假設我們要記錄100萬場比賽,
Sorted Set + Hash的內存使用量是220MB(242RSS)
Stream的內存使用量是16.8MB(18.11RSS)
這不僅僅是一個數量級的差異(實際上是13倍的差異),這意味著我們舊有的模式實在是太浪費了,而新的模式是完美可行的。Redis Streams還有其他神奇的地方:宏節(jié)點可以包括多個元素,它們使用叫做listpack的數據進行編碼。listpacks會對二進制形式的整數進行編碼,即時它是語義字符串。最重要的是,我們使用了增量壓縮和相同字段壓縮。我們可以通過ID或時間進行查詢,因為宏節(jié)點是用基數樹連接的?;鶖禈淙~被設計為使用很少的內存。所有的事情都使用極少的內存,但有趣的是,用戶并不能從語義上看到使Streams更加高效的實現細節(jié)。
現在我們來做一個簡單的計算,如果我保存了100萬個entry,使用了18MB內存,那么1000萬個就是180MB,1億個使用1.8GB,保存10億數據也只使用18GB內存。
有一個比較重要的事情需要注意,在我看來,上面我們用來記錄網球比賽的例子與把Redis Streams作為一個時間序列來使用非常不同。沒錯,邏輯上我們仍然是記錄一類事件,但本質上的區(qū)別是記錄日志和創(chuàng)建一個entry并存入對象的不同。在使用時間序列時,我們只是記錄一個外部事件,而不需要真的展示一個對象。你可能認為這個區(qū)別不重要,但事實不是這樣。對Redis用戶來說很重要的是,如果需要保存一系列有序的對象,并且給每個對象賦一個ID,那么就需要使用Redis Streams。
然而即時是一個簡單的時間序列,也是一個很大的用例,因為在Streams出現之前,Redis在面對這種用例時令人有些絕望。一個節(jié)省內存,并且靈活的流,對開發(fā)者來說是一個重要的工具。
感謝各位的閱讀,以上就是“Redis中的Redis Streams有什么作用”的內容了,經過本文的學習后,相信大家對Redis中的Redis Streams有什么作用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯,小編將為大家推送更多相關知識點的文章,歡迎關注!