Skip to content

Commit f15ec18

Browse files
committed
Amazon ElastiCache - Amazon RDS - Guidance
1 parent 5ab5bf9 commit f15ec18

File tree

11 files changed

+1093
-0
lines changed

11 files changed

+1093
-0
lines changed

guidance/.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export EC_REDIS_HOST=<ElastiCache endpoint>
2+
export EC_REDIS_PORT=6379
3+
export MYSQL_USER=admin
4+
export MYSQL_PASS=<MySQL password>
5+
export MYSQL_HOST=<MySQL Endpoint>
6+
export MYSQL_PORT=3306
7+
export MYSQL_DB=airportdb

guidance/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.env
2+
.venv/

guidance/README.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Guidance for boosting database performance reads with AWS ElastiCache
2+
3+
## Table of Content
4+
5+
1. [Overview](#overview)
6+
- [Cost](#cost)
7+
2. [Prerequisites](#prerequisites)
8+
- [Operating System](#operating-system)
9+
3. [Deployment Steps](#deployment-steps)
10+
4. [Deployment Validation](#deployment-validation)
11+
5. [Running the Guidance](#running-the-guidance)
12+
6. [Next Steps](#next-steps)
13+
7. [Cleanup](#cleanup)
14+
8. [FAQ, known issues, additional considerations, and limitations](#faq-known-issues-additional-considerations-and-limitations)
15+
9. [Notices](#notices)
16+
17+
## Overview
18+
19+
1. This guidance was created to help customers with database workloads that have high read:write (70:30) ratios and are looking to boost application performance, and at the same time reduce overall cost. Qualifying database workloads will see an increase in the number of transactions, a reduction in response time, and an overall reduction in cost. It is expected that two services together can perform a task faster. However, when AWS ElastiCache is paired with qualifying database workloads not only the performance increases but the total cost of the two services is lower than the cost of scaling the database alone to deliver a similar performance.
20+
21+
#### Architecture overview ####
22+
23+
<img width="676" alt="architecture-for-adding-caching-to-a-database" src="assets/images/architecture-diagram.png">
24+
25+
### Cost
26+
27+
You are responsible for the cost of the AWS services used while running this Guidance.
28+
29+
As of 03/28/2024, the cost for running this guidance with the default settings using AWS ElastiCache instance type cache.t2.x.small utilizing 1 primary, in the US East (N. Virginia) for on-demand pricing is approximately $24.82 USD total per month. AWS The RDS database cost is estimated at $14.71. However, cost will greatly depend on the, instance size, and RDS licensing model selected. Reserved instance pricing will reduce cost for both RDS and ElastiCache. ElastiCache is also available in a serverless offering where pay-per-consumption cost model is applicable.
30+
31+
| Service | Assumptions | Estimated Cost Per Month |
32+
| --------------------- | ------------------------------------------------- | ------------- |
33+
| Amazon ElastiCache | 2 Instance (cache.t2.small) used for 730 hours | $24.82 |
34+
| Amazon RDS MySQL | 1 Instance (db.t3.micro) used for 730 hours | $14.71 |
35+
36+
37+
## Prerequisites
38+
39+
This guidance is targeted towards those familiar with the AWS RDS Service. The users are expected to have a basic understanding of AWS RDS service and database access patterns. It guides users how to utilize AWS ElastiCache in addition to their existing relational database. Effectively paring your database with a caching service. It should be run in US East N.Virginia region.
40+
41+
42+
### Operating System
43+
44+
Tis guidance runs in the AWS cloud utilizing an AWS EC2 compute instance based on the Amazon Linux 2023 AMI. With network access to both AWS RDS database service and AWS ElastiCache (both are required). In addition the EC2 compute instance will require public access on port 8888. The included Cloud Formation template can be used to create such an EC2 instance. The sample code also includes two Jupyter notebooks to analyze and visually plot the performance results. Note that public access to the EC2 host on port 8888 should be enabled from your computer only not all end user computers.
45+
46+
### Software dependencies
47+
48+
Install dependencies by executing the setup_host.sh script. This script will install gcc python3-devel at the host level. In addition to the two packages installed a python virtual environment is created with dependent modules installed from the requirements.txt file. The python modules are only committed to the virtual environment not the host. The includes commands are optimized to work on the EC2 instance created by the included CloudFormation template and are specific for the Amazon Linux 2023 AMI al2023-ami-2023.4.20240319.1-kernel-6.1-arm64. This image is specific to the us-east-1 region. Other OS or AMI configuration may require additional steps.
49+
50+
- At the OS prompt execute the setup_host.sh script to install and configure all necessary software and to create the Python virtual environment.
51+
52+
### Third-party tools
53+
54+
This guidance uses Jupyter lab and the included notebooks to visualize/plot the performance data captured in json logs.
55+
For convenience reasons a Jupyter password has been set to 'test123'.
56+
Seed data is from the Airportdb sample database located here: https://dev.mysql.com/doc/airportdb/en/. However, by modifying the read and write queries, any seed data can be used.
57+
58+
### AWS account requirements
59+
60+
Ability to create an EC2 instance and networking configuration to permit access to both the RDS server and the ElastiCache service and public access to the EC2 on port 8888 from the customer end computer only. (CIDR/32)
61+
62+
**Example resources:**
63+
- RDS MySQL Database with the airportdb data loaded
64+
- AWS ElastiCache
65+
- VPC
66+
- SSH key in your region of choice
67+
68+
### Supported Regions
69+
70+
All regions where AWS RDS MySQL and AWS ElastiCache are offered.
71+
72+
## Deployment Steps
73+
74+
1. Create an EC2 instance with at least 1GB of memory using the Amazon Linux 2023 image. For convenience reason the repository includes the cloud formation template called guidance-ec2.yaml. Use AWS CloudFormation and with this template to create and EC2 instance.
75+
2. Log in to your instance from the AWS console via Session Manager or via SSH.
76+
3. Clone the repository by executing ```git clone <repo name> ```
77+
4. Change directory to the guidance directory ```cd guidance```
78+
5. Execute the setup_host script ```./setup_host.sh```
79+
6. Log in to the same instance from a separate session and navigate to the same directory and execute ```./setup_jupyter.sh``` script.
80+
7. In your computer browser enter the EC2's public IP address and port for example ```http://1.2.3.4:8888`` Note that this is not a secured service.
81+
8. Enter the preset password for your Jupyter notebook "test123"
82+
9. In your first session edit the .env file and update it with your database and ElastiCache related information.
83+
10. Source the .env file ```source .env``` to export the parameters.
84+
85+
## Deployment Validation
86+
87+
It is not part of this guidance to install and configure client applications for database and ElastiCache connectivity. However, at this point you can install client applications to validate connectivity to both the database and ElastiCache.
88+
89+
## Running the Guidance
90+
91+
* Execute the `scenario01.py` script. This workload accesses the database only and captures command level performance data in a logfile. In the directory where you executed the `setup_host.sh` and the Python virtual environment is activated, the first connection, execute:
92+
```bash
93+
(.venv) [ec2-user]$ python scenario01.py --users 10 --queries 1000 --read_rate 80
94+
```
95+
96+
* If deployment was correct you should see a response similar to this. (small sample execution)
97+
98+
```bash
99+
(.venv) [ec2-user]$ python scenario01.py --users 1 --queries 10 --read_rate 80
100+
Reads: 8
101+
Writes: 2
102+
Logfile located here: logs/scenario01_139007_mwae8c4k.json
103+
```
104+
* Open the Jupyter notebook `plot_results_db_only.ipynb` file and update the logfile name in the second cell. For example ```log_pattern = 'scenario01_139007_mwae8c4k.json```
105+
106+
* From the run option select run all cells. The output of the last cell will show both the number of executions per second and the average response time.
107+
108+
* To compare the performance boost provided by ElastiCache repeat the above steps but use the scenario02.py script. For example execute ```python scenario02.py --users 1 --queries 10 --read_rate 80``` The output should be similar.
109+
110+
```bash
111+
(.venv) [ec2-user]$ python scenario02.py --users 1 --queries 10 --read_rate 80
112+
Connected to Database
113+
Connected to ElastiCache
114+
Reads: 10
115+
Writes: 0
116+
Cache hits: 10
117+
Cache misses: 0
118+
Logfile located here: logs/scenario02_176908_0y2qr55f.json
119+
```
120+
121+
* Open the Jupyter notebook `plot_results_db_and_cache.ipynb` file and update the logfile name in the second cell. For example ```log_pattern = 'scenario02_176908_0y2qr55f.json```
122+
123+
Then select run all cells to plot the performance of the second scenario. Note that a small execution may not be sufficient to demonstrate the performance advantage of adding a cache.
124+
125+
## Next Steps
126+
127+
To see the potential improvements ElastiCache can provide to your application. Replace the database connection parameters with your test database values and modify the READ_QUERY and WRITE_QUERY text parameters to fit your schema.
128+
129+
## Cleanup
130+
131+
To clean up your environment stop all services and delete the MySQL database and ElastiCache cluster. Finally delete the EC2 instance from where you executed the commands.
132+
133+
134+
## FAQ, known issues, additional considerations, and limitations
135+
136+
Caching is beneficial for databases that execute a high read to write ratio workloads. For example 80:20 read to write workloads. The sample data provided in the airportdb is subject to change and accepting end user licensing agreement.
137+
138+
139+
**Additional considerations **
140+
141+
- This Guidance creates insecure Jupyter Notebook
142+
- Cashing is not applicable for workloads that are write intensive meaning that the majority of transactions are not repetitive read transactions.
143+
144+
For feedback please access the github page <here>
145+
146+
## Notices
147+
148+
Include a legal disclaimer
149+
150+
*Customers are responsible for making their own independent assessment of the information in this Guidance. This Guidance: (a) is for informational purposes only, (b) represents AWS current product offerings and practices, which are subject to change without notice, and (c) does not create any commitments or assurances from AWS and its affiliates, suppliers or licensors. AWS products or services are provided “as is” without warranties, representations, or conditions of any kind, whether express or implied. AWS responsibilities and liabilities to its customers are controlled by AWS agreements, and this Guidance is not part of, nor does it modify, any agreement between AWS and its customers.*

guidance/guidance-ec2.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Transform: 'AWS::Serverless-2016-10-31'
3+
Description: Create and EC2 to demonstrate the benefits of pairing RDBSM workloads with AWS ElastiCache
4+
Metadata:
5+
AWS::CloudFormation::Interface:
6+
ParameterGroups:
7+
- Label:
8+
default: Application EC2 Instance
9+
Parameters:
10+
- AppInstanceName
11+
- AppInstanceKeyName
12+
- AppInstanceClass
13+
- AppInstanceSecurityGroup
14+
- AppInstanceSubnet
15+
- AppInstanceStorage
16+
Parameters:
17+
### Key PARAMS
18+
AppInstanceKeyName:
19+
Description: 'Name of a key pair that exists in the region'
20+
Type: String
21+
Default: US-EAST1
22+
MinLength: '3'
23+
MaxLength: '63'
24+
AllowedPattern: "^[A-Za-z]+[0-9A-Z-]*$"
25+
26+
AppInstanceClass:
27+
Description: 'The application EC2 instance class'
28+
Type: String
29+
# Default: c6g.xlarge
30+
Default: t4g.micro
31+
MinLength: '8'
32+
MaxLength: '63'
33+
AllowedPattern: "^[a-z0-9.]*$"
34+
35+
AppInstanceSecurityGroup:
36+
Description: 'A security group with inbound rules for SSH connectivity from customer computer. And RDBMS and ElastiCache'
37+
Type: String
38+
Default: sg-0a87f73dcc1dffc4f
39+
MinLength: '8'
40+
MaxLength: '63'
41+
# AllowedPattern: "^[a-zA-Z]+[0-9]+[-]*$"
42+
43+
AppInstanceSubnet:
44+
Description: 'A valid subnet name in the default VPC'
45+
Type: String
46+
Default: subnet-05cfa282f9b9dc8df
47+
MinLength: '8'
48+
MaxLength: '63'
49+
# AllowedPattern: "^[A-Za-z]+[0-9A-Z-]*$"
50+
51+
AppInstanceStorage:
52+
Description: 'The application EC2 instance Storage in GB'
53+
Type: String
54+
Default: 8
55+
MinLength: '1'
56+
MaxLength: '3'
57+
AllowedPattern: "^[0-9]*$"
58+
59+
AppInstanceName:
60+
Description: 'The EC2 instance name'
61+
Type: String
62+
Default: GuidanceForCacheDatabaseQuery
63+
MinLength: '1'
64+
MaxLength: '64'
65+
AllowedPattern: "^[a-zA-Z0-9]*$"
66+
67+
Resources:
68+
AppInstance:
69+
Type: AWS::EC2::Instance
70+
Properties:
71+
InstanceType: !Ref AppInstanceClass
72+
ImageId: ami-0d8f91fa8ecdc3b58
73+
KeyName: !Ref AppInstanceKeyName
74+
Monitoring: true
75+
SecurityGroupIds:
76+
- !Ref AppInstanceSecurityGroup
77+
SubnetId: !Ref AppInstanceSubnet
78+
Tags:
79+
-
80+
Key: Name
81+
Value: !Ref AppInstanceName

guidance/plot_results_db_and_cache.ipynb

Lines changed: 168 additions & 0 deletions
Large diffs are not rendered by default.

guidance/plot_results_db_only.ipynb

Lines changed: 182 additions & 0 deletions
Large diffs are not rendered by default.

guidance/requirements.txt

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
aiofiles==22.1.0
2+
aiosqlite==0.19.0
3+
anyio==3.7.1
4+
argon2-cffi==23.1.0
5+
argon2-cffi-bindings==21.2.0
6+
arrow==1.2.3
7+
async-timeout==4.0.3
8+
attrs==23.2.0
9+
Babel==2.14.0
10+
backcall==0.2.0
11+
beautifulsoup4==4.12.3
12+
bleach==6.0.0
13+
cached-property==1.5.2
14+
certifi==2024.2.2
15+
cffi==1.15.1
16+
charset-normalizer==3.3.2
17+
cycler==0.11.0
18+
debugpy==1.7.0
19+
decorator==5.1.1
20+
defusedxml==0.7.1
21+
entrypoints==0.4
22+
exceptiongroup==1.2.0
23+
fastjsonschema==2.19.1
24+
fonttools==4.38.0
25+
fqdn==1.5.1
26+
greenlet==3.0.3
27+
idna==3.6
28+
importlib-metadata==6.7.0
29+
importlib-resources==5.12.0
30+
ipykernel==6.16.2
31+
ipython==7.34.0
32+
ipython-genutils==0.2.0
33+
isoduration==20.11.0
34+
jedi==0.19.1
35+
Jinja2==3.1.3
36+
json5==0.9.16
37+
jsonpointer==2.4
38+
jsonschema==4.17.3
39+
jupyter-events==0.6.3
40+
jupyter-server==1.24.0
41+
jupyter-ydoc==0.2.5
42+
jupyter_client==7.4.9
43+
jupyter_core==4.12.0
44+
jupyter_server_fileid==0.9.1
45+
jupyter_server_ydoc==0.8.0
46+
jupyterlab==3.6.7
47+
jupyterlab-pygments==0.2.2
48+
jupyterlab_server==2.24.0
49+
kiwisolver==1.4.5
50+
markdown-it-py==2.2.0
51+
MarkupSafe==2.1.5
52+
matplotlib==3.5.3
53+
matplotlib-inline==0.1.6
54+
mdurl==0.1.2
55+
mistune==3.0.2
56+
nbclassic==1.0.0
57+
nbclient==0.7.4
58+
nbconvert==7.6.0
59+
nbformat==5.8.0
60+
nest-asyncio==1.6.0
61+
notebook==6.5.6
62+
notebook_shim==0.2.4
63+
numpy==1.21.6
64+
packaging==24.0
65+
pandas==1.3.5
66+
pandocfilters==1.5.1
67+
parso==0.8.3
68+
pexpect==4.9.0
69+
pickleshare==0.7.5
70+
Pillow==9.5.0
71+
pkgutil_resolve_name==1.3.10
72+
prometheus-client==0.17.1
73+
prompt-toolkit==3.0.43
74+
psutil==5.9.8
75+
ptyprocess==0.7.0
76+
pycparser==2.21
77+
Pygments==2.17.2
78+
PyMySQL==1.1.0
79+
pyparsing==3.1.2
80+
pyrsistent==0.19.3
81+
python-dateutil==2.9.0.post0
82+
python-decouple==3.8
83+
python-json-logger==2.0.7
84+
pytz==2024.1
85+
PyYAML==6.0.1
86+
pyzmq==24.0.1
87+
redis==5.0.3
88+
requests==2.31.0
89+
rfc3339-validator==0.1.4
90+
rfc3986-validator==0.1.1
91+
rich==13.7.1
92+
Send2Trash==1.8.2
93+
six==1.16.0
94+
sniffio==1.3.1
95+
soupsieve==2.4.1
96+
SQLAlchemy==2.0.29
97+
terminado==0.17.1
98+
tinycss2==1.2.1
99+
tomli==2.0.1
100+
tornado==6.2
101+
traitlets==5.9.0
102+
typing_extensions==4.7.1
103+
uri-template==1.3.0
104+
urllib3==1.26.6
105+
wcwidth==0.2.13
106+
webcolors==1.13
107+
webencodings==0.5.1
108+
websocket-client==1.6.1
109+
y-py==0.6.2
110+
ypy-websocket==0.8.4
111+
zipp==3.15.0

0 commit comments

Comments
 (0)