6

Theo Amazon Kinesis Streams documentation, một bản ghi có thể được gửi nhiều lần. Cách duy nhất để đảm bảo xử lý mọi bản ghi chỉ một lần là lưu trữ tạm thời chúng trong cơ sở dữ liệu hỗ trợ kiểm tra Tính toàn vẹn (ví dụ: DynamoDB, Elasticache hoặc MySQL/PostgreSQL) hoặc chỉ kiểm tra RecordId cho từng phân đoạn Kinesis.Làm cách nào để xử lý các bản sao của Amazon Kinesis Record?

Bạn có biết cách xử lý bản sao tốt hơn/hiệu quả hơn không?

Trả lời

6

Chúng tôi đã có chính xác vấn đề mà khi xây dựng một hệ thống đo từ xa cho một ứng dụng điện thoại di động . Trong trường hợp của chúng tôi, chúng tôi cũng không chắc chắn rằng các nhà sản xuất gửi từng thông điệp một cách chính xác một lần, vì vậy cho mỗi bản ghi nhận được, chúng tôi đã tính toán MD5 của mình và kiểm tra xem nó có được lưu trữ dưới dạng lưu trữ liên tục hay không, bit khó nhất. Trước hết, chúng tôi đã thử cơ sở dữ liệu quan hệ tầm thường, nhưng nó nhanh chóng trở thành một nút cổ chai lớn của toàn bộ hệ thống vì đây không chỉ là trường hợp nặng và nặng, vì khối lượng dữ liệu mặc dù Kinesis khá đáng kể. .

Chúng tôi đã có bảng DynamoDB lưu trữ MD5 cho mỗi thông báo duy nhất. Vấn đề chúng tôi gặp phải là việc xóa các tin nhắn không dễ dàng - mặc dù bảng của chúng tôi có phân vùng và các phím sắp xếp, DynamoDB không cho phép thả tất cả các bản ghi với một khóa phân vùng đã cho, chúng tôi phải truy vấn tất cả các sắp xếp các giá trị khóa (làm lãng phí thời gian và dung lượng). Thật không may, chúng tôi đã phải chỉ đơn giản là thả toàn bộ bảng một lần trong một thời gian. Một giải pháp tối ưu khác là thường xuyên xoay các bảng DynamoDB lưu trữ các định danh thông báo. Tuy nhiên, gần đây DynamoDB đã giới thiệu một tính năng rất tiện dụng - Time To Live, có nghĩa là bây giờ chúng ta có thể kiểm soát kích thước của một bảng bằng cách cho phép tự động hết hạn trên cơ sở mỗi bản ghi. Trong ý nghĩa đó, DynamoDB có vẻ khá giống ElastiCache, tuy nhiên ElastiCache (ít nhất là Memcached cluster) ít bền hơn - không có dự phòng ở đó, và tất cả dữ liệu nằm trên các nút chấm dứt bị mất trong trường hợp quy mô hoạt động hay thất bại.

+1

Xin chào Dmitry. Tôi đã chạy một số điểm chuẩn bằng cách sử dụng một cái gì đó tương tự như cơ sở hạ tầng JustGiving được giải thích tại đây: https://aws.amazon.com/blogs/compute/serverless-cross-account-stream-replication-using-aws-lambda -amazon-dynamodb-and-amazon-kinesis-firehose/Tại sao bạn tính toán MD5 checksum thay vì sử dụng Shardid + SequenceNumber cho Bảng DDB của bạn? – Antonio

+2

Xin chào @Antonio Trong trường hợp của chúng tôi, nhà sản xuất có thể đăng cùng một thông điệp nhiều lần. Nếu đúng như vậy, thì Kinesis sẽ coi chúng là những thông điệp khác nhau (đơn giản vì có từ 2 bài viết trở lên từ nhà sản xuất). Như chúng ta biết rằng mọi thông điệp phải là duy nhất, chúng ta chỉ đơn giản bỏ qua các thông điệp mà md5 có Ngoài ra, md5 đã được tính toán bởi các nhà sản xuất, tiết kiệm thời gian tính toán cho các coser (được cho khối lượng dữ liệu tương đối lớn đi qua Kinesis) –

+0

Chỉ muốn ném ra khỏi đó - AWS lưu ý rằng khác nhau các nhà sản xuất có thể tự nhiên sản xuất cùng một bản ghi nhiều lần do các trường hợp lỗi, và cũng phổ biến hơn, nhiều người tiêu dùng có thể kéo cùng một tập hợp các bản ghi. Tôi đang đối phó với điều này trên hệ thống của chúng tôi bây giờ quá. Chúng tôi sử dụng elasticsearch và kế hoạch cho thời điểm này là sử dụng elastics được xây dựng trong phiên bản để đảm bảo rằng cùng một bản ghi không được cập nhật cùng một lúc và sau đó memozie danh sách các sự kiện gần đây được áp dụng cho bản ghi trên bản ghi. – genexp

7

Điều bạn đã đề cập là vấn đề chung của tất cả các hệ thống xếp hàng có phương pháp "ít nhất một lần". Ngoài ra, không chỉ hệ thống xếp hàng, nhà sản xuất và người tiêu dùng cả hai có thể xử lý cùng một thông báo nhiều lần (do lỗi ReadTimeout, v.v.). Kinesis và Kafka đều sử dụng mô hình đó. Thật không may không có một câu trả lời dễ dàng cho điều đó.

Bạn cũng có thể thử sử dụng hàng đợi tin nhắn "chính xác một lần", với cách tiếp cận giao dịch chặt chẽ hơn. Ví dụ: AWS SQS thực hiện: 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/. Lưu ý, thông lượng SQS nhỏ hơn nhiều so với Kinesis.

Để giải quyết vấn đề của bạn, bạn nên biết miền ứng dụng của mình và cố gắng giải quyết nội bộ như bạn đã đề xuất (kiểm tra cơ sở dữ liệu). Đặc biệt là khi bạn giao tiếp với dịch vụ bên ngoài (ví dụ như máy chủ email), bạn có thể khôi phục trạng thái hoạt động để ngăn việc xử lý kép (vì gửi đôi trong ví dụ máy chủ email, có thể dẫn đến nhiều bản sao của cùng một bài đăng trong hộp thư của người nhận).

Xem thêm các khái niệm sau;

  1. At-nhất-một lần giao hàng: http://www.cloudcomputingpatterns.org/at_least_once_delivery/
  2. Chính xác-once Delivery: http://www.cloudcomputingpatterns.org/exactly_once_delivery/
  3. Processor idempotent: http://www.cloudcomputingpatterns.org/idempotent_processor/
+0

Cảm ơn câu trả lời của bạn. Tôi không thể sử dụng SQS do thông lượng cao. Thông lượng cao cũng là lý do tại sao tôi điểm chuẩn một số giải pháp với các kho lưu trữ bền khác nhau (Mysql/PgSQL/Aurora/ElasticSearch/DynamoDB). Cách tốt nhất để lưu trữ tạm thời ID sự kiện là Redis, nhưng ElastiCache không thể cấp cho bạn độ bền dữ liệu. Đó là lý do tại sao tôi đang tìm kiếm những cách khác để thực hiện nó. – Antonio

+1

Redis cấp cho bạn theo dõi tx nghiêm ngặt nhưng đó là một nút duy nhất và RDS quá chậm, bạn đã đúng. DynamoDB có vẻ là giải pháp PaaS duy nhất của bạn. Tuy nhiên, nếu bạn muốn quản lý các cá thể EC2, bạn có thể thử các giải pháp nhóm trong bộ nhớ như Hazelcast hoặc VoltDB (trên nhiều nút r3)? – az3

+0

Cơ sở dữ liệu trong bộ nhớ không bền. Nếu cụm Hazelcast của bạn không thành công, bạn không thể hiểu được thư nào bạn đã xử lý. : ( – Antonio

Các vấn đề liên quan