C언어에서 초고속 키-값 저장소를 구축하려면 성능과 확장성이 뛰어난 데이터베이스가 필요합니다. Aerospike는 SSD 및 메모리 최적화를 통해 높은 처리 속도를 제공하는 NoSQL 데이터베이스로, 금융, 광고, IoT 등 대량의 데이터를 빠르게 처리해야 하는 환경에서 널리 사용됩니다.
본 기사에서는 C언어에서 Aerospike를 연동하여 키-값 저장소를 구축하는 방법을 설명합니다. Aerospike C 라이브러리 설치부터 기본적인 데이터 삽입, 조회, 갱신, 삭제, 성능 최적화까지 실용적인 예제와 함께 다룹니다. 이를 통해 대규모 데이터 처리에 적합한 키-값 저장소 시스템을 효과적으로 구축할 수 있습니다.
Aerospike 개요 및 특징
Aerospike는 고성능, 고가용성을 제공하는 NoSQL 키-값 데이터베이스로, 대량의 데이터를 빠르게 처리할 수 있도록 설계되었습니다. 특히 SSD 및 메모리 최적화 기술을 활용하여 뛰어난 성능을 발휘하며, 금융, 광고, IoT 등 데이터 중심 애플리케이션에서 널리 사용됩니다.
Aerospike의 주요 특징
1. 초고속 데이터 처리
Aerospike는 SSD 최적화 및 인덱싱 기술을 활용하여 높은 처리 속도를 제공합니다. 읽기 및 쓰기 성능이 뛰어나 실시간 데이터 처리에 적합합니다.
2. 강력한 확장성
클러스터 기반으로 동작하며, 노드를 추가하는 방식으로 손쉽게 확장할 수 있습니다. 이를 통해 대량의 데이터를 처리하는 시스템에서 성능 저하 없이 확장이 가능합니다.
3. 강력한 내결함성
Aerospike는 자동 복제 및 데이터 분산 기술을 지원하여 장애 발생 시에도 데이터 손실을 최소화하고 안정적인 운영을 보장합니다.
4. 다중 데이터 모델 지원
Aerospike는 단순한 키-값 저장뿐만 아니라 리스트, 맵, 바이너리 데이터 등 다양한 데이터 타입을 지원하여 유연한 데이터 처리가 가능합니다.
5. TTL(Time-to-Live) 기능 지원
데이터 만료 시간(TTL)을 설정할 수 있어 자동으로 오래된 데이터를 정리하는 기능을 제공합니다. 이를 통해 캐싱 시스템이나 세션 저장소로 활용할 수 있습니다.
Aerospike는 빠른 응답 시간과 높은 처리량을 요구하는 애플리케이션에서 효과적인 데이터베이스 솔루션이 될 수 있습니다. 다음 단계에서는 C언어에서 Aerospike를 연동하기 위한 환경 설정 및 설치 방법을 살펴보겠습니다.
C언어와 Aerospike 연동 준비
Aerospike를 C언어 환경에서 사용하려면 먼저 Aerospike C 클라이언트 라이브러리를 설치하고, 개발 환경을 설정해야 합니다. 이 과정에서는 필수 라이브러리 설치, 설정 파일 구성, 그리고 Aerospike 서버와 연동을 위한 준비 단계를 설명합니다.
1. Aerospike C 클라이언트 설치
Aerospike C 클라이언트를 사용하려면 공식 SDK를 설치해야 합니다. 다음은 Ubuntu 및 CentOS에서 설치하는 방법입니다.
Ubuntu 환경
sudo apt update
sudo apt install libssl-dev zlib1g-dev
wget https://download.aerospike.com/artifacts/aerospike-client-c/latest/aerospike-client-c-devel-ubuntu18.tgz
tar -xvzf aerospike-client-c-devel-ubuntu18.tgz
cd aerospike-client-c-*/
sudo ./install.sh
CentOS 환경
sudo yum install openssl-devel zlib-devel
wget https://download.aerospike.com/artifacts/aerospike-client-c/latest/aerospike-client-c-devel-el7.tgz
tar -xvzf aerospike-client-c-devel-el7.tgz
cd aerospike-client-c-*/
sudo ./install.sh
설치가 완료되면 libaerospike.so
라이브러리가 /usr/lib
또는 /usr/local/lib
에 추가됩니다.
2. 개발 환경 설정
Aerospike C 클라이언트를 사용하려면 컴파일 시 헤더 파일과 라이브러리를 포함해야 합니다.
- 컴파일러에
-I
옵션으로 헤더 파일 경로 추가 -L
옵션으로 라이브러리 경로 추가-laerospike
옵션으로 Aerospike 라이브러리 링크
예제:
gcc -o my_app my_app.c -I/usr/local/aerospike/include -L/usr/local/aerospike/lib -laerospike
3. Aerospike 서버 실행 및 접속 확인
Aerospike를 실행하기 위해 서버를 설치하고 실행해야 합니다.
Docker를 이용한 Aerospike 서버 실행
docker run -d --name aerospike -p 3000:3000 -p 3001:3001 -p 3002:3002 aerospike/aerospike-server
Aerospike 서버가 실행된 후, aql
명령어를 사용하여 정상적으로 동작하는지 확인할 수 있습니다.
aql -h 127.0.0.1
4. Aerospike 구성 파일 설정
Aerospike는 aerospike.conf
파일을 사용하여 설정을 관리합니다. 기본 설정 파일 예시는 다음과 같습니다.
service {
user root
group root
paxos-single-replica-limit 1
pidfile /var/run/aerospike/asd.pid
}
network {
service {
address any
port 3000
}
}
설정 파일을 적용한 후, Aerospike 서버를 재시작하여 변경사항을 반영할 수 있습니다.
이제 C언어에서 Aerospike 클라이언트를 사용하여 데이터베이스와 연동할 준비가 완료되었습니다. 다음 단계에서는 Aerospike 클라이언트 초기화 및 연결 방법을 살펴보겠습니다.
Aerospike 클라이언트 초기화 및 연결
C언어에서 Aerospike 서버와 연동하려면 클라이언트를 초기화하고, 데이터베이스에 연결해야 합니다. 이 과정에서는 Aerospike 클라이언트 구조체를 설정하고, 서버와의 연결을 확인하는 방법을 설명합니다.
1. Aerospike 클라이언트 초기화
Aerospike 클라이언트를 사용하려면 먼저 aerospike
구조체를 선언하고 초기화해야 합니다.
#include <stdio.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_policy.h>
int main() {
aerospike as;
as_config config;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000); // Aerospike 서버 주소와 포트 설정
aerospike_init(&as, &config);
return 0;
}
as_config_init()
: 기본 설정 초기화as_config_add_host()
: Aerospike 서버 주소 및 포트 추가aerospike_init()
: 클라이언트 구조체를 초기화
2. Aerospike 서버에 연결
초기화된 클라이언트로 Aerospike 서버에 연결합니다.
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_error.h>
int main() {
aerospike as;
as_config config;
as_error err;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000);
aerospike_init(&as, &config);
if (aerospike_connect(&as, &err) != AEROSPIKE_OK) {
printf("Aerospike 연결 실패: %s\n", err.message);
aerospike_destroy(&as);
return -1;
}
printf("Aerospike 연결 성공!\n");
aerospike_close(&as, &err);
aerospike_destroy(&as);
return 0;
}
aerospike_connect()
: 서버에 연결aerospike_close()
: 연결 종료aerospike_destroy()
: 클라이언트 리소스 정리
3. 연결 테스트
위 코드를 실행하면 다음과 같은 출력이 나오면 성공적으로 Aerospike 서버에 연결된 것입니다.
Aerospike 연결 성공!
연결이 실패하면 오류 메시지가 출력되며, 서버가 정상적으로 실행되고 있는지, IP 주소 및 포트가 올바른지 확인해야 합니다.
Aerospike와 연결이 완료되었으므로, 이제 데이터를 저장하고 검색하는 방법을 살펴보겠습니다.
키-값 데이터 삽입 및 조회
Aerospike에서 데이터를 저장하고 검색하는 기본적인 방법을 살펴봅니다. C언어 클라이언트를 사용하여 데이터를 삽입하고, 키를 이용해 값을 조회하는 예제를 제공합니다.
1. Aerospike 데이터 삽입
Aerospike에서는 데이터를 namespace
, set
, key
, bin
단위로 저장합니다.
- namespace : 데이터가 저장되는 논리적 구획
- set : 같은 종류의 데이터를 그룹화하는 컬렉션
- key : 개별 레코드를 구분하는 고유한 키
- bin : 하나의 레코드에서 여러 개의 값을 저장할 수 있는 필드
다음 예제는 Aerospike에 문자열 데이터를 삽입하는 코드입니다.
#include <stdio.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_key.h>
#include <aerospike/aerospike_record.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_error.h>
#include <aerospike/as_record.h>
#include <aerospike/as_string.h>
int main() {
aerospike as;
as_config config;
as_error err;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000);
aerospike_init(&as, &config);
if (aerospike_connect(&as, &err) != AEROSPIKE_OK) {
printf("Aerospike 연결 실패: %s\n", err.message);
aerospike_destroy(&as);
return -1;
}
// 키 정의 (namespace: "test", set: "demo", key: "user1")
as_key key;
as_key_init(&key, "test", "demo", "user1");
// 저장할 데이터 정의
as_record rec;
as_record_inita(&rec, 1);
as_record_set_str(&rec, "name", "John Doe");
// 데이터 저장
if (aerospike_key_put(&as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
printf("데이터 삽입 실패: %s\n", err.message);
} else {
printf("데이터 삽입 성공!\n");
}
// 메모리 해제
as_record_destroy(&rec);
aerospike_close(&as, &err);
aerospike_destroy(&as);
return 0;
}
as_key_init()
: 데이터를 저장할 키 정의as_record_inita()
: 레코드 초기화as_record_set_str()
: 문자열 데이터를 저장할 bin 설정aerospike_key_put()
: 데이터를 삽입
2. Aerospike 데이터 조회
저장된 데이터를 키를 이용해 조회하는 방법을 살펴보겠습니다.
#include <stdio.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_key.h>
#include <aerospike/aerospike_record.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_error.h>
#include <aerospike/as_record.h>
#include <aerospike/as_string.h>
int main() {
aerospike as;
as_config config;
as_error err;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000);
aerospike_init(&as, &config);
if (aerospike_connect(&as, &err) != AEROSPIKE_OK) {
printf("Aerospike 연결 실패: %s\n", err.message);
aerospike_destroy(&as);
return -1;
}
// 조회할 키 설정
as_key key;
as_key_init(&key, "test", "demo", "user1");
// 레코드 조회
as_record *rec = NULL;
if (aerospike_key_get(&as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
printf("데이터 조회 실패: %s\n", err.message);
} else {
const char *name = as_record_get_str(rec, "name");
printf("조회된 데이터: %s\n", name);
as_record_destroy(rec);
}
aerospike_close(&as, &err);
aerospike_destroy(&as);
return 0;
}
aerospike_key_get()
: 키를 이용해 데이터 조회as_record_get_str()
: bin에서 문자열 데이터 추출as_record_destroy()
: 조회한 레코드 메모리 해제
3. 실행 결과
위 코드를 실행하면 데이터가 정상적으로 저장되고 조회됩니다.
데이터 삽입 성공!
조회된 데이터: John Doe
이제 기본적인 키-값 저장 및 조회 기능을 구현했습니다. 다음 단계에서는 데이터를 갱신하고 삭제하는 방법을 살펴보겠습니다.
데이터 갱신 및 삭제
Aerospike에서 기존 데이터를 수정(갱신)하거나 삭제하는 방법을 살펴보겠습니다. 키-값 스토어에서 데이터를 유지하면서 특정 필드를 변경하는 것은 중요한 기능이며, 불필요한 데이터를 정리하는 삭제 기능도 필수적입니다.
1. Aerospike 데이터 갱신
Aerospike에 저장된 데이터를 수정하려면 aerospike_key_put()
을 다시 호출하여 기존 데이터를 덮어씁니다.
#include <stdio.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_key.h>
#include <aerospike/aerospike_record.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_error.h>
#include <aerospike/as_record.h>
int main() {
aerospike as;
as_config config;
as_error err;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000);
aerospike_init(&as, &config);
if (aerospike_connect(&as, &err) != AEROSPIKE_OK) {
printf("Aerospike 연결 실패: %s\n", err.message);
aerospike_destroy(&as);
return -1;
}
// 갱신할 키 설정
as_key key;
as_key_init(&key, "test", "demo", "user1");
// 데이터 갱신
as_record rec;
as_record_inita(&rec, 1);
as_record_set_str(&rec, "name", "Jane Doe");
if (aerospike_key_put(&as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
printf("데이터 갱신 실패: %s\n", err.message);
} else {
printf("데이터 갱신 성공!\n");
}
as_record_destroy(&rec);
aerospike_close(&as, &err);
aerospike_destroy(&as);
return 0;
}
위 코드를 실행하면 name
필드의 값이 "John Doe"
에서 "Jane Doe"
로 변경됩니다.
2. 데이터 조회로 갱신 확인
이전 코드에서 aerospike_key_get()
을 이용해 데이터를 조회하면 "Jane Doe"
로 변경된 값을 확인할 수 있습니다.
조회된 데이터: Jane Doe
3. Aerospike 데이터 삭제
Aerospike에서 특정 키의 데이터를 삭제하려면 aerospike_key_remove()
를 사용합니다.
#include <stdio.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_key.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_error.h>
int main() {
aerospike as;
as_config config;
as_error err;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000);
aerospike_init(&as, &config);
if (aerospike_connect(&as, &err) != AEROSPIKE_OK) {
printf("Aerospike 연결 실패: %s\n", err.message);
aerospike_destroy(&as);
return -1;
}
// 삭제할 키 설정
as_key key;
as_key_init(&key, "test", "demo", "user1");
// 데이터 삭제
if (aerospike_key_remove(&as, &err, NULL, &key) != AEROSPIKE_OK) {
printf("데이터 삭제 실패: %s\n", err.message);
} else {
printf("데이터 삭제 성공!\n");
}
aerospike_close(&as, &err);
aerospike_destroy(&as);
return 0;
}
aerospike_key_remove()
: 특정 키의 데이터를 삭제aerospike_close()
: 연결 종료aerospike_destroy()
: 클라이언트 정리
4. 데이터 삭제 확인
삭제 후 aerospike_key_get()
을 실행하면 다음과 같은 오류 메시지가 출력됩니다.
데이터 조회 실패: AEROSPIKE_ERR_RECORD_NOT_FOUND
이는 데이터가 성공적으로 삭제되었음을 의미합니다.
5. 갱신과 삭제의 활용
- 갱신 활용 사례: 사용자 프로필 정보 변경, 캐시 업데이트
- 삭제 활용 사례: 오래된 세션 데이터 제거, 만료된 키 삭제
Aerospike는 고성능 데이터 처리를 위해 최적화되어 있으며, 데이터를 손쉽게 삽입, 조회, 갱신, 삭제할 수 있습니다. 다음 섹션에서는 성능 최적화를 위한 설정 방법을 살펴보겠습니다.
성능 최적화를 위한 설정
Aerospike는 대량의 데이터를 처리하는 데 최적화된 데이터베이스이지만, 성능을 더욱 향상시키기 위해 몇 가지 설정을 조정할 수 있습니다. 이 섹션에서는 C언어 기반 애플리케이션에서 Aerospike를 효율적으로 활용하기 위한 성능 최적화 기법을 다룹니다.
1. 클라이언트 연결 풀(Connection Pool) 활용
Aerospike 서버와의 연결을 매번 생성하는 것은 성능 저하를 유발할 수 있습니다. 이를 방지하기 위해 연결 풀을 사용하면 여러 요청을 효율적으로 처리할 수 있습니다.
Aerospike C 클라이언트는 기본적으로 멀티스레드 환경을 지원하며, as_policies
구조체에서 연결 풀 크기를 조정할 수 있습니다.
as_config config;
as_config_init(&config);
config.max_conns_per_node = 100; // 노드당 최대 연결 수 설정
- 기본적으로 Aerospike는 자동으로 최적의 연결 개수를 관리하지만, 트래픽이 많을 경우 이 값을 조정하면 성능이 향상될 수 있습니다.
2. Batch Read를 사용하여 여러 키 조회
일반적으로 하나의 키를 조회하는 aerospike_key_get()
을 사용하지만, 다수의 키를 한 번에 조회하면 성능이 향상됩니다.
Aerospike는 Batch Read를 지원하며, aerospike_batch_get()
을 활용하면 여러 키를 동시에 조회할 수 있습니다.
#include <aerospike/aerospike_batch.h>
// 여러 키를 한 번에 조회
as_batch batch;
as_batch_inita(&batch, 2);
as_key_init(as_batch_keyat(&batch, 0), "test", "demo", "user1");
as_key_init(as_batch_keyat(&batch, 1), "test", "demo", "user2");
as_record** records = NULL;
if (aerospike_batch_get(&as, &err, NULL, &batch, &records) == AEROSPIKE_OK) {
printf("Batch Read 성공!\n");
}
- 여러 개의 키를 한 번에 조회하면 네트워크 오버헤드를 줄일 수 있어 성능이 개선됩니다.
3. Write Policy 설정으로 성능 향상
Aerospike는 데이터를 저장할 때 Write Policy
를 설정하여 성능을 최적화할 수 있습니다.
as_policy_write write_policy;
as_policy_write_init(&write_policy);
write_policy.commit_level = AS_POLICY_COMMIT_LEVEL_MASTER;
write_policy.timeout = 50; // 50ms 타임아웃 설정
commit_level = AS_POLICY_COMMIT_LEVEL_MASTER
: 데이터가 마스터 노드에만 저장되도록 설정 (기본값은 동기 복제)timeout
값을 줄이면 요청이 빨리 반환되며, 응답 속도가 향상됨
4. TTL(Time-To-Live) 활용
Aerospike는 자동 데이터 만료 기능(TTL)을 제공하여 불필요한 데이터를 효율적으로 제거할 수 있습니다.
as_record rec;
as_record_inita(&rec, 1);
as_record_set_str(&rec, "name", "John Doe");
rec.ttl = 600; // 데이터가 600초(10분) 후 자동 삭제됨
- TTL을 설정하면 특정 시간이 지나면 데이터가 자동으로 삭제되어 성능을 유지하는 데 도움이 됩니다.
- 캐싱 시스템이나 세션 데이터를 저장할 때 유용합니다.
5. Secondary Index를 활용한 성능 향상
Aerospike는 기본적으로 키-값 기반이지만, 특정 필드에 대한 검색을 최적화하기 위해 Secondary Index를 사용할 수 있습니다.
예를 들어, age
필드에 대해 검색할 수 있도록 인덱스를 생성하는 방법은 다음과 같습니다.
aql> CREATE INDEX age_index ON test.demo (age) NUMERIC
이제 age
필드에 대한 빠른 검색이 가능합니다.
aerospike_query_foreach(&as, &query, NULL, query_callback, NULL);
- 주의: Secondary Index를 사용하면 성능이 향상되지만, 메모리를 더 많이 사용하므로 필요할 때만 추가하는 것이 좋습니다.
6. UDF(User Defined Function) 사용
Aerospike에서는 데이터 저장 및 검색 시 추가적인 연산을 수행할 수 있도록 사용자 정의 함수(UDF)를 지원합니다.
Lua 스크립트를 활용하여 데이터를 저장할 때 특정 연산을 적용할 수 있습니다.
function increment(rec, bin)
rec[bin] = rec[bin] + 1
aerospike:update(rec)
end
위의 UDF는 특정 bin 값을 1 증가시키는 함수입니다.
C 코드에서 실행하려면 aerospike_key_apply()
를 사용합니다.
aerospike_key_apply(&as, &err, NULL, &key, "mymodule", "increment", NULL, &result);
7. 고성능 SSD 최적화
Aerospike는 SSD 최적화가 가능하며, 디스크 기반 저장소를 최대한 활용할 수 있도록 설정할 수 있습니다.
Aerospike 설정 파일(/etc/aerospike/aerospike.conf
)을 수정하여 성능을 향상시킬 수 있습니다.
namespace test {
storage-engine device {
device /dev/sdb
scheduler-mode noop
write-block-size 128K
}
}
- scheduler-mode noop : SSD에서 CPU 오버헤드를 줄이는 I/O 스케줄러 모드
- write-block-size 128K : 블록 크기를 조정하여 쓰기 성능을 최적화
결론
Aerospike는 기본적으로 고성능을 제공하지만, 적절한 설정을 통해 더욱 빠르고 효율적으로 데이터를 처리할 수 있습니다.
- 연결 풀을 사용하여 네트워크 오버헤드를 줄이기
- Batch Read를 활용하여 여러 개의 키를 한 번에 조회
- TTL을 설정하여 불필요한 데이터를 자동 삭제
- Secondary Index를 활용하여 특정 필드 검색 최적화
- SSD 최적화 설정을 적용하여 저장 성능 향상
다음 섹션에서는 Aerospike의 TTL(Time-to-Live)을 활용한 자동 데이터 만료 관리 기법을 살펴보겠습니다.
Aerospike의 TTL(Time-to-Live) 활용
Aerospike는 특정 데이터의 수명을 제한하는 TTL(Time-to-Live) 기능을 제공하여, 일정 시간이 지나면 자동으로 데이터를 삭제할 수 있도록 지원합니다. 이를 활용하면 만료된 데이터를 효율적으로 정리할 수 있어 성능을 유지하는 데 유용합니다.
1. TTL의 개념과 기본 동작
TTL은 레코드(데이터)에 대해 설정할 수 있는 만료 시간으로, 초 단위로 지정됩니다.
Aerospike에서 TTL은 다음과 같은 방식으로 동작합니다.
- 레코드에 TTL이 설정되면, 해당 시간이 지나면 자동으로 삭제됨
- TTL 값이
0
이면 영구 저장됨 - TTL 값이
-1
이면 기본 네임스페이스 TTL을 따름
Aerospike에서는 데이터를 저장할 때 TTL을 설정할 수 있으며, 정책을 이용하여 기본값을 변경할 수도 있습니다.
2. TTL을 설정하여 데이터 저장
Aerospike에서 TTL을 설정하여 데이터를 저장하는 예제입니다.
#include <stdio.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_key.h>
#include <aerospike/aerospike_record.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_error.h>
#include <aerospike/as_record.h>
int main() {
aerospike as;
as_config config;
as_error err;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000);
aerospike_init(&as, &config);
if (aerospike_connect(&as, &err) != AEROSPIKE_OK) {
printf("Aerospike 연결 실패: %s\n", err.message);
aerospike_destroy(&as);
return -1;
}
// 키 설정
as_key key;
as_key_init(&key, "test", "demo", "session1");
// 데이터 저장
as_record rec;
as_record_inita(&rec, 1);
as_record_set_str(&rec, "username", "Alice");
rec.ttl = 300; // 300초 후 만료
if (aerospike_key_put(&as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
printf("데이터 저장 실패: %s\n", err.message);
} else {
printf("데이터 저장 성공! (TTL 300초 설정됨)\n");
}
as_record_destroy(&rec);
aerospike_close(&as, &err);
aerospike_destroy(&as);
return 0;
}
위 코드에서는 "session1"
키를 가진 데이터가 300초(5분) 후에 자동으로 만료됩니다.
3. TTL이 적용된 데이터 조회
TTL이 적용된 데이터를 조회하면 TTL 값도 함께 확인할 수 있습니다.
as_record *rec = NULL;
if (aerospike_key_get(&as, &err, NULL, &key, &rec) == AEROSPIKE_OK) {
printf("조회된 데이터: %s\n", as_record_get_str(rec, "username"));
printf("남은 TTL: %d 초\n", rec->ttl);
}
- rec->ttl 값이 양수이면 데이터가 만료되기 전
- rec->ttl 값이 0 또는 음수이면 데이터가 만료되었거나 삭제됨
4. 기본 TTL 정책 변경
Aerospike에서는 네임스페이스(namespace) 단위로 기본 TTL을 설정할 수 있습니다.
기본 TTL 값을 변경하려면 설정 파일(/etc/aerospike/aerospike.conf
)을 수정해야 합니다.
namespace test {
default-ttl 86400 # 1일 (초 단위)
}
- 설정 후 서버를 재시작하면 적용됨
- TTL이
-1
인 레코드는 이 기본 TTL을 따름
5. TTL을 활용한 자동 데이터 관리
TTL을 활용하면 다음과 같은 방식으로 데이터를 효과적으로 관리할 수 있습니다.
- 세션 관리
- 로그인 세션 데이터는 일정 시간이 지나면 삭제되어야 하므로, TTL을 설정하여 자동 만료
- 예: 웹 애플리케이션에서 사용자의 로그인 세션 유지 시간 30분
- 캐시 시스템
- TTL을 사용하여 일정 시간 후 데이터를 삭제하면, 주기적으로 캐시를 비우는 작업이 필요 없음
- 예: 10분 동안 유지되는 뉴스 데이터 캐싱
- 이벤트 로그 정리
- 특정 이벤트 기록이 오래 남아있을 필요가 없을 때 TTL을 사용하여 자동 삭제
- 예: 7일간 유지되는 사용자 활동 로그
6. TTL이 만료된 데이터 조회
Aerospike는 TTL이 만료된 데이터를 자동으로 제거하기 때문에, 만료된 데이터는 AEROSPIKE_ERR_RECORD_NOT_FOUND
오류를 반환합니다.
if (aerospike_key_get(&as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
printf("데이터 조회 실패: 데이터가 만료되었습니다.\n");
}
이 코드를 실행하면 TTL이 지난 데이터는 삭제되었음을 확인할 수 있습니다.
7. TTL을 변경하여 데이터 갱신
Aerospike에서는 TTL을 변경하여 데이터의 수명을 연장하거나 단축할 수도 있습니다.
다음 코드에서 TTL을 600초(10분)으로 변경하는 방법을 보여줍니다.
as_record rec;
as_record_inita(&rec, 1);
rec.ttl = 600; // TTL 연장
if (aerospike_key_put(&as, &err, NULL, &key, &rec) == AEROSPIKE_OK) {
printf("TTL이 600초로 연장되었습니다.\n");
}
이제 해당 데이터는 10분 동안 유지됩니다.
결론
TTL을 활용하면 데이터의 수명을 효율적으로 관리할 수 있으며, 주기적인 정리 작업 없이도 불필요한 데이터를 자동으로 제거할 수 있습니다.
- 로그인 세션 관리: 일정 시간이 지나면 자동 삭제
- 캐시 관리: 특정 시간이 지나면 캐시 만료
- 임시 데이터 정리: 불필요한 데이터를 자동 삭제
다음 섹션에서는 Aerospike를 활용한 대규모 트랜잭션 처리 방법을 살펴보겠습니다.
Aerospike를 활용한 대규모 트랜잭션 처리
Aerospike는 초고속 키-값 저장소로서 대규모 트랜잭션을 효율적으로 처리할 수 있도록 설계되었습니다. 대량의 데이터를 빠르게 저장하고 검색하는 데 최적화된 Aerospike를 활용하면, 실시간 분석, 광고 기술, IoT 데이터 수집 등 다양한 고성능 애플리케이션에서 뛰어난 성능을 발휘할 수 있습니다.
이 섹션에서는 대규모 트랜잭션을 처리하는 최적화된 방법과 예제 코드를 살펴봅니다.
1. 대규모 데이터 삽입(Bulk Insert)
Aerospike는 트랜잭션 단위로 데이터를 삽입할 수도 있지만, 대량의 데이터를 효율적으로 저장하려면 병렬 처리 또는 배치 작업(Batch Write) 을 고려해야 합니다.
Aerospike는 기본적으로 Batch Write API를 지원하지 않으므로, 다중 쓰기 연산을 최적화하는 방법을 활용해야 합니다.
✅ 다중 쓰기 (멀티스레드 사용)
C에서 pthread
를 활용하여 여러 개의 데이터를 병렬로 저장할 수 있습니다.
#include <pthread.h>
#include <stdio.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_key.h>
#include <aerospike/aerospike_record.h>
#include <aerospike/aerospike_client.h>
#include <aerospike/aerospike_error.h>
#include <aerospike/as_record.h>
#define THREAD_COUNT 10 // 동시에 실행할 스레드 수
typedef struct {
aerospike *as;
int id;
} thread_data_t;
void *insert_data(void *arg) {
thread_data_t *data = (thread_data_t *)arg;
aerospike *as = data->as;
as_error err;
char key_str[20];
snprintf(key_str, sizeof(key_str), "user%d", data->id);
// 키 설정
as_key key;
as_key_init(&key, "test", "demo", key_str);
// 데이터 저장
as_record rec;
as_record_inita(&rec, 1);
as_record_set_int64(&rec, "value", data->id * 10);
if (aerospike_key_put(as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
printf("데이터 삽입 실패 (ID %d): %s\n", data->id, err.message);
} else {
printf("데이터 삽입 성공! (ID %d)\n", data->id);
}
as_record_destroy(&rec);
return NULL;
}
int main() {
aerospike as;
as_config config;
as_error err;
as_config_init(&config);
as_config_add_host(&config, "127.0.0.1", 3000);
aerospike_init(&as, &config);
if (aerospike_connect(&as, &err) != AEROSPIKE_OK) {
printf("Aerospike 연결 실패: %s\n", err.message);
aerospike_destroy(&as);
return -1;
}
pthread_t threads[THREAD_COUNT];
thread_data_t thread_data[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
thread_data[i].as = &as;
thread_data[i].id = i + 1;
pthread_create(&threads[i], NULL, insert_data, &thread_data[i]);
}
for (int i = 0; i < THREAD_COUNT; i++) {
pthread_join(threads[i], NULL);
}
aerospike_close(&as, &err);
aerospike_destroy(&as);
return 0;
}
🔹 위 코드의 특징
pthread_create()
를 활용하여 여러 개의 데이터를 동시에 저장user1, user2, ..., user10
키를 가진 데이터를 병렬로 삽입- 대량 데이터 저장 시 성능 향상
2. 대량 데이터 조회 (Batch Read)
Aerospike는 Batch Read API를 제공하여 여러 개의 키를 한 번에 조회할 수 있습니다.
#include <aerospike/aerospike_batch.h>
as_batch batch;
as_batch_inita(&batch, 3);
as_key_init(as_batch_keyat(&batch, 0), "test", "demo", "user1");
as_key_init(as_batch_keyat(&batch, 1), "test", "demo", "user2");
as_key_init(as_batch_keyat(&batch, 2), "test", "demo", "user3");
as_record **records = NULL;
if (aerospike_batch_get(&as, &err, NULL, &batch, &records) == AEROSPIKE_OK) {
printf("Batch Read 성공!\n");
}
- 여러 개의 키를 한 번에 조회하여 네트워크 오버헤드를 줄임
aerospike_batch_get()
을 사용하여 3개의 레코드를 동시에 가져옴
3. 트랜잭션 무결성 유지
Aerospike는 ACID(Atomicity, Consistency, Isolation, Durability)를 완벽히 지원하지 않지만, Atomic Operation(원자적 연산)을 활용하여 무결성을 유지할 수 있습니다.
✅ 원자적 증가 연산
Aerospike에서 특정 값(예: 카운터)을 원자적으로 증가시키려면 aerospike_key_operate()
를 사용할 수 있습니다.
as_operations ops;
as_operations_inita(&ops, 1);
as_operations_add_incr(&ops, "counter", 1);
if (aerospike_key_operate(&as, &err, NULL, &key, &ops, NULL) == AEROSPIKE_OK) {
printf("Counter 값 증가 성공!\n");
}
- 동시에 여러 개의 클라이언트가 접근하더라도 값이 올바르게 증가됨
- 이전 값을 가져오지 않고 직접 증가시키므로 성능이 향상됨
4. 대규모 트랜잭션 처리 최적화
대량의 트랜잭션을 처리할 때 성능을 극대화하려면 다음 방법을 활용할 수 있습니다.
✅ 연결 풀(Connection Pool) 설정
config.max_conns_per_node = 200; // 노드당 최대 연결 수 증가
- 트랜잭션이 많을 경우, 병렬 처리를 위해 연결 수를 늘림
✅ 네임스페이스 설정 최적화
namespace test {
memory-size 4G
storage-engine device {
device /dev/sdb
write-block-size 128K
}
}
- SSD 최적화: 쓰기 블록 크기를 조정하여 I/O 성능 향상
✅ TTL(Time-to-Live) 활용하여 오래된 데이터 자동 삭제
rec.ttl = 600; // 10분 후 데이터 자동 삭제
- 세션 데이터나 캐시 데이터는 TTL을 설정하여 자동 정리
결론
Aerospike는 대량의 트랜잭션을 처리하는 데 최적화된 데이터베이스입니다.
- 멀티스레드를 활용한 병렬 데이터 저장(Bulk Insert)
- Batch Read를 활용한 대량 데이터 조회 최적화
- Atomic Operations를 활용한 무결성 유지
- Connection Pool 및 SSD 최적화를 통한 성능 향상
Aerospike의 이러한 기능을 활용하면 실시간 빅데이터 처리 시스템, 광고 네트워크, IoT 센서 데이터 수집 등에서 탁월한 성능을 제공할 수 있습니다.
다음 섹션에서는 Aerospike 기반 키-값 저장소 구축의 핵심 내용을 정리합니다.
요약
본 기사에서는 C언어와 Aerospike를 연동하여 초고속 키-값 저장소를 구축하는 방법을 다루었습니다. Aerospike의 기본 개념부터 데이터 삽입, 조회, 갱신, 삭제, 성능 최적화, 대규모 트랜잭션 처리까지 실용적인 예제와 함께 설명하였습니다.
주요 내용은 다음과 같습니다:
- Aerospike 개요 및 특징: 고성능, 확장성, 내결함성을 갖춘 NoSQL 데이터베이스
- C언어 환경 설정: Aerospike C 클라이언트 설치 및 서버 연동
- 데이터 조작: 키-값 데이터 저장, 조회, 갱신 및 삭제
- 성능 최적화: 연결 풀, Batch Read, Secondary Index 활용
- TTL 설정: 자동 데이터 만료 기능을 활용한 효율적인 데이터 관리
- 대규모 트랜잭션 처리: 멀티스레드 및 원자적 연산(Atomic Operation) 활용
Aerospike는 빠른 데이터 처리가 필요한 광고, 금융, IoT, 실시간 분석 시스템에서 강력한 성능을 발휘할 수 있습니다. 본 기사의 내용을 활용하면, C언어 기반의 초고속 키-값 저장소를 효과적으로 구축하고 최적화할 수 있을 것입니다.