본문 바로가기
프로그래밍/Redis

BLOB 데이터 삽입 성능, Redis vs Timescale(PostgreSQL) vs C++ binary

by 남생 namsaeng 2022. 4. 18.
반응형

Redis와 Timescale은 이미지, 비디오, 사운드 등과 같은 멀티미디어 객체를 저장할 수 있는 바이너리 형태인 BLOB(Binary Large Object) 데이터를 column(또는 Key)에 삽입할 수 있다.

 

 

1. 실험 내용

  • Redis의 BLOB 데이터 타입 column 최대 사이즈: 512MB
  • Timescale의 BLOB 데이터 타입 column(bytea) 최대 사이즈: 1GB

 

2. 실험 환경

  • CPU : Intel Xeon Processor E3 v5/v6
  • RAM : DDR4-1866 ECC SDRAM 16GB
  • SDD : SATA NAND Flash 128GB

 

 

3. 기반 코드

 

1) Redis

  • 아래의 포스팅에서 사용한 ANIMAL 객체를 45,454,545개 생성해 500MB 사이즈만큼 버퍼에 쌓고 Key에 삽입했다.

https://namsaenga.tistory.com/28

 

Redis를 이용하여 구조체형식의 메시지 주고받기

두 호스트(device or PC) 간에 Ethernet을 이용하여 데이터를 주고받는 경우가 있다. 때때로 받은 내용을 디스크에 저장하지 않고 곧바로 클라이언트 상에서 사용하는데, 데이터의 빠른 액세스를 위해

namsaenga.tistory.com

 

2) Timescale

  • 아래의 포스팅에서 사용한 ONE_32 객체를 15,625,000개 생성해 500MB 사이즈만큼 버퍼에 쌓고 bytea에 삽입했다.

https://namsaenga.tistory.com/31

 

TimescaleDB에 구조체 삽입 후 조회(2)

이전 내용에서 크기가 고정된 데이터 유형을 멤버로 가지고 있는 구조체를 TimescaleDB에 넣고 꺼내어 값을 확인하였다. char 및 char array와 달리 string을 멤버로 가지고 있는 구조체는 데이터베이스

namsaenga.tistory.com

 

3) C++ binary로 저장

  • BLOB 데이터를 DBMS로 관리하는 이유는 특정 BLOB 데이터에 대한 관리 및 조회를 빠르게 하기 위해서인데, 단순히 저장 속도만 중요할 때는 DB보다 binary 파일로 저장하는 것이 빠르다. 

<C++ binary 저장 예시 코드>

struct ABC
{
  unsigned int a : 4;
  unsigned int b : 4;
  unsigned int c : 4;
  unsigned int d : 4;
};

struct ABC abc = {1,2,3,4};

long long SaveAsBinary1()
{

    auto start_time = std::chrono::high_resolution_clock::now();
    auto myfile = std::fstream("binary_file_1", std::ios::out | std::ios::binary);
    myfile.write((char*)&genBuff1[0], 500000000);  // 500MB: 500000000, 1GB: 1000000000
    myfile.close();
    auto end_time = std::chrono::high_resolution_clock::now();

    return std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
}

long long SaveAsBinary2()
{

    std::ios_base::sync_with_stdio(false);
    auto start_time = std::chrono::high_resolution_clock::now();
    auto myfile = std::fstream("binary_file_2", std::ios::out | std::ios::binary);
    myfile.write((char*)&genBuff1[0], 500000000);  // 500MB: 500000000, 1GB: 1000000000
    myfile.close();
    auto end_time = std::chrono::high_resolution_clock::now();

    return std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
}

void GatherSignal(int *num){
  for(int i=0; i<31250000; i++){ // 500MB: 31250000, 1GB: 62500000
    
    memmove(genBuff1+((*num)*sizeof(abc)), (char *)&abc, sizeof(abc));
    (*num)++;
  
  }
}


int main(int argc, char* argv[]) {
  
  int cnt=0;
  GatherSignal(&cnt);
  cout << "Call SaveAsBinary Function1, " << SaveAsBinary1() << "ms" << endl;
  cout << "Call SaveAsBinary Function2, " << SaveAsBinary2() << "ms" << endl;
  return 0;
}

 

 

4. 실험 결과 확인방법

 

  • Redis : xread 혹은 xrange 함수로 확인

 

  • Timescale : 파일크기로 조회
example=# select time, concat(length(bytea_content) / 1000000.0, ' MB') as filesize from test2;
            time            |         filesize         
----------------------------+--------------------------
 2022-04-13 14:21:43.313845 | 1000.0000000000000000 MB
 2022-04-13 14:21:56.486066 | 1000.0000000000000000 MB
 2022-04-18 11:39:56.320646 | 1000.0000000000000000 MB
 2022-04-18 11:43:39.0718   | 500.0000000000000000 MB
(4 rows)

 

  • C++ binary : ls -l 명령어로 확인
[namsaenga@localhost postgresql_examples]$ ./fstream_save
Call SaveAsBinary Function1, 407ms
Call SaveAsBinary Function2, 1488ms
Call SaveAsBinary Function3, 199ms
Call SaveAsBinary Function4, 228ms
[namsaenga@localhost postgresql_examples]$ ls -l binary_file_*
-rw-rw-r-- 1 victek victek 1000000000 Apr 18 11:49 binary_file_1
-rw-rw-r-- 1 victek victek 1000000000 Apr 18 11:49 binary_file_2
-rw-rw-r-- 1 victek victek  500000000 Apr 18 11:49 binary_file_3
-rw-rw-r-- 1 victek victek  500000000 Apr 18 11:49 binary_file_4

 

 

 

5. 성능 비교

 

  Redis Timescale C++ Binary
500MB 약 2초 약 5~7초 200~300ms
1GB X 약 11~14초 SaveAsBinary1: 400ms
SaveAsBinary2: 1300~2600ms

 

 

* 결론 : In-memory DBMS는 Disk-based DBMS보다 BLOB 데이터를 빠르게 넣지만 크기에 한계가 있으며, BLOB 데이터의 관리 및 관계를 이용한 조회가 아닌 단순한 BLOB의 빠른 저장만을 목표로 했을 시에는 C++ Binary를 이용하여 BLOB 데이터를 저장한다. 

반응형

댓글