-
-
Save stephenVertex/4f02350032f7bc2ae64fbf20e71ae8f3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import seaborn as sns | |
import matplotlib.pyplot as plt | |
import pandas as pd | |
## Calculate gp2 price, and return max throughput and IOPS | |
def mkGp2(vol_size_gb): | |
### See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/general-purpose.html#gp2-performance | |
d = {} | |
d['price'] = 0.10 * vol_size_gb | |
if vol_size_gb < 33.33: | |
d['iops'] = 100 | |
else: | |
d['iops'] = min(16000, 3 * vol_size_gb) | |
## Calculate throughput max, ignoring bursting from 170 to 334. | |
if vol_size_gb <= 334: | |
d['throughput_max'] = 128 | |
else: | |
d['throughput_max'] = 250 | |
return(d) | |
## Calculate gp3 price, as a function of size, required IOPS | |
## and required throughput | |
def mkGp3(vol_size_gb, req_iops, req_throughput): | |
storage_price = 0.08 * vol_size_gb | |
prov_iops = min(13000, max(req_iops - 3000, 0)) | |
prov_iops_price = 0.005 * prov_iops | |
prov_throughput = min(875, max(req_throughput - 125, 0)) | |
prov_throughput_price = 0.040 * prov_throughput | |
d = {} | |
d['price'] = storage_price + prov_iops_price + prov_throughput_price | |
d['iops'] = 3000 + prov_iops | |
d['throughput_max'] = 125 + prov_throughput | |
d['price_details'] = { | |
'storage' : storage_price, | |
'prov_iops': prov_iops_price, | |
'prov_throughput' : prov_throughput_price | |
} | |
return(d) | |
def transform_df(df): | |
""" | |
Given an input data frame, transport it to have a volume_type column. | |
This makes it easier to plot. | |
""" | |
melted_df = df.melt(id_vars=['size_gb'], value_vars=['price_gp2', 'price_gp3'], var_name='volume_type', value_name='price') | |
melted_df['volume_type'] = melted_df['volume_type'].apply(lambda x: x.split('_')[-1]) | |
return melted_df | |
def plot_df(df): | |
""" | |
Create a simple line plot of the price vs volume type | |
""" | |
sns.lineplot(x="size_gb", y="price", data=df, hue="volume_type") | |
plt.show() | |
def plot_df_2y(df_price, df_ratio): | |
""" | |
Create a two axis line plot where the left axis has the price comparison and the right | |
axis has the ratio | |
""" | |
fig, ax1 = plt.subplots() | |
sns.lineplot(x="size_gb", y="price", data=df_price, hue="volume_type", ax=ax1) | |
ax2 = ax1.twinx() | |
sns.lineplot(x="size_gb", y="ratio", data=df_ratio, color="yellow", ax=ax2) | |
plt.show() | |
## Iterate over sizes from 1GB to 16TB, in 100GB steps | |
sizes = range(1, 16000, 10) | |
prices = [] | |
for size_gb in sizes: | |
gp2 = lib2.mkGp2(size_gb) | |
gp3 = lib2.mkGp3(size_gb, gp2['iops'], gp2['throughput_max']) | |
x = { 'size_gb' : size_gb, | |
'price_gp2' : gp2['price'], | |
'price_gp3' : gp3['price'] | |
} | |
prices.append(x) | |
## Transform and plot data | |
df1 = pd.DataFrame(prices) | |
df2 = transform_df(df1) | |
price_ratio = df1.assign(ratio=df1["price_gp3"]/df1["price_gp2"])[['size_gb', 'ratio']] | |
price_ratio = price_ratio[price_ratio['size_gb'] > 1] | |
plot_df_2y(df2, price_ratio) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The following bit of Python code shows how the pricing simulation works.
Function: mkGp2 - Given a volume size, return a price (according to Feb 2023 us-east-1 pricing), as well as corresponding IOPS and throughput. Note: This does not take into account throughput bursting of gp2.
Function: mkGp3 - Given a volume size, IOPS, and throughput requirement, calculate a price. This function is used for calculating a price for a gp3 instance which is equivalent in performance to a gp2 instance.
Main: The main bit of code loops over volume sizes from 1GiB to 16TiB, in 10 GiB increments. For each volume size, it simulates a gp2 instance. Given the performance of the gp2 instance in terms of IOPS and throughput, it simulates an equivalent gp3 instance.
Plotting: This code uses the seaborn library for data visualization