

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 캐시 읽기 동작
<a name="cache-read"></a>

심은 DynamoDB에 대한 최종적으로 일관된 읽기 호출만 캐싱해야 합니다. 여기에 `get_item`, `batch_get_item`, `query` 및 `scan`도 추가되었습니다. 강력히 일관된 읽기 호출 또는 트랜잭션 읽기 호출을 캐싱해서는 안 됩니다. 이러한 호출은 본질적으로 캐시된 버전의 데이터를 보고 싶지 않기 때문입니다.

캐시 항목은 후속 요청과 동등한 요청을 식별하기 위해 요청의 서명을 이해해야 합니다. 각 호출의 서명은 결과에 영향을 미치는 요청의 모든 파라미터로 구성됩니다. `get_item` 호출의 경우 서명에는 , `TableName`, `Key` `ProjectionExpression`및 `ExpressionAttributeNames` 파라미터가 포함됩니다. 쿼리 호출의 경우 , `TableName`, `IndexName`, `KeyConditions``FilterExpression`, `ScanIndexForward`및 `Limit` 파라미터가 포함됩니다. 동일한 함수에 대한 두 호출의 서명이 동일한 경우 캐시 적중 가능성이 있습니다.

다음은 `get_item` 호출에 대한 샘플 로직 흐름입니다.
+ 인 경우 확인합니다`ConsistentRead=true`. 그렇다면 데이터베이스를 직접 호출하고 결과를 반환합니다. 매우 일관된 호출은 캐시를 사용해서는 안 됩니다.
+ 호출의 서명을 계산합니다. `TableName`, `Key``ProjectionExpression`, 및 `ExpressionAttributeNames` 파라미터를 해시하여 단일 문자열 서명 값을 가져옵니다.
+ 이 서명 키가 있는 캐시 항목이 있는지 확인합니다. 그렇다면 캐시 적중이므로 반환합니다.
+ 그렇지 않은 경우 호출을 데이터베이스에 전달하고, 결과를 검색하고,이 서명의 캐시 항목을 채우고, 결과를 반환합니다. 항목을 저장할 때 TTL(Time to Live) 만료 시간을 지정합니다.

예를 들어이 코드가 있다고 가정합니다.

```
cache_client.get_item(
  TableName='test',
  Key={ 'PK': { 'S': '123' } },
  ProjectionExpression='#attr1, #attr2',
  ExpressionAttributeNames={
    '#attr1': 'agent',
    '#attr2': 'count'
  },
  ConsistentRead=False
)
```

내부에서 `cache_client`코드는 호출의 해시 서명을 계산합니다. 서명은 `TableName`, `Key`, `ProjectionExpression`및 `ExpressionAttributeNames` 파라미터의 연결을 해싱하여 파생됩니다. 결정적이고 단일 문자열 값을 생성하는 한 모든 해시 시스템을 사용할 수 있습니다. 이 경우 로 해시한다고 가정해 보겠습니다`0xad4c812a`. 이 해시는이 파라미터 세트를 식별합니다.

이름이 변경된를 제외하고 동일한 다른 호출`#attr1`이 수행되면 어떻게 되나요`#attribute1`? 해당 호출의 서명이 동일한 것으로 간주해야 합니까? 의미상 동일하지만 모든 호출에서 의미론적 동등성을 파악하는 데 드는 오버헤드는 실용적이지 않기 때문에 가장 좋습니다. 파라미터 값을 시각적으로 해시하는 것이 훨씬 빠르며 정확한 일치가 필요합니다. 규칙은 호출이 *실제로* 동일한 호출인 경우 캐시 적중을 받을 수 있지만 *기본적으로* 동일한 호출인 경우에는 그렇지 않습니다.

내부에서 `cache_client`코드는 ElastiCache에서 아래에 저장된 항목 캐시의 항목을 찾습니다`0xad4c812a`. 항목이 있는 경우 캐시 적중입니다. 그렇지 않은 경우 값은 데이터베이스에서 가져오고 나중에 캐시 적중을 위해 ElastiCache에 저장됩니다.

다음은 세 가지 테이블, 키 및 프로젝션 파라미터 세트가 있는 세 가지 `get_item` 호출에 대한 캐시의 모습입니다.


| 의사 코드 | ElastiCache 키 계산 | ElastiCache 값 | 
| --- | --- | --- | 
| `get_item(t1, k1, p1)` | `hash('get', t1, k1, p1) = 0xad4c812a` | `{ 'Item': … }` | 
| `get_item(t1, k1, p2)` | `hash('get', t1, k2, p2) = 0x045deaab` | `{ 'Item': … }` | 
| `get_item(t1, k2, p1)` | `hash('get', t1, k2, p1) = 0x9cda78af` | `{ 'Item': … }` | 

`query` 및와 같은 다른 호출은 동일한 방식으로 `scan`작동하지만 다른 파라미터가 서명을 구성합니다.

이 설계는 HTTP 캐싱 프록시의 작동 방식을 상기시킬 수 있습니다. 동일한 요청이 다시 표시되면 이전 요청의 응답을 반환할 수 있습니다. HTTP에서 *동일한 요청*의 정의는 대부분 쿼리 문자열을 기반으로 합니다. DynamoDB를 사용하면 함수에 전달되는 호출 유형과 파라미터 세트가 결과에 영향을 미칩니다.

한 단계가 더 있습니다. 항목 캐싱은 각 항목의 기본 키와 해당 항목을 캐싱하는 데 적극적으로 사용되는 해시 목록 간의 매핑을 유지하는 것이 중요합니다. 이는 다음 섹션에 설명된 대로 쓰기 작업 중에 재생됩니다. 따라서 이전 키 및 값 외에도 다음과 같은 추가 캐시 항목이 있습니다.


| Operation | ElastiCache 키 계산  | ElastiCache 값 | 
| --- | --- | --- | 
| 테이블 `t1`, 키에 대한 항목 목록 추적 `k1` | `hash('list', t1, k1)` | ( `0xad4c812a, 0x045deaab` ) | 
| 테이블 `t1`, 키에 대한 항목 목록 추적 `k2` | `hash('list', t1, k2) ` | ( `0x9cda78af` ) | 