arcus-memcached icon indicating copy to clipboard operation
arcus-memcached copied to clipboard

[persistence] 즉시 재시작 기능 개발

Open MinWooJin opened this issue 5 years ago • 4 comments

재시작 회복 시간 중에도 client의 요청을 처리할 수 있도록 하는 즉시 재시작 기능을 개발한다.

우선 순위

  1. client 요청
  2. recovery

operation 우선 순위에 따라서 같은 item에 대해 client 요청이 먼저 반영 되었을 경우 recovery 는 skip 한다. (client 요청 반영 여부를 확인할 수 있는 별도의 자료가 필요하다.)

MinWooJin avatar Aug 12 '19 02:08 MinWooJin

방법 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 상태에서 수행되기 때문에 동시성 문제는 없을 것으로 보임.

MinWooJin avatar Sep 17 '19 06:09 MinWooJin

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

MinWooJin avatar Sep 18 '19 00:09 MinWooJin

log record 재수행 도중 실패에 대한 handling

  • 즉시 재시작 모드가 아닐 경우 log record 재수행 도중 실패는 잘못된 data로 복구되는 것을 막기 위해 log를 기록하고 engine을 fail 상태로 shutdown 시킨다.
  • 즉시 재시작 모드에서 log record 재수행 시점은 클라이언트 요청을 받고있는 시점이기 때문에, log만 기록 후 재수행 종료. 그 상태대로 서비스를 지속하도록 하는게 맞다고 판단된다.

MinWooJin avatar Sep 19 '19 23:09 MinWooJin

설계 정리.

즉시 재시작은 설정으로 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로 생성 후 삽입
    • 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 아이템의 경우 item 단위로 의미가 부여된다. 따라서 클라이언트 요청을 우선순위로 두고, 복구되는 동안 old item에 대한 조회가 허용될 수 있다.
  • Collection type 아이템의 경우 Collection 단위로 의미가 부여된다. 복구가 끝나기 전이면 collection 구조 생성이 완료 되기 전이라고 볼 수 있다. 이 때 클라이언트가 collection을 조회 또는 변경하는 경우, 해당 collection은 의미 없는 상태 이기 때문에 허용하지 않는다.

MinWooJin avatar Nov 01 '19 01:11 MinWooJin