根據亞馬遜Kinesis Streams documentation,一條記錄可以多次遞送。你如何處理亞馬遜Kinesis記錄重複?
要確保一次處理每條記錄的唯一方法是將它們臨時存儲在支持完整性檢查(例如DynamoDB,Elasticache或MySQL/PostgreSQL)的數據庫中,或者只是爲每個Kinesis分片檢查點RecordId。
你知道更好/更有效的處理重複的方法嗎?
根據亞馬遜Kinesis Streams documentation,一條記錄可以多次遞送。你如何處理亞馬遜Kinesis記錄重複?
要確保一次處理每條記錄的唯一方法是將它們臨時存儲在支持完整性檢查(例如DynamoDB,Elasticache或MySQL/PostgreSQL)的數據庫中,或者只是爲每個Kinesis分片檢查點RecordId。
你知道更好/更有效的處理重複的方法嗎?
我們建立一個遙測系統在移動應用時不得不正是問題。在我們的例子中,我們也不確定哪些生產者只發送一次消息,因此對於每個收到的記錄,我們都會動態計算MD5並檢查它是否以某種持久存儲形式呈現,但實際上使用的是最棘手的一點。首先,我們嘗試了一個簡單的關係數據庫,但它很快成爲整個系統的一個主要瓶頸,因爲這不僅僅是讀數量大而且是寫重的情況,因爲通過Kinesis的數據量非常大。
我們最終爲DynamoDB表存儲了每個唯一消息的MD5。我們遇到的問題是刪除消息並不容易 - 即使我們的表包含分區和排序鍵,DynamoDB不允許使用給定的分區鍵刪除所有記錄,但我們必須查詢所有的記錄才能獲取排序鍵值(浪費時間和容量)。不幸的是,我們不得不只是簡單地放下整個桌子。另一種不理想的解決方案是定期輪換存儲消息標識符的DynamoDB表。
然而,最近DynamoDB推出了一款非常方便的功能 - Time To Live,這意味着我們現在可以通過啓用基於每個記錄的基礎自動到期控制表的大小。從這個意義上說,DynamoDB似乎與ElastiCache非常相似,但ElastiCache(至少Memcached集羣)的耐久性要差得多 - 在那裏沒有冗餘,並且在運行或失敗的規模情況下,駐留在終止節點上的所有數據都會丟失。
你提到的問題是所有隊列系統都有「至少一次」方法的一般問題。另外,不僅是隊列系統,生產者和消費者都可能多次處理相同的消息(由於ReadTimeout錯誤等)。 Kinesis和Kafka都使用這種範例。不幸的是,這不是一個簡單的答案。
您也可以嘗試使用「精確一次」的消息隊列,並採用更嚴格的事務處理方法。例如,AWS SQS可以:https://aws.amazon.com/about-aws/whats-new/2016/11/amazon-sqs-introduces-fifo-queues-with-exactly-once-processing-and-lower-prices-for-standard-queues/。請注意,SQS吞吐量遠小於Kinesis。
要解決您的問題,您應該瞭解您的應用程序域,並嘗試像您建議的那樣在內部解決它(數據庫檢查)。特別是當你與外部服務(比如說一個電子郵件服務器)通信時,你應該能夠恢復操作狀態,以防止雙重處理(因爲在電子郵件服務器例子中雙重發送,可能會導致多個副本收件人郵箱中的同一篇文章)。
另請參閱以下概念;
謝謝你的回答。由於吞吐量高,我無法使用SQS。高吞吐量也是我使用不同的持久存儲(Mysql/PgSQL/Aurora/ElasticSearch/DynamoDB)對幾種解決方案進行基準測試的原因。 臨時存儲事件ID的最佳方式是Redis,但ElastiCache無法授予您數據持久性。這就是爲什麼我正在尋找替代方法。 – Antonio
Redis授予您嚴格的tx跟蹤,但它是單節點,RDS太慢,您是對的。 DynamoDB似乎是您唯一的PaaS解決方案。但是,如果您想要管理EC2實例,則可以嘗試使用內存集羣解決方案,如Hazelcast或VoltDB(在很多r3節點上)? – az3
內存數據庫不耐用。如果您的Hazelcast羣集失敗,則無法瞭解您已處理的郵件。 :( – Antonio
嗨德米特里。我正在運行幾個基準使用類似的JustGiving基礎設施解釋這裏:https://aws.amazon.com/blogs/compute/serverless-cross-account-stream-replication-using-aws-lambda -amazon-dynamodb-and-amazon-kinesis-firehose /。爲什麼你計算MD5校驗和而不是使用Shardid + SequenceNumber作爲DDB表? – Antonio
Hi @Antonio在我們的例子中,生產者可能會發布相同的消息如果是這樣的話,那麼Kinesis會認爲它們是不同的信息(因爲有兩個或更多來自制作人的帖子),因爲我們知道每條信息必須是唯一的,所以我們只是忽略了md5的信息md5也是由生產者計算出來的,爲cosume節省了一些計算時間(考慮到Kinesis數據量相對較大) –
只是想拋棄 - AWS注意到不同的由於錯誤情況,生產者可以自然地生成相同的記錄,更常見的情況是,多個消費者可以拉同一組記錄。我現在也在我們的系統上處理這個問題。我們使用elasticsearch,並且此時的計劃是使用版本控制中構建的彈性體來確保同一記錄不會同時更新,然後記錄應用於記錄本身上的記錄的近期事件列表。 – genexp