Làm thế nào để xử lý các ràng buộc khóa ngoại khi di chuyển từ nguyên khối sang microservice?


18

Nhóm của tôi đang chuyển từ một ứng dụng ASP.NET nguyên khối sang .NET Core và Kubernetes. Các thay đổi mã dường như sẽ diễn ra tốt như có thể dự kiến ​​nhưng nơi nhóm của tôi gặp phải nhiều bất hòa là xung quanh cơ sở dữ liệu.

Chúng tôi hiện có cơ sở dữ liệu SQL Server khá lớn chứa tất cả dữ liệu cho toàn bộ doanh nghiệp của chúng tôi. Tôi đang đề xuất rằng chúng tôi chia cơ sở dữ liệu theo cách tương tự để phân tách dữ liệu danh mục mã trong một cơ sở dữ liệu (logic), dữ liệu kiểm kê trong một cơ sở dữ liệu khác, v.v. - và mỗi microservice sẽ là người gác cổng cho cơ sở dữ liệu của nó .

Hàm ý ở đây là các khóa ngoại vượt qua các ranh giới microservice sẽ phải bị xóa và các sprocs và các khung nhìn vượt qua các ranh giới sẽ bị cấm. Tất cả các mô hình dữ liệu có thể hoặc không thể nằm trong cùng một cơ sở dữ liệu vật lý, nhưng ngay cả khi chúng có, chúng không nên tương tác trực tiếp với nhau. Đơn đặt hàng vẫn có thể tham chiếu các mục danh mục theo Id nhưng tính toàn vẹn dữ liệu sẽ không được thực thi nghiêm ngặt ở cấp cơ sở dữ liệu và dữ liệu đó sẽ phải được nối trong mã thay vì trong SQL.

Tôi thấy sự mất mát của những điều này là sự đánh đổi cần thiết khi chuyển sang microservice và nhận được những lợi ích về khả năng mở rộng đi kèm. Miễn là chúng ta chọn đường may của mình một cách khôn ngoan và phát triển xung quanh chúng thì sẽ ổn thôi. Các thành viên khác trong nhóm đều kiên quyết rằng mọi thứ phải nằm trong cùng một cơ sở dữ liệu nguyên khối để mọi thứ đều có thể được ACID và có tính toàn vẹn tham chiếu được bảo tồn ở mọi nơi.

Điều này mang lại cho tôi câu hỏi của tôi. Đầu tiên, lập trường của tôi về các ràng buộc khóa ngoại và tham gia có hợp lý không? Nếu vậy, có ai biết bất kỳ tài liệu đọc đáng tin cậy nào tôi có thể cung cấp cho các đồng nghiệp của tôi không? Vị trí của họ gần như tôn giáo và dường như họ sẽ không bị ảnh hưởng bởi bất cứ điều gì mà chính Martin Fowler nói với họ rằng họ đã sai.


5
Tính toàn vẹn tham chiếu là vô cùng quý giá. Là quy mô của cơ sở dữ liệu thực sự là nút cổ chai ở đây? Bạn có thực sự cần khả năng mở rộng theo kiểu microservice không? Bạn biết rõ hơn tôi rằng liệu sự thay đổi trong kiến ​​trúc có phù hợp với tổ chức của bạn hay không, nhưng vui lòng xem xét rằng nó đơn giản không phù hợp với nhiều trường hợp sử dụng. Có thể có những cách khác để mở rộng quy mô với sự đánh đổi hấp dẫn hơn. Ví dụ: nếu các truy vấn cơ sở dữ liệu mỗi giây quá cao, có thể sao chép cơ sở dữ liệu là tất cả những gì cần thiết. Và bạn có thể mở rộng quy mô máy chủ web mà không cần phải sử dụng microservice.
amon

Điểm tốt. Chúng tôi đang xem xét một số tùy chọn cho lợi ích ngắn hạn. Tuy nhiên, việc chuyển sang microservice là trò chơi dài. Theo tôi, nó sẽ cho phép chúng tôi mở rộng quy mô trong nhiều năm chứ không phải hàng tháng.
Raymond Saltrelli

3
Tôi chắc chắn rằng khách hàng của bạn sẽ vui mừng khi đơn hàng họ đặt nhanh hơn 0,05ms bị hủy vì người khác đã đặt hàng cùng một sản phẩm khi chỉ còn một sản phẩm trong kho.
Andy

@amon Làm cho câu trả lời này và tôi sẽ nâng cao nó. Đây là một câu hỏi hay và những ưu và nhược điểm cần được thể hiện một cách công bằng.
đánh dấu

@mcottle ok, xong rồi!
amon

Câu trả lời:


19

Không có giải pháp rõ ràng bởi vì điều này phụ thuộc hoàn toàn vào bối cảnh của bạn - đặc biệt, dọc theo kích thước mà hệ thống của bạn có nghĩa vụ phải mở rộng và vấn đề thực tế của bạn là gì. Là cơ sở dữ liệu thực sự tắc nghẽn của bạn?

Câu trả lời này (không may là khá dài) sẽ đọc một chút giống như micros microservice là xấu, nguyên khối cho cuộc sống!, Nhưng đó không phải là ý định của tôi. Quan điểm của tôi là microservice và cơ sở dữ liệu phân tán có thể giải quyết các vấn đề khác nhau, nhưng không phải không có một số vấn đề của riêng họ. Để đưa ra lập luận mạnh mẽ cho kiến ​​trúc của bạn, bạn phải chỉ ra rằng những vấn đề này không được áp dụng, có thể được giảm thiểu và kiến ​​trúc này là lựa chọn tốt nhất cho nhu cầu kinh doanh của bạn.

Dữ liệu phân tán là khó khăn.

Tính linh hoạt tương tự cho phép mở rộng quy mô tốt hơn là mặt trái của các đảm bảo yếu hơn. Đáng chú ý, các hệ thống phân tán khó hơn nhiều để lý do.

Cập nhật nguyên tử, giao dịch, tính nhất quán / tính toàn vẹn tham chiếu và độ bền là vô cùng quý giá và không nên từ bỏ một cách vội vàng. Có rất ít điểm trong việc có dữ liệu nếu nó không đầy đủ, lỗi thời hoặc hoàn toàn sai. Khi bạn có ACID như một yêu cầu nghiệp vụ nhưng đang sử dụng công nghệ cơ sở dữ liệu không thể cung cấp nó ngoài hộp (ví dụ: nhiều cơ sở dữ liệu NoQuery hoặc kiến ​​trúc DB-per-microservice), thì ứng dụng của bạn phải lấp đầy khoảng trống và cung cấp các đảm bảo đó.

  • Điều này không phải là không thể làm được, nhưng khó khăn để có được quyền. Rất khôn lanh. Đặc biệt là trong một thiết lập phân tán, nơi có nhiều người viết cho mỗi cơ sở dữ liệu. Khó khăn này dẫn đến khả năng có nhiều lỗi, có thể bao gồm dữ liệu bị mất, dữ liệu không nhất quán, v.v.

    Ví dụ, hãy xem xét việc đọc các phân tích của Jepsen về các hệ thống cơ sở dữ liệu phân tán nổi tiếng , có lẽ bắt đầu bằng việc phân tích Cassandra . Tôi không hiểu một nửa phân tích đó, nhưng TL; DR là các hệ thống phân tán rất khó khăn đến nỗi ngay cả các dự án dẫn đầu ngành đôi khi cũng hiểu sai, theo những cách có vẻ rõ ràng trong nhận thức muộn màng.

  • Hệ thống phân tán cũng ngụ ý một nỗ lực phát triển lớn hơn. Ở một mức độ nhất định, có sự đánh đổi trực tiếp giữa chi phí phát triển hoặc giảm tiền cho phần cứng mạnh hơn.

Ví dụ: tài liệu tham khảo lơ lửng

Trong thực tế, bạn không nên nhìn vào khoa học máy tính mà nhìn vào các yêu cầu kinh doanh của bạn để xem liệu ACID có thể được thư giãn hay không. Ví dụ, nhiều mối quan hệ khóa ngoại có thể không quan trọng như vẻ ngoài của chúng. Xem xét một sản phẩm - loại n: m mối quan hệ. Trong RDBMS, chúng tôi có thể sử dụng ràng buộc khóa ngoài để chỉ các sản phẩm hiện có và các danh mục hiện có có thể là một phần của mối quan hệ đó. Điều gì xảy ra nếu chúng tôi giới thiệu các dịch vụ sản phẩm và danh mục riêng biệt và một sản phẩm hoặc danh mục bị xóa?

Trong trường hợp này, đó có thể không phải là một vấn đề lớn và chúng tôi có thể viết ứng dụng của mình để nó lọc ra bất kỳ sản phẩm hoặc danh mục nào không còn tồn tại. Nhưng có sự đánh đổi!

  • Lưu ý rằng điều này có thể yêu cầu cấp độ ứng dụng JOINtrên nhiều cơ sở dữ liệu / microservice, chỉ đơn thuần là di chuyển xử lý từ máy chủ cơ sở dữ liệu sang ứng dụng của bạn. Điều này làm tăng tổng tải và phải di chuyển thêm dữ liệu qua mạng.

  • Điều này có thể gây rối với phân trang. Ví dụ: bạn yêu cầu 25 sản phẩm tiếp theo từ một danh mục và lọc ra các sản phẩm không có sẵn từ phản hồi đó. Bây giờ ứng dụng của bạn hiển thị 23 sản phẩm. Về lý thuyết, một trang không có sản phẩm cũng có thể!

  • Thỉnh thoảng bạn sẽ muốn chạy một tập lệnh dọn sạch các tham chiếu lơ lửng, sau mỗi thay đổi có liên quan hoặc theo các khoảng thời gian đều đặn. Lưu ý rằng các tập lệnh như vậy khá tốn kém vì chúng phải yêu cầu mọi sản phẩm / danh mục từ cơ sở dữ liệu / microservice sao lưu để xem liệu nó có còn tồn tại hay không.

  • Điều này là rõ ràng, nhưng để rõ ràng: không sử dụng lại ID. ID kiểu tự động có thể hoặc không thể tốt. GUID hoặc băm cho phép bạn linh hoạt hơn, ví dụ: bằng cách có thể gán ID trước khi mục được chèn vào cơ sở dữ liệu.

Ví dụ: đơn đặt hàng đồng thời

Bây giờ thay vì xem xét một mối quan hệ sản phẩm - đặt hàng. Điều gì xảy ra với một đơn đặt hàng nếu một sản phẩm bị xóa hoặc thay đổi? Ok, chúng ta chỉ cần sao chép dữ liệu sản phẩm có liên quan vào mục nhập đơn hàng để giữ cho nó có sẵn - không gian đĩa giao dịch cho đơn giản. Nhưng điều gì sẽ xảy ra nếu giá của sản phẩm thay đổi hoặc sản phẩm không có sẵn ngay trước khi đơn đặt hàng cho sản phẩm đó được thực hiện? Trong một hệ thống phân tán, các hiệu ứng cần có thời gian để lan truyền và thứ tự có thể sẽ đi qua với dữ liệu lỗi thời.

Một lần nữa, làm thế nào để tiếp cận điều này phụ thuộc vào yêu cầu kinh doanh của bạn. Có thể đơn hàng lỗi thời là chấp nhận được và sau đó bạn có thể hủy đơn hàng nếu không thể thực hiện được.

Nhưng có lẽ đó không phải là một lựa chọn, ví dụ cho các cài đặt đồng thời cao. Hãy xem xét 3000 người đổ xô mua vé buổi hòa nhạc trong vòng 10 giây đầu tiên và giả sử một sự thay đổi về tính khả dụng sẽ cần 10ms để tuyên truyền. Xác suất bán vé cuối cùng cho nhiều người là gì? Phụ thuộc vào cách xử lý các va chạm đó, nhưng sử dụng phân phối Poisson với λ = 3000 / (10s / 10ms) = 3chúng tôi sẽ có P(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%cơ hội va chạm trên mỗi khoảng thời gian 10ms. Việc bán và sau đó hủy phần lớn các đơn đặt hàng của bạn là có thể mà không có hành vi gian lận có thể dẫn đến một cuộc trò chuyện thú vị với bộ phận pháp lý của bạn.

Chủ nghĩa thực dụng có nghĩa là chọn anh đào những tính năng tốt nhất.

Tin vui là bạn không phải chuyển sang mô hình cơ sở dữ liệu phân tán, nếu điều đó không bắt buộc. Sẽ không ai thu hồi tư cách thành viên Câu lạc bộ microservice của bạn nếu bạn không thực hiện microservice đúng cách, bởi vì không có câu lạc bộ nào như vậy - và không có cách nào thực sự để xây dựng microservice.

Chủ nghĩa thực dụng chiến thắng mọi lúc, vì vậy hãy trộn và kết hợp các cách tiếp cận khác nhau khi chúng giải quyết vấn đề của bạn. Điều này thậm chí có thể có nghĩa là microservice với một cơ sở dữ liệu tập trung. Thực sự, đừng trải qua nỗi đau của cơ sở dữ liệu phân tán nếu bạn không phải làm vậy.

Bạn có thể mở rộng mà không cần microservice.

Dịch vụ vi mô có hai lợi ích chính:

  • Lợi ích tổ chức mà họ có thể được phát triển và triển khai độc lập bởi các nhóm riêng biệt (do đó đòi hỏi các dịch vụ phải cung cấp giao diện ổn định).
  • Lợi ích hoạt động mà mỗi microservice có thể được thu nhỏ độc lập .

Nếu không cần mở rộng quy mô độc lập, microservice sẽ kém hấp dẫn hơn rất nhiều.

Một máy chủ cơ sở dữ liệu đã là một loại dịch vụ mà bạn có thể chia tỷ lệ (phần nào) một cách độc lập, ví dụ: bằng cách thêm các bản sao đọc. Bạn đề cập đến các thủ tục lưu trữ. Việc giảm chúng có thể có tác động lớn đến mức mọi cuộc thảo luận về khả năng mở rộng khác đều phải tranh luận.

Và hoàn toàn có thể có một khối nguyên khối có thể mở rộng bao gồm tất cả các dịch vụ như thư viện. Sau đó, bạn có thể mở rộng quy mô bằng cách khởi chạy thêm các phiên bản của khối, điều này tất nhiên đòi hỏi mỗi trường hợp phải không trạng thái.

Điều này có xu hướng hoạt động tốt cho đến khi khối nguyên khối quá lớn để được triển khai hợp lý hoặc nếu một số dịch vụ có yêu cầu tài nguyên đặc biệt để bạn có thể muốn mở rộng chúng một cách độc lập. Các miền vấn đề liên quan đến tài nguyên bổ sung có thể không liên quan đến một mô hình dữ liệu riêng biệt.

Bạn có một trường hợp kinh doanh mạnh mẽ?

Bạn nhận thức được nhu cầu kinh doanh của tổ chức của mình và do đó có thể tạo một đối số cho kiến ​​trúc cơ sở dữ liệu trên mỗi microservice, dựa trên phân tích:

  • rằng cần phải có một quy mô nhất định và kiến ​​trúc này là cách tiếp cận hiệu quả nhất về chi phí để có được khả năng mở rộng đó, có tính đến nỗ lực phát triển gia tăng cho một giải pháp thay thế và thiết lập như vậy; và
  • rằng các yêu cầu kinh doanh của bạn cho phép các đảm bảo ACID có liên quan được nới lỏng, mà không dẫn đến các vấn đề khác nhau như những vấn đề được thảo luận ở trên.

Ngược lại, nếu bạn không thể chứng minh điều này, đặc biệt nếu thiết kế cơ sở dữ liệu hiện tại có thể hỗ trợ đủ quy mô trong tương lai (như các đồng nghiệp của bạn dường như tin tưởng), thì bạn cũng có câu trả lời của mình.

Ngoài ra còn có một thành phần YAGNI lớn cho khả năng mở rộng. Trước sự không chắc chắn, đây là một quyết định kinh doanh chiến lược về xây dựng khả năng mở rộng (tổng chi phí thấp hơn, nhưng liên quan đến chi phí cơ hội và có thể không cần thiết) so với trì hoãn một số công việc về khả năng mở rộng (tổng chi phí cao hơn nếu cần, nhưng bạn có tốt hơn ý tưởng của quy mô thực tế). Đây không phải là một quyết định kỹ thuật.


Câu trả lời tuyệt vời, cảm ơn bạn. Bạn có thể giải thích về tuyên bố này? Bạn có nghĩa là giảm số lượng các thủ tục có thể có ảnh hưởng lớn đến hiệu suất? Bạn đề cập đến các thủ tục lưu trữ. Việc giảm chúng có thể có tác động lớn đến mức mọi cuộc thảo luận về khả năng mở rộng khác đều phải tranh luận.
alan

1
@alan Các thủ tục được lưu trữ có thể được sử dụng tốt, nhưng chúng gây ra hai vấn đề về hiệu năng: (1) Các truy vấn phức tạp hơn sẽ khó khăn hơn cho cơ sở dữ liệu để tối ưu hóa. (2) Sử dụng sprocs có nghĩa là thực hiện nhiều công việc hơn trên máy chủ DB. OP muốn tách DB để mở rộng quy mô hơn, nhưng tránh các sprocs phức tạp có thể đã cung cấp khoảng không đó. Tất nhiên, sprocs và truy vấn phức tạp cũng có thể tốt cho hiệu suất, ví dụ như khi chúng giảm thiểu lượng dữ liệu phải được chuyển ra khỏi DB để trả lời truy vấn. Việc tách DB sẽ làm cho vấn đề đó trở nên tồi tệ hơn khi cần THAM GIA máy chủ chéo.
amon

0

Tôi tin rằng cả hai cách tiếp cận đều hợp lý. Bạn có thể chọn để đạt được khả năng mở rộng hy sinh lợi ích của cơ sở dữ liệu ACID và nguyên khối, cũng như tuân theo kiến ​​trúc hiện tại và hy sinh khả năng mở rộng và nhanh nhẹn của kiến ​​trúc phân tán hơn. Quyết định đúng đắn sẽ đến từ mô hình kinh doanh hiện tại và chiến lược buz cho những năm tiếp theo. Hoàn toàn từ quan điểm công nghệ, có những nỗi đau giữ cho nó nguyên khối cũng như chuyển sang một cách tiếp cận phân tán hơn. Tôi sẽ phân tích hệ thống và xem những ứng dụng / mô-đun / quy trình kinh doanh nào quan trọng hơn để mở rộng quy mô và đánh giá rủi ro, chi phí và lợi ích để quyết định những ứng dụng nên chờ đợi hoặc tiếp tục trong kiến ​​trúc nguyên khối.


-1

Lập trường của bạn là hợp lý và chính xác.

Làm thế nào để thuyết phục nhuộm trong những người nghiện db len là một câu hỏi khác. Tôi muốn nói rằng bạn có hai lựa chọn.

  1. Tìm một ví dụ cụ thể trong đó DB đã đạt đến giới hạn của nó. Bạn có 'bảng lưu trữ' chẳng hạn? Tại sao vậy? Số lượng đơn đặt hàng tối đa mỗi giây bạn có thể nhận là bao nhiêu? vv Hiển thị rằng DB không đáp ứng yêu cầu và giải pháp của bạn khắc phục chúng.

  2. Thuê các nhà thầu đắt tiền để nói với bạn giải pháp tốt nhất. Bởi vì họ là chi phí và có blog mọi người sẽ tin họ


1
Tôi không phải là -1 nhưng để đây là một câu trả lời hay, tôi sẽ mất điểm của điểm 2 và mở rộng khi cần có nhiều cơ sở dữ liệu. Tôi không nghĩ các bảng lưu trữ nhất thiết phải là một antipotype trong cơ sở dữ liệu không hỗ trợ, phân vùng. Cơ sở dữ liệu tôi hiện đang sử dụng có khoảng 130GB dữ liệu với 26 bảng> 10 triệu hàng và hiệu suất không đủ xa để có thể phân tách cơ sở dữ liệu; Vì vậy, tôi rất hoài nghi và tôi muốn nghe lý do tại sao đây là một ý tưởng tốt và khi nào nó cần được thực hiện - câu trả lời này là gần nhất tôi đã thấy cho đến nay.
đánh dấu

tốt. Tôi đề cập đến các bảng lưu trữ bởi vì chúng làm hỏng các ràng buộc FK. đó là một vết nứt trong áo giáp. phân tách bằng microservice không phải là một kích thước của điều db mà nó giữ cho điều dịch vụ micros micros của bạn tách biệt. Nếu bạn không thể tắt một cái và vứt nó đi, nó không thực sự là một dịch vụ siêu nhỏ. lại điểm 2. OP đề cập đến MF, theo nghĩa đen họ có thể thuê anh ta / nhà tư tưởng đến và bảo họ tách db
Ewan

"Nếu bạn không thể tắt một cái và vứt nó đi, nó không thực sự là một dịch vụ siêu nhỏ." Điều đó đúng với bản thân dịch vụ, nhưng không nhất thiết là lý do tại sao dịch vụ cần cơ sở dữ liệu riêng. Cuối cùng, cơ sở dữ liệu tự nó là một dịch vụ đang được microservice sử dụng. Microservice không thực sự biết hoặc quan tâm liệu dữ liệu mà nó sử dụng nằm trong một cơ sở dữ liệu riêng biệt hay cơ sở dữ liệu dùng chung. Bạn có thể quay lên hoặc xuống các bản sao của microservice này và không có gì thực sự thay đổi.
Chris Pratt

Đối số tốt nhất cho cơ sở dữ liệu trên mỗi dịch vụ là giới hạn kết nối. Không có gì lạ khi sử dụng nhóm kết nối, vì vậy mỗi microservice đã yêu cầu nhiều kết nối đến thể hiện cơ sở dữ liệu, sau đó bạn có thể có nhiều phiên bản của mỗi dịch vụ này, mỗi dịch vụ đều có nhóm riêng. Cuối cùng, mọi thứ có thể đi đến đầu, nơi bạn chỉ đơn giản là cạn kiệt khả năng của cơ sở dữ liệu để xử lý tất cả các kết nối mà nó nhận được.
Chris Pratt
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.