키-값 쌍 읽기
Workers KV에서 키-값 쌍을 읽는 get() 및 getWithMetadata() 메서드 사용법을 알아봐요. 단일 키와 여러 키 읽기, 타입 매개변수, cacheTtl, 그리고 성능 최적화 기법까지 함께 살펴봐요.
출처: 문서
본문
주어진 키에 대한 값을 얻으려면 Worker 코드에 바인딩한 아무 KV 네임스페이스에서 KV 바인딩의 get() 메서드를 호출하면 돼요:
// Read individual key
env.NAMESPACE.get(key);
// Read multiple keys
env.NAMESPACE.get(keys);
# Read individual key
self.env.NAMESPACE.get(key)
# Read multiple keys
self.env.NAMESPACE.get(keys)
get() 메서드는 값을 얻기 위해 await 할 수 있는 promise를 반환해요.
단일 키를 문자열로 요청하면 promise에서 단일 응답을 얻게 돼요. 키를 찾을 수 없으면 promise는 리터럴 값 null 로 resolve돼요.
키 배열을 요청할 수도 있어요. 반환 값은 찾은 키-값 쌍들의 Map 이며, 찾지 못한 키는 null 값을 가져요.
export default {
async fetch(request, env, ctx) {
try {
// Read single key, returns value or null
const value = await env.NAMESPACE.get("first-key");
// Read multiple keys, returns Map of values
const values = await env.NAMESPACE.get(["first-key", "second-key"]);
// Read single key with metadata, returns value or null
const valueWithMetadata = await env.NAMESPACE.getWithMetadata("first-key");
// Read multiple keys with metadata, returns Map of values
const valuesWithMetadata = await env.NAMESPACE.getWithMetadata(["first-key", "second-key"]);
return new Response({
value: value,
values: Object.fromEntries(values),
valueWithMetadata: valueWithMetadata,
valuesWithMetadata: Object.fromEntries(valuesWithMetadata)
});
} catch (e) {
return new Response(e.message, { status: 500 });
}
},
};
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
try:
# Read single key, returns value or None
value = await self.env.NAMESPACE.get("first-key")
# Read multiple keys, returns dict of values
values = await self.env.NAMESPACE.get(["first-key", "second-key"])
# Read single key with metadata
value_with_metadata = await self.env.NAMESPACE.getWithMetadata("first-key")
# Read multiple keys with metadata
values_with_metadata = await self.env.NAMESPACE.getWithMetadata(["first-key", "second-key"])
return Response.json({
"value": value,
"values": values,
"valueWithMetadata": value_with_metadata,
"valuesWithMetadata": values_with_metadata,
})
except Exception as e:
return Response(str(e), status=500)
get() 및 getWithMetadata() 메서드는 오래된(stale) 값을 반환할 수 있어요. 주어진 키가 특정 위치에서 최근에 읽혔다면, 다른 위치에서 이루어진 키의 쓰기나 업데이트가 표시되기까지 최대 60초 (또는 cacheTtl 의 지속 시간)가 걸릴 수 있어요.
참조
KV에서 읽기 위해 제공되는 메서드는 다음과 같아요:
get() 메서드
get() 메서드를 사용해 단일 값, 또는 여러 키가 주어지면 여러 값을 얻어요:
- get(key: string) 로 단일 키 읽기
- get(keys: string[]) 로 여러 키 읽기
get(key: string) 으로 단일 키 요청하기
단일 키에 대한 값을 얻으려면 Worker 코드에 바인딩한 아무 KV 네임스페이스에서 get() 메서드를 다음과 같이 호출하면 돼요:
env.NAMESPACE.get(key, type?);
// OR
env.NAMESPACE.get(key, options?);
self.env.NAMESPACE.get(key, type)
# OR
self.env.NAMESPACE.get(key, options)
매개변수 (Parameters)
key:string- KV 쌍의 키예요.
type:"text" | "json" | "arrayBuffer" | "stream"- 선택 사항. 반환될 값의 타입이에요.
text가 기본값이에요.
- 선택 사항. 반환될 값의 타입이에요.
options:{ cacheTtl?: number, type?: "text" | "json" | "arrayBuffer" | "stream" }- 선택 사항. 선택적인
cacheTtl및type속성을 포함하는 객체예요.cacheTtl속성은 KV 결과가 접근되는 글로벌 네트워크 위치에 캐시되는 시간(초)을 정의해요 (최소 30).type속성은 반환될 값의 타입을 정의해요.
- 선택 사항. 선택적인
응답 (Response)
response:Promise<string | Object | ArrayBuffer | ReadableStream | null>- 요청된 KV 쌍의 값이에요. 응답 타입은
get()명령에 제공된type매개변수에 따라 다음과 같이 달라져요: text:string(기본값).json: JSON 문자열에서 디코딩된 객체.arrayBuffer:ArrayBuffer↗︎ 인스턴스.stream:ReadableStream↗︎.
- 요청된 KV 쌍의 값이에요. 응답 타입은
get(keys: string[]) 으로 여러 키 요청하기
여러 키에 대한 값을 얻으려면 Worker 코드에 바인딩한 아무 KV 네임스페이스에서 get() 메서드를 다음과 같이 호출하면 돼요:
env.NAMESPACE.get(keys, type?);
// OR
env.NAMESPACE.get(keys, options?);
self.env.NAMESPACE.get(keys, type)
# OR
self.env.NAMESPACE.get(keys, options)
매개변수 (Parameters)
keys:string[]- KV 쌍들의 키예요. 최대: 100개 키.
type:"text" | "json"- 선택 사항. 반환될 값의 타입이에요.
text가 기본값이에요.
- 선택 사항. 반환될 값의 타입이에요.
options:{ cacheTtl?: number, type?: "text" | "json" }- 선택 사항. 선택적인
cacheTtl및type속성을 포함하는 객체예요.cacheTtl속성은 KV 결과가 접근되는 글로벌 네트워크 위치에 캐시되는 시간(초)을 정의해요 (최소 30).type속성은 반환될 값의 타입을 정의해요.
- 선택 사항. 선택적인
여러 키를 읽는 .get() 함수는 arrayBuffer 나 stream 반환 타입을 지원하지 않아요. arrayBuffer 나 stream 타입의 여러 키를 읽어야 한다면, Promise.all() 로 개별 키를 병렬로 읽는 .get() 함수를 사용하는 것을 고려해 보세요.
응답 (Response)
response:Promise<Map<string, string | Object | null>>- 요청된 KV 쌍의 값이에요. 키를 찾을 수 없으면 해당 키에 대해
null이 반환돼요. 응답 타입은get()명령에 제공된type매개변수에 따라 다음과 같이 달라져요:text:string(기본값).json: JSON 문자열에서 디코딩된 객체.
- 요청된 KV 쌍의 값이에요. 키를 찾을 수 없으면 해당 키에 대해
응답 크기의 제한은 25MB예요. 이 크기를 초과하는 응답은 413 Error 오류 메시지와 함께 실패해요.
getWithMetadata() 메서드
getWithMetadata() 메서드를 사용해 단일 값과 함께 그 메타데이터를, 또는 여러 값과 함께 그 메타데이터를 얻어요:
- getWithMetadata(key: string) 로 단일 키 읽기
- getWithMetadata(keys: string[]) 로 여러 키 읽기
getWithMetadata(key: string) 으로 단일 키 요청하기
주어진 키에 대한 값과 함께 그 메타데이터를 얻으려면 Worker 코드에 바인딩한 아무 KV 네임스페이스에서 getWithMetadata() 메서드를 호출하면 돼요:
env.NAMESPACE.getWithMetadata(key, type?);
// OR
env.NAMESPACE.getWithMetadata(key, options?);
self.env.NAMESPACE.getWithMetadata(key, type)
# OR
self.env.NAMESPACE.getWithMetadata(key, options)
메타데이터는 각 KV 항목에 추가하는 직렬화 가능한 값이에요.
매개변수 (Parameters)
key:string- KV 쌍의 키예요.
type:"text" | "json" | "arrayBuffer" | "stream"- 선택 사항. 반환될 값의 타입이에요.
text가 기본값이에요.
- 선택 사항. 반환될 값의 타입이에요.
options:{ cacheTtl?: number, type?: "text" | "json" | "arrayBuffer" | "stream" }- 선택 사항. 선택적인
cacheTtl및type속성을 포함하는 객체예요.cacheTtl속성은 KV 결과가 접근되는 글로벌 네트워크 위치에 캐시되는 시간(초)을 정의해요 (최소 30).type속성은 반환될 값의 타입을 정의해요.
- 선택 사항. 선택적인
응답 (Response)
response:Promise<{ value: string | Object | ArrayBuffer | ReadableStream | null, metadata: string | null }>- 요청된 KV 쌍에 대한 값과 메타데이터를 포함하는 객체예요.
value속성의 타입은getWithMetadata()명령에 제공된type매개변수에 따라 다음과 같이 달라져요:text:string(기본값).json: JSON 문자열에서 디코딩된 객체.arrayBuffer:ArrayBuffer↗︎ 인스턴스.stream:ReadableStream↗︎.
- 요청된 KV 쌍에 대한 값과 메타데이터를 포함하는 객체예요.
요청된 키-값 쌍과 연관된 메타데이터가 없으면 메타데이터에 대해 null 이 반환돼요.
getWithMetadata(keys: string[]) 으로 여러 키 요청하기
주어진 키 집합에 대한 값과 함께 그 메타데이터를 얻으려면 Worker 코드에 바인딩한 아무 KV 네임스페이스에서 getWithMetadata() 메서드를 다음과 같이 호출하면 돼요:
env.NAMESPACE.getWithMetadata(keys, type?);
// OR
env.NAMESPACE.getWithMetadata(keys, options?);
self.env.NAMESPACE.getWithMetadata(keys, type)
# OR
self.env.NAMESPACE.getWithMetadata(keys, options)
매개변수 (Parameters)
keys:string[]- KV 쌍들의 키예요. 최대: 100개 키.
type:"text" | "json"- 선택 사항. 반환될 값의 타입이에요.
text가 기본값이에요.
- 선택 사항. 반환될 값의 타입이에요.
options:{ cacheTtl?: number, type?: "text" | "json" }- 선택 사항. 선택적인
cacheTtl및type속성을 포함하는 객체예요.cacheTtl속성은 KV 결과가 접근되는 글로벌 네트워크 위치에 캐시되는 시간(초)을 정의해요 (최소 30).type속성은 반환될 값의 타입을 정의해요.
- 선택 사항. 선택적인
여러 키를 읽는 .get() 함수는 arrayBuffer 나 stream 반환 타입을 지원하지 않아요. arrayBuffer 나 stream 타입의 여러 키를 읽어야 한다면, Promise.all() 로 개별 키를 병렬로 읽는 .get() 함수를 사용하는 것을 고려해 보세요.
응답 (Response)
response:Promise<Map<string, { value: string | Object | null, metadata: string | Object | null }>- 요청된 KV 쌍에 대한 값과 메타데이터를 포함하는 객체예요.
value속성의 타입은getWithMetadata()명령에 제공된type매개변수에 따라 다음과 같이 달라져요:text:string(기본값).json: JSON 문자열에서 디코딩된 객체.
- 메타데이터의 타입은 저장된 내용에 따라 달라지며, 문자열 또는 객체일 수 있어요.
- 요청된 KV 쌍에 대한 값과 메타데이터를 포함하는 객체예요.
요청된 키-값 쌍과 연관된 메타데이터가 없으면 메타데이터에 대해 null 이 반환돼요.
응답 크기의 제한은 25MB예요. 이 크기를 초과하는 응답은 413 Error 오류 메시지와 함께 실패해요.
가이드
타입 매개변수
단순한 값에는 기본 text 타입을 사용해서 값을 string 으로 얻을 수 있어요. 편의를 위해 json 타입도 지정할 수 있는데, 이는 JSON 값을 객체로 변환한 뒤 객체를 반환해요. 큰 값에는 stream 을 사용해 ReadableStream 을 요청해요. 이진 값에는 arrayBuffer 를 사용해 ArrayBuffer 를 요청해요.
큰 값의 경우 type 선택은 지연 시간과 CPU 사용량에 눈에 띄는 영향을 줄 수 있어요. 참고로 type 은 빠른 것부터 느린 것 순으로 stream, arrayBuffer, text, json 으로 정렬할 수 있어요.
CacheTtl 매개변수
cacheTtl 은 KV 결과가 접근되는 글로벌 네트워크 위치에 캐시되는 시간(초)을 정의하는 매개변수예요.
상대적으로 드물게 읽히는 키에서 콜드 읽기 지연을 줄이는 데 초(sec) 단위로 시간을 정의하는 것이 유용해요. cacheTtl 은 데이터가 한 번 쓰거나 드물게 쓰는 경우 유용해요.
핫(hot) 읽기와 콜드(cold) 읽기 — 핫 읽기는 데이터가 CDN ↗︎을 사용해 Cloudflare 에지 네트워크에 캐시된다는 뜻이에요 (로컬 캐시든 리전 캐시든). 콜드 읽기는 데이터가 캐시되지 않아 중앙 저장소에서 가져와야 한다는 뜻이에요. 존재하는 키-값 쌍과 존재하지 않는 키-값 쌍 (네거티브 조회라고도 함) 모두 에지에서 캐시돼요.
데이터가 자주 업데이트되고 쓰인 직후에 업데이트가 보이길 원한다면 cacheTtl 은 권장하지 않아요. 다른 글로벌 네트워크 위치에서 발생한 쓰기는 캐시된 값이 만료될 때까지 보이지 않기 때문이에요.
cacheTtl 매개변수는 30 이상의 정수여야 해요. 기본값은 60 이에요. cacheTtl 의 최대값은 Number.MAX_SAFE_INTEGER ↗︎ 예요.
키가 특정 리전에서 특정 cacheTtl 로 읽히면, 해당 리전에서 cacheTtl 이 끝나거나 축출될 때까지 캐시된 상태로 남아요. 이는 KV 내장 캐시 계층의 리전 및 중앙 계층에 영향을 줘요. Workers KV에 쓸 때, KV 내부의 리전 및 중앙 캐시 계층에 있는 리전은 새로 쓰여진 결과로 재검증돼요.
벌크 요청으로 Worker 호출당 더 많은 키 요청하기
Workers는 호출당 외부 서비스에 대한 작업이 1,000개로 제한돼요. 이는 Workers KV 제한에 문서화된 대로 Workers KV에도 적용돼요.
작업당 1,000개가 넘는 키를 읽으려면 벌크 읽기 작업을 사용해 단일 작업에서 여러 키를 읽을 수 있어요. 이는 1,000개 작업 제한에 대해 단일 작업으로 계산돼요.
키 병합(coalescing)으로 카디널리티 줄이기
혼합 사용 패턴 (일부 핫 키와 일부 콜드 키) 을 가진 관련 키-값 쌍 집합이 있다면, 병합(coalescing)을 고려해 보세요. 콜드 키를 핫 키와 병합하면, 콜드 키가 핫 키와 함께 캐시되어 개별 키로 캐시되지 않은 경우보다 더 빠른 읽기를 제공할 수 있어요.
"슈퍼(super)" KV 항목으로 병합하기
한 가지 병합 기법은 모든 키와 값을 하나의 슈퍼 키-값 객체의 일부로 만드는 거예요. 예시는 아래와 같아요.
key1: value1
key2: value2
key3: value3
이것이 이렇게 됩니다
coalesced: {
key1: value1,
key2: value2,
key3: value3,
}
값을 병합하면 콜드 키는 더 따뜻한 키들의 접근 패턴 덕분에 캐시에서 따뜻하게 유지되는 이점을 얻어요.
이 방식은 값을 서로 독립적으로 업데이트할 필요가 없을 때 가장 잘 동작해요. 독립 업데이트는 경합 조건(race condition)을 유발할 수 있어요.
- 장점: 자주 접근하지 않는 키가 캐시에 유지돼요.
- 단점: 결과 값의 크기가 Worker를 메모리 한계 밖으로 밀어낼 수 있어요. 값을 안전하게 업데이트하려면 어떤 종류의 잠금 메커니즘이 필요해요.
KV에 접근하는 다른 방법
또한 명령줄에서 Wrangler로 키-값 쌍을 읽고 REST API로 읽을 수 있어요.
더 알아보기 (Learn more)
읽기 성능과 최적화에 대한 더 깊은 이해는 KV 작동 방식 문서를 참고하세요. 쓰기와 메타데이터 사용법은 쓰기 문서에서 확인할 수 있어요.