cache

캐싱엔진을 설정한다. /usr/local/m2/setting.json 다음 영역에 대해 기술한다.

{
  "functions": {
    "network": {
      "cache": {
        ...
      }
    }
  }
}

meta

가상호스트 단위의 캐싱엔진 동작을 설정한다.

"meta": {
  "fixedCount": 0,
  "indexingLimitCount": 0
}
fixedCount (기본: 0, 최대: 1000000)

설정된 개수만큼 완전한 캐싱객체가 서비스 되도록 보장한다. 완전한 서비스는 다음을 의미한다.

  • 메모리 부족시 정리 대상이 되지 않는다.

  • 인덱싱 초과시 삭제 대상이 되지 않는다.

  • 해당 가상호스트는 자원소거시 초 단위의 LRU(Least Recently Used) 를 보장받는다. (최대 3일)

Warning

이 기능은 핵심 API등 메모리 적재량 및 서비스 시나리오상 충분히 효과가 예측되는 상황에서만 신중히 설정되어야 한다. 과도하게 설정되거나 자칫 너무 큰 데이터가 메모리에 적재되면 이를 보장하느라 Out Of Memory 상황을 초래할 위험이 매우 높다.

indexingLimitCount (기본: 0)

가상호스트당 최대 캐싱개수 제한. 주로 API캐싱 서비스에서 패턴 Purge등이 과도한 경우 개수를 제한하여 성능을 높이기 위한 목적으로 사용된다.

Warning

위의 fixedCount 보다 작을 수 없다.

ttl

캐싱엔진이 콘텐츠를 서비스하는 유효시간/TTL 정책을 구성한다.

{
  "functions": {
    "network": {
      "cache": {
        "ttl": {
          ...
        }
      }
    }
  }
}

resCode

원본 응답코드별로 TTL을 설정한다.

{
  "functions": {
    "network": {
      "cache": {
        "ttl": {
          "resCode": {
            ...
          }
        }
      }
    }
  }
}

res2xx

원본서버가 200 OK로 응답했을 때 TTL을 설정한다. 콘텐츠를 처음 저장할 때 sec 초 뒤에 콘텐츠가 만료(TTL)되도록 설정한다. (TTL만료 후) 원본서버에서 변경되지 않았다면(304 Not Modified) ratio 비율(0~100)만큼 TTL을 연장한다. TTL은 최대 max 까지 증가한다.

"res2xx": {
  "sec": 1800,
  "ratio": 0,
  "max": 0
}
sec (기본: 1800초)

캐싱시간

ratio (기본: 0%)

304 Not Modified 를 받았을 때 TTL 연장비율(0~100)

max (기본: 86400초)

최대 캐싱시간

noCache

res2xx 와 동일하나 원본서버가 no-cache 헤더로 응답하는 경우에만 적용된다.

cache-control: no-cache 또는 private 또는 must-revalidate
cache-control: max-age=0 또는 s-maxage=0

maxAge 값이 0보다 크다면 max-age 헤더의 값을 변경할 수 있다.

../../../../_images/nocache_maxage.png

Max-Age만큼 클라이언트에 Caching된다.

"noCache": {
  "sec": 5,
  "ratio": 0,
  "max": 5,
  "maxAge": 0,
  "expire": false
}
sec (기본: 5초)

캐싱시간

ratio (기본: 0%)

304 Not Modified 를 받았을 때 TTL 연장비율(0~100)

max (기본: 5초)

최대 캐싱시간

maxAge (기본: 0초)

0보다 크다면 해당 값을 max-age 헤더의 값으로 준다.

expire (기본: false)

설정이 true 라면 캐싱 즉시 콘텐츠를 만료시킨다. 동시 발생된 요청에 대해서 일괄 응답되며 이후 만료된 콘텐츠로 처리되기 때문에 항상 갱신 과정을 거친다.

noStore

res2xx 와 동일하나 원본서버가 no-store 헤더로 응답하는 경우에만 적용된다.

"noStore": {
  "sec": 5,
  "ratio": 0,
  "max": 5,
  "maxAge": 0,
  "bypass": false
}
sec (기본: 5초)

캐싱시간

ratio (기본: 0%)

304 Not Modified 를 받았을 때 TTL 연장비율(0~100)

max (기본: 5초)

최대 캐싱시간

maxAge (기본: 0초)

0보다 크다면 해당 값을 max-age 헤더의 값으로 준다.

bypass (기본: false)

설정이 true 라면 콘텐츠는 캐싱되지 않으며, 캐싱 시간동안 클라이언트 요청을 원본서버로 바이패스 시킨다. 다시 말해 “바이패스해야 한다는 상황” sec 시간 동안 캐싱된다.

res3xx

원본서버가 3xx로 응답했을 때 TTL을 설정한다. Redirect용도로 사용되는 경우가 많다.

"res3xx": {
  "sec": 300
}
sec (기본: 300초)

캐싱시간

res4xx

원본서버가 4xx로 응답했을 때 TTL을 설정한다. 404 Not Found 인 경우가 많다.

"res4xx": {
  "sec": 30
}
sec (기본: 30초)

캐싱시간

res5xx

원본서버가 5xx로 응답했을 때 TTL을 설정한다. 원본서버 내부 장애상황인 경우가 많다.

"res5xx": {
  "sec": 30
}
sec (기본: 30초)

캐싱시간

onError

"onError": {
  "connectTimeout": 3,
  "receiveTimeout": 3
}
connectTimeout (기본: 3초)

원본서버로 접속하지 못하는 경우 TTL을 설정한다. 콘텐츠가 이미 저장되어 있다면 connectTimeout 초 만큼 TTL을 연장한다. 콘텐츠가 저장되어 있지 않다면 connectTimeout 초 만큼 장애상황으로 응답한다. 이는 장애상황을 서비스한다는 의미보다는 TTL시간동안 (아마도 장애상황일) 원본서버에 부담을 주지 않기 위함이다.

receiveTimeout (기본: 3초)

접속은 됐으나 데이터를 수신하지 못하는 경우 TTL을 설정한다. connectTimeout 과 의미적 동일하다.

custom

URL마다 별도로 TTL을 설정한다. 명확한 URL 또는 패턴 URL에 매칭되는 콘텐츠마다 고정된 TTL을 설정할 수 있다.

"custom": [
  {
    "pattern": "*.jsp*",
    "sec": 10
  },
  {
    "pattern": "/index.html",
    "sec": 5
  },
  {
    "pattern": "/script/*.js",
    "sec": 300
  },
  {
    "pattern": "/events/*",
    "sec": 86400,
    "schedule": "0 0"
  },
  {
    "pattern": "$URL[/image/ad.jpg] & $ORGSTATUS[4xx]",
    "sec": 10
  }
]
pattern

매칭 패턴

sec

TTL 초

schedule

만료 주기

응답코드에 따라 TTL을 지정할 수 있다. $ORGSTATUS[ ] 표현의 값은 명시적인 원본 응답코드(200, 404) 또는 응답코드 그룹(2xx, 3xx, 4xx, 5xx)으로 설정 가능하다. 결합조건(&)을 지원하며, 부정조건(!)은 지원하지 않는다.

"custom": [
  {
    "pattern": "$URL[/image/ad.jpg]",
    "sec": 1800
  },
  {
    "pattern": "$URL[*.jpg] & $ORGSTATUS[200]",
    "sec": 10
  },
  {
    "pattern": "$URL[*] & $ORGSTATUS[304]",
    "sec": 1000
  }

TTL 만료시간 주기를 지정할 수 있다.

"custom": [
  {
    # 자정(00시 00분)에 TTL을 만료한다.
    "pattern": "/events/*",
    "sec": 86400,
    "schedule": "0 0"
  },
  {
    # 22시 38분에 TTL을 만료한다.
    "pattern": "/foo/bar",
    "sec": 86400,
    "schedule": "38 22"
  },
  {
    # 매 시간마다 TTL을 만료한다.
    "pattern": "/index.html",
    "sec": 86400,
    "schedule": "0 *"
  },
  {
    # 5분마다 TTL을 만료한다.
    "pattern": "/script/*.js",
    "sec": 86400,
    "schedule": "*/5 *"
  },
  {
    # 매 6시간마다 TTL을 만료한다.
    "pattern": "/image/ad.jpg",
    "sec": 86400,
    "schedule": "0 */6"
  }
]

예제의 {TTL} 값이 86400인 이유는 TTL을 설정할 때 {TTL}{minute hour} 중 작은 값을 선택하기 때문이다.

/api/v1/*, 30
/api/v2/*, 30, * *

예를 들어 위 설정의 경우 요청(=캐싱)시간을 기준으로 만료시간이 작은 값을 기준으로 설정된다.

패턴

요청시간

만료시간

/api/v1/*

1:15:10

1:15:40

/api/v1/*

1:15:40

1:16:10

/api/v2/*

1:15:10

1:15:40

/api/v2/*

1:15:40

1:16:00

Note

설정을 변경해도 이미 캐싱된 객체의 TTL이 변경되지는 않는다. TTL은 객체가 초기화(=캐싱) 되는 시점에 고정되기 때문이다.

policies

캐싱 기본동작 및 우선순위를 구성한다.

"policies": {
  "priority": [ "cc_nocache", "custom", "cc_maxage", "rescode", "cc_nostore", "cc_smaxage", "hook" ],
  "extendBy4xx": false,
  "extendBy5xx": true,
  "extendByFail": true,
  "unvalidatableObjectResCode": 0,
  "baseTime": "response"
}
priority (기본: cc_nocache, custom, cc_maxage, rescode, cc_nostore, cc_smaxage, hook)

TTL 적용 우선순위

  • cc_nocache - 원본응답을 noCache 로 판정한 경우

  • custom - 커스텀 TTL

  • cc_maxage - 원본이 Cache-Control 헤더에 maxage 를 명시한 경우

  • rescode - 원본 응답코드별 기본 TTL

  • cc_nostore - 원본이 Cache-Control: no-store 로 응답한 경우

  • cc_smaxage - 원본이 Cache-Control 헤더에 s-maxage 를 명시한 경우

  • hook - 요청 재정의 .cacheTtl 필드가 정의된 경우

extendBy4xx (기본: false)

true 라면 객체 갱신시점에 4xx 응답을 받더라도 304 not modified 를 받은 것처럼 동작한다.

extendBy5xx (기본: true)

true 라면 객체 갱신시점에 5xx 응답을 받더라도 304 not modified 를 받은 것처럼 동작한다.

extendByFail (기본: true)

true 라면 객체 갱신시점에 원본통신이 실패하더라도 304 not modified 를 받은 것처럼 동작한다. false 인 경우 캐싱 오류 메시지가 서비스된다.

unvalidatableObjectResCode (기본: 0)

콘텐츠의 TTL은 만료되었지만 원본서버가 모두 배제되어 정상적으로 콘텐츠를 갱신(Revalidate)할 수 없을 때의 정책을 설정한다.

  • 0 - 만료된 콘텐츠의 TTL을 ttl.rescode.onError.connectTimeout 만큼 연장한다.

  • HTTP 응답코드 - 갱신할 수 없다면 설정된 응답코드로 응답한다.

baseTime (기본: response)

TTL을 결정하는 기준 시점을 설정한다.

  • response (기본) - 원본으로부터 응답을 받은 시점에 TTL을 계산한다.

  • request - 원본으로 요청을 보내는 시점에 TTL을 계산한다.

cachingKey

{
  "functions": {
    "network": {
      "cache": {
        "cachingKey": {
          ...
        }
      }
    }
  }
}

case

대소문자를 구분하여 캐싱키에 반영한다.

"case": {
  "enable": true
}
enable (기본: true)

대소문자 구분

  • true (기본) - URL 대소문자를 구분한다.

  • false - URL 대소문자를 구분하지 않는다. 모두 소문자로 처리된다.

queryString

HTTP 쿼리스트링을 캐싱키에 반영한다.

"queryString": {
  "enable": true
}
enable (기본: true)

쿼리스트링 구분

  • true (기본) - QueryString을 인식한다. 예외조건을 만족하면 QueryString이 무시된다.

  • false - QueryString을 무시한다. 예외조건을 만족하면 QueryString을 인식한다.

QueryString 예외조건은 matchingList 에 설정한다.

"queryString": {
  "enable": true,
  "matchingList": [
    {
      "pattern": "/private/personal.jsp?login=ok*"
    },
    {
      "pattern": "/image/ad.jpg"
    }
  ]
}

예외조건은 "enable" 설정에 따라 의미가 달라지는데, "enable": true 인 경우 matchingList 는 쿼리스트링 무시 리스트가 되며, "enable": false 인 경우 쿼리스트링 인식 리스트가 된다. 명확한 URL또는 패턴( * 만 허용한다)으로 설정이 가능하다.

matchingList

매칭리스트

pattern

매칭 패턴

acceptEncoding

Accept-Encoding 헤더를 캐싱키에 반영한다.

"acceptEncoding": {
  "enable": true
}
enable

헤더 캐싱키 반영

  • true (기본) - HTTP 클라이언트가 보내는 Accept-Encoding 헤더를 인식한다.

  • false - HTTP 클라이언트가 보내는 Accept-Encoding 헤더를 무시한다.

원본서버에서 압축을 지원하지 않거나, 압축이 필요없는 대용량 파일의 경우 "enable": false 로 설정하는 것이 바람직하다.

postMethod

POST 요청을 캐싱하도록 설정한다. POST 요청의 특성상 URL은 같지만 Body데이터가 다를 수 있다.

"postMethod": {
  "enable": false,
  "bodySensitive": true,
  "bodyContentLengthMax": 102400
}
enable (기본: false)

POST 요청캐싱

  • false (기본) - POST요청이 오면 세션을 종료한다.

  • true - POST요청을 Caching한다.

실제로 POST요청을 처리하는 대부분의 경우는 Body데이터를 캐싱키로 사용한다. bodySensitive 속성과 예외조건을 통해 정교한 설정이 가능하다.

bodySensitive (기본: true)

Body데이터까지 캐싱키로 인식한다.

  • true (기본) - Body데이터까지 Caching-Key로 인식한다. 최대 길이는 bodyContentLengthMax 속성으로 제한한다. 예외조건에 만족하면 Body데이터를 무시한다.

  • false - Body데이터는 무시한다. 예외조건에 만족하면 Body데이터를 인식한다.

bodyContentLengthMax (기본: 102400bytes)

인식할 최대 Body데이터 길이제한

POST요청 예외조건은 matchingList 에 설정한다.

"postMethod": {
  "enable": true,
  "bodySensitive": true,
  "bodyContentLengthMax": 102400,
  "matchingList": [
    {
      "pattern": "/bigsale/*.php?nocache=*"
    },
    {
      "pattern": "/goods/search.php"
    }
  ]
}

예외조건이 bodySensitive 설정에 따라 의미가 달라짐에 주의한다. 명확한 URL 또는 패턴( * 만 허용한다.)으로 설정이 가능하다.

이 설정은 아래 postMethod 와 정책적으로 혼란스러울 수 있다.

{
  "functions": {
    "network": {
      "http": {
        "frontEnd": {
          "bypass": {
            "postMethod": {
              "enable": true,
            }
          }
        }
      }
    }
  }
}

위 설정에 POST요청이 캐싱되지 않을 수 있다. 따라서 POST요청을 캐싱하기 위해서는 위 설정을 "enable": false 로 수정하거나 또는 matchingList 를 설정해야 한다. 정리하면 우선순위는 다음과 같다.

  • 바이패스 조건( postMethod )에 만족할 경우 원본서버로 바이패스 한다.

  • Content-Length 헤더가 없다면 연결을 종료한다.

  • functions.networks.cache.cachingKey.postRequest.enabletrue 로 설정되어 있고 Content-Length 헤더 값이 bodyContentLengthMax 설정 값을 넘지 않는다면 캐싱엔진에 의해 처리된다.

  • 이상의 시나리오에서 처리되지 않은 요청은 종료한다.

Note

bodyContentLengthMax 속성을 너무 크게 설정할 경우 Caching-Key 관리에 많은 메모리가 필요하다. 가능한 작게 설정하는 것이 좋다.

matchingList

매칭리스트

pattern

매칭 패턴

vary

Vary헤더를 인식하여 콘텐츠를 구분한다. 일반적으로 Vary헤더는 캐싱효율을 크게 저하시킨다.

"vary": {
  "enable": false,
  "headers": [ ]
}
enable (기본: false)

vary 헤더 캐싱키 반영

headers

원본서버가 응답한 Vary헤더 중 지원할 헤더목록을 설정한다. 구분자는 콤마(,)를 사용한다.

예를 들어 원본서버가 다음과 같이 Vary헤더를 보냈다고 하더라도 "enable": false 라면 무시한다.

Vary: Accept-Encoding, Accept, User-Agent

User-Agent 를 제외한 Accept-EncodingAccept 헤더만을 인식하도록 하려면 다음과 같이 설정한다.

"vary": {
  "enable": true,
  "headers": [ "Accept-Encoding", "Accept" ]
}

원본서버가 보낸 모든 Vary 헤더를 인식하게 하려면 다음과 같이 설정한다.

"vary": {
  "enable": true,
  "headers": [ "*" ]
}

purge

"purge": {
  "mode": "sync",
  "noCacheRequestExpire": false,
  "refreshExpired": true,
  "purge2Expire": "none",
  "rootPurgeExpire": "all",
  "rootHardPurge": true,
  "resCodeNoCtrlTarget": 200,
  "resCodeDenyCtrlTarget": 200,
  "queryStringCollective": false
}

mode (기본: sync)

  • sync (기본) Purge계열 API가 동기로 동작한다.

  • async Purge계열 API가 비동기로 동작한다.

noCacheRequestExpire (기본: false)

클라이언트 HTTP요청에 no-cache 설정이 하나 이상 명시된 경우 해당 콘텐츠를 즉시 만료시킬 수 있다.

refreshExpired (기본: true)

변경확인 후 응답한다. false 라면 변경확인 응답을 기다리지 않고 응답한다. 새로운 콘텐츠의 다운로드가 완료되면 그때 콘텐츠를 교체한다.

purge2Expire (기본: "none)

Purge 요청을 설정에 따라 Expire 로 처리한다. 예를 들어 특정 패턴 *.jpg 를 Purge 하는 경우 의도하지 않게 많은 컨텐츠가 삭제되어 원본에 과도한 부하를 발생시킬 수 있다. 이런 경우 Expire 로 처리하도록 설정하면 과도한 원본부하를 방지할 수 있다.

  • NONE - Expire 로 처리하지 않는다.

  • ROOT - 도메인 전체 /* 에 대한 Purge 를 Expire 로 처리한다.

  • PATTERN - 모든 패턴 Purge 를 Expire 로 처리한다.

  • ALL - 모든 Purge 를 Expire 로 처리한다.

rootPurgeExpire (기본: all)

전체 콘텐츠에 대한 의도하지 않은 Purge / Expire 는 과도한 원본서버 부하를 발생시킬 수 있다. 이 설정을 통하여 전체 콘텐츠에 대한 Purge / Expire 를 차단할 수 있다. 이 설정은 purge2Expire 보다 우선한다.

  • all Purge / Expire 를 허용한다.

  • purge Purge 만 허용한다.

  • expire Expire 만 허용한다.

  • none 모든 Purge / Expire 를 금지한다.

rootHardPurge (기본: true)

전체 콘텐츠( /* ) 에 대한 HardPurge 는 모든 캐싱을 삭제하기 때문에 매우 위험하다.

  • true 전체 콘텐츠의 HardPurge 를 허용한다.

  • false 전체 콘텐츠의 HardPurge 를 금지한다.

resCodeNoCtrlTarget (기본: 200)

Purge등의 명령어 대상객체가 없을 때의 HTTP 응답코드를 설정한다.

resCodeDenyCtrlTarget (기본: 200)

rootPurgeExpire , rootHardPurge 설정에 의해서 API 호출이 거부 될 경우 설정된 응답코드로 응답 한다.

queryStringCollective (기본: false)

Purge API가 호출되었을 대상을 지정한다.

  • false - 입력된 URL만을 대상으로 지정한다.

  • true - 파라미터 URL뿐만 아니라 URL에 QueryString이 존재하는 모든 컨텐츠를 대상으로 지정한다.

phantom

PHANTOM 객체는 (데이터 없이) HTTP 메타정보만 캐싱된 객체를 의미한다. 메모리 소거시점에 생성된다.

"phantom": {
  "enable": false
}
enable (기본: false)

메모리 모드에서 캐싱된 콘텐츠가 소거될 때 해당 객체를 초기화할지 PHANTOM 객체로 유지할지 설정한다.

  • false(기본) 캐싱된 콘텐츠가 소거될 때 객체를 초기화하여 재캐싱을 유도한다.

  • true 캐싱된 콘텐츠가 소거될 때 객체 메타정보를 유지시켜 재캐싱 없이 304 Not Modified 를 처리할 수 있도록 구성한다.