Posting

Machbase의 최신 소식을 지금 만나보세요

[MACHBASE 테스트] APPEND 성능 변화

마크베이스 연구원 김동용

최근 스마트 팩토리와 같이 생산 공정에서 센서를 통해 수집하는 데이터를 기반으로 한 IOT 산업이 이목을 끌고 있습니다. 생산 공정 중에 발생할 수 있는 상황에 유연하게 대처하기 위해서는 공장 내 설비와 기계에 설치된 수많은 센서들로부터 엄청난 양의 데이터를 수집해야 합니다.

이 포스팅에서는 마크베이스 DB가 수많은 센서들로부터 데이터를 안정적으로 수집할 수 있는지 검증하기 위해 multi-session을 구성해서 append와 select를 반복하는 stress 테스트를 수행했고, 그에 따른 결과를 정리하였습니다. 그래서 그에 따른 성능 저하는 없는지 검증하고, 사용자로 하여금 서버에는 어느 정도의 부하를 주는지, Session을 어느 정도까지 늘려도 되는지를 판단할 수 있도록 하고자 합니다.

1.  테스트 개요

테스트는 다음과 같은 과정으로 진행됩니다.

  • 1,000개(session 개수)의 session을 생성한 후 append를 1,000만건(총 record 개수) 수행한다.
  • 각 session은 10,000(총 record 개수 / session 개수)건씩 append를 한다.
  • 한 번의 append(append-open과 append-close 1회 호출)는 100건 씩만 이루어지며, append 이후  총 record의 개수를 구하는 쿼리를 수행한다.
  • 각 세션이 10,000건을 append할 때까지 append를 반복한다.

그리고 session 개수와 총 record 개수를 조정함에 따라 나타나는 성능 상의 변화를 측정합니다.

2. 테스트 환경

CPU제품명 : Intel(R) Xeon(R) CPU E3-1231 v3 @ 3.40GHz
CPU Core 개수 : 8
CPU 당 물리 Core 개수 : 4
Memory32GB
Disk256GB (SSD)
user process count1024000

대량의 session을 연결하고자 한다면 machbased 서버를 운용할 host 의 user process의 limit 값을 수정해야 합니다.

user process count의 기본값은 1024입니다.

$ ulimit -u 1024

이를 수정하는 방법은 다음과 같습니다.

$ sudo vi /etc/security/limits.conf

nproc (user process count)의 값을 1024인 것을 확인할 수 있습니다.

*                hard   nproc           1024
*                soft   nproc           1024

만일 운영체제가 CentOS 6 이상(RHEL 6 이상) 이라면 아래의 파일도 고쳐야 합니다.

$ sudo vi /etc/security/limits.d/90-nproc.conf

nproc의 값을 수정한 후 서버를 재시작하거나, 다시 계정에 접속합니다.

$ ulimit -u 1024000

user process count 값이 수정된 것을 확인할 수 있습니다.

3. 예제 테이블 syslog_table 스키마

create table syslog_table (
tm datetime,
n1 short,
n2 int,
n3 long,
n4 float,
n5 double,
host varchar(128),
msg varchar(512),
ip4 ipv4,
ip6 ipv6
);

4. append 프로그램 코드

아래의 코드는 클라이언트 프로그램의 소스 코드로, c언어로 작성되었습니다.

int gSessionCount = 0;
int gRecordPerThr = 0;

void db_connect(SQLHENV * aEnv, SQLHDBC * aCon, int aPort);     
void db_disconnect(SQLHENV * aEnv, SQLHDBC * aCon);
void outError(SQLHDBC aCon, SQLHENV aEnv, const char *aMsg, SQLHSTMT aStmt);
void testSelect(SQLHDBC aCon, SQLHENV aEnv);

void testAppend(SQLHDBC aCon, SQLHENV aEnv, int aIteratorNum, int * oOutputCount)
{
    ...

    for (i = 0; i < aIteratorNum; i++)
    {
        ...

        if( (rc = SQLAppendDataV2(sStmt, sParam)) != SQL_SUCCESS )
        {
            ...
        }
        (*oOutputCount)++;
    }

    ...
}

void * testAppendNSelect(void *aPort)
{
    ...

    db_connect(&sEnv, &sCon, sPort);
    while (sTotalAppendRows < gRecordPerThr) // 할당된 레코드를 채울 때까지
    {
        if (sIteratorNum > gRecordPerThr - sTotalAppendRows) // 채울 레코드 개수가 100보다 작을 때
        {
            sIteratorNum = gRecordPerThr - sTotalAppendRows;
        }
        testAppend(sCon, sEnv, sIteratorNum, &sTotalAppendRows);
        testSelect(sCon, sEnv);
    }
    db_disconnect(&sEnv, &sCon);

    ...
}
     
int main(int argc, char **argv)
{
    ...

    gSessionCount = atol(argv[1]);
    sTotalRecord  = atol(argv[2]);
    gRecordPerThr = sTotalRecord / gSessionCount;
    sPort = atoi(argv[3]);

    sThrArr = (pthread_t*)malloc(sizeof(pthread_t) * gSessionCount);

    for (i = 0; i < gSessionCount; i++)
    {
        pthread_create(&sThrArr[i], NULL, testAppendNSelect, &sPort);
    }

    for (i = 0; i < gSessionCount; i++)
    {
        pthread_join(sThrArr[i], NULL);
    }

    ...

    return 0;
}

클라이언트 프로그램의 main 함수는 인자로 받은 Session 개수(gSessionCount)만큼 thread를 만들어 각 thread의 main 함수를 testAppendNSelect 함수를 실행하도록 했습니다. 그리고 마지막에는 모든 thread를 join합니다.

각 thread는 함수 db_connect를 호출하여 DB와의 connection을 열고, 함수 testAppend와 testSelect를 반복적으로 호출합니다.

함수 testAppend는 인자로 받은 aIteratorNum만큼 append를 수행합니다.

함수 testSelect는 `select count(*)  from syslog_table;`의 쿼리를 실행해서 서버에 부하를 주기 위해 사용됩니다.

thread의 main 함수는 testAppend를 호출할 때 인자 aIteratorNum을 100으로 하여, 한번에 100건씩 append를 하는데 thread에 할당된 record 개수(gRecordPerThr)가 채워질 때까지 append를 반복합니다. append가 모두 완료되면 함수 db_disconect를 호출하여 DB와의 connection을 종료합니다.

해당 클라이언트 프로그램의 소스코드는 https://github.com/MACHBASE/multi-session-example 에 업로드했습니다.

실행 예시

$ ./append 1000 10000000 32000   // Session 개수, 전체 record 개수, DB Port

5. 성능 측정

본 테스트에서는 마크베이스의 성능을 검증하기 위해, 아래의 3가지를 측정했습니다.

  • 최대 메모리 사용량
  • 최대 cpu 사용률 : 전체 CPU를 대상으로 측정했으며, 측정 interval time은 3초입니다.
  • 소요 시간
  • 총 입력 Throughput : 소요 시간 / 총 입력 건수

a) 최대 CPU 사용률 (%)

session 개수 / 총 record 개수10,000,00050,000,000100,000,000
1,000515151
2,000586158
4,000676770
6,000697080
8,000747585
10,000789273
12,000988387

session 개수를 8,000개까지 점차적으로 늘렸을 때에는 CPU 사용률이 크게 변동이 없다가 10,000개 이상으로 늘리니 상승폭이 커지는 것을 확인할 수 있습니다.

b) 최대 Memory 사용량 (MB)

session 개수 / 총 record 개수10,000,00050,000,000100,000,000
1,0001,0571,1411,227
2,0001,9412,0742,117
4,0004,0084,1034,013
6,0005,8875,9105,800
8,0007,9058,0478,423
10,00010,93410,42211,154
12,00013,48412,24211,831

Session 개수가 늘어남에 따라 최대 메모리 사용량도 점차적으로 증가합니다. 1 Session 당 1MB 정도 크기의 메모리를 사용합니다.

c) 소요 시간 (초)

session 개수 / 총 record 개수10,000,00050,000,000100,000,000
1,000105490985
2,000104510942
4,00094482926
6,0001135511348
8,0001525941231
10,0001407481298
12,0001918011347

Session 개수를 늘림에 따라 소요 시간이 서서히 증가함을 확인할 수 있습니다.

d) 총 입력 throughput (건)

session 개수 / 총 record 개수10,000,00050,000,000100,000,000
1,00095,238102,031101,523
2,00096,15498,039106,157
4,000106,383103,734107,991
6,00088,49690,74474,184
8,00065,78984,17581,235
10,00071,42966,84577,042
12,00052,35662,42274,239

총 입력 Throughtput은 Session 개수가 늘어남에 따라 계속해서 감소함을 확인할 수 있다.

Session 개수가 14,000개 이상이면 CPU 사용률이 100%까지 상승하더니 `Client unable to establish connection`라는 에러가 발생하면서 테스트가 종료됩니다. trc 파일에는 아래의 log가 남아 있었습니다.

[2019-05-29 03:07:40 P-24232 T-139848474810112][WARN] New Task Run Failed :(176:Failed to create thread, errno = 11.)    
[2019-05-29 03:17:03 P-26732 T-139727733839616][INFO] Accept error: (4013) Failed to receive accept data repeatedly in 1000000 miliseconds..    
[2019-05-29 03:17:10 P-26732 T-139727733839616][INFO] Accept error: (4010) Receive error (40033)..

프로세스 별로 쓸 수 있는 메모리를 초과하여 thread를 생성하다 보니 발생한 에러같습니다.

지금까지 마크베이스 DB를 대상으로 한 multi-session에서의 stress 테스트 과정과 테스트에서 측정한 결과를 다뤄 보았습니다. 이 테스트를 통해 Session 개수가 증가함에 따라 CPU 사용률, 메모리 사용량이 증가하면서 입력 성능이 어느 정도 저하되었지만 한번에 100건씩 append를 해서 append-open과 append-close가 빈번했음에도 10,000개 이상의 Session에서 잘 동작했다는 것을 확인할 수 있었습니다.

이상으로 포스팅을 마치겠습니다.

연관 포스트

C언어로 Binary data를 Machbase에 넣기

1.개요 Data를 다루다 보면 numeric, varchar 형 데이터뿐만 아니라 JPG, PNG, MP3와 같은 Binary data도 database에 저장해야 할 때가 존재한다. 그러나 일반 data들과는 달리 Binary

[MACHBASE 연동] Android studio에서 JDBC 연결하기

마크베이스 기술지원본부 이현민 1. 개요 수많은 데이터들이 많은 환경에서 생성되고 있는 오늘날, 우리 현대인들의 동반자인 스마트폰 또한 데이터생성의 주체로써 또는 전달자로서 알게 모르게 그 구실을