arcus-memcached
arcus-memcached copied to clipboard
[persistence] 즉시 재시작 기능 개발
재시작 회복 시간 중에도 client의 요청을 처리할 수 있도록 하는 즉시 재시작 기능을 개발한다.
우선 순위
- client 요청
- recovery
operation 우선 순위에 따라서 같은 item에 대해 client 요청이 먼저 반영 되었을 경우 recovery 는 skip 한다. (client 요청 반영 여부를 확인할 수 있는 별도의 자료가 필요하다.)
방법 1. hash_item 구조체 내부에 order / by alloced를 표현하는 value를 추가해서 구분 가능.
방법 2. hash_item의 iflag (internal flag) 16 사용. iflag list
/* Item internal flag (1 byte) : item type and flag */
/* 1) item type: increasing order (See ENGINE_ITEM_TYPE) */
#define ITEM_IFLAG_LIST 1 /* list item */
#define ITEM_IFLAG_SET 2 /* set item */
#define ITEM_IFLAG_MAP 3 /* map item */
#define ITEM_IFLAG_BTREE 4 /* b+tree item */
#define ITEM_IFLAG_COLL 7 /* collection item: list/set/map/b+tree */
/* 2) item flag: decreasing order */
#define ITEM_LINKED 32 /* linked to assoc hash table */
#define ITEM_INTERNAL 64 /* internal cache item */
#define ITEM_WITH_CAS 128 /* having CAS value */
동작
- item alloc의 경우 기존 코드 그대로 allocate 수행.
- recovery
- new item allocate 하고 order / by alloced / iflag를 설정해서 link.
- old item이 있으면 항상 order / by alloced / iflag 변수를 확인해서 기본값으로 세팅되어 있으면 skip.
apply 동작도 CACHE LOCK 상태에서 수행되기 때문에 동시성 문제는 없을 것으로 보임.
collection item의 경우 recovery 도중 client의 element update 성격 operation이 요청되었을 때 이에 대한 handling 고민이 필요함.
- case 1
- recovery에 의해 collection item create 된 뒤
- client 요청에 의해 element insert with create 요청이 들어왔을 때 handling
- case 2
- recovery에 의해 일부 element insert가 되었고,
- client 요청에 의해 같은 element key insert 요청이 들어왔을 때 handling
- case 3
- recovery에 의해 일부 element insert가 되었고,
- client 요청에 의해 새로운 element key insert 요청이 들어왔을 때 handling
log record 재수행 도중 실패에 대한 handling
- 즉시 재시작 모드가 아닐 경우 log record 재수행 도중 실패는 잘못된 data로 복구되는 것을 막기 위해 log를 기록하고 engine을 fail 상태로 shutdown 시킨다.
- 즉시 재시작 모드에서 log record 재수행 시점은 클라이언트 요청을 받고있는 시점이기 때문에, log만 기록 후 재수행 종료. 그 상태대로 서비스를 지속하도록 하는게 맞다고 판단된다.
설계 정리.
즉시 재시작은 설정으로 enable hash_item 구조체 내부에 recovery flag 추가
typedef struct _hash_item {
...
bool recovery;
}
복구 중 일반 요청 처리가 항상 우선이 되도록 한다. 동작 방법.
- 복구 로직의 즉시 재시작
- 복구 과정 중 item_apply_***() 함수 내부에서 즉시 재시작 로직 처리.
- KV type 변경 연산
- old item != NULL
- recovery flag 가 false이면 skip
- true 이면 수행
- old item == NULL
- recovery flag true로 생성 후 삽입
- old item != NULL
- collection 변경 연산
- item의 recovery flag가 false 이면 skip
- 일반 요청 처리 로직의 즉시 재시작
- KV type 변경 연산
- recovery flag false로 생성 후 삽입
- collection 변경 연산
- item의 recovery flag가 true 이면 모든 element 제거. delete log 생성
- recovery flag flase로 update
- collection 조회 연산
- item의 recovery flag가 true 이면 NOT_FOUND return
- KV type 변경 연산
즉시 재시작 기능의 사용 가능성
- KV type 아이템의 경우 item 단위로 의미가 부여된다. 따라서 클라이언트 요청을 우선순위로 두고, 복구되는 동안 old item에 대한 조회가 허용될 수 있다.
- Collection type 아이템의 경우 Collection 단위로 의미가 부여된다. 복구가 끝나기 전이면 collection 구조 생성이 완료 되기 전이라고 볼 수 있다. 이 때 클라이언트가 collection을 조회 또는 변경하는 경우, 해당 collection은 의미 없는 상태 이기 때문에 허용하지 않는다.