Tại sao cơ sở dữ liệu như hàng đợi rất xấu? [đóng cửa]


33

Tôi vừa đọc bài viết này , và tôi bối rối.

Hãy tưởng tượng 1 ứng dụng web và 1 ứng dụng riêng biệt đóng vai trò là "công nhân", cả hai đều chia sẻ cùng một cơ sở dữ liệu .

Ồ, tôi đã nói "chia sẻ" .. nhưng bài báo cảnh báo về điều gì? :

Thứ tư, chia sẻ cơ sở dữ liệu giữa các ứng dụng (hoặc dịch vụ) là một điều xấu. Thật quá hấp dẫn khi đặt trạng thái chia sẻ vô định hình vào đó và trước khi bạn biết nó sẽ có một con quái vật cực kỳ ghép đôi.

=> không đồng ý. Có một số trường hợp các ứng dụng riêng biệt vẫn là một phần của cùng một đơn vị, và do đó, khái niệm "vấn đề khớp nối" không có ý nghĩa gì trong trường hợp này.

Hãy tiếp tục: Ứng dụng web xử lý các yêu cầu HTTP của máy khách và có thể cập nhật bất cứ lúc nào một số tổng hợp (thuật ngữ DDD), tạo ra các sự kiện miền tương ứng.
Mục tiêu của công nhân sẽ là xử lý các sự kiện miền đó bằng cách xử lý các công việc cần thiết.

Điểm mấu chốt là:

Làm thế nào dữ liệu sự kiện nên được truyền cho công nhân?

Giải pháp đầu tiên, như bài viết đã đọc quảng bá, sẽ là sử dụng RabbitMQ, là một phần mềm trung gian hướng thông điệp tuyệt vời.

Quy trình làm việc sẽ đơn giản:

Bất cứ khi nào web dyno tạo ra một sự kiện, nó sẽ xuất bản nó thông qua RabbitMQ, nơi cung cấp cho nhân viên.
Hạn chế là không có gì đảm bảo tính nhất quán ngay lập tức giữa cam kết của bản cập nhật tổng hợp và xuất bản sự kiện, mà không xử lý các lỗi gửi tiềm năng ... hoặc các sự cố phần cứng; đó là một vấn đề chính khác

Ví dụ: Có thể một sự kiện đã được xuất bản mà không thành công trong bản cập nhật tổng hợp ... dẫn đến một sự kiện thể hiện sự thể hiện sai của mô hình miền.
Bạn có thể lập luận rằng XA toàn cầu (cam kết hai pha) tồn tại, nhưng đó không phải là giải pháp phù hợp với tất cả các cơ sở dữ liệu hoặc phần mềm trung gian.

Vì vậy, những gì có thể là một giải pháp tốt để đảm bảo tính nhất quán ngay lập tức này? :
IMO, lưu trữ sự kiện trong cơ sở dữ liệu, trong cùng một giao dịch cục bộ như cập nhật tổng hợp.
Một bộ lập lịch không đồng bộ đơn giản sẽ được tạo và chịu trách nhiệm truy vấn các sự kiện chưa được công bố hiện tại từ cơ sở dữ liệu và gửi chúng đến RabbitMQ, từ đó đưa vào công nhân.

Nhưng tại sao cần một bộ lập lịch bổ sung trong webapp và nhân tiện: tại sao cần RabbitMQ trong trường hợp này?

Theo giải pháp này, có vẻ như logic, rằng RabbitMQ có thể không cần thiết, đặc biệt là vì cơ sở dữ liệu được chia sẻ.
Thật vậy, bất kể trường hợp nào, chúng tôi thấy rằng tính nhất quán ngay lập tức liên quan đến việc bỏ phiếu từ cơ sở dữ liệu.
Vì vậy, tại sao công nhân sẽ không chịu trách nhiệm trực tiếp cho cuộc bỏ phiếu này?

Do đó, tôi tự hỏi tại sao rất nhiều bài viết trên web chỉ trích việc xếp hàng cơ sở dữ liệu khó khăn, trong khi quảng bá phần mềm trung gian hướng thông báo.

Trích đoạn của bài viết:

Đơn giản, sử dụng công cụ phù hợp cho công việc: kịch bản này đang khóc cho một hệ thống nhắn tin. Nó giải quyết tất cả các vấn đề được mô tả ở trên; không bỏ phiếu, gửi tin nhắn hiệu quả, không cần xóa tin nhắn đã hoàn thành khỏi hàng đợi và không có trạng thái chia sẻ.

Và nhất quán ngay lập tức, bỏ qua?

Tóm lại, có vẻ như bất kể trường hợp nào, có nghĩa là cơ sở dữ liệu được chia sẻ hay không, chúng ta cần bỏ phiếu cơ sở dữ liệu .

Tôi đã bỏ lỡ một số khái niệm quan trọng?

Cảm ơn


2
Bỏ phiếu là một loại cá trích đỏ, bởi vì hầu hết tất cả các cơ sở dữ liệu chính đều có một số cơ chế để thông báo không đồng bộ một số quy trình khác rằng đã đến lúc rút một số công việc ra khỏi bàn.
Blrfl

Câu trả lời:


28

Nếu bạn đang xây dựng một ứng dụng đơn giản với lưu lượng truy cập thấp, có một điều cần nói về việc giữ một thành phần khác ra khỏi hệ thống của bạn. Rất có khả năng rằng không sử dụng xe buýt tin nhắn là câu trả lời đúng cho bạn. Tuy nhiên, tôi sẽ đề nghị xây dựng hệ thống của bạn theo cách bạn có thể trao đổi hệ thống hàng đợi dựa trên cơ sở dữ liệu cho một giải pháp phần mềm trung gian. Tôi đồng ý với bài báo đó. Một cơ sở dữ liệu không phải là công cụ phù hợp cho hệ thống dựa trên hàng đợi, nhưng nó có thể đủ tốt cho bạn.

Hệ thống dựa trên hàng đợi như RabbitMq được xây dựng trên quy mô lớn trên phần cứng vừa phải. Kiến trúc của họ có thể đạt được điều này bằng cách tránh các quy trình làm cho hệ thống cơ sở dữ liệu tuân thủ ACID chậm theo bản chất của chúng. Vì một bus tin nhắn chỉ cần đảm bảo tin nhắn được lưu trữ và xử lý thành công, nên nó không cần bận tâm đến việc khóa và ghi nhật ký giao dịch. Cả hai khái niệm này hoàn toàn cần thiết cho một hệ thống ACID nhưng thường là nguyên nhân gây tranh cãi.

Hiệu suất khôn ngoan đến từ: bạn có một bảng SQL. Rất nhiều đọc và rất nhiều bài viết. Cả hai đều yêu cầu một số loại khóa để cập nhật hàng, trang và chỉ mục. Cơ chế bỏ phiếu của bạn liên tục khóa một chỉ mục để thực hiện tra cứu về nó. Điều này ngăn việc viết xảy ra; tốt nhất là họ đang xếp hàng. Mã thực hiện quá trình xử lý cũng đang khóa để cập nhật trạng thái trên hàng đợi khi chúng hoàn thành hoặc không thành công. Có, bạn có thể thực hiện tối ưu hóa truy vấn sau khi tối ưu hóa để làm việc này hoặc bạn có thể sử dụng một hệ thống được thiết kế riêng cho tải công việc bạn đang yêu cầu. Một RabbitMq ăn hết khối lượng công việc này mà không đổ mồ hôi; trên hết, bạn có thể lưu cơ sở dữ liệu của mình khỏi khối lượng công việc giúp nó có nhiều chỗ hơn để mở rộng quy mô làm những việc khác.

Một điều khác cần xem xét là hầu hết các hệ thống xếp hàng thường không sử dụng kỹ thuật bỏ phiếu (một số cho phép HTTP, nhưng khuyến nghị tránh sử dụng cho phía nhận). RabbitMq sử dụng các giao thức mạng được thiết kế đặc biệt cho các bus tin nhắn như AMPQ .

Chỉnh sửa: Thêm trường hợp sử dụng.

Cách tôi đã sử dụng Rabbit là tôi đã có một điểm cuối API chấp nhận thay đổi đòi hỏi một bảng cơ sở dữ liệu được sử dụng nhiều. Bảng này đang bị tranh chấp liên tục và đôi khi sẽ không thể lưu thay đổi kịp thời từ API. Thay vào đó, những gì tôi làm là viết yêu cầu thay đổi vào hàng đợi và sau đó có một dịch vụ xử lý các thông báo này khi có thể. Nếu sự tranh chấp cơ sở dữ liệu xảy ra, hàng đợi chỉ tăng lên và xử lý tin nhắn bị trì hoãn. Thông thường thời gian xử lý xuống trong phạm vi 14ms, nhưng trong thời gian tranh chấp cao, chúng tôi nhận được tới 2-3 giây.


Làm thế nào bạn có thể xử lý sự đồng ý ngay lập tức trong trường hợp này? Nếu việc xuất bản được thực hiện nhưng ngay sau đó, giao dịch chịu trách nhiệm cập nhật các rollback mô hình miền ... Phần mềm trung gian sẽ hoàn toàn không biết và sẽ xử lý sự kiện.
Mik378

Bạn đã viết: "không cần bận tâm đến việc khóa". Nhưng chắc chắn có một loại khóa để đảm bảo thứ tự tăng dần (kịp thời) của các sự kiện được định tuyến (đối với công nhân), phải không?
Mik378

@ Mik378 Hãy xem bài viết này về tính không tin nhắn . Có về mặt kỹ thuật, bạn mất một số lời hứa về tính nhất quán, nhưng tôi cá rằng bạn sẽ thấy những gì bạn đạt được về độ tin cậy của thời gian hoạt động của ứng dụng và hiệu suất là rất xứng đáng. Nó cũng khá dễ dàng để thay đổi cách bạn xử lý tin nhắn để làm cho các tổn thất khá đau đớn.
brianfeucht

2
Có, bạn sẽ cần khóa để đảm bảo trật tự. Một số hệ thống xếp hàng có thể cung cấp điều này với giá hiệu suất. Nếu bạn có thể chấp nhận thực tế là đôi khi các hoạt động sẽ xảy ra không theo thứ tự và tìm ra cách xử lý nó ở phía bộ xử lý, bạn sẽ đạt được theo cấp số nhân từ quan điểm hiệu suất.
brianfeucht

1
@ Mik378 - Tôi đã thêm trường hợp sử dụng vào câu trả lời của mình. Tôi hy vọng nó sẽ giúp!
brianfeucht
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.