단일 스레드 및 다중 스레드 데이터베이스 성능


58

H2는 성능면에서 평판이 좋은 단일 스레드 데이터베이스입니다. 다른 데이터베이스는 다중 스레드입니다.

내 질문은 언제 멀티 스레드 데이터베이스가 단일 스레드 데이터베이스보다 더 흥미로워 집니까? 얼마나 많은 사용자? 몇 개의 프로세스가 있습니까? 방아쇠는 무엇입니까? 누구든지 공유 경험이 있습니까?

요약

  • 일반적인 병목 현상은 디스크 액세스입니다
  • SSD는 빠르지 만 깨지기 쉽습니다 (실패 절차는 필수입니다)
  • 단일 스레드 시스템에서 하나의 긴 쿼리는 다른 모든 스레드를 차단합니다
  • 멀티 스레딩 시스템 구성이 까다로울 수 있습니다
  • 멀티 스레드 데이터베이스는 단일 코어 시스템에서도 유용합니다

스레드는 지금까지 내가 말할 수있는이 질문의 목적을 위해 "스레드 또는 프로세스"를 의미한다 - 예를 들어 포스트 그레스를 멀티 스레드되지 않습니다 하지만 문제는 (오라클, SQL 서버 등)에 대해 (H2, 포스트 그레스)를 비교하려고하지 않습니다
잭 Douglas

답변:


31

내 의견은 다음과 같습니다.

일반적으로 DB 시스템의 병목 현상 (또는 가장 느린 부분)은 디스크입니다. CPU는 산술 연산, 처리 또는 CPU가 수행하는 다른 작업 중에 만 스파이크를 발생시킵니다. 적절한 아키텍처를 사용하면 멀티 스레딩은 느린 디스크 읽기 / 쓰기를 수행하는 대신 CPU에 대한 쿼리로드를 오프셋하는 데 도움이됩니다. 이전에 디스크에 저장된 계산 열을 생성하고 디스크에서이 열을 읽는 것보다 CPU주기를 사용하여 값을 계산하는 것이 더 빠른 경우가 있습니다.

일부 RDBMS에는 정렬, 해싱, 임시 변수 등을 위해 해당 인스턴스의 모든 DB에서 사용하는 임시 DB (tempdb)가 있습니다.이 tempdb 파일의 멀티 스레딩 및 분할을 사용하여 tempdb의 처리량을 향상시킬 수 있습니다 전체 서버 성능을 향상시킵니다.

멀티 스레딩 (병렬)을 사용하면 쿼리의 결과 집합을 분할하여 하나의 코어 만 사용하지 않고 서버의 다른 코어에서 처리 할 수 ​​있습니다. 이 기능은 항상 성능을 향상 시키지는 않지만 성능이 향상되는 경우가 있으므로 기능을 사용할 수 있습니다.

DB에서 사용할 수있는 스레드는 디스크 읽기 / 쓰기, 사용자 연결, 백그라운드 작업, 잠금 / 래칭, 네트워크 IO 등 여러 용도로 사용됩니다. OS 아키텍처에 따라 스레드는 CPU에 선제 적으로 공급되며 대기 및 대기열을 사용하여 관리됩니다. CPU가 이러한 스레드를 매우 빨리 처리 할 수 ​​있으면 대기 시간이 짧습니다. 단일 스레드 DB에서는 다른 스레드를 쉽게 사용할 수있는 것보다 하나의 스레드 만 재활용하는 오버 헤드가 있기 때문에 다중 스레드 DB는 단일 스레드 DB보다 빠릅니다.

확장 된 DB 시스템을 관리하고 실행하기 위해 더 많은 스레드가 필요하기 때문에 확장 성도 문제가됩니다.


통찰력에 감사드립니다. 사람들이 솔리드 스테이트 드라이브를 칭찬하는 것을 들었습니다. 쿼리 작성이 잘되고 응용 프로그램이 합리적으로 병렬화 된 후에 투자하는 것이 최선의 방법 일 것입니다.
Jérôme Verstrynge

@Stan-나는 multithreaded이 맥락에서 뭔가 다른 것을 의미 한다고 생각 한다 . 즉, 누가가 그의 답변에서 언급 한 것처럼 모든 거래는 직렬화된다.
잭 더글러스

@JVerstry ~ 아니요, 실제로는 아닙니다. SSD에 대한 Jeff Atwood의 생각을 읽어보십시오 ... 고장률이 높습니다. 가장 좋은 방법은 데이터를 올바르게 색인화하고 잘 작성된 쿼리를 작성하는 것입니다.
jcolebrand

@jcolebrand 좋아, 그는 그들이 실패 할 때 강력한 백업 시스템으로 만 속도를 옹호하는 것으로 보인다
Jérôme Verstrynge

2
@Jverstry ~ 네, 그 개념을 이해하고 잘 이해하고 전체 프로덕션 환경을 재구성하거나 (또는 ​​자동화 된 장애 조치가 시작되어 가까운 시점에 어느 시점에서 재 빌드되기를 기다리는 지) 신경 쓰지 마십시오. 그들은 더 빨리 일을 할 것입니다.
jcolebrand

47

MySQL에 대해 말할 수있는 한 가지 사실은 트랜잭션 (ACID 호환) 스토리지 엔진 인 InnoDB가 실제로 다중 스레드라는 것입니다. 그러나 그것은 당신이 그것을 구성하는 것처럼 멀티 스레드입니다 !!! "즉시 사용 가능"하더라도 InnoDB는 기본 설정으로 단일 CPU 환경에서 뛰어난 성능을 발휘합니다. InnoDB 멀티 스레딩 기능을 활용하려면 많은 옵션을 활성화해야합니다.

innodb_thread_concurrency 는 InnoDB가 열린 상태로 유지할 수있는 동시 스레드 수의 상한을 설정합니다. 이 설정에 가장 적합한 라운드 수는 (2 X CPU 수) + 디스크 수입니다. 업데이트 : Percona NYC Conference에서 직접 배웠을 때 InnoDB Storage Engine이 실행중인 환경에 가장 적합한 스레드 수를 찾도록 경고하려면이를 0으로 설정해야합니다.

innodb_concurrency_tickets 는 동시성 검사를 무시할 수없는 스레드 수를 설정합니다. 이 한계에 도달하면 스레드 동시성 검사가 다시 표준이됩니다.

innodb_commit_concurrency 는 커밋 할 수있는 동시 트랜잭션 수를 설정합니다. 기본값은 0이므로 설정하지 않으면 여러 트랜잭션을 동시에 커밋 할 수 있습니다.

innodb_thread_sleep_delay 는 InnoDB 대기열에 다시 들어가기 전에 InnoDB 스레드가 휴면 될 수있는 시간 (밀리 초)을 설정합니다. 기본값은 10000 (10 초)입니다.

innodb_read_io_threadsinnodb_write_io_threads (MySQL 5.1.38 이후)는 읽기 및 쓰기를 위해 지정된 수의 스레드를 할당합니다. 기본값은 4이고 최대 값은 64입니다.

innodb_replication_delay 는 슬레이브에 스레드 지연을 부과하여 innodb_thread_concurrency에 도달합니다.

innodb_read_ahead_threshold 는 비동기 판독으로 전환하기 전에 설정된 범위 (64 페이지 [페이지 = 16K])의 선형 판독을 허용합니다.

더 많은 옵션을 지명하면 시간이 나를 벗어날 것입니다. 이에 대한 정보는 MySQL의 Documentation 에서 확인할 수 있습니다 .

대부분의 사람들은 이러한 기능을 인식하지 못하고 ACID 호환 트랜잭션을 수행하는 InnoDB에 상당히 만족합니다. 이러한 옵션을 조정하면 위험을 감수해야합니다.

MySQL 5.5 다중 버퍼 풀 인스턴스 (9 버퍼 풀 인스턴스에서 162GB)를 사용하여 데이터를 메모리에 자동 분할하려고 시도했습니다. 일부 전문가들은 이것이 50 %의 성능 향상을 제공해야한다고 말합니다. 내가 얻은 것은 실제로 InnoDB를 크롤링하는 많은 스레드 잠금이었습니다. 나는 1 버퍼 (162GB)로 전환했고 세계에서 다시 잘되었습니다. 이것을 설정하려면 Percona 전문가가 필요하다고 생각합니다. 나는 내일 뉴욕에서 열리는 Percona MySQL Conference에 참석할 것이며 기회가 충분하다면 이것에 대해 물을 것입니다.

결론적으로, InnoDB는 다중 스레드 작업에 대한 기본 설정이 주어지면 다중 CPU 서버에서 잘 작동합니다. 그것들을 조정하려면 많은주의, 인내심, 훌륭한 문서 및 훌륭한 커피 (또는 Red Bull, Jolt 등)가 필요합니다.

좋은 아침, 좋은 밤, 좋은 밤!

업데이트 2011-05-27 20:11

목요일 뉴욕 에서 열린 Percona MySQL Conference에서 돌아 왔습니다 . 무슨 회의입니다. 많은 것을 배웠지 만 InnoDB와 관련하여 살펴볼 답변이 있습니다. 나는 Ronald Bradford에 의해 innodb_thread_concurrency를 0으로 설정하면 InnoDB가 스레드 동시성으로 내부적으로 최상의 행동 과정을 결정할 수 있다고 알렸다 . 나는 MySQL 5.5에서 이것을 더 실험 할 것이다.

업데이트 2011-06-01 11:20

하나의 긴 쿼리가 진행되는 한 InnoDB는 ACID를 준수 하며 MultiVersion Concurrency Control을 사용하여 매우 잘 작동 합니다 . 트랜잭션은 다른 사람이 데이터에 액세스하지 못하도록 차단하는 격리 수준 (기본적으로 반복 가능한 읽기)을 수행 할 수 있어야합니다.

멀티 코어 시스템의 경우 InnoDB는 먼 길을 왔습니다. 과거에는 InnoDB가 멀티 코어 환경에서 제대로 작동하지 못했습니다. 여러 코어가 여러 mysqld 프로세스를 CPU에 분산 시키려면 단일 서버에서 여러 mysql 인스턴스를 실행해야했던 것을 기억합니다. 퍼 노나 (Percona)와 이후 MySQL (eh, Oracle, 여전히 저를 개그라고 말함) 덕분에 더 이상 필요하지 않습니다. InnoDB를 더 많은 튜닝없이 단순하게 코어에 액세스 할 수있는보다 성숙한 스토리지 엔진으로 개발했기 때문입니다. 현재 InnoDB 인스턴스는 단일 코어 서버에서 잘 작동 할 수 있습니다.


11

동시 사용자 또는 프로세스가 여러 명이거나 다중 스레드 데이터베이스 액세스 권한을 가진 단일 프로세스가있는 즉시 스레딩을 지원하는 데이터베이스가 있으면 흥미로울 것입니다.

H2는 스레드로부터 안전하지만 데이터베이스에 대한 모든 요청을 직렬화합니다. 이는 무거운로드 시나리오에서 잠재적 인 성능 문제가 될 수 있습니다. 이것이 실제로 특정 프로젝트에 해당되는지 여부는 성능 요구 사항, 데이터베이스에 액세스하는 스레드 / 사용자 / 프로세스 수,이 스레드에 의해 실행 된 쿼리 빈도 및 평균 및 최악의 성능 조합에 따라 다릅니다. 쿼리.

예를 들어, 성능 요구 사항이 1 초 내에 응답해야하는 경우 실행하는 데 0.05 초가 걸리는 단일 쿼리를 실행하는 동시 사용자가 10 명을 넘지 않으면 단일 스레드 데이터베이스에서 여전히 이러한 목표를 달성 할 수 있습니다 (멀티 스레드 임) 이미 눈에 띄는 성능 향상을 제공했을 것입니다). 그러나 0.5 초의 최악의 성능을 가진 단일 잠재적 쿼리를 사용하는 동일한 시나리오에서 데이터베이스 액세스를 직렬화해도 더 이상 성능 목표를 달성 할 수 없습니다.

현재 프로젝트에서 H2를 사용하는 경우로드 시나리오에서 코드베이스에 대해 프로파일 러를 실행하는 것이 좋습니다 (일부 일반적인 사용 사례를 사용하여 코드를 동시에 치는 x 개의 스레드 수를 시작하십시오). 이를 통해 이론화하는 대신 코드베이스의 성능 및 병목 현상에 대한 실제 메트릭을 제공 할 수 있습니다. 데이터베이스 액세스를 기다리는 데 많은 시간을 소비 한 요청이 스레드 데이터베이스로 이동해야 할 때입니다.


H2는 모든 요청 또는 DML 만 직렬화합니까?
잭 더글러스

8

내가 말할 수 있듯이 "단일 스레드"는 H2에 대한 약간의 오해입니다. 요점은 모든 트랜잭션을 직렬화 한다는 것입니다 (즉, 한 번에 하나씩).

응용 프로그램에 "OK"인지 아닌지에 대한 중요한 질문은 "얼마나 많은 사용자입니까?"가 아닙니다. 또는 "얼마나 많은 프로세스입니까?", "내 거래는 얼마나 걸립니까?"

모든 거래가 1 초 미만이면 완료 될 수 있습니다. 완료하는 데 몇 시간이 걸리면 보류중인 다른 모든 거래가 완료되기를 기다리는 것이 좋지 않을 수 있습니다. 이것이 "좋은"인지 아닌지에 대한 결정은 자신의 성능 요구 사항에 따라 달라집니다. 즉, 사용자가 트랜잭션으로 데이터베이스를 칠 때까지 허용되는 대기 시간

--편집하다

H2는 실제로 트랜잭션을 직렬화하는 것이 아니라 DML로 보입니다. 다시 말해 하나의 긴 트랜잭션 내에서 많은 짧은 업데이트 가 다른 업데이트를 차단하지는 않습니다 . 그러나 실험적인 MVCC 기능을 사용하지 않는 한 테이블 잠금은 실제로 유사한 효과를 나타냅니다. 거기에 또한 실험은 "multi_threaded"기능이 있지만 MVCC와 동시에 사용할 수 없습니다


5

PostgreSQL 사이트에서 인용구를 인용하면 ...이 인수의 장점을 전혀 알지 못합니다. 단지 의견에 맞지 않았습니다.

개발자 FAQ에서 ( "스레드가 사용되지 않는 이유 ...") :

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

스레드는 현재 백엔드에 여러 프로세스 대신 사용되지 않습니다. (...)

  • 한 백엔드의 오류는 다른 백엔드가 단일 프로세스 내의 스레드 인 경우 손상 될 수 있습니다.
  • 스레드를 사용한 속도 향상은 나머지 백엔드 시작 시간에 비해 작습니다.
  • 읽기 전용 실행 가능 매핑 공유 및 shared_buffers 사용은 스레드와 같은 프로세스가 매우 메모리 효율적임을 의미합니다.
  • 정기적 인 프로세스 생성 및 제거는 메모리 조각화를 방지하여 장기 실행 프로세스에서 관리하기 어려울 수 있습니다.

할 일 목록에서 ( "우리가 원하지 않는 기능") :

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

단일 프로세스에서 스레드로 실행되는 모든 백엔드 (원하지 않음)

이것은 현재 설정에서 얻는 프로세스 보호를 제거합니다. 스레드 생성은 일반적으로 최신 시스템에서의 프로세스 생성과 동일한 오버 헤드이므로 순수한 스레드 모델을 사용하는 것은 현명하지 않은 것으로 보이며 MySQL과 DB2는 스레드가 해결하는 것만 큼 많은 문제를 발생시키는 것으로 나타났습니다. (...)

다시 말하지만, 나는 위의 장점을 전혀 모릅니다. 주석에 맞추기에는 너무 길었습니다.


-3

다중 스레드 데이터베이스는 데이터베이스에 대한 병렬 쿼리가 둘 이상있을 때만 이점이 있습니다. 보유한 사용자 수에 따라 다릅니다. 응용 프로그램에서 동시에 작업하는 사용자가 10 명 이상인 경우 데이터베이스에서 동시에 둘 이상의 쿼리를 생성 할 가능성이 높습니다.

또한 멀티 스레드 데이터베이스는 CPU에 멀티 코어가있을 때만 이점을 얻을 수 있습니다. 단일 코어가있는 경우 다중 스레드 데이터베이스는 작업을 대기시키고 단일 코어에서 순차적으로 실행해야합니다. 멀티 코어가있는 경우 각 코어는 하나의 스레드를 병렬로 실행할 수 있습니다. 따라서 더 나은 성능.

이 질문에 대답합니까?


7
멀티 스레드 데이터베이스는 단일 코어 시스템에서도 유리합니다. 장기 실행 쿼리 하나가 다른 모든 데이터베이스 액세스를 차단하지 못하도록하고 디스크 나 네트워크 I / O에서 여러 스레드를 대기하는 동안 다른 스레드가 쿼리를 적극적으로 구문 분석하고 프리 페치 된 데이터를 처리하는 등의 작업을 수행 할 수 있습니다.

한 명의 사용자가 일부 작업을 병렬화하는 하나의 프로그램을 사용할 수 있습니다. 이 프로그램은 데이터베이스에 멀티 스레딩 / 멀티 프로세싱 기능도있는 경우 가장 유용합니다.
joanolo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.