2012-10-13 5 views
2

나는이 질문을 여러 번 stackoverflow에서 물어 알고 있습니다. 이 질문을 게시하여 내 디자인에 가장 적합한 것이 무엇인지 찾아야합니다. 내 직업에 대한 다음 스키마가 있습니다. 우리가이 테이블에 뭐하는 작업메모리 관계형 데이터베이스에서

_unique_key  varchar(256) NULL 
_job_handle  varchar(256) NULL 
_data    varchar(1024) NULL 
_user_id   int(11) NULL 
_server_ip   varchar(39) NULL 
_app_version  varchar(256) NULL 
_state    int(11) NULL 
_is_set_stopped bool 

: 우리는 하나의 업데이트 및이 테이블에 10 선택 쿼리를 낳게 될 것입니다 각 작업에 대해

  1. . 따라서 우리는 읽기 및 쓰기에 높은 주파수가 필요합니다.
  • _data 필드 크기 1 MB의 5킬로바이트 다릅니다
  • 을 _user_id is_set_stopped
  • _state
    1. _unique_key :
    2. 은 필터링을 수행하여이 테이블을 조작 많은 응용 프로그램이 있습니다 응용 프로그램 및 사용자의 유형에 따라 다릅니다.
    3. 응용 프로그램은 선택적 속성을 업데이트 할 수 있습니다. 우리가 생각

    솔루션 :

    MySQL의 InnoDB의

    나는 MySQL이 높아 읽기 및 쓰기에 대한 요구 사항을 충분히 확장되지 것이라 생각합니다. 이 용액 메모리 테이블

    MySQL의

    문제

    1. 그것은 동적 필드 크기를 지원하지 않는다는 것이다. MEMORY 테이블은 고정 길이의 행 저장 형식을 사용합니다. VARCHAR와 같은 가변 길이 유형은 고정 길이를 사용하여 저장됩니다. Source http://dev.mysql.com/doc/refman/5.0/en/memory-storage-engine.html
    2. select for .... 전체 테이블을 잠글니다. 나는 그것이 문제가 될 것인지 모른다.

    레디 스

    레디 스의 모습은 좋은 선택을 좋아한다. 하지만 내 테이블 키 값 캐시 서버에 좋지 않은 것 같아요.

    1. 매우 많은 데이터 유형 세트 만 지원합니다. 목록에 문자열 만 저장할 수 있습니다. 필드를 JSON 또는 다른 형식으로 저장해야합니다.
    2. 클라이언트가 특정 속성을 업데이트하려면 전체 값을 다운로드 한 다음 객체 구문 분석을 수행하고 서버에 다시 푸시해야합니다. 내가 잘못 했나요? 할 수있는 방법이 있습니까?
    3. 값을 기준으로 필터링하는 것은 불가능합니다. 내가 잘못 했나요? 할 수있는 방법이 있습니까?

    MySQL의 InnoDB의 TMPFS의 파일 시스템

    이 유망 보인다. 그러나 메모리 테이블에서 Redis 또는 MySQL과 비슷한 정도로 확장되지는 않습니다.

  • +1

    실제 읽기/쓰기 속도 요구 사항은 무엇입니까? –

    +0

    @ Joachim Isaksson. 현재 요구 사항은 완전한 행의 경우 초당 1380 개의 읽기 및 쓰기이고 is_set_stopped 열의 경우 초당 6900 개의 읽기입니다. 서버에서 작업 수가 증가함에 따라 카운트가 증가합니다. –

    +0

    왜 InnoDB가있는 MySQL은 관련성이 없다고 생각합니까? 당신은 그것을 아주 잘 조정할 필요가있을 것입니다 ... –

    답변

    4

    이 질문에서 원시 성능 (즉, 효율성)과 확장 성을 혼동하고 있습니다. 그들은 다른 개념입니다.

    InnoDB와 메모리 엔진 사이에서 InnoDB는 가장 확장 성이 높습니다. InnoDB는 멀티 버젼의 동시성 제어를 지원하고, 경합을 처리 할 수있는 많은 최적화를 가지고있어, 동시 액세스를 메모리 엔진보다 훨씬 잘 처리 할 것입니다. 일부 I/O 바운드 상황에서 속도가 느려지더라도.

    Redis는 단일 스레드 서버입니다. 모든 조작이 직렬화됩니다. 그것은 확장 성이 없습니다. 비효율적 인 것은 아닙니다. 반대로, MySQL (epoll 기반 이벤트 루프로 인해)과 트래픽 (매우 효율적인 잠금없는 구현과 메모리 내 데이터 구조로 인해)의 연결을 더 많이 지원할 것입니다.

    질문에 답하기 위해 InnoDB를 사용하여 MySQL을 시험해 보겠습니다. 올바르게 구성 되었으면 (동기 확약, 충분한 캐시 버퍼 등이 없음), 양호한 처리량을 유지할 수 있습니다. 그리고 tmpfs 위에서 실행하는 대신 SSD 하드웨어를 고려할 것입니다.

    이제 Redis (관계형 저장소 btw가 아님)를 사용하려는 경우 확실히 할 수 있습니다. 데이터를 체계적으로 직렬화/비 직렬화 할 필요가 없습니다. 모든 액세스 경로를 예상하고 적응 된 데이터 구조를 찾을 수 있다면 실제로 필터링이 가능합니다. 예를 들어

    : 작업 당

    • 한 해시 객체입니다. 열쇠는 _unique_key입니다. 해시의 필드는 관계형 테이블의 열에 대응해야합니다.

      HMSET job:AAA job_handle BBB data CCC user_id DDD server_ip EEE app_version FFF state GGG is_set_stopped HHH 
      SADD state:GGG AAA 
      SADD is_set_stopped:HHH AAA 
      SADD user_id:DDD AAA 
      

      당신에게 : 각 작업 삽입에 대한 사용자 ID 값

    당 is_set_stopped

  • 한 세트에 대한
  • 한 세트의 상태 값 당 ​​
  • 2 세트는 다음과 같은 명령 파이프 라인 필요 해당 세트를 유지 관리하는 경우 개별 필드를 개별적으로 쉽게 업데이트 할 수 있습니다.

    집합을 교차하여 필터링 쿼리를 수행 할 수 있습니다. 예 :

    SINTER is_set_stopped:HHH state:GGG 
    

    Redis를 사용하면 데이터 필드가 큰 경우 병목 현상이 네트워크가 될 수 있습니다. 1MB의 직업보다 5KB 많은 직업을 갖기를 바랍니다. 예를 들어 1MB 객체의 1000 글자/s는 8GB/s를 나타냅니다. 이는 네트워크가 유지할 수있는 것 이상일 것입니다. 이것은 Redis와 MySQL 모두에 해당됩니다.

  • +0

    아하 감사합니다. 나는 네트워크 제한에 대해 생각해 본 적이 없다. –

    1

    postgresql은 mysql보다 기능이 뛰어나고 (복잡한 쿼리 및 데이터 유형을 지원할 수있는 기능이 더 많음) 많은 튜닝 옵션을 제공합니다.

    postgresql에 충분한 메모리를 지정하고 매개 변수를 조정하면 메모리에있는 모든 데이터가 캐시됩니다.

    또는 tmpfs에서도 사용할 수 있으며 하드 카피의 디스크 기반 데이터베이스에 스트리밍 복제를 사용하십시오.

    스트리밍 복제에는 비동기 적으로, 수신시, fsync에서 3 가지 작동 모드가 있습니다. 첫 번째 비동기를 사용하는 경우 복제 서버의 디스크에 동기화 할 때까지 기다릴 필요가 없기 때문에 모든 업데이트가 tmpfs로 매우 빠릅니다.

    또 다른 기능이 도움이 될 수있는 텍스트 필드가 많은 것처럼 보입니다. postgresql은 행에 textsearch 벡터를 저장할 수 있으며 색인을 추가하고 연결된 내용의 트리거를 통해 업데이트 할 수 있습니다. 검색중인 모든 행 이렇게하면 여러 열에서 텍스트 검색을 수행 할 때와 비교하여 성능면에서 놀라운 향상을 얻을 수 있습니다.

    에 관계없이 데이터베이스의 당신은을 사용

    당신은 그 _data이 VARCHAR의 [1024] 인 상태, 그러나 당신이 데이터를 1M로 5K를 포함 말? 이게 실제로 BLOB입니까? 길이가 실수였다하더라도, mysql은 길이가 65535 바이트보다 긴 varchar 필드를 지원하지 않습니다! 나는 그것이 다른 행만큼 많이 업데이트되지 않았다고 가정합니다. 정적 데이터가있는 테이블과 동적 데이터가있는 테이블을 디스크 액세스를 최소화하기 위해 두 개의 테이블로 분리하는 것이 현명 할 수 있습니다.