2016-07-11 1 views
-2

제 질문은 구체적이지 않지만 추상적입니다. 나는 종종 내 프로젝트에서 백그라운드 DB 프로세싱을 다루지 만, 제대로 수행하는 방법은 아직 없다.MySQL InnoDB, 멀티 스레딩, 멀티 인서트 및 락. 올바른 전략 찾기

예를 들어, 우리는 많은 레코드, 수십만 개의 레코드 또는 이벤트 수백만 개의 테이블을 가지고 있습니다. 백그라운드 데몬은이 테이블의 데이터를 영구적으로 수정합니다. 그것은 외부에서 얻은 다른 데이터를 기반으로 레코드를 업데이트하고 삽입합니다. 시간을 절약하기 위해 다중 INSERT를 사용하여 시간을 절약합니다. 레코드를 하나씩 업데이트하는 데 얼마나 오래 걸릴지 상상할 수 없기 때문에 시간을 절약 할 수 있습니다. 또한 백그라운드 프로세스가 멀티 스레딩 모드로 실행되기 때문에 필자는 해당 테이블에서 WRITE LOCK을 사용해야했습니다. 그렇게하지 않으면 각 멀티 삽입이 테이블의 갭과 자동 증가를 차단하고 독립적으로 실행할 수 없기 때문에 교착 상태 오류가 많이 발생합니다. WRITE LOCK은 모든 쿼리를 큐에 넣고 순차적으로 실행합니다. 다음 쿼리는 이전이 완료 될 때까지 대기합니다. 여기에 내 실수가있을 수 있지만 멀티 쓰레드 모드에서 멀티 인서트를 실행하는 다른 효과적인 방법을 찾지 못했습니다. 다른 측면에서

MAIN PROCESS 
-- WORKER 1: Receiving data over HTTP --> INSERT table VALUES (..., ..., ...) 
-- WORKER 2: Receiving data over HTTP --> INSERT table VALUES (..., ..., ...) 
-- WORKER 3: Receiving data over HTTP --> INSERT table VALUES (..., ..., ...) 

우리는 테이블에서 데이터를 표시하는 사용자 인터페이스가 : 데몬의 간단한 스키마는 것 같습니다. 테이블에서 SELECT 쿼리를 수행합니다. 그러나 백그라운드 프로세스가 실행 중이라면 WRITE 잠금이 활성화되었다고 말했습니다. 즉, 잠금 작동 중에 READ 조작도 기다려야합니다. 사용자의 경우 전체 서버가 정지 된 것처럼 보입니다.

왜 나는이 질문을 쓰고 있습니다. 방대한 양의 데이터를 읽을 수있는 능력과 함께 수정하는 전략이 있습니까?

+1

데이터 삽입 작업자 **가 ** 작업 테이블에 잠그지 않고 삽입합니다. 위의 귀하의 정보에서, 그 3 인 작업자는 독립적으로 삽입 작업을 수행합니다.onsey-twosey 또는 일괄 처리. 이벤트 [001] (http://stackoverflow.com/a/37901661/1816093) 및 [Evt 개요] (http://stackoverflow.com/a/32508935) 및 [디버깅/성능 모니터링] (http : // (삽입, 조인 패턴 삽입, 중복 키 업데이트 삽입, 이름 지정) ---> 실제 테이블에 삽입합니다. 작업 테이블의 행이 처리되면 완료로 플래그가 지정됩니다. evt의 끝에서 정리. – Drew

+1

따라서 이벤트 또는 이벤트는 선택한 일정에 따라 실행됩니다. 아니 cron 등 그들은 필요한 데이터가 있습니다. 이론적으로 전체 잠금 측면이 제거되거나 범위와 영향이 심각하게 감소합니다. – Drew

답변

1

WRITE LOCK 대신 교착 상태를 최소화하고 여전히 발생하는 문제를 처리합시다.

  • 일괄 처리 할 데이터 (다중 삽입 또는 업데이트)를 정렬하십시오.
  • "너무 많이"배치하지 마십시오. 약 100 행을 넘는 배치 삽입은 "수익 감소"입니다. 즉, 한번에 1000을 배치 할 필요가 없습니다. 100이 너무 많은 교착 상태를 제공하면 더 낮은 숫자를 선택하십시오.
  • 교착 상태가 발생하면 트랜잭션을 재생하십시오.
  • 통계를 수집하십시오. 행 수, 트랜잭션 수, 교착 상태 수 등. 이러한 메트릭은 일괄 처리를 조정하는 데 도움이됩니다.

스테이징 테이블. 또 다른 접근법은 스테이징 테이블 (작업 테이블)을 통해 단일 프로세서로 퍼널하는 것입니다. 여러 출처가 그것을 먹일 수 있습니다. 즉, 색인이없고 가능한 한 적은 오버 헤드로 단일 테이블에 많은 연결을 삽입하십시오. 다른 테이블에서 작업중인 프로세스가 있습니다. 완료되면 테이블을 플립 플롭. high speed ingestion을 참조하십시오.

데이터가 준비 테이블에있는 동안 정규화 및 기타 복잡한 프로세스를 처리 할 수 ​​있으므로 주 테이블과 읽기를 방해하지 않습니다.

방금 ​​설명한 내용은 @Drew가 주석에서 언급 한 내용과 유사합니다. 그러나 계속 처리하고 플립 플롭 (flipflopping)을 권장합니다. 이렇게하면 삭제가 복잡 해지는 것을 피할 수 있습니다.

을 읽는 경우 쿼리가 잘 최적화되었는지 확인하십시오.