Trong microservice, đó là cơ sở dữ liệu đơn hoặc cơ sở dữ liệu đơn cho mỗi dịch vụ?


50

Tôi hiểu rằng mỗi dịch vụ trong kiến ​​trúc microservice nên có cơ sở dữ liệu riêng. Tuy nhiên, bằng cách có cơ sở dữ liệu riêng của mình, điều đó thực sự có nghĩa là chỉ cần có một cơ sở dữ liệu khác trong cùng một thể hiện cơ sở dữ liệu hoặc theo nghĩa đen có một thể hiện cơ sở dữ liệu khác?

Bằng cách này, tôi không có nghĩa là chia sẻ cơ sở dữ liệu, đây là trường hợp không có, mà là trường hợp cơ sở dữ liệu.

Ví dụ: nếu tôi đang sử dụng AWS và có 3 dịch vụ, tôi có tạo 3 cơ sở dữ liệu cho mỗi dịch vụ trên một phiên bản RDS không hoặc tôi có tạo 3 phiên bản RDS cho mỗi dịch vụ chứa một cơ sở dữ liệu được sử dụng độc lập bởi 3 dịch vụ không?

Nếu sử dụng nhiều cơ sở dữ liệu trên một cá thể RDS là một ý tưởng tốt hơn, liệu nó có đánh bại mục đích có các dịch vụ độc lập vì:

  1. Tài nguyên của RDS sẽ được chia sẻ giữa các dịch vụ. Dịch vụ A có thể sử dụng cơ sở dữ liệu nặng vào một thời điểm cụ thể có ảnh hưởng đến Dịch vụ B sử dụng một cơ sở dữ liệu khác nhưng trên cùng một RDS không?

  2. Tất cả các dịch vụ sẽ phụ thuộc vào phiên bản cơ sở dữ liệu trên phiên bản RDS đó.


8
Đó là bất cứ điều gì tốt nhất đáp ứng yêu cầu cụ thể của bạn.
Robert Harvey

1
Tôi không chắc chắn tôi sẽ gọi mình là một chuyên gia về 'microservice' nhưng bạn có thể có bất kỳ cách thiết lập và dbs nào. Bạn có thể có một db được đọc bởi một dịch vụ và được viết bởi một dịch vụ khác. Hoặc ngoài ra, bạn chỉ có thể có 1 db (hoặc ít hơn về mặt kỹ thuật) cho toàn bộ hệ thống.
Mark Rogers

Đây là một bài đọc tốt về vấn đề này: plainoldobjects.com/2015/09/02/ trên
RandomUs1r

Đọc về 'Nguyên tắc trách nhiệm duy nhất'. Bạn đã nghĩ đến việc triển khai một 'dịch vụ siêu nhỏ cơ sở dữ liệu' mà các dịch vụ siêu nhỏ khác sử dụng chưa?
ChuckCottrill

Câu trả lời:


20

Nó thực sự phụ thuộc vào các yêu cầu về khả năng mở rộng của bạn và làm thế nào / nếu các trường hợp microservice của bạn cần hợp tác để cung cấp một kết quả duy nhất. Nó giúp biết được sự đánh đổi là gì:

Giữ tất cả trong một cơ sở dữ liệu

  • Cấu hình dễ dàng hơn
  • Không cần phối hợp hoặc liên lạc với các phiên bản khác của dịch vụ của bạn
  • Dễ dàng hơn để khám phá dữ liệu đầy đủ của bạn
  • Hiệu năng hệ thống bị giới hạn bởi hiệu suất cơ sở dữ liệu

Giữ cơ sở dữ liệu riêng biệt

  • Câu trả lời đầy đủ cho một yêu cầu có thể được trải rộng trên các phiên bản microservice
  • Trong trường hợp đó, bạn đã tăng cường giao tiếp và đàm phán để giải quyết yêu cầu
  • Xử lý dữ liệu khi bạn mất nút microservice đó (ngay cả khi cơ sở dữ liệu vẫn hoạt động, bạn không thể truy cập vào đó cho đến khi một nút mới có cấu hình phù hợp được sao lưu)
  • Độ phức tạp cấu hình tăng

Vấn đề bạn đang giải quyết là gì?

Trong một số trường hợp, bạn chỉ lo lắng về dữ liệu phù du. Nếu cơ sở dữ liệu đi xuống, đó không phải là vấn đề lớn. Trong những trường hợp đó, bạn thậm chí có thể không cần cơ sở dữ liệu để bắt đầu. Chỉ cần giữ tất cả trong bộ nhớ và làm cho mọi thứ nhanh chóng rực rỡ. Đây là giải pháp dễ nhất để làm việc.

Trong các trường hợp khác, bạn cần tính toàn vẹn dữ liệu, nhưng cơ sở dữ liệu của bạn có khả năng mở rộng khả năng của nó dựa trên số lượng nút mà nó có. Trong trường hợp này, một cơ sở dữ liệu có lẽ là quá đủ và quản lý độc lập khả năng đáp ứng của nó là câu trả lời đúng.

Có một số trường hợp ở giữa. Ví dụ: bạn có thể có các cơ sở dữ liệu cụ thể theo vùng, do đó, đối với mỗi phiên bản dịch vụ của bạn ở một khu vực khác, bạn có một cơ sở dữ liệu riêng. Thông thường, việc bảo vệ cơ sở dữ liệu không hoạt động tốt giữa các khu vực, vì vậy đây là cách để bản địa hóa dữ liệu một chút và tự kiểm soát sự phối hợp.

Học thuyết và thực tế

Tôi đã đọc một số bài viết về microservice và cách chúng nên được mô đun hóa. Các đề xuất bao gồm giữ toàn bộ mặt trước, microservice và tầng dữ liệu dưới dạng toàn bộ đơn vị đến chia sẻ cơ sở dữ liệu và / hoặc mã mặt trước cho tất cả các trường hợp. Thông thường, sự cô lập nhiều hơn cung cấp khả năng mở rộng lớn nhất, nhưng nó đi kèm với chi phí tăng độ phức tạp.

Nếu microservice của bạn nặng tính toán, sẽ rất hợp lý khi cho phép số lượng thang đo microservice đó khi cần - chia sẻ cơ sở dữ liệu hoặc thậm chí mã giao diện người dùng không làm tổn thương hoặc cản trở phương pháp này.

Thực tế là các nhu cầu cụ thể của dự án của bạn sẽ cần một bộ thỏa hiệp khác để hoàn thành công việc kịp thời và xử lý tải hệ thống mà bạn đang đo (cộng thêm một chút nữa). Xem xét bộ ba mặt trước, microsrervice và tầng dữ liệu bị cô lập hoàn toàn là mục tiêu cao cả. Càng nhiều nhu cầu trên hệ thống của bạn, bạn càng cần đến mục tiêu đó. Chúng ta không phải là tất cả [insert name of highly successful web entity here], và họ đã không bắt đầu từ nơi họ đang ở. Đôi khi bạn chỉ cần bắt đầu với một tình huống không hoàn hảo, và hài lòng với điều đó.


71

Giả sử bạn có một số dịch vụ có thể sử dụng cùng loại hệ thống và phiên bản DB, nếu bạn sử dụng các trường hợp cơ sở dữ liệu hoặc db khác nhau là một quyết định bạn không cần phải đưa ra tại thời điểm thiết kế. Thay vào đó, bạn sẽ có thể đưa ra quyết định tại thời điểm triển khai, một cái gì đó bạn có thể chỉ cần cấu hình. Thiết kế các dịch vụ của bạn để không bị nghi ngờ về nơi lưu trữ cơ sở dữ liệu của các dịch vụ khác.

Trong quá trình vận hành, bạn có thể bắt đầu với một phiên bản và nếu hệ thống hoạt động tốt, hãy để nguyên như vậy. Tuy nhiên, nếu bạn nhận thấy điều này không mở rộng tốt cho hệ thống của bạn, vì các cơ sở dữ liệu khác nhau trong một trường hợp chia sẻ quá nhiều tài nguyên, bạn luôn có tùy chọn sử dụng các phiên bản khác nhau, nếu điều đó có ích.

Vì vậy, một dịch vụ không vi phạm kiến ​​trúc microservice chỉ vì bạn để hai trong số chúng chia sẻ một số tài nguyên - nó vi phạm khi chia sẻ tài nguyên trở thành bắt buộc.


Đây là loại âm thanh như một tối ưu hóa sớm. Điều gì xảy ra nếu tài nguyên tiêu thụ không bao giờ đáng khen? Sau đó, bạn đã lãng phí thời gian để xây dựng sự linh hoạt
reggaeg Ức

5
@reggaeg Ức: chi phí cho việc này thường không đáng kể - trên thực tế, đối với kiến ​​trúc microservice, có thể sẽ nỗ lực hơn trong việc cố gắng tập trung cấu hình cơ sở dữ liệu giữa các dịch vụ khác nhau hơn là giữ vị trí db cho từng dịch vụ có thể định cấu hình riêng lẻ. Hơn nữa, toàn bộ quan điểm của kiến ​​trúc microservice là khả năng mở rộng cao, nếu không cần điều đó, người ta không nên đưa ra quyết định cho microservice ngay từ đầu.
Doc Brown

1
@DocBrown Điều đó có ý nghĩa, cảm ơn vì đã phản hồi!
reggaeg Ức

13

Nó không thành vấn đề.

Kịch bản duy nhất mà về mặt lý thuyết có thể là vấn đề nếu một dịch vụ cần di chuyển sang các phiên bản khác nhau của cơ sở dữ liệu. Nhưng ngay cả sau đó, không có sự khác biệt thực sự giữa việc có các phiên bản riêng biệt từ đầu so với việc di chuyển một dịch vụ từ một cá thể được chia sẻ sang một cá thể riêng biệt. Tôi thực sự nói rằng có các trường hợp riêng biệt chỉ vì kịch bản này là một ví dụ về YAGNI.


1
Giả sử nếu một dịch vụ cụ thể có mức sử dụng lớn trên một cá thể RDS, thì cuối cùng nó sẽ ăn hết tài nguyên trong trường hợp đó và ảnh hưởng đến các dịch vụ khác sử dụng cùng thể hiện RDS đó?
xenon

1
@xenon: có, nhưng đó là lý do để suy nghĩ về việc cải thiện hiệu suất RDS thông qua điều chỉnh, phần cứng hoặc phân cụm tốt hơn, chứ không phải thay đổi kiến ​​trúc hệ thống của bạn - nếu dịch vụ đó hết dung lượng cho các dịch vụ khác, thì nó sẽ sớm hết dung lượng Tất cả dựa vào nó. Mặc dù tôi đoán bạn có thể có những yêu cầu đặc biệt rằng một dịch vụ quá tải không được ảnh hưởng đến những người khác. Trên thực tế, một số RDS vẫn có thể cho phép điều đó bằng cách xác định giới hạn tài nguyên trên cơ sở người dùng.
Michael Borgwardt

kịch bản mà nó quan trọng là khi cá thể microservice có trạng thái riêng. Sau đó, nó nên được triển khai với db cá thể của chính nó , cũng có thể là một nút cổ chai hiệu năng
Ewan

3

Một ví dụ RDS là một hộp duy nhất. Nếu bạn có nhiều cơ sở dữ liệu trên một thể hiện thì chúng chia sẻ CPU / Bộ nhớ, v.v.

Nếu hiệu suất microservice của bạn bị ràng buộc bởi hiệu suất cơ sở dữ liệu của nó : thì triển khai nhiều bản sao của microservice, mỗi bản sử dụng một cơ sở dữ liệu khác nhau, nhưng với mỗi cơ sở dữ liệu trên cùng một thể hiện RDS. Là vô nghĩa * (ngoại trừ chuyển đổi dự phòng). Cụm microservice của bạn sẽ chạy ở cùng tốc độ với một microservice duy nhất

Tuy nhiên , tôi sẽ nói rằng một microservice mà bị ràng buộc bởi hiệu suất cơ sở dữ liệu là không bình thường.

Thông thường microservice của bạn sẽ lấy dữ liệu từ db, thực hiện một số logic và viết một số thông tin trở lại cơ sở dữ liệu. Nút thắt hiệu suất là logic , không phải là chọn và / hoặc chèn.

Trong trường hợp này, bạn có thể chỉ cần chia sẻ cùng một cơ sở dữ liệu trên tất cả các phiên bản microservice của bạn


Tôi phải đặt câu hỏi cho sự khẳng định của bạn rằng logic là nút cổ chai chứ không phải cơ sở dữ liệu. Theo kinh nghiệm của tôi, nơi có khả năng nhất để tìm thấy các cải tiến hiệu suất là với cơ sở dữ liệu.
RubberDuck

hmm có, nhưng chắc chắn những cải tiến hiệu suất đó đạt được bằng cách di chuyển logic ra khỏi db và vào dịch vụ. Một khi bạn đã làm điều đó, THEN logic là nút cổ chai
Ewan

1
Thông thường, không. Những cải tiến đến từ việc điều chỉnh các chỉ mục và truy vấn.
RubberDuck

tốt, đó sẽ thuộc trường hợp bất thường trong kinh nghiệm của tôi. Không phải là không có chỗ cho những cải tiến đó, nhưng sau khi loại bỏ bất kỳ thứ gì thực sự xấu, cơ sở dữ liệu vẫn là yếu tố hạn chế.
Ewan

1

Mục tiêu của việc giữ một cơ sở dữ liệu riêng tư cho một dịch vụ là đóng gói. Microservice của bạn là một hộp đen mà các dịch vụ khác trong hệ thống sẽ sử dụng thông qua giao diện công cộng.

Có hai mặt phẳng mà đóng gói này hoạt động:

  • Đầu tiên là hợp lý, ở cấp độ ứng dụng. Dịch vụ của bạn sở hữu một số đối tượng kinh doanh trong hệ thống của bạn và nó cần phải duy trì trạng thái về các đối tượng này. Rằng một số cơ sở dữ liệu cụ thể hỗ trợ các đối tượng kinh doanh này chỉ là chi tiết triển khai. Bằng cách giữ một cơ sở dữ liệu riêng biệt, bạn ngăn các dịch vụ khác có quyền truy cập cửa sau vào việc triển khai của bạn, buộc họ phải sử dụng giao diện công cộng của bạn thay thế. Mục tiêu ở đây là kiến ​​trúc sạch và lập trình kỷ luật. Trường hợp chính xác cơ sở dữ liệu không liên quan ở cấp độ này, miễn là dịch vụ của bạn có các chi tiết kết nối phù hợp để có thể tìm thấy nó.

  • Cấp độ thứ hai là hoạt động. Ngay cả khi thiết kế của bạn là một hộp đen hoàn hảo, như bạn chỉ ra, các công việc khác nhau được tập trung trên một máy có thể cạnh tranh để giành tài nguyên. Đây là một lý do tốt để đặt cơ sở dữ liệu logic riêng biệt trên các máy riêng biệt. Như các câu trả lời khác đã lưu ý, nếu nhu cầu của bạn không đòi hỏi nhiều và ngân sách của bạn eo hẹp, thì đây là một lập luận thực tế cho việc định vị trên một máy. Tuy nhiên, như mọi khi, sự đánh đổi: thiết lập này có thể yêu cầu giữ trẻ nhiều hơn khi hệ thống của bạn phát triển. Nếu ngân sách cho phép, tôi gần như luôn thích hai máy nhỏ riêng biệt để chạy hai tác vụ so với chia sẻ một máy lớn hơn.


1

Tôi nghĩ rằng nó có thể giúp một chút lý thuyết ở đây. Một trong những ý tưởng thúc đẩy đằng sau microservice được chia sẻ - không có gì, thông qua các quy trình. Một microservice giống như một diễn viên trong mô hình Diễn viên. Điều này có nghĩa là mỗi quá trình duy trì trạng thái cục bộ của riêng mình và cách duy nhất để một tiến trình truy cập trạng thái của người khác là gửi tin nhắn (và thậm chí sau đó quá trình kia có thể phản hồi theo cách nó thích với những tin nhắn đó). Điều gì có nghĩa là "mỗi microservice có cơ sở dữ liệu riêng" thực sự là trạng thái của một quá trình (tức là microservice) là cục bộriêng tư . Ở một mức độ lớn, điều này cho thấy rằng "cơ sở dữ liệu" nên được sắp xếp lạivới microservice, tức là "cơ sở dữ liệu" sẽ được lưu trữ và thực thi trên cùng một nút logic như microservice. Các "trường hợp" khác nhau của microservice là các quy trình riêng biệt và do đó mỗi quy trình nên có "cơ sở dữ liệu" riêng.

Một cơ sở dữ liệu toàn cầu hoặc cơ sở dữ liệu được chia sẻ giữa các dịch vụ micros micros hoặc thậm chí các phiên bản của microservice, từ quan điểm này, sẽ tạo thành trạng thái chia sẻ. Cách "thích hợp" để xử lý việc này từ phối cảnh microservice là để cơ sở dữ liệu dùng chung được trung gian bởi một dịch vụ siêu nhỏ "cơ sở dữ liệu". Các dịch vụ siêu nhỏ khác muốn biết về nội dung của cơ sở dữ liệu sẽ gửi tin nhắn đến "microservice cơ sở dữ liệu" đó. Điều này thường sẽ không loại bỏ sự cần thiết của trạng thái cục bộ (ví dụ: "cơ sở dữ liệu" của microservice) cho các dịch vụ micros micros gốc! Những gì thay đổi là những gì mà nhà nước địa phương đại diện. Thay vì lưu trữ "User Sally là quản trị viên", nó sẽ lưu trữ "microservice cơ sở dữ liệu cho biết 'User Sally là quản trị viên' năm phút trước". Nói cách khác, về tình trạng của các dịch vụ siêu nhỏ khác.

Lợi ích của việc này là mỗi microservice đều khép kín. Điều này làm cho microservice trở thành một đơn vị nguyên tử của sự thất bại. Bạn (hầu hết) không phải lo lắng về một dịch vụ siêu nhỏ trong một số trạng thái chức năng. Tất nhiên, vấn đề đã được chuyển sang mạng microservice. Một dịch vụ siêu nhỏ có thể không thể thực hiện chức năng mong muốn do không thể liên hệ với các dịch vụ siêu nhỏ khác. Tuy nhiên, lợi ích là microservice sẽ ở trạng thái được xác định rõ và có thể cung cấp dịch vụ bị suy giảm hoặc bị hạn chế, ví dụ như bằng cách làm mất niềm tin đã lỗi thời. Nhược điểm là rất khó để có được một ảnh chụp nhanh toàn bộ hệ thống, và có thể có khá nhiều sự dư thừa và không mong muốn.

Tất nhiên, đề xuất không gắn một thể hiện của Oracle vào mọi container Docker. Đầu tiên, không phải mọi microservice đều cần một "cơ sở dữ liệu". Một số quy trình không cần bất kỳ trạng thái liên tục để hoạt động chính xác. Ví dụ, một dịch vụ siêu nhỏ dịch giữa hai giao thức không nhất thiết cần bất kỳ trạng thái liên tục nào. Vì khi cần trạng thái liên tục, từ "cơ sở dữ liệu" chỉ là một từ để chỉ "trạng thái liên tục". Nó có thể là một tệp có JSON trong đó hoặc cơ sở dữ liệu Sqlite hoặc bản sao chạy Oracle cục bộ nếu bạn muốn hoặc bất kỳ phương tiện cục bộ nào kháclưu trữ dữ liệu liên tục. Nếu "cơ sở dữ liệu" không phải là cục bộ, thì từ góc độ microservice thuần túy, nó sẽ được coi như một dịch vụ (vi mô) riêng biệt. Cuối cùng, không có nghĩa gì khi có một cá thể RDS là "cơ sở dữ liệu" cho một dịch vụ siêu nhỏ. Một lần nữa, viễn cảnh không phải là "một loạt các dịch vụ siêu nhỏ với cơ sở dữ liệu RDS của riêng họ" mà là "một nhóm các dịch vụ siêu nhỏ giao tiếp với cơ sở dữ liệu RDS". Tại thời điểm này, không có sự khác biệt cho dù dữ liệu được lưu trữ trong cùng một cơ sở dữ liệu hay không.

Thực tế, một kiến ​​trúc microservice thêm một số lượng lớn phức tạp. Sự phức tạp này chỉ là cái giá của việc xử lý nghiêm túc với thất bại một phần. Đối với nhiều người, đó là quá mức có thể không có giá trị lợi ích. Bạn nên cảm thấy tự do để kiến ​​trúc sư hệ thống của bạn theo bất kỳ cách nào có vẻ có lợi nhất. Có một cơ hội tốt rằng những lo ngại về sự đơn giản và hiệu quả có thể dẫn đến những sai lệch so với kiến ​​trúc microservice thuần túy. Chi phí sẽ là khớp nối thêm giới thiệu sự phức tạp của riêng nó, chẳng hạn như tương tác vô hình giữa các dịch vụ và hạn chế về quyền tự do triển khai và mở rộng theo ý muốn của bạn.


"do không thể liên hệ với các dịch vụ siêu nhỏ khác." - Tôi nghĩ microservice không bao giờ nên liên hệ với microservice khác?
Marc
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.