반응형
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
2) Timescale
- 아래의 포스팅에서 사용한 ONE_32 객체를 15,625,000개 생성해 500MB 사이즈만큼 버퍼에 쌓고 bytea에 삽입했다.
https://namsaenga.tistory.com/31
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 데이터를 저장한다.
반응형
'프로그래밍 > Redis' 카테고리의 다른 글
docker redis-server 스냅샷을 OS경로로 저장 (0) | 2022.05.30 |
---|---|
docker를 이용하여 redis server 사용하기 (0) | 2022.04.11 |
Redis를 이용하여 구조체형식의 메시지 주고받기 (0) | 2022.03.19 |
Windows MFC에서 Redis Client 이용하기 (0) | 2022.03.14 |
댓글