在 Amazon Neptune Gremlin 中快取查詢結果 - Amazon Neptune

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

在 Amazon Neptune Gremlin 中快取查詢結果

引擎 1.0.5.1 版開始,Amazon Neptune 支援 Gremlin 查詢的結果快取。

您可以啟用查詢結果快取,然後使用查詢提示來快取 Gremlin 唯讀查詢的結果。

然後,只要快取的結果仍在快取中,重新執行查詢就會擷取這些結果,延遲低且沒有 I/O 成本。這適用於在HTTP端點上提交和使用 Websockets 的查詢,無論是作為字節碼或字符串形式。

注意

即使啟用查詢快取,也不會快取傳送至設定檔端點的查詢。

您可以透過數種方式控制 Neptune 查詢結果快取的行為。例如:

  • 您可以透過區塊取得分頁的快取結果。

  • 您可以為指定的查詢指定 time-to-live (TTL)。

  • 您可以清除所指定查詢的快取。

  • 您可以清除整個快取。

  • 您可以設定,若結果超過快取大小,則會收到通知。

快取是使用 least-recently-used (LRU) 政策來維護,這表示一旦分配給快取的空間已滿, least-recently-used 結果會在快取新結果時移除以騰出空間。

重要

t3.mediumt4.medium 執行個體類型上無法使用查詢結果快取。

在 Neptune 中啟用查詢結果快取

若要在 Neptune 中啟用查詢結果快取,請使用主控台將 neptune_result_cache 資料庫執行個體參數設定為 1 (已啟用)。

一旦啟用了結果快取,Neptune 就會留出目前記憶體的一部分來快取查詢結果。您使用的執行個體類型越大且可用的記憶體越多,Neptune 為快取留出的記憶體就越多。

如果結果快取記憶體已滿,Neptune 會自動捨棄 least-recently-used (LRU) 快取的結果,讓位給新的結果。

您可以使用 執行個體狀態 命令檢查結果快取的目前狀態。

使用提示快取查詢結果

一旦啟用了查詢結果快取,就會使用查詢提示來控制查詢快取。以下所有範例都適用於相同的查詢周遊,即:

g.V().has('genre','drama').in('likes')

使用 enableResultCache

啟用查詢結果快取後,您可以使用 enableResultCache 查詢提示,快取 Grinlin 查詢的結果,如下所示:

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

Neptune 接著會將查詢結果傳回給您,同時也會快取它們。稍後,您可以再次發出完全相同的查詢來存取快取的結果:

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

識別快取結果的快取金鑰是查詢字串本身,即:

g.V().has('genre','drama').in('likes')

使用 enableResultCacheWithTTL

您可以使用查詢提示,指定應快取 enableResultCacheWithTTL 查詢結果多長時間。例如,下列查詢會指定查詢結果應在 120 秒後到期:

g.with('Neptune#enableResultCacheWithTTL', 120) .V().has('genre','drama').in('likes')

同樣地,識別快取結果的快取金鑰是基礎查詢字串:

g.V().has('genre','drama').in('likes')

您可以再次搭配 enableResultCache 查詢提示使用該查詢字串,存取快取的結果:

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

如果自緩存結果以來已經過了 120 秒或更多秒,則該查詢將返回新的結果,並緩存它們,而不會有任何結果 time-to-live。

您也可以使用 enableResultCacheWithTTL 查詢提示再次發出相同的查詢來存取快取的結果。例如:

g.with('Neptune#enableResultCacheWithTTL', 140) .V().has('genre','drama').in('likes')

在 120 秒過去之前 (也就是TTL目前有效),這個使用查詢提示的新enableResultCacheWithTTL查詢會傳回快取的結果。120 秒後,它將返回新結果並緩存它們 140 秒。 time-to-live

注意

如果查詢索引鍵的結果已快取,則使用的相同查詢索引鍵enableResultCacheWithTTL不會產生新的結果,也不會影響目前快取 time-to-live 的結果。

  • 如果之前使用快取結果enableResultCache,則必須先清除快取,然後才能enableResultCacheWithTTL產生新的結果,並根據其指定的快取快取快取。TTL

  • 如果之前使用快取結果enableResultCachewithTTL,則先前的結果TTL必須先過期,然後才能enableResultCacheWithTTL產生新的結果,並根據其指定的結果快取它們。TTL

使用 invalidateResultCacheKey

您可以使用 invalidateResultCacheKey 查詢提示來清除某個特定查詢的快取結果。例如:

g.with('Neptune#invalidateResultCacheKey', true) .V().has('genre','drama').in('likes')

該查詢會清除查詢金鑰 g.V().has('genre','drama').in('likes') 的快取,並傳回該查詢的新結果。

您也可以結合 invalidateResultCacheKeyenableResultCacheenableResultCacheWithTTL。例如,下列查詢會清除目前快取的結果、快取新結果,然後傳回它們:

g.with('Neptune#enableResultCache', true) .with('Neptune#invalidateResultCacheKey', true) .V().has('genre','drama').in('likes')

使用 invalidateResultCache

您可以使用 invalidateResultCache 查詢提示來清除查詢結果快取中的所有快取結果。例如:

g.with('Neptune#invalidateResultCache', true) .V().has('genre','drama').in('likes')

該查詢會清除整個結果快取,並傳回查詢的新結果。

您也可以結合 invalidateResultCacheenableResultCacheenableResultCacheWithTTL。例如,下列查詢會清除整個結果快取、快取此查詢的新結果,然後傳回它們:

g.with('Neptune#enableResultCache', true) .with('Neptune#invalidateResultCache', true) .V().has('genre','drama').in('likes')

對快取的查詢結果進行分頁

假設您已快取大量的結果,如下所示:

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes')

現在假設您發出以下範圍查詢:

g.with('Neptune#enableResultCache', true) .V().has('genre','drama').in('likes').range(0,10)

Neptune 首先尋找完整的快取金鑰,即 g.V().has('genre','drama').in('likes').range(0,10)。如果該金鑰不存在,Neptune 接下來會查看該查詢字串是否有金鑰沒有範圍 (即 g.V().has('genre','drama').in('likes'))。當它找到該金鑰時,Neptune 接著會從其快取中擷取前十個結果,如範圍所指定。

注意

如果您搭配結尾有範圍的查詢使用 invalidateResultCacheKey 查詢提示,Neptune 會在找不到與具有範圍的查詢完全相符的項目時,Neptune 會清除沒有範圍的查詢快取。

搭配使用 numResultsCached.iterate()

使用 numResultsCached 查詢提示,您可以填入結果快取,而不會傳回所有快取的結果,這在您偏好對大量結果進行分頁時很有用。

numResultsCached 查詢提示僅會使用結尾為 iterate() 的查詢。

例如,如果您想要快取範例查詢的前 50 個結果:

g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').iterate()

在此情況下,快取中的查詢金鑰是:g.with("Neptune#numResultsCached", 50).V().has('genre','drama').in('likes')。您現在可以使用此查詢,擷取前十個快取結果:

g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').range(0, 10)

您也可以從查詢中擷取接下來的十個結果,如下所示:

g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').range(10, 20)

請不要忘記包含 numResultsCached 提示!它是查詢金鑰的必要部分,因此必須存在才能存取快取的結果。

使用 numResultsCached 時要謹記的一些事項:
  • 您使用 numResultsCached 提供的數目會在查詢結束時套用。  例如,這表示下列查詢實際上會快取範圍 (1000, 1500) 內的結果:

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 500) .V().range(1000, 2000).iterate()
  • 您使用 numResultsCached 提供的數目會指定要快取的結果數目上限。  例如,這表示下列查詢實際上會快取範圍 (1000, 2000) 內的結果:

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 100000) .V().range(1000, 2000).iterate()
  • 結尾為 .range().iterate() 的查詢所快取的結果具有自己的範圍。  例如,假設您使用如下的查詢來快取結果:

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 500) .V().range(1000, 2000).iterate()

    若要從快取中擷取前 100 個結果,您將撰寫如下的查詢:

    g.with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 500) .V().range(1000, 2000).range(0, 100)

    這百個結果將等同於來自範圍 (1000, 1100) 中基礎查詢的結果。

用來尋找快取結果的查詢快取金鑰

在已快取查詢結果之後,具有相同「查詢快取金鑰」的後續查詢會從快取擷取結果,而不是產生新的結果。查詢的查詢快取金鑰會進行如下的評估:

  1. 所有快取相關的查詢提示都會被忽略,但 numResultsCached 除外。

  2. 最後一個 iterate() 步驟會被忽略。

  3. 查詢的其餘部分會根據其位元碼表示法進行排序。

產生的字串會與快取中已存在的查詢結果索引進行比對,以判斷查詢是否有快取命中。

例如,採取以下查詢:

g.withSideEffect('Neptune#typePromotion', false).with("Neptune#enableResultCache", true) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes').iterate()

它將儲存為如下的位元碼版本:

g.withSideEffect('Neptune#typePromotion', false) .with("Neptune#numResultsCached", 50) .V().has('genre','drama').in('likes')

與結果快取相關的例外狀況

如果即使在移除先前快取的所有項目之後,您嘗試快取的查詢結果仍太大而無法容納於快取記憶體中,Neptune 就會引發 QueryLimitExceededException 錯誤。系統不會傳回任何結果,且例外狀況會產生下列錯誤訊息:

The result size is larger than the allocated cache, please refer to results cache best practices for options to rerun the query.

您可以使用 noCacheExceptions 查詢提示來隱藏此訊息,如下所示:

g.with('Neptune#enableResultCache', true) .with('Neptune#noCacheExceptions', true) .V().has('genre','drama').in('likes')