很是高興有機會和你們在這裏交流Redis5.0之Stream應用。今天的分享更多的是一個拋磚引玉,歡迎你們提出更多關於Redis的思考。html
首先,咱們來個假設,這裏有個杯子,這個杯子是去年我老婆送的,送的緣由是我之前的杯子保溫性能太好,致使我不多能喝上水,而這樣敞口的杯子能促使我多喝水。雖然這杯子在商家的貨架上只是千千萬萬只杯子中的一隻,可是它對我來講仍然是不一樣的。不一樣的是過往,是記憶。這記憶提及來是數據的一類,這類數據也讓咱們生活更美好。mysql
這種數據的特色是什麼呢?產生是一次產生的,可是咱們會但願常常看到,但願將這種美好填充到各類東西中。而杯子自己也能夠說是一個生產-消費模型:數據出現,而後被各類消費。sql
消費的一種狀況數據庫
所以,杯子不只僅是一個杯子,實際上背後的可挖掘的東西很是多。意義越多,鏈接越多,關係越複雜,咱們數據量也越大,因此,但願價值最大化的咱們,就產生了大量但願被高速處理的數據,這數據體如今系統上,每每就成了數據洪峯,成了系統難以承受之重。緩存
在不少狀況下,咱們採集端所包含的信息可能遠遠超出這個數值。例如,霧霾天裏,咱們的房間,咱們的位置,它的空氣質量是怎樣的,各項污染物參數是多少?咱們這個辦公區,這棟樓,這個房間的空氣質量又是怎樣的,電力消耗是怎樣的,行人情況,車輛數據,等等。上億的數據,涉及互聯互通,須要保證高併發可靠傳輸。同時數據收集上來後要進行處理和存儲、分析,對系統的挑戰都是巨大的。網絡
巨大的、網狀的互聯互通,須要帶寬巨大、順暢的管道;這麼多的數據,會造成巨大的數據洪流,採集完成後在雲端進行分析,也能夠產生巨大的用戶價值。數據結構
區域檢測監控併發
這些數據雖然形式各不相同,可是也有共同的特色,就是和時間有關。例如,一戶人家,從主臥到書房,從客廳到餐廳,不一樣的房間不一樣的位置放置一些空氣監測儀,監測儀裏面的化學藥劑接觸空氣中的各類成分,隨時間緩慢變化,變化過程當中產生信號,這些信號通過初步整理計算,造成一個平面的空氣質量數據;從清晨到傍晚,從春到秋,不一樣的時間點,甲醛、TVOC等各類污染物成分的數值也不同,所以平面的數據在這裏造成了時序數據。分佈式
湊巧的是,Redis的流就是專門爲時序數據設計的。咱們回顧一下Redis的流的存儲設計:主線是一個消息鏈表,將全部消息按照順序串起來。所以Redis的流在這方面支持度是很是不錯的,咱們能夠將平面內的數據按照時間序列加入到Redis流裏面。固然這些數據咱們可能須要初步處理,所以咱們也可使用Redis的其它數據結構,例如list,再憑藉Redis對Lua腳本的支持,用不多的外部應用邏輯驅動它完成處理。這處理由於是在Redis內部完成,因此總體上來講,計算消耗是比較低的。Redis本來憑藉它原生C的優點,還有內存實現和數據結構的優化,內存佔用就比較小,CPU要求也低,使它在小型設備上高效率的運行成爲可能。將來可能會有萬億級的智能設備基於ARM平臺,前景仍是很是廣闊的。高併發
因此從設備端,咱們已經可使用Redis來完成數據的臨時存儲和基本的處理,加入Redis流後,再使用MQTT、TCP、808等協議,經過網絡上傳數據。一般咱們須要採集的區域會比較廣,設備數量不少,所以數據也比較多,那數據可能還須要在局部,進行初步的彙總處理。這裏數據洪峯每每就開始顯露了。若是咱們指望保存進mysql等數據庫,一般是頂不住壓力的。由於數據庫的原子性、一致性、隔離性、持久性等,對性能的損耗是比較大的。因此這裏咱們可使用Redis來接收洪峯監測數據,而後分發給存儲服務、處理服務、展現服務,等等。在分發處理完成前,Redis自己做爲高速內存存儲,流裏面的數據也是能夠做爲普通的緩存數據,被反覆訪問的,因此也在必定程度上,對消息消費前的空檔期,作了補充,也給予了後臺更寬裕一些的處理時間。
咱們來回顧一下其中Redis的使用:快,Redis的性能很高;小,輕便簡潔,對內存和CPU要求小;豐富,數據結構豐富,用法多樣;時序,流是爲時序應用設計的;支持Lua腳本,能自定義邏輯。
飯要一口一口吃,路得一步一步走。讓咱們回到技術自己,從巨大的洪流裏截取出一部分和Redis有關的,還原成基本的工做流程。
我這裏截取的是空氣監測的存儲和處理。咱們來看一下示意圖,儀器上報數據,Redis接收數據流,而且提供給存儲、分析消費,同時供應用使用。
檢測數據產生,組別創建
首先來了一條空氣數據,檢測數據產生,存儲、分析消費組也創建起來了。空氣數據包含了hcho和tvoc污染物值。咱們看看命令,這裏有個maxlen,這是爲了不隊列過長,因此設置的最大長度。爲何須要這麼設置呢?由於Redis的流順序消費後,甚至xdel後,數據並不會被清理,隊列會愈來愈長,因此這裏咱們設置個最大長度,避免溢出。
這裏有兩個存儲服務。假設存儲相對比較慢,爲了能及時處理,咱們構建了更多的存儲服務。
咱們看看存儲和分析服務消費數據的過程。這裏兩個存儲服務都嘗試獲取數據,可是很明顯,只有一個獲取到了數據進行處理。分析在這時嘗試取3條數據加入分析處理,可是由於stream裏只有1條,因此這裏只取到1條。
存儲、分析服務消費數據
分析服務率先完成了數據的消費,因此在分析服務裏立刻答覆了一個ack給stream,告訴它,已經消費完成了。隨後存儲服務也完成了存儲,存儲服務也發送了個ack給stream。
消費完成,答覆ACK
分析服務剛剛答覆完ack,由於某些緣由,重啓了。分析服務啓動的時候,不清楚消費到哪裏了,因此嘗試從初始位置開始消費。這裏由於前面已經消費過而且返回了ack,因此沒有取到任何可消費的數據。若是有數據沒消費完成的,經過這種方式能夠進行再次消費,因此服務在消費時須要可以處理重入。
分析服務重啓,開頭消費起
在這裏咱們看到,檢測數據也在不停地到來,存儲和分析服務一樣按照前面的規則消費。分析服務按照本身的能力,依然嘗試一次取用3條,根據結果咱們能夠看到,此次分析服務取到了兩條消費數據。
新檢測數據
分析服務消費數據
存儲服務呢?兩個存儲服務也都取到了數據進行消費。
存儲服務消費數據
這時候用戶開始訪問應用了,他打算看下污染狀況是怎樣的。咱們都能理解,剛剛購買一件新東西的時候,咱們會更傾向於立刻看看,因此這裏用戶確定是指望看到污染物狀況的。可是這時數據既沒有分析完畢,也沒有存儲完畢,咱們須要怎麼處理呢?
應用服務能夠先檢測狀態,發現須要的數據尚未處理完成,所以從常規緩存裏面獲取明顯是獲取不到的。因此應用直接從stream裏獲取了,咱們能夠看到,用戶順利地秒看到了監測數值,對身邊的情況立刻有了一個瞭解。用戶想看看還有沒有新數據,因此在應用上點了下刷新,咱們看到,此次仍然能從stream中獲取到須要的數據。固然,若是用戶想針對性地看看狀況,應用中也能夠指定ID讀取。那還有沒有其它方式呢?xrange也是批量取出須要消息的一種方法。
應用使用xread方式讀取數據
應用使用xrange方式截取數據
從這裏能夠感覺到,雖然咱們的日子,在時間的流裏面勇往直前,一去不返了,但幸運的是,在Redis的流裏面,咱們仍然能夠從過往裏截取出任意一段,從新品嚐,溫故知新。
回到例子。用戶刷完兩次後,存儲和分析服務處理好數據了,因此存儲和分析服務再次向stream發送ack消息,示意已經處理完成。
消費完畢,返回ack
固然,這些Redis裏面的處理,都是一如既往地高性能、高效的。
這裏只是一個簡單的截面,一個示意。實際上,Redis本來的使用場景就很是豐富,例如,做爲會話緩存,做爲頁面的全頁緩存,手機或者網頁的驗證碼,服務訪問的頻率限制,密碼防暴力破解,競技場、吃雞、短視頻女神榜等各類排行榜,點贊、閱讀數等計數器和排行,關注某個標籤、或者某個明星的人,限時優惠活動,證券的實時指標計算,號碼發放器,甚至還有geo地理信息,基於LUA的自定義邏輯,還有訂閱發佈,等等,很是豐富。這些都是基於Redis豐富的數據結構,開發出來的使用方式。
羅胖在時間的朋友演講說,大趨勢每每不是一個小趨勢逐步成長起來的,而是趨勢撞擊趨勢,改變帶來改變,逐漸滾動、交織變大的。那麼Redis的流,能在這些已經存在的應用場景裏,提供怎樣的碰撞?又能在新的領域裏,帶來怎樣的趨勢?歡迎你們前來共同討論。
也歡迎你們到華爲雲分佈式緩存免費領取Redis 5.0。如今Redis 5.0是公測階段,能夠免費體驗。領取也很是簡單,申請公測,而後花費幾秒建立Redis 5.0實例,就能夠了。