나는 데이터베이스 전문가가 아니며 공식적인 컴퓨터 과학 배경이 없으므로 나와 함께하십시오. ACID와 호환 되지 않는 v4 이전 의 이전 MongoDB 버전 을 사용하는 경우 발생할 수있는 실제 부정적인 종류에 대해 알고 싶습니다 . 이것은 모든 ACID 비준수 데이터베이스에 적용됩니다.
MongoDB는 Atomic Operations를 수행 할 수 있지만 성능상의 이유로 “전통적인 잠금 및 복잡한 트랜잭션”을 지원하지 않는다는 것을 알고 있습니다. 또한 데이터베이스 트랜잭션의 중요성과 데이터베이스가 은행을위한 경우의 예를 이해하고 모두 동기화해야하는 여러 레코드를 업데이트하는 경우 트랜잭션이있는 경우 트랜잭션이 초기 상태로 되돌아 가기를 원합니다. 정전으로 인해 신용은 구매 등과 같습니다.
그러나 MongoDB에 대한 대화를 할 때 데이터베이스가 실제로 어떻게 구현되는지에 대한 기술적 세부 사항을 모르는 사람들은 다음과 같은 문장을 던지기 시작합니다.
MongoDB는 MySQL 및 Postgres보다 훨씬 빠르지 만 1 백만 분의 1과 같이 “올바르게 저장되지 않을”가능성은 적습니다.
“정확하게 저장하지 않습니다”부분은 이러한 이해를 언급합니다. MongoDB에 쓰는 순간 정전이 발생하면 특정 기록이있을 수 있습니다 (예 : 10 개의 속성이있는 문서에서 페이지 뷰를 추적하고 있음) 각각), 문서 중 하나는 5 개의 속성 만 저장했습니다. 이는 시간이지나면서 페이지 뷰 카운터가 “약간”꺼질 것임을 의미합니다. 당신은 그들이 얼마나 99.999 %이지만 100 %가 아니라는 것을 알지 못할 것입니다. 이것은 특별히 mongodb atomic operation으로 설정하지 않는 한 조작이 원자적임을 보장하지 않기 때문입니다.
제 질문은 MongoDB가 “올바르게 저장되지”않을시기와 이유에 대한 올바른 해석은 무엇입니까? ACID의 어떤 부분이 만족스럽지 않으며 어떤 상황에서 데이터의 0.001 %가 꺼져 있는지 어떻게 알 수 있습니까? 어떻게 든 고칠 수 없습니까? 그렇지 않은 경우 users
레코드가 저장되지 않을 수 있으므로 테이블 과 같은 것을 MongoDB에 저장해서는 안된다는 의미입니다 . 그러나 다시 한 번 1 / 1,000,000 명의 사용자는 “다시 가입을 시도”해야합니다.
MongoDB와 같은 ACID 비 호환 데이터베이스에서 부정적 일이 발생하는시기 / 이유 목록을 찾고 있으며 이상적으로 표준 해결 방법이있는 경우 (데이터를 정리하기 위해 백그라운드 작업을 실행하거나이를 위해 SQL 만 사용하는 등) 이상적입니다. .
답변
MongoDB에서 잃어버린 한 가지는 다중 수집 (테이블) 트랜잭션입니다. MongoDB의 원자 수정자는 단일 문서에 대해서만 작동 할 수 있습니다.
재고에서 품목을 제거하고 동시에 다른 사람의 주문에 추가해야하는 경우에는 할 수 없습니다. 재고와 주문이라는 두 가지가 동일한 문서에 존재하지 않는 한 (아마도 그렇지 않을 수도 있음)
작업중 인 응용 프로그램 에서이 같은 문제가 발생하여 선택할 수있는 두 가지 가능한 솔루션이 있습니다.
1) 가능한 한 문서를 최대한 구성하고 원자 수정자를 최대한 사용하고 나머지 비트는 백그라운드 프로세스를 사용하여 동기화되지 않은 레코드를 정리하십시오. 예를 들어, 인벤토리에서 항목을 제거하고 원자 수정자를 사용하여 동일한 문서의 reservedInventory 배열에 항목을 추가합니다.
이렇게하면 고객이 예약 한 품목이기 때문에 재고에서 품목을 사용할 수 없음을 항상 알 수 있습니다. 고객이 체크 아웃하면 reservedInventory에서 품목을 제거합니다. 그것은 표준 거래가 아니며 고객이 장바구니를 버릴 수 있기 때문에 버려진 장바구니를 찾아 예약 된 재고를 사용 가능한 재고 풀로 다시 옮기는 백그라운드 프로세스가 필요합니다.
이것은 이상적이지는 않지만 mongodb가 필요에 완벽하게 맞지 않는 큰 응용 프로그램의 유일한 부분입니다. 또한 지금까지 완벽하게 작동합니다. 이것은 많은 시나리오에서 가능하지는 않지만 사용중인 문서 구조로 인해 적합합니다.
2) MongoDB와 함께 트랜잭션 데이터베이스를 사용하십시오. MongoDB (또는 다른 NoSQL)가 최선을 다하는 것을 허용하면서 MySQL을 사용하여 절대적으로 필요한 것에 대한 트랜잭션을 제공하는 것이 일반적입니다.
# 1의 솔루션이 장기적으로 작동하지 않으면 MongoDB를 MySQL과 결합하는 방법에 대해 더 조사 할 것이지만 현재 # 1은 내 요구에 잘 맞습니다.
답변
MongoDB가 ACID를 준수하지 않는 것은 실제로 올바르지 않습니다. 반대로 MongoDB는 문서 수준에서 ACID- 컴파일러입니다 .
단일 문서에 대한 모든 업데이트는
- 원자 : 그것은 완전히 완료되거나 그렇지 않습니다
- 일관된 : “부분적으로 적용된”업데이트를 읽는 독자가 없습니다.
- 격리 됨 : 다시 말하지만 독자는 “더러운”판독 값을 볼 수 없습니다
- 내구성 : (적절한 쓰기 관련)
MongoDB에없는 것은 트랜잭션 입니다. 롤백 할 수 있고 ACID를 준수하는 다중 문서 업데이트입니다.
2 단계 커밋 을 사용하여 단일 문서에 대한 ACID 호환 업데이트를 기반으로 트랜잭션을 빌드 할 수 있습니다 .
답변
“Starbucks는 2 단계 커밋을 사용하지 않습니다”에 좋은 설명이 있습니다 .
NoSQL 데이터베이스에 관한 것이 아니라 때때로 트랜잭션이 손실되거나 데이터베이스가 일시적으로 일관성이없는 상태가 될 수있는 시점을 보여줍니다.
나는 그것이 “고정”될 필요가 있다고 생각하지 않을 것이다. 수정은 ACID 호환 관계형 데이터베이스를 사용하는 것입니다. 동작이 애플리케이션 요구 사항을 충족 할 경우 NoSQL 대안을 선택합니다.
답변
다른 사람들이 이미 좋은 대답을했다고 생각합니다. 그러나 ACID NOSQL DB (예 : http://ravendb.net/ ) 가 있음을 추가하고 싶습니다 . 따라서 결정은 NOSQL뿐만 아니라 ACID와 ACID의 관계도 없습니다.
답변
“올바로 저장하지 않는다”는 의미는 다음과 같습니다.
-
기본적으로 MongoDB는 변경 사항을 드라이브에 즉시 저장하지 않습니다. 따라서 사용자에게 “업데이트 성공”을 알리고 정전이 발생하여 업데이트가 유실 될 수 있습니다. MongoDB는 업데이트 수준 “내구성”을 제어하는 옵션을 제공합니다. 다른 복제본이 메모리에서이 업데이트를 수신 할 때까지 기다리거나 로컬 저널 파일에 대한 쓰기가 수행 될 때까지 기다릴 수 있습니다.
-
여러 모음에 대한 쉬운 “원자”업데이트는 없으며 동일한 모음에있는 여러 문서까지도 없습니다. Two Phase Commit 으로 우회 하거나 스키마를 재구성하여 단일 문서를 업데이트 할 수 있기 때문에 대부분의 경우 문제가되지 않습니다 . 이 질문을 참조하십시오 : 문서 데이터베이스 : 중복 데이터, 참조 등 (MongoDB)
답변
MongoDB v4.0부터 다중 문서 ACID 트랜잭션이 지원됩니다. 스냅 샷 격리를 통해 트랜잭션은 전 세계적으로 일관된 데이터보기를 제공하고 데이터 무결성을 유지하기 위해 전혀 또는 전혀 실행하지 않습니다.
그들은 다음과 같은 관계 세계의 거래처럼 느껴집니다.
with client.start_session() as s:
s.start_transaction()
try:
collection.insert_one(doc1, session=s)
collection.insert_one(doc2, session=s)
s.commit_transaction()
except Exception:
s.abort_transaction()
https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb를 참조 하십시오.
답변
더 나은 이해를 위해 ACID 속성 에 대해 읽으십시오 .
또한 MongoDB 문서에서 질문과 답변을 찾을 수 있습니다 .
MongoDB는 ACID를 준수하지 않습니다. ACID 준수에 대한 설명은 아래를 참조하십시오.
- MongoDB는
A
문서 수준에서만 토믹합니다. 관계형 데이터베이스 시스템, 특히 위의 링크에서 아는 원자의 정의를 준수하지 않습니다. 이런 의미에서 MongoDB는 ACID의 A를 준수하지 않습니다. - MongoDB는
C
기본적으로 온 사이트입니다.
그러나 복제본 세트의 보조 서버에서 읽을 수 있습니다 . 이 경우 최종 일관성 만 가질 수 있습니다 . 약간 오래된 데이터를 읽지 않아도되는 경우에 유용합니다. - MongoDB는
I
위의 정의에 따라 격리를 보장하지 않습니다 .
- 동시 판독기와 기록기가 여러 개인 시스템의 경우 MongoDB는 클라이언트가 쓰기 작업이 반환되기 전에 쓰기 작업 결과를 읽을 수 있도록합니다.
- 저널이 커미트하기 전에 mongod가 종료되면 쓰기가 성공적으로 리턴 되더라도 쿼리가 mongod가 다시 시작된 후 존재하지 않는 읽기 데이터를 가질 수 있습니다.
그러나 MongoDB는 (삽입 및 업데이트를 위해) 각 문서를 개별적으로 수정합니다. 다중 문서 트랜잭션이 아닌 문서 레벨에서만.
D
내구성 과 관련하여 –write concern
확실하지 않은 옵션 으로이 동작을 구성 할 수 있습니다 . 아마 누군가가 더 잘 알고있을 것입니다.
NoSQL을 ACID 제약 또는 이와 유사한 것으로 옮기려는 일부 연구가 진행되고 있다고 생각합니다. NoSQL 데이터베이스는 일반적으로 빠르며 ACID 제약으로 인해 성능이 크게 느려질 수 있으므로 문제가됩니다.
