Christian Pino Tossi

Cache Keys  Why we should know them?

Blog Post created by Christian Pino Tossi Employee on Jan 18, 2016

Disclaimer:

This Article does describe the concept of the Akamai Cache Key. Therefore several sample Settings of an Akamai Configuration are presented. It is not recommended to try this settings without consulting Akamai Professional Services beforehand.

Also we expect the reader to understand the Akamai Delivery concept in general.

Have some basic experiences with Akamai Property Manager and OPEN API.

 

The Akamai Platform does offer a variety of Solutions and Features.

One of the core Features is Caching.

 

  • How does the Edge Server knows which File needs to be cached?
  • How does the Edge Server retrieve the cached object from the “Cache Store”?

 

How does the Edge Server knows which File needs to be cached?

Akamai Edge Server does cache based on Instruction provided via

  • the Client Request
  • a corresponding Akamai Configuration (Property Manager)
  • Instruction received by the Origin (optional)

NOTE: There is an exception in which all Akamai Settings are part of the Client Request URL (aka ARL v1) which will be discussed in more detail later on.

How does the Edge Server retrieve the Cached object from his Cache Store?

 

Content is cached on the so called “Cache Store”. The “Cache Store” does represent either the Memory (RAM) or Hard disk of a certain Edge Server.

 

To access content/objects from the “Cache Store” we need to know the corresponding “Cache Key”. This concept is also known as Key/Value Store:

Definition of a Cache Key

To store an object on the Edge Server “Cache Store” we need to create the “Cache Key” first.

The EdgeSuite Configuration Guide does mention that the Akamai Edge Server forms the “Cache Key”  based on parts of the "Request ARL".

 

This does lead to the following two questions:

  • What is an ARL?
  • Which part of the ARL define the Cache Key?

 

What is an ARL?

The ARL (Akamai Resource Location) is similar to an URL. The difference being that the ARL is specifically defined for objects to be served via the Akamai Network. There are two types of ARLs:

  • ARL v1
  • ARL v2

 

ARL v1

This is the original ARL used in the earlier days of Akamai. It contains instructions for the Edge Server coded into its structure. :

Such an ARL might look like this:

 

http://a123.g.akamai.net/7/123/456/e358f5de00e9/www.example.com/logo.gif

ARL v2

Instead of coding all instruction into the URL like done for ARL v1, ARL v2 does reference a Configuration File hosted on the Edge Server.

This Configuration files provide extensive content control compared to ARL v1.

 

 

Also the configuration file can be managed either via the Property Manager or via PAPI (OPEN API Property API).

ARL v2 is a combination of the URL and the corresponding Configuration File:

http://www.example.com/logo.gif + www.example.com.xml

 

NOTE: The Origin can also influence the ARLv2 but because this is optional it is not mentioned here.

Which part of the ARL define the Cache Key?

NOTE: The following description count mainly for ARL v2, we are not going to elaborate on ARL v1 as this are not used that often nowadays.

ARL Components which form the Cache Key.

  • Typecode*
  • Forward [fwd] path (origin server, pathname, filename and extension)
  • Query string (Optional)**
  • Secure Network Delivery Indicator***
  • HTTP Method (GET, HEAD, etc.)

*We are not going to explain Typecodes in detail here, we just need to know that Typecodes are represented by a Single Characters.

**Query String parameter are optional and by default added to the Cache Key. If needed they can be ignored inside the corresponding Akamai Configuration.

***Secure Network Delivery Indicator does only show up in case Content is delivered via the Secure Network.

Retrieve a Cache Key

To create a Cache Key we need the following three Components:

  1. Content/Website which will be served via Akamai
  2. Akamai Configuration to serve Content via Akamai
  3. DNS CNAME which does point the Website to the Akamai Platform and therefore to the corresponding Akamai Configuration.

 

Therefore we did setup:

  1. Website: shop.edgegate.de
  2. Akamai Configuration: shop.edgegate.de.xml
  3. DNS: shop.edgegate.de CNAME cpinotossi.edgesuite.net

 

The Website shop.edgegate.de does provide information about three different Products:

  1. Web Performance
  2. Media Delivery
  3. Cloud Security

via the following three URLs:

 

The URL Path is the same for all three products (/products.jsp). Which Product/Content is going to be presented depends on the value of the query parameter "productId":

  • 1 = Web Performance
  • 2 = Media Delivery
  • 3 = Cloud Security

 

To retrieve the corresponding Cache Key we can use one of the following Tools/Options:

  • Akamai Debug Header: Pragma: akamai-x-get-cache-key
  • Akamai Debug Header: Pragma: akamai-x-get-true-cache-key
  • OPEN API Diagnostic Tool Akamai Translator

 

Akamai Debug Header are added to the HTTP Request which is send to the Edge Server.OPEN API represents the RESTful Interface to the Akamai Platform.

Akamai Debug Header: Pragma: akamai-x-get-cache-key

REQUEST to the Edge Server:

GET /products.jsp?productId=1 HTTP/1.1

host: shop.edgegate.de

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0Accept: */*

Pragma: akamai-x-get-cache-key

 

RESPONSE from the Edge Server:

HTTP/1.1 200 OK

Content-Type: text/html; charset=iso-8859-1

Server: Google Frontend

Cache-Control: private, max-age=0

Expires: Thu, 17 Dec 2015 00:00:06 GMT

Date: Thu, 17 Dec 2015 00:00:06 GMT

Content-Length: 1127

X-Cache-Key: /L/1168/78685/1m/edgegatecpinotossi.appspot.com/products.jsp?productId=1

Connection: keep-alive

 

The Response Header “X-Cache-Key” does consist of the following Cache Key Components:

 

NameValue
TypecodeL
Serial1168
CPCode78685
TTL1m
fwd Pathedgegatecpinotossi.appspot.com/products.jsp
Query String?productId=1

 

The Cache Key does contains more components as expected:

  • Serial
  • CPCode
  • TTL

But is missing:

  • HTTP Method

 

NOTE: “Secure Network Delivery Indicator” is not expected to show up as this Content is not served via the Akamai Secure Network. If we would have send the Request via the Akamai Secure Network the response Header would have been as follow:

 

X-Cache-Key: /S/L/1168/78685/1m/edgegatecpinotossi.appspot.com/products.jsp?productId=1

 

Note the leading "/S" which does indicate the secure delivery via HTTPS.

Akamai Debug Header: Pragma: akamai-x-get-true-cache-key

REQUEST to the Edge Server:

GET /products.jsp?productId=1 HTTP/1.1

host: shop.edgegate.de

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0Accept: */*

Pragma: akamai-x-get-true-cache-key

 

RESPONSE from the Edge Server:

HTTP/1.1 200 OK

Content-Type: text/html; charset=iso-8859-1

Server: Google Frontend

Cache-Control: private, max-age=0

Expires: Thu, 17 Dec 2015 00:00:06 GMT

Date: Thu, 17 Dec 2015 00:00:20 GMT

Content-Length: 1127

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/products.jsp?productId=1

Connection: keep-alive

 

The Response Header “X-True-Cache-Key” does contain the following Cache Key Components:

 

NameValue
TypecodeL
fwd Pathedgegatecpinotossi.appspot.com/products.jsp
Query String?productId=100

 

But we are missing the following one:

  • HTTP Method (GET, HEAD, etc.)

 

OPEN API Diagnostic Tools Akamai Translator

Akamai Translator is part of the OPEN API Diagnostic Tools collection and does mention to be able to retrieve ARL information for a certain Hostname:NOTE: to make use of the OPEN API we need:

  1. Setup an API User via the Akamai Portal (https://control.akamai.com).
  2. Use one of the available EdgeGrid Tools to Authenticated versus the OPEN API
  3. Send the RESTful API call.

 

It is not the intention of this Blog to explain how exactly this can be achieved. This is already covered by several other Blogs (search for OPEN API or go to developer.akamai.com).

 

Even if the API Documentation does mention that we can only provide the Hostname we are still going to have a look of how the output will look like.

After having everything in place we did create a Node.js script to call the Akamai Translator:

 

node aka_translator -h shop.edgegate.de                                                        ⏎

{

  "arl": {   

     "typeCode": "Object changes when ARL changes",   

     "originServer": "edgegatecpinotossi.appspot.com",   

     "cpCode": "78685",   

     "serialNumber": "16382",

    "ttl": "Infinite",

    "pragma": "no-cache",

    "cacheControl": "max-age=0, no-cache, no-store",

    "errorString": null 

  }

}

 

The OPEN API JSON Response does provide the following Cache Key Components:

 

NameValue
Typecode"Object changes when ARL changes"
TTLinfinity
originServeredgegatecpinotossi.appspot.com
serialNumber16382
CPCode78685

 

We are missing the following component:

  • fwd Path
  • Query Strings
  • HTTP Method (GET, HEAD, etc.)

 

In addition it does mention a different Serial as the one provided by the Pragma Header.

To proof which one is correct we can do a simple Names Lookup. The corresponding CNAME Chain will include a Domain which starts with the character 'a' followed by a number, the Serial (1168):

dig shop.edgegate.de
; <<>> DiG 9.8.3-P1 <<>> shop.edgegate.de;; global options: +cmd;;

Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40347;;

flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION

:;shop.edgegate.de.        IN    A


;; ANSWER SECTION:

shop.edgegate.de.    300    IN    CNAME    cpinotossi.edgesuite-staging.net.

cpinotossi.edgesuite-staging.net. 21600    IN CNAME a1168.b.akamai-staging.net.

a1168.b.akamai-staging.net. 20    IN    A    165.254.92.136

a1168.b.akamai-staging.net. 20    IN    A    165.254.92.144
;; Query time: 106 msec;;

SERVER: 172.27.216.42#53(172.27.216.42);;

WHEN: Tue Dec 22 00:03:57 2015;; MSG SIZE  rcvd: 149

This does proof that the Outcome of the Pragma Header does provide the correct serial.

The output of the Akamai Translator seems really different to the once collected before.

 

Summary#1

  • We understood that Cache Keys are needed to find the corresponding cached content inside the Edge Server Cache Store.
  • We know that the Cache Key is build based on parameters which we received during the Client Request combined with parameters setup in the corresponding Akamai Configuration.

 

We used three different Options to retrieve the Cache Key and received the following results:

 

akamai-x-get-cache-keyakamai-x-get-true-cache-keyAkamai Translator
TypecodeYESYESYES
fwd PathYESYESNO
Query StringYESYESNO
Secure NetworkYES*YES*NO*
HTTP MethodNONONO

*We did not send the Request via the Secure Delivery Network.

 

The Akamai Debug Header “akamai-x-get-true-cache-key” did provide results which are closest to the definition of the Cache Key.

Great, now we know how our Cache Key looks like but what can we do with it?

There are two thing you can use it for:

  1. verify if content is stored properly
  2. remove content from the cache

 

Verify if content is stored properly

like mentioned at the beginning of this Blog, each Cache Key does refer an Object which is stored inside the Edge Server Cache Store.What goes into the corresponding Cache Key is controlled by the so called Akamai Configuration.

Let us assume we are going to ignore Query Parameters inside the Cache Key. This practice is used in case a Query Parameter which varies by Request does still result into the same Content:Even if the URL looks different:

The corresponding Response/Image is always the same. In such a case we would like to ignore the Query Parameter “query” to avoid so called “cache pollution”.

Cache Polution would increase the number of Cache Keys for the same Object. That is exactly what we don´t want, instead we would like to serve whenever possible from cache, independent of the value of “query”:

 

NOTE: If we ignore "query", we will be able to serve the second request from Cache instead of having to go forward to the Customer Origin.

 

Now that we understood how a Cache Key looks like and how to retrieve the Cache Key we can verify this very easily via the Pragma Headers:

 

REQUEST to the Edge Server:

GET /image.jpg?query=1 HTTP/1.1

host: shop.edgegate.de

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0

Accept: */*

Pragma: akamai-x-get-true-cache-key

 

RESPONSE from the Edge Server:

HTTP/1.1 200 OK

ETag: "i0wzHg"

Content-Type: image/jpeg

Server: Google Frontend

Content-Length: 148087

Cache-Control: public, max-age=60

Expires: Mon, 21 Dec 2015 23:35:50 GMT

Date: Mon, 21 Dec 2015 23:34:50 GMT

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/image.jpg?query=1

 

The X-True-Cache-Key does include the Query “query” as part of the Cache Key.

That's not what we want like explained before therefore we are going to modify the Akamai Configuration as follow via the Property Manager:

If we redo the Test we will get the following result:

 

REQUEST to the Edge Server:

GET /image.jpg?query=1 HTTP/1.1

host: shop.edgegate.de

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0

Accept: */*

Pragma: akamai-x-get-true-cache-key

 

RESPONSE from the Edge Server:

HTTP/1.1 200 OK

ETag: "i0wzHg"

Content-Type: image/jpeg

Server: Google Frontend

Content-Length: 148087

Cache-Control: public, max-age=60

Expires: Mon, 21 Dec 2015 23:35:50 GMT

Date: Mon, 21 Dec 2015 23:34:50 GMT

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/image.jpg

 

Perfect, that's exactly what we want :).

Remove Content from Cache

There could be many reason why you would like to remove content from the Akamai Edge Server Cache before the corresponding TTL (Time to Live) of that certain Object expires.

The most common reason is because your content has been updated at the Origin and therefore you need to clear the old content from the Edge Server.

There are two options how you can achieve this:

 

Both option accept an URL or ARL as input parameter.

let us use the OPEN API.

 

NOTE: We are not going to explain in details how to setup the OPEN API here as there are many other Blogs and Articles which do cover this Topic in great detail.

 

We created a Node.js Script to interact with the Purge API. The Script does accept the URL as input Parameter:

 

node shop.edgegate.de.js -u http://shop.edgegate.de/image.jpg                                           

 

{ 

  "estimatedSeconds": 240,

  "progressUri": "/ccu/v2/purges/db887a0d-a849-11e5-86de-39f3a5a6eb50",

  "supportId": "17PY1450747087345725-411055296",

  "httpStatus": 201,  "detail": "Request accepted.",

  "purgeId": "db887a0d-a849-11e5-86de-39f3a5a6eb50",

  "pingAfterSeconds": 240

}

 

If we request the Object afterwards we will receive an TCP_REFRESH_HIT:

HTTP/1.1 200 OK

ETag: "i0wzHg"

Content-Type: image/jpeg

Server: Google Frontend

Content-Length: 148087

Cache-Control: public, max-age=60

Expires: Tue, 22 Dec 2015 01:13:08 GMT

Date: Tue, 22 Dec 2015 01:12:08 GMT

X-Cache: TCP_REFRESH_MISS from a165-254-92-140.deploy.akamaitechnologies.com (AkamaiGHost/7.4.0.3.1-16456689) (S)

X-True-Cache-Key: /=/edgegatecpinotossi.appspot.com/image.jpg

 

NOTE: To verify if the object is served from Cache (TCP_REFRESH_MISS) we did used the Pragma Header “Pragma: akamai-x-cache-on” which is explained in more detail here: https://community.akamai.com/community/web-performance/blog/2015/03/31/using-akamai-pragma-headers-to-investigate-or-troubleshoot-akamai-content-delivery

Summary#2

  • We have seen that Cache Key are useful to avoid the “Cache Pollution” issue.
  • Also we have seen that Content can be removed from Akamai Edge Server very easily, even without knowing the Cache Key.

 

But stop, we did remove content even without knowing the Cache Key, so it is unclear till know why we need to know about the cache key in case we like to remove or invalidate content.

Let us try to make our example a little bit more complicated to see if this will change the situation.

Language support - Cookie values as part of the Cache Key

We are going to extend the offering of our website. We will allow User to select the preferred language. By default we will assign "english" (en) to all new visitors. But if the customer choose to change this to "german" the Origin will set a cookie at the client called "prefLanguage". Based on the cookie value ("en" or "de”) the Origin will send different content for the same URL:

We are going to use a Cookie instead of adding this information to the URL to allow the browser to remember the end user decision when he visits the page the next time.

But how can we add the Cookie into the Cache Key?

So far all the information which did went into the Cache Key did not mention Cookie Values.

 

Happy we are there is a Feature available called Flexible Cache ID (aka Cache-ID). It makes it possible to add information to the default cache key from cookies and HTTP headers. It also provides a mechanism for including or excluding arguments from the query string.

You do this by defining a set of rules for what information should be included or excluded from the cache key. These rules are then compared with the request to determine how the object should be cached. If none of the rules match, the object is uncacheable and is discarded after the requesting client is served.

 

Whenever the Cache-ID feature is used, the cache key is composed of two parts:

  • The existing cache-key minus the query string, which is included in the cache ID as appropriate
  • The Cache-ID computed from the additional information (query arguments, cookie values, HTTP header contents).

 

That is exactly what we need. So let us add the Cookie "prefLanguage" and the Query Parameter "productId" into the Cache-ID Section via Property Manager:

 

Request:

GET /products.jsp?productId=1 HTTP/1.1

Host: shop.edgegate.de

cookie: prefLanguage=de;


Response:

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/products.jsp cid=_prefLanguage=de_

and

 

Request:

GET /products.jsp?productId=1 HTTP/1.1

Host: shop.edgegate.de

cookie: prefLanguage=en;


Response:

HTTP/1.1 200 OK

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/products.jsp cid=_prefLanguage=en_

 

If we split this into all the Cache Key components it looks as follow:But stop there is something wrong, the Query String “productId” is no longer part of the Cache Key. It seems like we need to mention the Query String also inside the Cache ID Section of the Property Manager as follow:

 

If we redo the test we can see that both Query Parameter “productId” and Cookie Value “prefLanguage” are now part of the Cache Key:

 

Request:

GET /products.jsp?productId=1 HTTP/1.1

Host: shop.edgegate.de

cookie: prefLanguage=en;


Response:

HTTP/1.1 200 OK

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/products.jsp cid=productId=1_prefLanguage=en_

 

Great, now we are able to support different Languages via the same URL:And the Cache Key did help us to verify this.

 

Summary#3

  • Flexible Cache-ID allow to add additional Parameter to the Cache Key

 

But stop how can we remove this content from Edge Server Cache if needed. Remember, our Akamai PURGE API does only support URLs or ARLs. None of both allow to provided the Cookie "prefLanguage".

When you purge an object that uses the Flexible Cache ID feature, a request to purge any object with that URL will cause all objects with the same “Base Path” to be purged.

Let us see what that means for our Website. We do provide currently the following URLs:

 

 

Each of the URL does provide different Content. The corresponding X-True-Cache-Key look as follow:

 

  • /L/edgegatecpinotossi.appspot.com/products.jsp cid=productId=1_prefLanguage=en_
  • /L/edgegatecpinotossi.appspot.com/products.jsp cid=productId=2_prefLanguage=en_
  • /L/edgegatecpinotossi.appspot.com/products.jsp cid=productId=3_prefLanguage=en_
  • /L/edgegatecpinotossi.appspot.com/products.jsp cid=productId=1_prefLanguage=de_
  • /L/edgegatecpinotossi.appspot.com/products.jsp cid=productId=2_prefLanguage=de_
  • /L/edgegatecpinotossi.appspot.com/products.jsp cid=productId=3_prefLanguage=de_

 

The base URL (the part before the “cid”) is the same (/products.jsp) for all the different version.

A request to purge any one of these items would purge all six version, as they all are based on the same base Path “/products.jsp/”.

 

Mmmhhh, somehow that is not what we wanted, we would like still to have the flexibility to only Purge

  • a certain Product Page
  • and his corresponding language

 

Therefore we will need to move the query parameter "productId" out of the Cache-ID section by changing the Flexible Cache ID from the current Output:Into the following one:The corresponding Property Manager Setup looks as follow:

And the corresponding Test Results looks as follow:

Request:

GET /products.jsp?productId=1 HTTP/1.1

Host: shop.edgegate.de

cookie: prefLanguage=en;


Response:

HTTP/1.1 200 OK

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/products.jsp?productId=1 cid=___PREF_LANGUAGE=en

 

Great are we done now? Not really, we are still not able to remove content by Languages. In our case we would still need to remove both Languages (en and de) because they are still part of the Cache ID section. One option would be to move the cookie value out of the Cache-ID Section and into the Query Parameter Part of the Cache Key:NOTE: We still like to keep the Cookie as we like the Browser to remember which Language has been selected by the client.

 

Therefore on one hand we need to provide a cookie to the client and on the other hand we need to add the value into the none cid section.

 

To achieve this we would just need to modify things inside the Akamai Edge Server as follow:

 

The core of the solution is the usage of the feature called <forward:modify-path>. 

This feature is used to modify the URL path when forwarding the request. The cache key for the object is computed based on the forward request path. Edge Server will therefore use the following Cache Key:

 

Request:

GET /products.jsp?productId=1 HTTP/1.1

Host: shop.edgegate.de

cookie: prefLanguage=en;


Response:

HTTP/1.1 200 OK

X-True-Cache-Key: /L/edgegatecpinotossi.appspot.com/products.jsp?productId=1&prefLanguage=en

Summary#4

  • It seems like best practice to try to get everything added into the URL instead of using Cookies but if Cookies are needed there are ways to work around it.

 

Conclusion

The solution presented here are partly achieved by using so called “Advanced Settings”. This kind of changes can only be done by Akamai Professional Services.

It is hard to judge if this needs to be like this or not but the more important take away here is that there is a lot of options to configure how the Edge Server does compute the Cache Key and therefore how efficient things are cached inside Akamai.

 

NOTE:

We did not discuss situation in which vanity URLs are used. Think about the case that we would like to introduce more SEO Friendly URLs like:

in parallel to the existing URLs:

 

If possible we would like to use the same stored Object and therefore the same Cache Key for both.

 

Next Step:

If you like to discuss this topic in more detail or similar topics please feel free to reach out to your Akamai representative to inquire about Akamai's consulting services

Outcomes