Skip to content

Commit 29ae830

Browse files
Fix for #34 (#35)
Code changes to launch the HTTP server in port 4000 because of conflict with Lambda insights. Updates to README file with information around performance testing Co-authored-by: Hari Ohm Prasath <[email protected]>
1 parent 9b8237d commit 29ae830

File tree

6 files changed

+36
-4
lines changed

6 files changed

+36
-4
lines changed

cache-extension-demo/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ bin/*
22
.idea/*
33
go.sum
44
run.sh
5+
SAM/.aws-sam/*

cache-extension-demo/README.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This extension demo's the Lambda layer that enables both data cache (using dynam
1111
Here is how it works:
1212
- Uses `config.yaml` defined part of the lambda function to determine the items that needs to be cached
1313
- All the data are cached in memory before the request gets handled to the lambda function. So no cold start problems
14-
- Starts a local HTTP server at port `3000` that replies to request for reading items from the cache depending upon path variables
14+
- Starts a local HTTP server at port `4000` that replies to request for reading items from the cache depending upon path variables
1515
- Uses `"CACHE_EXTENSION_TTL"` Lambda environment variable to let users define cache refresh interval (defined based on Go time format, ex: 30s, 3m, etc)
1616
- Uses `"CACHE_EXTENSION_INIT_STARTUP"` Lambda environment variable used to specify whether to load all items specified in `"cache.yml"` into cache part of extension startup (takes boolean value, ex: true and false)
1717

@@ -24,6 +24,14 @@ Here is the high level view of all the components
2424

2525
![architecture](img/architecture.svg)
2626

27+
Once deployed the extension performs the following steps:
28+
1. On start-up, the extension reads the `config.yaml` file which determines which resources to cache. The file is deployed as part of the lambda function.
29+
2. The boolean `CACHE_EXTENSION_INIT_STARTUP` Lambda environment variable specifies whether to load into cache the items specified in config.yaml. If false, an empty map is initialized with the names inside the extension.
30+
3. The extension retrieves the required data from DynamoDB and the configuration from Parameter Store. The data is stored in memory.
31+
4. The extension starts a local HTTP server using TCP port 4000 which serves the cache items to the function. The Lambda can accessed the local in-memory cache by invoking the following endpoint: `http://localhost:4000/<cachetype>?name=<name>`
32+
5. If the data is not available in the cache, or has expired, the extension accesses the corresponding AWS service to retrieve the data. It is cached first, and then returned to the lambda function. The `CACHE_EXTENSION_TTL` Lambda environment variable defines the refresh interval (defined based on Go time format, ex: 30s, 3m, etc.)
33+
34+
2735
## Initialize extension and reading secrets from the cache
2836
Below sequence diagram explains the initialization of lambda extension and how lambda function
2937
reads cached items using HTTP server hosted inside the extension
@@ -203,7 +211,7 @@ XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [cache-extension-demo] Register response: {
203211
}
204212
XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [cache-extension-demo] Cache successfully loaded
205213
XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [cache-extension-demo] Waiting for event...
206-
XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [cache-extension-demo] Starting Httpserver on port 3000
214+
XXXX-XX-XXTXX:XX:XX.XXX-XX:XX [cache-extension-demo] Starting Httpserver on port 4000
207215
XXXX-XX-XXTXX:XX:XX.XXX-XX:XX EXTENSION Name: cache-extension-demo State: Ready Events: [INVOKE,SHUTDOWN]
208216
...
209217
...
@@ -216,3 +224,26 @@ XXXX-XX-XXTXX:XX:XX.XXX-XX:XX INFO Finally got some response here: "{\"Data\"
216224
XXXX-XX-XXTXX:XX:XX.XXX-XX:XX END RequestId: d94434eb-705d-4c22-8600-c7f53a0c2204
217225
XXXX-XX-XXTXX:XX:XX.XXX-XX:XX REPORT RequestId: d94434eb-705d-4c22-8600-c7f53a0c2204 Duration: 17.09 ms Billed Duration: 18 ms Memory Size: 1472 MB Max Memory Used: 89 MB Init Duration: 289.40 ms
218226
```
227+
228+
## Performance Testing
229+
230+
To test the performance of the cache extensions, lets take two scenarios:
231+
Scenario 1: A simple Golang lambda function to access the secrets from AWS Secrets Manager in every invocation.
232+
Scenario 2: Lambda function (ExtensionsCache-SampleFunction) using cache extensions, deployed using the above SAM template to access the secrets from AWS Secrets Manager
233+
For the load test, we are using Artillery to test the lambda functions. Both these functions use 512MB of execution memory and the timeout set to 30 seconds. The load was tested for 100 asynchronous invocations for a period of 2 minutes
234+
235+
![Scenario1](img/performance-scenario1.png)
236+
![Scenario2](img/performance-scenario2.png)
237+
238+
From the above images, we can see that Scenario 1 took an approximate average of 22 ms, whereas in Scenario 2 it took an average of 3ms to complete the execution. With just a simple test, we are able to clearly see the difference in performance.
239+
240+
Lambda functions frequently accessing the DynamoDB database can also leverage this extension to quickly cache the data. Some other advantages of using this extension:
241+
1. Better performance, since all the data gets cached in-memory
242+
2. Less number of AWS API calls, thereby reducing the AWS API throttling while frequently accessing AWS services
243+
3. Cache extension is written in Golang and the executable can be easily integrated with other runtimes like Node JS, Python, Java,..etc.
244+
4. Data is not stored in a physical file, which provides lesser libraries required to read/write from the file and to manage the lifecycle of the file
245+
5. Simple and easy to configure YAML template if required to add additional services
246+
247+
## Conclusion
248+
249+
This cache extension provides a secure way of caching data in parameter store, and DynamoDB also provides a way to implement TTL for cache items. By using this framework, we can reuse the caching code among multiple lambda functions and package all the required AWS dependencies part of AWS layers.

cache-extension-demo/example-function/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ exports.handler = function(event, context, callback) {
77

88
const options = {
99
hostname: 'localhost',
10-
port: 3000,
10+
port: 4000,
1111
path: '/dynamodb?name=DynamoDbTable-pKey1-sKey1',
1212
method: 'GET'
1313
};
Loading
Loading

cache-extension-demo/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func main() {
3939
extension.InitCacheExtensions()
4040

4141
// Start HTTP server
42-
ipc.Start("3000")
42+
ipc.Start("4000")
4343

4444
// Will block until shutdown event is received or cancelled via the context.
4545
processEvents(ctx)

0 commit comments

Comments
 (0)