Key-value item은 하나의 key에 대해 하나의 value만을 저장하는 item이다.
제약조건
Key의 최대 크기는 4000 character이다.
Cache item의 최대 크기는 1MB이다.
Key-value item에 대해 수행 가능한 연산들은 아래와 같다.
Key-Value Item 저장
key-value item을 저장하는 API로 set, add, replace, prepend/append가 있다.
새로운 아이템을 저장하거나 기존 아이템을 교체하는 API는 다음과 같다.
memcached_set: 주어진 key에 value를 저장한다.
memcached_add: 주어진 key가 존재하지 않을 경우에만 value를 저장한다.
memcached_replace: 주어진 key가 존재하는 경우에만 value를 저장한다.
Copy memcached_return_t
memcached_set(memcached_st *ptr,
const char *key, size_t key_length,
const char *value, size_t value_length,
time_t expiration, uint32_t flags)
memcached_return_t
memcached_add(memcached_st *ptr,
const char *key, size_t key_length,
const char *value, size_t value_length,
time_t expiration, uint32_t flags)
memcached_return_t
memcached_replace(memcached_st *ptr,
const char *key, size_t key_length,
const char *value, size_t value_length,
time_t expiration, uint32_t flags)
대표적으로 set을 수행하는 예시는 다음과 같다.
Copy int arcus_kv_store(memcached_st *memc)
{
const char *key= "item:a_key";
const char *value= "value";
uint32_t exptime= 600;
uint32_t flags= 0;
memcached_return_t rc;
rc= memcached_set(memc, key, strlen(key), value, strlen(value), exptime, flags);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_set: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
assert(rc == MEMCACHED_SUCCESS);
return 0;
}
존재하는 아이템의 value에 데이터를 추가시키는 API는 다음과 같다.
memcached_prepend: 주어진 key의 value에 새로운 데이터를 prepend한다.
memcached_append: 주어진 key의 value에 새로운 데이터를 append한다.
Copy memcached_return_t
memcached_prepend(memcached_st *ptr,
const char *key, size_t key_length,
const char *value, size_t value_length,
time_t expiration, uint32_t flags)
memcached_return_t
memcached_append(memcached_st *ptr,
const char *key, size_t key_length,
const char *value, size_t value_length,
time_t expiration, uint32_t flags)
대표적으로 prepend를 수행하는 예시는 다음과 같다.
Copy int arcus_kv_attach(memcached_st *memc)
{
const char *key= "item:a_key";
const char *value= "value";
uint32_t exptime= 600;
uint32_t flags= 0;
memcached_return_t rc;
rc= memcached_prepend(memc, key, strlen(key), value, strlen(value), exptime, flags);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_prepend: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
assert(rc == MEMCACHED_SUCCESS);
return 0;
}
Key-Value Item 조회
Key-value item을 조회하는 API는 두 가지가 있다.
하나의 키에 대한 값을 조회하는 API는 아래와 같다. 반환된 결과가 NULL이 아닌 경우 반드시 free 해주어야 한다.
Copy char *
memcached_get(memcached_st *ptr,
const char *key, size_t key_length,
size_t *value_length, uint32_t *flags,
memcached_return_t *error)
하나의 키에 대한 값을 조회하는 예시는 다음과 같다.
Copy int arcus_kv_get(memcached_st *memc)
{
const char *key= "item:a_key";
const char *value;
size_t value_length;
uint32_t flags;
memcached_return_t rc;
value= memcached_get(memc, key, strlen(key), &value_length, &flags, &rc);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_get: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
assert(rc == MEMCACHED_SUCCESS);
if (value != NULL) {
fprintf(stdout, "memcached_get: %s=%s\n", key, value);
free((void*)value);
} else {
fprintf(stdout, "memcached_get: %s=<empty value>.\n", key);
}
return 0;
}
여러 키들의 값들을 일괄 조회하는 API는 다음과 같다.
memcached_mget
은 주어진 key 배열에 대한 value들을 조회하는 요청을 보낸다.
keys 인자는 key pointer array이고, key_length 인자는 key length array이다.
memcached_fetch
는 mget 요청에 대한 결과를 하나씩 가져온다.
error 값이 MEMCACHED_END가 될 때까지 계속 실행하면 되며, 반환된 결과가 NULL이 아닌 경우 반드시 free 해주어야 한다.
Copy memcached_return_t
memcached_mget(memcached_st *ptr,
const char * const *keys, const size_t *key_length,
const size_t number_of_keys)
char *
memcached_fetch(memcached_st *ptr,
char *key, size_t *key_length,
size_t *value_length, uint32_t *flags,
memcached_return_t *error)
여러 키들의 값을 일괄 조회하는 예시는 다음과 같다.
Copy int arcus_kv_mget(memcached_st *memc)
{
const char * const keys[]= { "item:a_key1", "item:a_key2", "item:a_key3" };
size_t keys_len[3];
size_t number_of_keys = 3;
uint32_t flags;
memcached_return_t rc;
for (size_t i=0; i<number_of_keys; i++)
{
keys_len[i]= strlen(keys[i]);
}
rc= memcached_mget(memc, keys, keys_len, number_of_keys);
if (rc == MEMCACHED_FAILURE) {
fprintf(stderr, "Failed to memcached_get: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_SOME_ERRORS);
while (true)
{
char key[MEMCACHED_MAX_KEY];
size_t key_length;
size_t value_length;
char *value= memcached_fetch(memc, key, &key_length, &value_length, &flags, &rc);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_fetch: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
if (rc == MEMCACHED_END) {
break;
}
assert(rc == MEMCACHED_SUCCESS);
if (value != NULL) {
fprintf(stdout, "memcached_mget: %s=%s\n", key, value);
free((void*)value);
} else {
fprintf(stdout, "memcached_mget: %s=<empty value>.\n", key);
}
}
return 0;
}
Key-Value Item 값의 CAS
아이템을 조회한 후, 해당 아이템이 변경되지 않았다면 새로운 값을 저장하는 Compare and Set(CAS) API는 다음과 같다 주의 사항으로, CAS 연산을 수행하기 위해서는 MEMCACHED_BEHAVIOR_SUPPORT_CAS 플래그가 설정된 memcached_st 구조체를 사용해야 한다.
key에 해당하는 아이템의 cas 값을 확인한 후, 일치하면 새로운 값을 저장한다.
해당 item이 없거나 cas 값이 일치하지 않으면 오류가 발생한다.
Copy memcached_return_t
memcached_cas(memcached_st *ptr,
const char *key, size_t key_length,
const char *value, size_t value_length,
time_t expiration, uint32_t flags,
uint64_t cas)
Compare and Set 연산을 수행하는 예시는 다음과 같다.
Copy int arcus_kv_compare_and_set(memcached_st *memc)
{
const char *key= "item:a_key";
char *old_value= NULL;
char *new_value= NULL;
uint64_t cas_value;
uint32_t exptime= 600;
uint32_t flags= 0;
int result= 0;
memcached_return_t rc;
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true);
old_value= memcached_get(memc, key, strlen(key), NULL, NULL, &rc);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_gets: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
cas_value= memcached_result_cas(&memc->result);
// make a new_value based on the old_value
new_value= make_new_value_from_old_value(old_value);
rc= memcached_cas(memc, key, strlen(key), new_value, strlen(new_value), exptime, flags, cas_value);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_cas: %d(%s)\n", rc, memcached_strerror(memc, rc));
result= -1;
}
if (old_value) free(old_value);
if (new_value) free(new_value);
return result;
}
Key-Value Item 값의 증감
특정 key에 해당하는 item이 가진 숫자형 값을 증감 연산하는 API는 다음과 같다.
offset 만큼 증가/감소하며, 증감 후의 값을 value 인자로 반환한다.
해당 item이 없거나 해당 item이 숫자형 값을 가지지 않는다면 오류를 낸다.
Copy memcached_return_t
memcached_increment(memcached_st *ptr,
const char *key, size_t key_length,
uint32_t offset, uint64_t *value)
memcached_return_t
memcached_decrement(memcached_st *ptr,
const char *key, size_t key_length,
uint32_t offset, uint64_t *value)
특정 key에 해당하는 item이 있다면 증감 연산을 수행하고, 그 item이 없다면 초기값을 가진 item을 생성하는 API는 다음과 같다.
해당 item이 있다면 offset 만큼 증가/감소한다.
해당 item이 없다면 initial 값을 가진 item을 생성한다.
증감 or 생성 후의 item의 값을 value 인자로 반환한다.
Copy memcached_return_t
memcached_increment_with_initial(memcached_st *ptr,
const char *key, size_t key_length, uint64_t offset,
uint64_t initial, uint32_t flags, time_t expiration,
uint64_t *value)
memcached_return_t
memcached_decrement_with_initial(memcached_st *ptr,
const char *key, size_t key_length, uint64_t offset,
uint64_t initial, uint32_t flags, time_t expiration,
uint64_t *value)
특정 item의 숫자형 값을 증가시키는 예시는 다음과 같다.
Copy int arcus_kv_arithmetic(memcached_st *memc)
{
const char *key= "item:a_key";
uint64_t value= 0;
// uint64_t initial = 0;
uint32_t flags= 10;
uint32_t exptime= 600;
uint32_t offset= 10;
memcached_return_t rc;
rc= memcached_increment(memc, key, strlen(key), offset, &value);
// rc= memcached_increment_with_initial(memc, key, strlen(key), offset, initial, flags, exptime, &value);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_increment: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
assert(rc == MEMCACHED_SUCCESS);
fprintf(stdout, "incremented value: %llu\n", value);
return 0;
}
Key-Value Item 삭제
주어진 key에 해당하는 item을 삭제하는 API는 다음과 같다. expiration은 현재 지원하지 않으며, 0을 값으로 주어야 한다.
Copy memcached_return_t
memcached_delete(memcached_st *ptr,
const char *key, size_t key_length,
time_t expiration)
특정 key를 가진 item을 제거하는 예시는 다음과 같다.
Copy int arcus_kv_delete(memcached_st *memc)
{
const char *key= "item:a_key";
memcached_return_t rc;
rc= memcached_delete(memc, key, strlen(key), 0);
if (memcached_failed(rc)) {
fprintf(stderr, "Failed to memcached_delete: %d(%s)\n", rc, memcached_strerror(memc, rc));
return -1;
}
assert(rc == MEMCACHED_SUCCESS);
return 0;
}