73 억 행의 시장 데이터를 저장하는 방법 (읽기 위해 최적화 됨)? 개의 주식에 대한 1

1998 년 이후로 1,000 개의 주식에 대한 1 분 데이터의 데이터 세트가 있는데, 그 총합은 (2012-1998)*(365*24*60)*1000 = 7.3 Billion행입니다.

대부분 (99.9 %)의 경우 읽기 요청 만 수행 합니다.

이 데이터를 db에 저장하는 가장 좋은 방법은 무엇입니까?

  • 7.3B 행이있는 큰 테이블 1 개?
  • 각각 730 만 개의 행이있는 1000 개의 테이블 (각 주식 기호에 대해 하나씩)?
  • 데이터베이스 엔진에 대한 권장 사항이 있습니까? (Amazon RDS의 MySQL을 사용할 계획입니다)

저는 이렇게 큰 데이터 세트를 다루는 데 익숙하지 않으므로 이것은 제가 배울 수있는 좋은 기회입니다. 많은 도움과 조언에 감사드립니다.

편집하다:

다음은 샘플 행입니다.

‘XX’, 20041208, 938, 43.7444, 43.7541, 43.735, 43.7444, 35116.7, 1, 0, 0

열 1은 주식 기호, 열 2는 날짜, 열 3은 분, 나머지 열은 시가-고가-저가-종가, 거래량 및 3 개의 정수 열입니다.

대부분의 쿼리는 “2012 년 4 월 12 일 12:15에서 2012 년 4 월 13 일 12:52 사이에 AAPL의 가격을 알려주세요”와 같습니다.

하드웨어 정보 : Amazon RDS를 사용할 계획이므로 유연하게 사용할 수 있습니다.



답변

쿼리 및 하드웨어 환경에 대해 알려주십시오.

나는 아주 아주 갈 유혹 될 수 없는 NoSQL을 사용하여, 하둡 만큼 당신이 병렬 처리를 활용할 수있는, 또는 비슷한.

최신 정보

좋아, 왜?

우선, 내가 질문에 대해 물었다는 것을 주목하십시오. 워크로드가 어떤 것인지 모른 채 이러한 질문에 답할 수는 없습니다. (이에 대한 기사가 곧 나타날 것입니다.하지만 오늘은 연결할 수 없습니다.) 그러나 문제 의 규모 는 Big Old Database에서 멀어 질 것을 생각하게합니다.

  • 유사한 시스템에 대한 경험에 따르면 액세스는 큰 순차 (일종의 시계열 분석 계산)이거나 매우 유연한 데이터 마이닝 (OLAP) 일 것입니다. 순차적 데이터는 순차적으로 더 좋고 더 빠르게 처리 할 수 ​​있습니다. OLAP는 많은 시간 또는 많은 공간이 소요되는 많은 인덱스를 계산하는 것을 의미합니다.

  • 그러나 OLAP 세계의 많은 데이터에 대해 효과적으로 큰 실행을 수행하는 경우 열 기반 접근 방식이 가장 좋습니다.

  • 무작위 쿼리, 특히 교차 비교를 수행하려는 경우 Hadoop 시스템이 효과적 일 수 있습니다. 왜? 때문에

    • 비교적 작은 상용 하드웨어에서 병렬 처리를 더 잘 활용할 수 있습니다.
    • 또한 높은 안정성과 중복성을 더 잘 구현할 수 있습니다.
    • 이러한 문제 중 다수는 자연스럽게 MapReduce 패러다임에 적합합니다.

하지만 사실은 우리가 여러분의 작업량을 알 때까지 확실한 말을 할 수 없다는 것입니다.


답변

따라서 데이터베이스는 지속적으로 변경되는 크고 복잡한 스키마가있는 상황을위한 것입니다. 간단한 숫자 필드로 가득 찬 하나의 “테이블”만 있습니다. 나는 이렇게 할 것이다 :

레코드 형식을 보유 할 C / C ++ 구조체를 준비합니다.

struct StockPrice
{
    char ticker_code[2];
    double stock_price;
    timespec when;
    etc
};

그런 다음 sizeof (StockPrice [N])를 계산합니다. 여기서 N은 레코드 수입니다. (64 비트 시스템에서) 몇 백 기가 여야하고 50 달러 HDD에 맞습니다.

그런 다음 파일을 해당 크기로 자르고 mmap (리눅스에서는 또는 Windows에서는 CreateFileMapping 사용)을 메모리에 저장합니다.

//pseduo-code
file = open("my.data", WRITE_ONLY);
truncate(file, sizeof(StockPrice[N]));
void* p = mmap(file, WRITE_ONLY);

mmaped 포인터를 StockPrice *로 캐스팅하고 배열을 채우는 데이터를 전달합니다. mmap을 닫으면 나중에 다시 mmap 할 수있는 파일에 하나의 큰 이진 배열에 데이터가 있습니다.

StockPrice* stocks = (StockPrice*) p;
for (size_t i = 0; i < N; i++)
{
    stocks[i] = ParseNextStock(stock_indata_file);
}
close(file);

이제 모든 프로그램에서 다시 읽기 전용으로 mmap 할 수 있으며 데이터를 쉽게 사용할 수 있습니다.

file = open("my.data", READ_ONLY);
StockPrice* stocks = (StockPrice*) mmap(file, READ_ONLY);

// do stuff with stocks;

이제 메모리 내 구조체 배열처럼 처리 할 수 ​​있습니다. “쿼리”에 따라 다양한 종류의 인덱스 데이터 구조를 만들 수 있습니다. 커널은 디스크와의 데이터 교환을 투명하게 처리하므로 엄청나게 빠릅니다.

특정 액세스 패턴 (예 : 연속 날짜)이있을 것으로 예상되는 경우 배열을 순서대로 정렬하여 디스크에 순차적으로 도달하도록하는 것이 가장 좋습니다.


답변

나는 1000 개의 주식에 대한 1 분 데이터의 데이터 셋을 가지고있다. […] 대부분의 (99.9 %) 내가 수행 할 시간 읽기 요청 .

한 번 저장하고 여러 번 시간 기반 숫자 데이터를 읽는 것은 “시계열”이라는 사용 사례입니다. 다른 일반적인 시계열은 사물 인터넷의 센서 데이터, 서버 모니터링 통계, 애플리케이션 이벤트 등입니다.

이 질문은 2012 년에 제기되었으며 그 이후로 여러 데이터베이스 엔진이 시계열 관리를위한 기능을 특별히 개발해 왔습니다. 나는 훌륭한 결과를 얻었습니다오픈 소스이고 Go로 작성되었으며 MIT 라이센스를받은 InfluxDB를 .

InfluxDB는 시계열 데이터를 저장하고 쿼리하도록 특별히 최적화되었습니다. 시계열을 저장하는 데 매우 좋다고 종종 선전되는 Cassandra보다 훨씬 더 많습니다.

InfluxDB 대 Cassandra 쿼리 속도

시계열 최적화에는 특정 장단점이 포함되었습니다. 예를 들면 :

기존 데이터에 대한 업데이트는 거의 발생하지 않으며 논쟁적인 업데이트는 발생하지 않습니다. 시계열 데이터는 주로 업데이트되지 않는 새로운 데이터입니다.

장점 : 업데이트에 대한 액세스를 제한하면 쿼리 및 쓰기 성능이 향상됩니다.

단점 : 업데이트 기능이 크게 제한됨

에서 열린 소싱 벤치 마크 ,

InfluxDB는 27 배 더 큰 쓰기 처리량으로 세 가지 테스트 모두에서 MongoDB를 능가하는 반면, 84 배 더 적은 디스크 공간을 사용하고 쿼리 속도면에서 비교적 동일한 성능을 제공했습니다.

InfluxDB 대 MongoDB 온 디스크 스토리지 요구 사항 및 압축

쿼리도 매우 간단합니다. 행이 다음 <symbol, timestamp, open, high, low, close, volume>과 같으면 InfluxDB를 사용하여 저장 한 다음 쉽게 쿼리 할 수 ​​있습니다. 지난 10 분 동안의 데이터에 대해

SELECT open, close FROM market_data WHERE symbol = 'AAPL' AND time > '2012-04-12 12:15' AND time < '2012-04-13 12:52'

ID, 키, 만들 조인이 없습니다. 많은 흥미로운 집계를 수행 할 수 있습니다 . PostgreSQL처럼 테이블수직으로 분할 하거나 MongoDB처럼 스키마를 초 단위로 변환 할 필요가 없습니다 . 또한 InfluxDB는 압축이 매우 잘되는 반면 PostgreSQL은 보유한 데이터 유형에 대해 압축을 수행 할 수 없습니다 .


답변

좋아, 그래서 이것은 다른 답변과 다소 거리가 있지만 … 파일 시스템 (아마도 파일 당 하나의 스톡)에 고정 된 레코드 크기로 데이터가 있으면 데이터를 얻을 수 있다고 생각합니다. 정말 쉽게 : 특정 주식 및 시간 범위에 대한 쿼리가 주어지면 올바른 위치를 찾고 필요한 모든 데이터를 가져오고 (정확히 몇 바이트인지 알 수 있음) 데이터를 필요한 형식으로 변환 할 수 있습니다. 저장 형식에 따라 매우 빠릅니다.)

Amazon 스토리지에 대해서는 아무것도 모르지만 직접 파일 액세스와 같은 것이 없다면 기본적으로 Blob을 가질 수 있습니다. 큰 Blob의 균형을 맞춰야합니다 (레코드는 적지 만 각각 필요한 것보다 더 많은 데이터를 읽을 수 있음). 시간) 작은 blob으로 (더 많은 레코드가 더 많은 오버 헤드를 제공하고 아마도 더 많은 요청을 가져 오지만 매번 반환되는 쓸모없는 데이터는 적습니다).

다음으로 캐싱을 추가합니다. 예를 들어 다른 서버에 처리 할 다른 주식을 제공하는 것이 좋습니다. 메모리에서 거의 제공 할 수 있습니다. 충분한 서버에 충분한 메모리를 확보 할 수 있다면 “요청시로드”부분을 건너 뛰고 시작시 모든 파일을로드하십시오. 이는 시작 속도가 느린 비용으로 상황을 단순화 할 수 있습니다 ( 특정 재고에 대해 항상 두 개의 서버를 보유 할 수있는 여유가없는 경우 도움이되는 경우).

각 레코드에 대해 주식 기호, 날짜 또는 분 을 저장할 필요가 없습니다. 로드중인 파일과 파일 내 위치에 암시 적이기 때문입니다. 또한 각 값에 필요한 정확도와이를 효율적으로 저장하는 방법을 고려해야합니다. 질문에 6SF를 제공하여 20 비트로 저장할 수 있습니다. 64 비트 저장소에 3 개의 20 비트 정수를 저장할 수 있습니다.이를 a long(또는 64 비트 정수 값이 무엇이든간에) 로 읽고 마스킹 / 시프트를 사용하여 3 개의 정수로 되돌립니다. 물론 사용할 스케일을 알아야합니다. 일정하게 만들 수없는 경우 여분의 4 비트로 인코딩 할 수 있습니다.

다른 세 개의 정수 열이 어떤 것인지는 말하지 않았지만,이 세 가지에 대해 64 비트를 사용할 수 있다면 전체 레코드를 16 바이트로 저장할 수 있습니다. 그것은 전체 데이터베이스에 대해 ~ 110GB에 불과합니다.

편집 : 고려해야 할 다른 사항은 아마도 주식이 주말 동안 또는 실제로 밤새 변경되지 않는다는 것입니다. 주식 시장이 하루에 8 시간, 주당 5 일만 열려 있다면 168 대신 주당 40 개의 값만 필요합니다.이 시점에서 파일에 약 28GB의 데이터 만 남게 될 수 있습니다. 원래 생각했던 것보다 훨씬 작습니다. 메모리에 많은 데이터가있는 것은 매우 합리적입니다.

편집 : 이 접근 방식이 여기에 적합한 이유에 대한 설명을 놓친 것 같습니다. 주식 시세 표시기, 날짜 및 시간과 같은 데이터의 상당 부분에 대해 매우 예측 가능한 측면이 있습니다. 티커를 한 번 (파일 이름으로) 표현하고 날짜 / 시간을 데이터 위치 에 완전히 암시 적으로두면 전체 작업을 제거하는 것입니다. a String[]와 a 의 차이와 비슷 Map<Integer, String>합니다. 배열 인덱스가 항상 0에서 시작하여 배열 길이까지 1 씩 증가한다는 것을 알면 빠른 액세스와보다 효율적인 스토리지가 가능합니다.


답변

HDF5 는 하나의 잠재적 인 응용 프로그램으로 재고 데이터의 시계열 저장을 위해 특별히 설계 되었다는 것이 제 이해입니다 . 동료 스태커들은 HDF5가 염색체 , 물리학 등 많은 양의 데이터에 유용하다는 것을 입증했습니다 .


답변

다음은 무료 오픈 소스 프로젝트 인 OLAP 분석에 좋은 Microsoft SQL Server 2012 데이터베이스 위에 Market Data Server를 생성하려는 시도입니다.

http://github.com/kriasoft/market-data


답변

첫째, 연중 365 일 거래일이 없으며, 공휴일 52 주 주말 (104) = 250 x 누군가가 말한 것처럼 실제 하루 시장이 열리는 시간이며,이 기호를 기본 키로 사용하는 것은 좋은 생각이 아닙니다. 기호가 변경되기 때문에 기호가 A 또는 GAC-DB-B.TO와 같을 수 있으므로 기호 (char)와 함께 k_equity_id (숫자)를 사용하면 가격 정보의 데이터 테이블에 7.3의 추정치가 있습니다. 10 억은 14 년 동안 심볼 당 행이 약 170 만 개에 불과하기 때문에 지나치게 계산되었습니다.

k_equity_id k_date k_minute

및 EOD 테이블의 경우 (다른 데이터에 비해 1000 배 표시됨)

k_equity_id k_date

둘째, 1 년 동안 pnf 또는 꺾은 선형 차트를보고자하는 사람은 누구나 by에 관심이 없기 때문에 분 단위 데이터를 및 EOD 테이블 (하루 종료)과 동일한 DB 테이블에 저장하지 마십시오. 분 정보.