

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 快取讀取行為
<a name="cache-read"></a>

該 shim 應僅快取對 DynamoDB 所做的最終一致讀取呼叫。其中包括 `get_item`、`batch_get_item`、`query` 和 `scan`。它不應快取強式一致性讀取呼叫或交易讀取呼叫，因為這些呼叫本質上不希望看到資料的快取版本。

快取項目必須了解請求的簽章，才能識別後續的同等請求。每個呼叫的簽章都包含影響結果的請求的所有參數。對於 `get_item`呼叫，簽章包含 `TableName`、`ProjectionExpression`、 `Key`和 `ExpressionAttributeNames` 參數。對於查詢呼叫，它包含 `TableName`、`IndexName`、`KeyConditions`、`FilterExpression`、 `ScanIndexForward`和 `Limit` 參數。如果對相同函數的兩個呼叫具有相同的簽章，則可能是快取命中。

以下是`get_item`呼叫的範例邏輯流程：
+ 檢查 是否 `ConsistentRead=true`。如果是這樣，請直接呼叫資料庫並傳回結果。高度一致的呼叫不應使用快取。
+ 計算呼叫的簽章。將 `TableName`、`ProjectionExpression`、 `Key`和 `ExpressionAttributeNames` 參數雜湊在一起，以取得單一字串簽章值。
+ 查看此簽章金鑰是否存在快取項目。如果是，則為快取命中，因此請傳回它。
+ 如果沒有，請將呼叫傳遞給資料庫、擷取結果、填入此簽章的快取項目，然後傳回結果。當您存放項目時，請指定存留時間 (TTL) 到期時間。

例如，假設您有此程式碼：

```
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，傳遞給函數的呼叫類型和參數集會影響其結果。

還有一個步驟。項目快取必須保留每個項目主索引鍵與用來快取該項目的雜湊清單之間的映射。這將在寫入操作期間發揮作用，如下一節所述。因此，除了先前的金鑰和值之外，還會有額外的快取項目，例如：


| 作業 | ElastiCache 金鑰計算  | ElastiCache 值 | 
| --- | --- | --- | 
| 資料表 的追蹤項目清單`t1`，索引鍵 `k1` | `hash('list', t1, k1)` | ( `0xad4c812a, 0x045deaab` ) | 
| 資料表 的追蹤項目清單`t1`，索引鍵 `k2` | `hash('list', t1, k2) ` | ( `0x9cda78af` ) | 