首先說一下隊列設計。
假設有一本很長的書,并且有許多人閱讀。有些人可以在午餐時間閱讀,有些人在周一晚上閱讀,其他人則在周末帶回家。這本書很長,在任何時候,我們都有數百人閱讀它。
書的讀者需要跟蹤他們在書中的位置,因此他們通過在書中放置書簽來跟蹤他們的位置。有些讀者閱讀速度很慢,書簽就在開頭。而有些讀者半途而廢,將自己的書簽留在書中,再也不會回來。
更糟糕的是,我們每天都在給這本書加頁。沒有人能真正讀完這本書。
最終,書被書簽塞滿了,直到有一天,它太重了,搬不動,沒人能再讀了。
于是有一個非常聰明的人決定不允許讀者在書中放置書簽,而必須在日記中寫下他們要翻到的頁數。
這就是 Apache Kafka 的設計,而且是一個非常有彈性的設計。
其他隊列的常見替代設計是讓隊列服務跟蹤讀者所在的位置——這意味著需要為每個讀者分配內存。行為不端的讀者可能會反復請求新的隊列會話,這會使隊列服務不堪重負。因此,這不是一個好的設計,因為我們希望讀者可以隨意閱讀而不會對隊列造成任何風險。
Kafka
Kafka 是圍繞一系列事件而設計的,例如:
1001:'甲'購買了旅游套餐'A'
1002:'甲'更新了他的訂閱偏好為“每日”
1003:'乙'使用'iphone'登錄
1004:'乙'打開了旅游套餐'巴厘島'
1005:'乙'使用'桌面Web'登錄
1006:'乙'購買了旅游套餐'巴厘島'
Kafka 事件閱讀器會跟蹤它們已讀取的流中的 ID,這意味著事件服務器不需要跟蹤它們。即使有許多行為不佳的讀者, Kafka 事件服務器也能保持可預測的內存使用。
Kafka 聽起來很不錯,為什么需要 redis Streams?
Kafka 是存儲事件流的絕佳選擇,它專為大規模而設計。為了達到這種規模,Kafka 承擔了額外的復雜性,配置和管理 Kafka 設置需要了解一些復雜的概念。但對于較小的項目,更簡單、更小的系統可能是更好的選擇。
Redis 是簡單的、非持久性數據存儲的最常見選擇之一。它對所有流行的編程語言都有很好的庫支持,并且被大多數開發人員所熟知。Redis 支持更簡單版本的 Kafka 事件流概念,使每個人都可以輕松使用。
Redis Streams使用示例
- 創建一個名為“stream”的流
XADD stream * data hello
- 讀取名為“stream”的流中的所有消息
XREAD STREAMS stream $
- 讀取名為“stream”的流中的最新消息
XREAD STREAMS stream 0
- 讀取名為“stream”的流中的最新消息,并等待1秒鐘以獲取更多消息
XREAD STREAMS stream 0 BLOCK 1000
- 讀取名為“stream”的流中的最新消息,并等待1秒鐘以獲取更多消息,最多獲取10條消息
XREAD STREAMS stream 0 COUNT 10 BLOCK 1000
- 讀取名為“stream”的流中的最新消息,并將其標記為已處理
XREAD STREAMS stream 0 COUNT 1 BLOCK 1000
XACK stream group 1526569493336-0
總結
在一些需要使用事件流的場景中,一般使用 Kafka ,但在一些簡單的場景下,也可以考慮使用 Redis Stream,畢竟Redis Stream更加簡單,成本更低。