데이터베이스가 대기열로 나쁜 이유는 무엇입니까? [닫은]


33

방금이 기사를 읽었으며 혼란스러워합니다.

하나의 webapp과 하나의 고유 한 응용 프로그램이 "작업자"역할을 하고 동일한 데이터베이스를 공유 한다고 가정 해 봅시다 .

아, "공유"라고했는데이 기사에서는 무엇에 대해 경고합니까? :

넷째, 응용 프로그램 (또는 서비스)간에 데이터베이스를 공유하는 것은 좋지 않습니다. 비정질 공유 상태를 거기에 넣는 것은 너무 유혹적이며 그것을 알기 전에는 엄청나게 결합 된 괴물이 있습니다.

=> 동의하지 않습니다. 개별 응용 프로그램이 여전히 동일한 장치의 일부인 경우가 있으므로 "커플 링 문제"라는 개념은이 경우에 의미가 없습니다.

계속하자 : webapp는 클라이언트 HTTP 요청을 처리하고 언제든지 일부 집계 (DDD 용어)를 업데이트하여 해당 도메인 이벤트를 생성 할 수 있습니다.
작업자의 목표는 필요한 작업을 처리하여 해당 도메인 이벤트를 처리하는 것입니다.

요점은 :

이벤트 데이터를 작업자에게 어떻게 전달해야합니까?

읽은 기사에서 알 수 있듯이 첫 번째 해결책은 훌륭한 메시지 지향 미들웨어 인 RabbitMQ를 사용하는 것입니다.

작업 과정은 간단합니다.

웹 dyno가 이벤트를 생성 할 때마다 RabbitMQ를 통해 이벤트를 게시하여 작업자에게 피드를 제공합니다.
단점은 잠재적 전송 실패 또는 하드웨어 문제를 처리하지 않고 집계 업데이트 커밋과 이벤트 게시간에 즉각적인 일관성을 보장하는 것이 아무것도 없다는 것입니다 . 그것은 또 다른 주요 이슈입니다.

예 : 도메인 업데이트의 잘못된 표현을 나타내는 이벤트에서 집계 업데이트가 성공하지 않고 이벤트가 게시되었을 수 있습니다.
글로벌 XA (2 단계 커밋)가 존재한다고 주장 할 수 있지만 모든 데이터베이스 또는 미들웨어에 적합한 솔루션은 아닙니다.

그렇다면 이러한 즉각적인 일관성을 보장하는 좋은 솔루션은 무엇입니까? :
IMO, 데이터베이스에 이벤트를 집계 업데이트와 동일한 로컬 트랜잭션으로 저장합니다.
간단한 비동기식 스케줄러가 생성되어 데이터베이스에서 현재 게시되지 않은 이벤트를 쿼리하고이를 RabbitMQ로 보내어 작업자를 채 웁니다.

그러나 왜 webapp 측에 추가 스케줄러가 필요합니까?이 경우 RabbitMQ가 필요한 이유는 무엇입니까?

이 솔루션을 사용하면 특히 데이터베이스가 공유되므로 RabbitMQ가 불필요 할 수 있습니다.
실제로 어떤 경우이든 즉각적 일관성 에는 데이터베이스의 폴링이 포함됩니다.
따라서 왜이 설문 조사에 대해 근로자가 직접 책임을지지 않습니까?

따라서 왜 웹에서 많은 기사가 데이터베이스 큐잉을 거의 비판하지 않고 메시지 지향 미들웨어를 홍보하는지 궁금합니다.

기사의 발췌 :

간단하고 업무에 적합한 도구를 사용하십시오.이 시나리오는 메시징 시스템에 적합하지 않습니다. 위에서 설명한 모든 문제를 해결합니다. 더 이상 폴링, 효율적인 메시지 전달, 큐에서 완료된 메시지를 지울 필요가 없으며 공유 상태가 없습니다.

그리고 즉각적인 일관성, 무시?

요약하면 실제로 데이터베이스 공유 여부에 관계없이 데이터베이스 폴링이 필요한 것 같습니다 .

몇 가지 중요한 개념을 놓쳤습니까?

감사


2
폴링은 일종의 붉은 청어입니다. 대부분의 주요 데이터베이스에는 다른 프로세스에 테이블에서 일부 작업을 수행 할 시간을 비동기 적으로 알리는 메커니즘이 있기 때문입니다.
Blrfl

답변:


28

트래픽이 적은 간단한 응용 프로그램을 구축하는 경우 시스템에서 다른 구성 요소를 유지하는 것에 대해 언급해야합니다. 메시지 버스를 사용하지 않는 것이 정답 일 것입니다. 그러나 데이터베이스 기반 대기열 시스템을 미들웨어 솔루션으로 교체 할 수있는 방식으로 시스템을 구축하는 것이 좋습니다. 기사에 동의합니다. 데이터베이스는 큐 기반 시스템에 적합한 도구는 아니지만 충분할 수 있습니다.

RabbitMq와 같은 대기열 기반 시스템은 중간 규모의 하드웨어에서 대규모로 구축됩니다. 그들의 아키텍처는 ACID 호환 데이터베이스 시스템을 본질적으로 느리게 만드는 프로세스를 피함으로써이를 달성 할 수 있습니다. 메시지 버스는 메시지를 저장하고 성공적으로 처리하기 만하면되므로 트랜잭션 로그를 잠 그거나 쓰는 데 신경 쓸 필요가 없습니다. 이 두 개념은 ACID 시스템에 반드시 필요하지만 종종 경합의 원인입니다.

성능 측면에서는 SQL 테이블이 있습니다. 많은 읽기와 많은 쓰기. 둘 다 행, 페이지 및 색인을 업데이트하기 위해 일종의 잠금이 필요합니다. 폴링 메커니즘은 색인을 지속적으로 조회하여 조회를 수행합니다. 이렇게하면 쓰기가 발생하지 않습니다. 기껏해야 그들은 대기열에 있습니다. 처리를 수행하는 코드는 큐가 완료되거나 실패함에 따라 큐의 상태를 업데이트하기 위해 잠금 상태입니다. 예, 최적화 후에 쿼리 최적화를 수행하여이를 작동 시키거나 요청하는 작업 부하에 맞게 특별히 설계된 시스템을 사용할 수 있습니다. RabbitMq는 땀을 흘리지 않고도 이러한 유형의 작업량을 소비합니다. 또한 작업 부하에서 데이터베이스를 저장하여 다른 작업을 수행 할 수있는 더 많은 공간을 확보 할 수 있습니다.

고려해야 할 또 다른 사항은 대부분의 큐 시스템이 일반적으로 폴링 기술을 사용하지 않는다는 것입니다 (일부는 HTTP를 허용하지만 수신 측에는 사용하지 않는 것이 좋습니다). RabbitMq 구체적 같은 메시지 버스 설계된 네트워크 프로토콜을 사용 AMPQ를 .

편집 : 사용 사례 추가.

내가 Rabbit을 사용한 방법은 많이 사용되는 데이터베이스 테이블이 필요한 변경을 허용하는 API 엔드 포인트가 있다는 것입니다. 이 테이블은 지속적인 경합 상태이며 때때로 API에서 적시에 변경 사항을 저장할 수 없습니다. 내가 대신하는 일은 변경 요청을 대기열에 작성한 다음 가능한 한 이러한 메시지를 처리하는 서비스를 제공하는 것입니다. 데이터베이스 경합이 발생하면 대기열이 증가하고 메시지 처리가 지연됩니다. 일반적으로 14ms 범위에서 처리 시간이 줄어들지 만 경합이 많은 시간에는 최대 2-3 초가 걸립니다.


이 경우 즉각적인 편의를 어떻게 처리 할 수 ​​있습니까? 게시가 이루어 지 자마자 게시 된 경우 도메인 모델 롤백 업데이트를 담당하는 트랜잭션 ... 미들웨어는 완전히 인식하지 못하고 이벤트를 처리합니다.
Mik378

"잠금에 신경 쓸 필요가 없습니다"라고 썼습니다. 그러나 (종업원을 향한) 라우트 된 이벤트의 오름차순 (시간에 따라)을 보장하기 위해 반드시 일종의 잠금이 있습니까?
Mik378

@ Mik378 메시지 dem 등성 에 대한이 기사를 살펴보십시오 . 기술적으로는 일관성에 대한 약속을 잃지 만 응용 프로그램 가동 시간의 안정성과 성능면에서 얻을 수있는 것을 찾을 가치가 있습니다. 손실을 상당히 고통스럽지 않게하기 위해 메시지 처리 방식을 변경하는 것도 매우 쉽습니다.
brianfeucht

2
예, 주문을 보장하려면 잠금이 필요합니다. 일부 대기열 시스템은 성능을 대가로이를 제공 할 수 있습니다. 때때로 작동이 잘못 될 수 있다는 사실을 받아들이고 프로세서 측에서 처리하는 방법을 알아낼 수 있다면 성능 측면에서 기하 급수적으로 향상 될 것입니다.
brianfeucht

1
@ Mik378-답변에 유스 케이스를 추가했습니다. 도움이 되길 바랍니다!
brianfeucht
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.