Khôi phục bản đồ mongodb

Thiết kế và thao tác với cơ sở dữ liệu như thế nào luôn là một vấn đề vô cùng khó khăn khi bạn thực hiện một dự án Microservice. Ở bài viết này, mình sẽ phân tích các pattern để thiết kế cơ sở dữ liệu cùng với ưu nhược điểm của mình

Hãy tưởng tượng, bạn xây dựng một hệ thống thương mại điện tử (viết thế cho oách) với Microservice Architecture. Ta cần có một cơ sở dữ liệu ở định dạng như sau.

Khôi phục bản đồ mongodb

Lão Văn Tuấn @kaitou229

Theo dõi

1. 3K 59 13

Đã đăng vào ngày 8 tháng 19 năm 2019 6. 17 CH 12 phút đọc

10. 2k

1

17

Tìm hiểu về Microservices - Phần 3. Quản lý cơ sở dữ liệu trên Microservices

  • Report
  • Add to series of me

Thiết kế và thao tác với cơ sở dữ liệu như thế nào luôn là một vấn đề vô cùng khó khăn khi bạn thực hiện một dự án Microservice. Ở bài viết này, mình sẽ phân tích các pattern để thiết kế cơ sở dữ liệu cùng với ưu nhược điểm của mình

Hãy tưởng tượng, bạn xây dựng một hệ thống thương mại điện tử (viết thế cho oách) với Microservice Architecture. Ta cần có một cơ sở dữ liệu ở định dạng như sau.

1. Request

  • Các dịch vụ cần đảm bảo mối quan hệ thả lỏng để triển khai, phát triển và mở rộng quy mô được độc lập
  • Một số giao dịch kinh doanh cần truy vấn dữ liệu thuộc quyền sở hữu của các dịch vụ khác nhau
  • Một số giao dịch kinh doanh cần thực thi tính nhất quán và bất biến trên nhiều dịch vụ. VD. Đặt hàng cần xác minh rằng đơn hàng mới sẽ không vượt quá giới hạn tín hiệu của khách hàng. Một số giao dịch kinh doanh khác nhau, phải cập nhật dữ liệu thuộc quyền sở hữu của các dịch vụ khác nhau
  • Một số truy vấn cần tham gia dữ liệu thuộc sở hữu của các dịch vụ khác nhau
  • Cơ sở dữ liệu kép khi phải được nhân rộng hoặc phân chia để mở rộng quy mô
  • Các dịch vụ khác nhau có yêu cầu lưu trữ dữ liệu khác nhau. Đối với một số dịch vụ, SQL là lựa chọn tốt nhất. Các dịch vụ khác có thể cần đến một nền tảng NoSQL như MongoDB

2. cơ sở dữ liệu dùng chung

Đây là dạng Cơ sở dữ liệu được chia sẻ cho nhiều dịch vụ. Các dịch vụ được tự do truy cập các bảng của nhau để đảm bảo giao dịch ACID

Ví dụ. OrderService và CustomerService tự do truy cập các bảng của nhau. OrderService có thể sử dụng giao dịch ACID sau khi đảm bảo rằng một đơn đặt hàng mới sẽ không vi phạm giới hạn tín hiệu của khách hàng

BEGIN TRANSACTION
…
SELECT ORDER_TOTAL
 FROM ORDERS WHERE CUSTOMER_ID = ?
…
SELECT CREDIT_LIMIT
FROM CUSTOMERS WHERE CUSTOMER_ID = ?
…
INSERT INTO ORDERS …
…
COMMIT TRANSACTION

Lợi ích

  • Một cơ sở dữ liệu duy nhất là đơn giản hơn để hoạt động
  • Các nhà phát triển có thể dễ dàng sử dụng giao dịch ACID để thực hiện tính năng thống kê dữ liệu tốt nhất

Un mode

  • Khớp nối thời gian phát triển. Ví dụ. Sự thay đổi lược đồ của DB sẽ gây ảnh hưởng đến việc nhiều dịch vụ truy cập trực tiếp vào các bảng và trong khi các thành viên lập trình cho mỗi dịch vụ là khác nhau thì rõ ràng khớp nối này làm chậm quá trình phát triển
  • khớp nối thời gian chạy. Tất cả các dịch vụ đều truy cập vào cùng một cơ sở dữ liệu, chúng có khả năng xen kẽ nhau. Ví dụ. nếu một giao dịch CustomerService mất nhiều thời gian và khóa bảng ORDER thì OrderService sẽ bị chặn
  • Thực tế đối với các hệ thống lớn, một DB đơn lẻ không thể đáp ứng đủ yêu cầu về lưu trữ và truy cập dữ liệu của tất cả các dịch vụ

3. Cơ sở dữ liệu cho mỗi dịch vụ

Đây là dạng Cơ sở dữ liệu dành riêng cho mỗi máy chủ. Các dịch vụ khác nếu muốn thao tác với DB này thì cần phải thông qua API của dịch vụ quản lý DB đó

With ví dụ ban đầu, ta có sơ đồ cho cấu trúc của mẫu này như sau.

Cơ sở dữ liệu của dịch vụ là một phần của việc triển khai dịch vụ đó. Nó không thể truy cập trực tiếp bởi các dịch vụ khác

Có một số cách khác nhau để giữ DB của mỗi dịch vụ là riêng tư. Bạn không cần phải cung cấp cơ sở dữ liệu máy chủ cho mỗi dịch vụ. Ví dụ đối với SQL

  • Bàn riêng cho mỗi dịch vụ. Mỗi dịch vụ sở hữu một tập tin các bảng chỉ được truy cập bởi các dịch vụ đó
  • Lược đồ cho mỗi dịch vụ. Mỗi dịch vụ có một lược đồ riêng tư với dịch vụ đó
  • Cơ sở dữ liệu-máy chủ-mỗi dịch vụ. Mỗi dịch vụ có một máy chủ cơ sở dữ liệu riêng

Bảng riêng cho mỗi dịch vụ và lược đồ cho mỗi dịch vụ sẽ có chi phí thấp nhất và việc sử dụng lược đồ cho mỗi dịch vụ tốt hơn vì nó làm cho quyền sở hữu trở nên rõ ràng. Trong khi đó, một số dịch vụ có lượng truy cập cao sẽ cần có máy chủ cơ sở dữ liệu của riêng nó (Database-server-per-service)

Lợi ích

  • Giúp đảm bảo rằng các dịch vụ được kết nối một cách thuyết phục. Việc thay đổi cơ sở dữ liệu của một dịch vụ không ảnh hưởng đến bất kỳ dịch vụ nào khác
  • Mỗi dịch vụ có thể sử dụng loại cơ sở dữ liệu phù hợp nhất với nhu cầu của nó. Ví dụ. dịch vụ tìm kiếm có thể sử dụng Tìm kiếm đàn hồi. Trong khi đó các dịch vụ khác có thể sử dụng MySQL, MongoDB hay Neo4j,

Un mode

  • Thực hiện trải nghiệm giao dịch mở rộng trên nhiều dịch vụ không đơn giản. Các phân tán giao dịch nên bị hạn chế do định lý CAP. Hơn nữa, nhiều cơ sở dữ liệu hiện đại (NoSQL) không hỗ trợ chúng
  • Việc thực hiện các truy vấn cần tham gia dữ liệu có trong nhiều cơ sở dữ liệu là một chế độ thức
  • Sự phức tạp của công việc quản lý nhiều cơ sở dữ liệu SQL và NoSQL

Có nhiều mô hình/giải pháp khác nhau để giải quyết các truy vấn thanh toán và giao dịch trên nhiều dịch vụ

  • Để thực hiện giao dịch trên nhiều dịch vụ ta có thể sử dụng Saga pattern
  • Để thực hiện truy vấn trên nhiều dịch vụ ta có thể sử dụng. Thành phần API hoặc Phân tách trách nhiệm truy vấn lệnh (CQRS)

4. mô hình saga

Đối với các hệ thống lựa chọn mô hình Cơ sở dữ liệu cho mỗi Dịch vụ, mỗi dịch vụ sẽ có một Cơ sở dữ liệu riêng. Tuy nhiên, một số giao dịch cần trải rộng trên nhiều dịch vụ. You need a machine to ensure the best system of data on the serivces

Giải pháp được đưa ra như sau. Ta sẽ coi mỗi trải nghiệm giao dịch trên nhiều dịch vụ là một Saga. Và mỗi một Saga là một chuỗi các bộ giao dịch cục bộ trên từng dịch vụ khác nhau. Nếu một bộ giao dịch cục bộ thất bại, Saga sẽ thực hiện một loạt các giao dịch để khôi phục các thay đổi đã được thực hiện trước đó.

Có 2 cách để phát triển Saga

a. Câu chuyện dựa trên sự kiện/vũ đạo

Dịch vụ đầu tiên thực hiện giao dịch và sau đó xuất bản một sự kiện. Sự kiện này được lắng nghe bởi một hoặc nhiều dịch vụ thực hiện các giao dịch cục bộ và xuất bản (hoặc không) các sự kiện mới

Phân tán giao dịch kết thúc khi dịch vụ cuối cùng thực hiện bộ cục bộ giao dịch của nó và không xuất bản bất kỳ sự kiện nào hoặc sự kiện được xuất bản không được nghe thấy bởi bất kỳ dịch vụ nào của saga

Trong ví dụ này, hệ thống thương mại điện tử sẽ tạo ra đơn đặt hàng như sau

  • Dịch vụ đặt hàng sẽ tạo ra một đơn hàng ở trạng thái chờ xử lý và gửi đi ORDER_CREATED_EVENT
  • Dịch vụ thanh toán lắng nghe ORDER_CREATED_EVENT, trừ tiền của khách hàng và gửi đi BILLED_ORDER_EVENT
  • Stock Service lắng nghe BILLED_ORDER_EVENT, cập nhật lại stock, chuẩn bị các sản phẩm và gửi đi ORDER_PREPARED_EVENT
  • Delivery Service lắng nghe ORDER_PREPARED_EVENT, sau đó nhận và giao sản phẩm. Cuối cùng nó gửi đi ORDER_DELIVERED_EVENT
  • Dịch vụ đặt hàng lắng nghe ORDER_DELIVERED_EVENT và đặt lại trạng thái của đơn hàng

Trong trường hợp trạng thái của đơn hàng cần cập nhật liên tục thì Order Service sẽ lắng nghe tất cả các sự kiện và cập nhật trạng thái cho đơn hàng

Trong trường hợp xảy ra lỗi trong chuỗi giao dịch cục bộ. You must rollback những gì đã thay đổi.

Ví dụ như một lỗi trong Stock Service

  • Dịch vụ chứng khoán sẽ gửi đi PRODUCT_OUT_OF_STOCK_EVENT
  • Dịch vụ đặt hàng và Dịch vụ thanh toán lắng nghe PRODUCT_OUT_OF_STOCK_EVENT. Dịch vụ thanh toán hoàn trả tiền cho khách hàng còn Dịch vụ đặt hàng cập nhật trạng thái đơn hàng không thành công

Mô hình này thực sự rất dễ hiểu và các dịch vụ có sự kết nối là vô cùng chậm chạp. Nếu giao dịch của bạn chỉ có từ 2 đến 4 bước thì đây sẽ là sự lựa chọn tuyệt vời. Tuy nhiên, chúng sẽ trở nên khó khăn khi bạn muốn bổ sung, mở rộng giao dịch. Nó cũng gây khó khăn cho việc kiểm tra vì bạn phải chạy tất cả các dịch vụ

b. Câu chuyện dựa trên chỉ huy/dàn nhạc

Sẽ có một dịch vụ mới chịu trách nhiệm điều phối logic của Saga. Nó chịu trách nhiệm duy nhất là nói cho mỗi dịch vụ phải làm gì và khi nào. Dịch vụ Saga giao tiếp với từng dịch vụ theo kiểu lệnh/trả lời để cho họ biết thực hiện thao tác nào.

Trong ví dụ này, hãy cùng tìm hiểu cách hệ thống thương mại điển tự hoạt động với Command/Orchestration

  • Dịch vụ đặt hàng tạo ra một đơn hàng ở trạng thái chờ xử lý và yêu cầu Order Saga Orchestrator (OSO) bắt đầu một giao dịch đặt hàng
  • OSO gửi lệnh Thực hiện thanh toán đến Dịch vụ thanh toán và Dịch vụ thanh toán trả tiền bằng tin nhắn Thanh toán được thực hiện đối với Kênh trả lời Oder Saga
  • OSO gửi lệnh Chuẩn bị đơn hàng đến Dịch vụ chứng khoán và Dịch vụ chứng khoán trả lời bằng tin nhắn Đơn hàng đã chuẩn bị
  • OSO gửi lệnh Deliver Order to Delivery Service, and get back Order Delivered message

Việc khôi phục lại Saga trở nên dễ dàng hơn nhiều khi bạn có một Dàn nhạc điều khiển mọi thứ.

  • Dịch vụ Chứng khoán gửi cho OSO một thông báo Hết hàng;
  • OSO nhận ra rằng giao dịch thất bại và bắt đầu khôi phục. Trong trường hợp này, chỉ một thao tác duy nhất được thực hiện thành công trước khi thất bại, nên OSO sẽ gửi lệnh Hoàn tiền cho Khách hàng đến Dịch vụ thanh toán và đặt trạng thái của đơn hàng là không thành công

Rõ ràng cách tiếp cận này tốt hơn vì nó tập trung vào việc điều phối các giao dịch phân tán, làm giảm sự phức tạp của các dịch vụ vì chúng chỉ cần quan tâm đến việc thực thi/trả lời các lệnh. Họ cũng đang làm công việc triển khai, thử nghiệm hay quản lý rollback trở nên dễ dàng hơn. Đồng thời làm giảm mức độ phức tạp khi bạn muốn thêm các bước mới vào giao dịch

Chúng ta đã tìm hiểu cách thiết kế và thao tác với cơ sở dữ liệu đối với một hệ thống áp dụng kiến ​​trúc microservices. Hi vọng bài viết này sẽ giúp các bạn có cái tổng quan cũng như hiểu hơn về cách hoạt động của các hệ thống nhìn microservices