Cách thích hợp để đồng bộ hóa dữ liệu trên microservice là gì?


17

Tôi còn khá mới với kiến ​​trúc microservice. Chúng tôi có một ứng dụng web có kích thước vừa phải và tôi đang cân nhắc những ưu và nhược điểm của việc chia nhỏ nó thành microservice thay vì một hệ thống nguyên khối mà chúng tôi hiện đang tiến lên.

Theo như tôi hiểu, hãy xem xét các dịch vụ siêu nhỏ ABmỗi dịch vụ đều dựa vào một tập hợp dữ liệu mà người kia có. Nếu một tin nhắn được đăng bằng cách Anói rằng một cái gì đó đã thay đổi, Bcó thể sử dụng tin nhắn đó và sao chép một bản sao Athông tin địa phương và sử dụng nó để làm bất cứ điều gì Bcần làm.

Tuy nhiên, điều gì xảy ra nếu Bđi xuống / thất bại và sau một thời gian, sẽ quay trở lại. Trong thời gian xuống, Ađã xuất bản thêm hai tin nhắn. Làm thế nào để Bbiết cách cập nhật bản sao Athông tin địa phương của nó ?

Cấp, nếu Blà người tiêu dùng duy nhất của Ahàng đợi, thì nó có thể bắt đầu đọc nó khi nó trở lại trực tuyến nhưng nếu có những người tiêu dùng khác của hàng đợi đó và những tin nhắn đó được tiêu thụ thì sao?

Một ví dụ cụ thể hơn, nếu một Usersdịch vụ có địa chỉ email được cập nhật trong khi Billingmicroservice ngừng hoạt động, nếu Billingmicroservice trở lại một lần nữa, làm thế nào để biết rằng email đã được cập nhật?

Khi microservice trở lại, nó có phát sóng thông báo "Này, tôi đã sao lưu, cung cấp cho tôi tất cả thông tin hiện tại của bạn?"

Nói chung, các thực hành công nghiệp tốt nhất để đồng bộ hóa dữ liệu là gì?


1
Để tránh nó bất cứ khi nào có thể.
Telastyn

1
Tại sao không Orderscần phải biết bất cứ điều gì về Users?
kdgregory

Đó chỉ là một ví dụ. Thay thế hai bằng bất cứ điều gì bạn muốn có ý nghĩa.
noblerare

một quạt ra định tuyến sẽ giải quyết 'tin nhắn của bạn bị tiêu thụ bởi vấn đề của người khác. nhưng nó thực sự không rõ ràng những gì bạn đang cố gắng để đạt được.
Ewan

@Ewan Tôi đã cập nhật bài viết gốc của mình để giải thích rõ hơn những gì tôi đang cố gắng hỏi.
noblerare

Câu trả lời:


6

Sau khi thực hiện một nghiên cứu thêm chút, tôi stumbled khi này bài báo từ mà tôi đã kéo một số dấu ngoặc kép ra rằng tôi nghĩ là hữu ích cho những gì tôi muốn đạt được (và cho bất kỳ độc giả trong tương lai). Điều này cung cấp một cách để áp dụng một mô hình lập trình phản ứng trên một mô hình lập trình bắt buộc.

Tìm nguồn cung ứng sự kiện

Ý tưởng ở đây là đại diện cho sự chuyển đổi trạng thái của mọi ứng dụng dưới dạng một sự kiện bất biến. Các sự kiện sau đó được lưu trữ dưới dạng nhật ký hoặc nhật ký khi chúng xảy ra (còn được gọi là 'cửa hàng sự kiện'). Chúng cũng có thể được truy vấn và lưu trữ vô thời hạn, nhằm thể hiện trạng thái của ứng dụng, nói chung, phát triển theo thời gian.

Điều này giúp đạt được điều đó là nếu một dịch vụ siêu nhỏ đi xuống nhưng các sự kiện khác liên quan đến nó đang được xuất bản các sự kiện được sử dụng bởi các dịch vụ khác của microservice, khi dịch vụ đó xuất hiện, nó có thể tham khảo điều này event stoređể lấy tất cả các sự kiện mà nó đã bỏ lỡ trong suốt thời gian nó đi xuống.

Apache Kafka là nhà môi giới sự kiện

Hãy xem xét việc sử dụng Apache Kafka có thể lưu trữ và gửi hàng ngàn sự kiện mỗi giây và có các cơ chế sao chép và chống lỗi tích hợp. Nó có một kho lưu trữ các sự kiện liên tục có thể được lưu trữ trên đĩa vô thời hạn và được tiêu thụ bất cứ lúc nào (nhưng không bị xóa) khỏi Chủ đề (hàng đợi ưa thích của Kafka) đã được gửi tới.

Các sự kiện sau đó được chỉ định bù đắp mà xác định chúng một cách đơn nhất trong Chủ đề - Kafka có thể tự quản lý các khoản bù trừ đó, dễ dàng cung cấp cho nhiều nhất một lần một hoặc một ít ngữ nghĩa giao hàng, nhưng chúng cũng có thể được đàm phán khi một người tiêu dùng sự kiện tham gia Chủ đề , cho phép microservice bắt đầu tiêu thụ các sự kiện từ bất kỳ nơi nào tùy ý - thường là từ nơi người tiêu dùng rời đi. Nếu phần bù sự kiện được tiêu thụ cuối cùng được duy trì giao dịch trong bộ lưu trữ cục bộ của dịch vụ khi usecase 'hoàn thành thành công', phần bù đó có thể dễ dàng được sử dụng để đạt được một chính xác một lần ngữ nghĩa phân phối sự kiện.

Trên thực tế, khi người tiêu dùng tự nhận mình là Kafka, Kafka sẽ ghi lại những tin nhắn nào được gửi đến người tiêu dùng nào để nó không phục vụ lại.

Sagas

Đối với các usecase phức tạp hơn, nơi thực sự cần liên lạc giữa các dịch vụ khác nhau, trách nhiệm hoàn thành usecase phải được công nhận - usecase được phân cấp và chỉ kết thúc khi tất cả các dịch vụ liên quan thừa nhận nhiệm vụ của họ đã hoàn thành thành công, nếu không thì toàn bộ usecase phải thất bại và các biện pháp khắc phục phải được kích hoạt để khôi phục lại bất kỳ trạng thái cục bộ không hợp lệ nào.

Đây là khi saga đi vào chơi. Một saga là một chuỗi các giao dịch địa phương. Mỗi giao dịch cục bộ cập nhật cơ sở dữ liệu và xuất bản một thông báo hoặc sự kiện để kích hoạt giao dịch cục bộ tiếp theo trong saga. Nếu một giao dịch cục bộ thất bại vì nó vi phạm quy tắc kinh doanh thì saga thực hiện một loạt các giao dịch bù trừ hoàn tác các thay đổi được thực hiện bởi các giao dịch địa phương trước đó. Đọc này để biết thêm.


Tôi vẫn không hiểu tại sao bạn muốn xây dựng một cấu trúc phức tạp như vậy. Nó thường dễ dàng hơn nhiều nếu mỗi dịch vụ chỉ giữ dữ liệu của riêng mình và cung cấp cho các dịch vụ khác theo yêu cầu.
J. Fabian Meier

^ Nhưng nó sẽ làm giảm tính khả dụng của hệ thống. Cấu trúc phức tạp có thể được bảo hành nếu cần khả năng phục hồi cao.
avmohan

4

Tôi sẽ thách thức toàn bộ ý tưởng của bạn về "đẩy dữ liệu đến tất cả các dịch vụ siêu nhỏ khác".

Thông thường, nếu một dịch vụ thanh toán cần một địa chỉ email, nó chỉ hỏi dịch vụ địa chỉ cho địa chỉ email của khách hàng cụ thể. Nó không cần phải giữ một bản sao của tất cả dữ liệu địa chỉ và cũng sẽ không được thông báo nếu có bất cứ điều gì thay đổi. Nó chỉ hỏi và nhận được câu trả lời từ dữ liệu mới nhất.


Tôi nghĩ rằng câu trả lời này là chính xác. Nó loại bỏ rất nhiều vấn đề liên quan đến đồng bộ hóa. Trên thực tế, tôi đang xem mã ngay bây giờ có vấn đề như vậy bởi vì các dịch vụ khác nhau đang giữ các bản sao thông tin và có các vấn đề đồng bộ như vậy.
DaveG

2
Cảm ơn câu trả lời của bạn. Vậy tại sao sau đó lại cần một mô hình pub / sub và hàng đợi tin nhắn? Nếu chúng tôi đang cố gắng "kéo" thay vì "đẩy" dữ liệu, chúng tôi lo lắng về độ trễ dịch vụ.
noblerare

AFAIK, dịch vụ của bạn không cần phải phản ứng ngay lập tức nếu có gì đó thay đổi (như trong quán rượu / phụ), nhưng đôi khi cần dữ liệu. Sau đó tôi sẽ chỉ kéo nó. Nếu bạn lo lắng về độ trễ, bạn có thể lưu trữ dữ liệu, nhưng điều này một lần nữa phải trả giá khi không biết liệu dữ liệu có được cập nhật hay không. Nếu tệp của bạn lớn, bạn cũng có thể hỏi xem có gì thay đổi trước khi bạn lấy lại thứ gì đó không.
J. Fabian Meier

Hãy nhớ rằng giải pháp này có chi phí kết hợp chặt chẽ dịch vụ phụ thuộc, điều đó có nghĩa là địa chỉ email sẽ không khả dụng khi dịch vụ người dùng không khả dụng. Một trong những ý tưởng ban đầu về việc thoát ra khỏi các dịch vụ để chúng có thể triển khai độc lập, có thể mở rộng, v.v. Nếu tất cả các dịch vụ liên lạc trực tiếp với nhau mà không có bộ đệm hoặc đảm bảo tính sẵn sàng cao thì khi một hệ thống ngừng hoạt động, tất cả đều bị hỏng đi xuống.
dukethrash

@dukethrash Sau đó làm cho chúng có sẵn cao.
J. Fabian Meier

0

Bạn có thể thay thế hàng đợi sự kiện thông thường bằng mô hình nhà xuất bản / người đăng ký, trong đó Adịch vụ xuất bản một thông báo mới về chủ đề TBloại microservice sẽ đăng ký vào cùng một chủ đề.

Lý tưởng nhất Bsẽ là một dịch vụ phi trạng thái và nó sẽ sử dụng một dịch vụ kiên trì tách rời, sao cho một Btrường hợp dịch vụ thất bại sẽ được thay thế bằng cách sinh ra một hoặc nhiều Btrường hợp dịch vụ để tiếp tục công việc của mình, đọc từ cùng một dịch vụ kiên trì được chia sẻ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.