Skip to content

Commit d832ac9

Browse files
Merge pull request #4354 from ovh/develop
Develop > Master deployment
2 parents 9cb4ead + f681661 commit d832ac9

File tree

97 files changed

+4384
-360
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+4384
-360
lines changed

pages/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,7 @@
784784
+ [AI Deploy - Tutorial - Deploy an interactive app for EDA and prediction using Streamlit](platform/ai/deploy_tuto_07_streamlit_eda_iris)
785785
+ [AI Deploy - Tutorial - Deploy and call a spam classifier with FastAPI](platform/ai/deploy_tuto_08_fastapi_spam_classifier)
786786
+ [AI Deploy - Tutorial - Create and deploy a Speech to Text application using Streamlit](platform/ai/deploy_tuto_09_streamlit_speech_to_text_app)
787+
+ [AI Deploy - Tutorial - How to load test your application with Locust](platform/ai/deploy_tuto_10_locust)
787788
+ [Data Analytics](public-cloud-data-analytics)
788789
+ [Data Processing](public-cloud-data-analytics-data-processing)
789790
+ [Concepts](public-cloud-data-analytics-data-processing-concepts)
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
---
2+
title: AI Deploy - Tutorial - How to load test your application with Locust
3+
slug: deploy/load-test-app
4+
routes:
5+
canonical: 'https://docs.ovh.com/gb/en/publiccloud/ai/deploy/load-test-app/'
6+
excerpt: Understand how you can easily benchmark your APIs and find their limits
7+
section: AI Deploy - Tutorials
8+
order: 10
9+
updated: 2023-03-13
10+
---
11+
12+
**Last updated 13th March, 2023.**
13+
14+
## Objective
15+
16+
The aim of this tutorial is to load test your deployed applications, by gradually querying your APIs with a load testing tool.
17+
Usually, your challenge is to forecast your compute needs, for example how many CPUs or GPUs will be required for 1000 API calls per hour and acceptable latency.
18+
19+
There are several applications to simulate the amount of users and requests that you may have to address.
20+
21+
In this tutorial, we will use one of them and interpret the results.
22+
23+
## Requirements
24+
25+
- Access to the [OVHcloud Control Panel](https://www.ovh.com/auth/?action=gotomanager&from=https://www.ovh.de/&ovhSubsidiary=de).
26+
- A [Public Cloud project](https://www.ovhcloud.com/de/public-cloud/) in your OVHcloud account.
27+
- An app with an API running in AI Deploy on your Public Cloud project.
28+
- A python environment, with enough CPU and RAM and internet access (a virtual machine is recommended).
29+
30+
### Selecting the right load testing tool for your needs
31+
32+
Depending on your preferred programming language and time to spend on this topic, you can opt for different options.
33+
34+
First you can go for a SaaS load tester, such as [Gatling.io](https://gatling.io/) or [K6.io](https://k6.io). Nothing to install, easy to start.
35+
36+
A second option is using open source load testing tools. Some tools are only command-line based, such as [hey](https://github.com/rakyll/hey) or [Wrk2](https://github.com/giltene/wrk2), others come with a web interface like [Locust](https://locust.io/).
37+
38+
Selecting the right tool for the right test is mandatory. For the next parts, **we will select and use Locust**, allowing us to show visual graphs.
39+
40+
## Instructions
41+
42+
### Deploy an app with a REST API
43+
44+
Feel free to deploy any app and API that you would like to load test, as long as you can query it via REST queries.
45+
46+
For this tutorial, we will load test a spam classifier API from the [AI Deploy app portfolio](https://docs.ovh.com/de/publiccloud/ai/deploy/apps-portfolio/).
47+
This API takes sentences (emails) as input text, and outputs a spam probability score.
48+
49+
You can deploy this API easily from the [OVHcloud control panel](https://www.ovh.com/auth/?action=gotomanager&from=https://www.ovh.de/&ovhSubsidiary=de) or [OVHcloud CLI](https://docs.ovh.com/de/publiccloud/ai/cli/install-client/). A good strategy is to deploy with autoscaling, with minimum and maximum replicas. This way we will monitor the growth of used replicas.
50+
51+
Here is the CLI command used to deploy it, with autoscaling going from 1 to 5 replicas and a CPU threshold of 75%:
52+
53+
```console
54+
ovhai app run --name spamclassifier --cpu 1 \
55+
--auto-min-replicas 1 \
56+
--auto-max-replicas 5 \
57+
--auto-resource-type CPU \
58+
--auto-resource-usage-threshold 75 \
59+
priv-registry.gra.training.ai.cloud.ovh.net/ai-deploy-portfolio/fastapi-spam-classification
60+
```
61+
62+
### Verify that your API is up and running with cURL
63+
64+
> [!primary]
65+
> To be able to connect to your AI Deploy app, you have to [create a token](https://docs.ovh.com/de/publiccloud/ai/cli/app-token-cli/) bearer for your OVHcloud AI user.
66+
>
67+
68+
Once deployed, let's test first our API with a simple cURL command. Here is the command to try in a terminal:
69+
70+
```console
71+
curl -s -X POST \
72+
"<api_url>/spam_detection_path \
73+
-H "Authorization: Bearer <token>" \
74+
-H "Content-Type: application/json" \
75+
-d '{"message":"This is a test from my machine"}' | jq
76+
```
77+
78+
Here is the result given by our call:
79+
80+
```console
81+
{
82+
"label": "ham",
83+
"label_probability": 0.9875114695528484
84+
}
85+
```
86+
87+
A few explanations on the lines above:
88+
89+
- In the first line, we specify that we will use a POST method.
90+
- We specify the url where the POST request will be executed. The `api_url` is the url of your API. It should be similar to: `https://baac2c13-2e69-4d0f-ae6b-dg9eff9be513.app.gra.ai.cloud.ovh.net/`.
91+
- We put the token to access our API, generated via the OVHcloud Control Panel or `ovhai` CLI. We specify it in the header of the request. If you want to know more about generation and use of tokens, you can follow [this tutorial](https://docs.ovh.com/de/publiccloud/ai/deploy/tokens/).
92+
- We specify that our body is in a JSON format.
93+
- We put in our body the message we want to send to the spam classifier. In your case, the body could be different because it depends of the API. Our objective is that the spam classifier will send us the probability of each response. The last `| jq` instruction allows us to have a good display of the result in the terminal.
94+
95+
We now have the confirmation that our API is up and running, let's try to load test it.
96+
97+
We will simply simulate several curl commands. With the Locust tool, we can simulate several users and define a number of calls per minute to the API. This can be easily done with Locust's interface. But before using this interface, we need to launch Locust and configure the tool. This can be easily done with python.
98+
99+
### Install locust.io
100+
101+
Locust is an open source Python package that you can install with one line of code. Follow their [official documentation](https://docs.locust.io/en/stable/index.html):
102+
103+
```console
104+
pip3 install locust
105+
```
106+
107+
You can install it on your personal computer, but keep in mind that load testing tools will require four elements to **not become the bottleneck in your load test**:
108+
109+
- Enough compute (CPU).
110+
- Enough memory (RAM).
111+
- Low latency connectivity to your API.
112+
- No "noisy neighbors", meaning no software installed that can compromise your results. Imagine your CPU power getting used by video rendering, it will bias your results.
113+
114+
For all these reasons, a **Public Cloud instance is recommended**, such as a medium-sized virtual machine. For this tutorial, we will use an OVHcloud B2-30 instance.
115+
116+
### Configure Locust
117+
118+
To configure the software, you need to create a file named `locustfile.py`. In this file, you can put the path where you want to make your request, the headers of your request, the type of the request (POST, GET, etc) and the body if you want to add a body to the request.
119+
120+
A generic file will look like this:
121+
122+
```python
123+
from locust import HttpUser, task
124+
125+
class HelloWorldUser(HttpUser):
126+
@task
127+
def hello_world(self):
128+
self.client.get("/hello")
129+
self.client.get("/world")
130+
```
131+
132+
For our API and our needs, the locust file will be slightly modified:
133+
134+
```python
135+
# Import the Locust dependencies
136+
from locust import HttpUser, task
137+
138+
# Import general library from python
139+
import os
140+
import random
141+
142+
# Import lorem ipsum library to generate some random texts
143+
from lorem_text import lorem
144+
145+
# Import dotenv to load the environments variables
146+
from dotenv import load_dotenv
147+
load_dotenv()
148+
149+
# Create a table with some lorem ipsum texts
150+
messages = []
151+
152+
# Add 1000 random texts of 10 paragraphs each (simulate 1000 emails)
153+
for i in range(1000):
154+
messages.append(lorem.paragraphs(10))
155+
156+
# Define the headers of the request. Token is stored as an environment variable here
157+
headers = {
158+
"Authorization": "Bearer {os.getenv('TOKEN')}", "Content-Type": "application/json"}
159+
160+
161+
class HelloWorldUser(HttpUser):
162+
# Definition of the first path where we do our post request
163+
@task
164+
def hello_world(self):
165+
# Define the body with the email choose randomly from the tab of all the emails
166+
body = {"message": random.choice(messages)}
167+
# Do the post request on the spam detection path
168+
self.client.post("/spam_detection_path",
169+
headers=headers, json=body)
170+
```
171+
172+
For your own needs, you will have to change the path, the headers and the body because these are parameters which change from one API to another.
173+
174+
Once your `locustfile.py` is ready, open the Locust web interface on `<http://your_IP:8089>`.
175+
176+
The web interface should look as below:
177+
178+
![image](images/locust.png){.thumbnail}
179+
180+
### Run your load tests
181+
182+
You now have your app running on OVHcloud, and Locust configured. Let's simulate some user calls.
183+
184+
From the web interface, fill in the amount of simultaneous users (API calls) and incremental step (spaw rate).
185+
186+
For this tutorial, we will add 480 users in total, and a spawn rate of 2 users added per second. We will simulate this for a duration of 4 minutes. We suppose that this case is for a rush on the API. Most of the times, we can assume that there aren't so many users on the platform.
187+
188+
Launch the test.
189+
190+
### Interpret the results via Locust
191+
192+
At the end of the load test, you will see this quick summary:
193+
194+
![image](images/result_locust.png){.thumbnail}
195+
196+
If we want to get more details about our test, we can see the graphs provided by Locust in the `charts` tab. Here is what we can see:
197+
198+
![image](images/locust_graphs.png){.thumbnail}
199+
200+
We deployed this API from 1 to 5 replicas, with 1 CPU for each of them, completed with auto-scaling. We can see that our API has been a bit overloaded. Indeed, with the graphics or with the quick summary, we can see some failures. These failures are due to server errors. We may suppose that we reached some hardware limits at some point, for example before scaling to a greater amount of replicas.
201+
202+
Also, we can see an increasing call latency over time. At the end, we can expect more than 3 seconds per call.
203+
204+
Result interpretation may depend of your needs and performance criterias. We can of course make a new test with more users to see the limits of our APIs, and put several tasks in the `locustfile.py`.
205+
206+
One thing can not be seen here: OVHcloud backend scaling. We deployed our app with autoscaling, from 1 replica minimum to 5 replicas maximum.
207+
Did we use them ? Were they useful and at maximum capacity?
208+
209+
Let's see the same results in details with the AI Deploy monitoring tool.
210+
211+
### Interpret the results with the AI Deploy Monitoring
212+
213+
Go in the OVHcloud Control Panel and get the detail of your deployed application. Click on the `Access Dashboards`{.action} button.
214+
215+
This dashboard is provided for free in AI Deploy, for each deployed application. All of the deployed apps are combined in a simple Grafana Dashboard.
216+
217+
You can select the deployed app at the top of this Grafana dashboard, as shown below:
218+
219+
![image](images/general_dashboard.png){.thumbnail}
220+
221+
With this dashboard, you can see the percentage of CPU used in real time, the HTTP latency of your API, the autoscaling of the app, network bandwidth and more.
222+
Vertical blue bars show scaling events.
223+
224+
Here is the result for the CPU load, overall (all replicas combined):
225+
226+
![image](images/cpu_spam.png){.thumbnail}
227+
228+
We can see that our app has scaled a few times and hasn't reach maximum capacity usage, thanks to autoscaling. Let's now take a look at the latency of our application:
229+
230+
![image](images/latency_spam.png){.thumbnail}
231+
232+
Here we see that the latency has increased gradually, since we have a spawn rate of two new users per second. API latency was stable with approximately 750ms then peaked to 1.5s.
233+
234+
Again, interpretation will depend on your needs. Do we need to provide more CPU because the latency is too high? This question will vary depending on your customers need. For an anti-spam, adding 1 second is quite big for a company receiving thousands of mails per day, not so disturbing if it's a dozen per day. Let's now take a look at the scaling of our application:
235+
236+
![image](images/scaling_spam.png){.thumbnail}
237+
238+
We can see that the threshold has been capped at 75% for the autoscaling and this has been respected. On the 5 replicas provided to the application, 4 have been used.
239+
240+
As a conclusion, both Locust and AI Deploy Monitoring are useful to interpret results but, more than tools, the most important thing is to define realistic workloads and performance criterias.
241+
242+
Last point : while Locust is measuring an end-to-end latency (from Locust virtual machine here, to the API model deployed), AI Deploy monitoring is only measuring backbone latency (from the query to the answer). That's why latency values are higher on Locust side, reaching 2.5 seconds.
243+
244+
## Go further
245+
246+
Locust official documentation : [Locust.io](https://docs.locust.io/en/stable/)
247+
248+
Comparison of load testing tools : [Comparison of load testing tools](https://k6.io/blog/comparing-best-open-source-load-testing-tools/)
249+
250+
## Feedback
251+
252+
Please send us your questions, feedback and suggestions to improve the service:
253+
254+
- On the OVHcloud [Discord server](https://discord.com/invite/vXVurFfwe9)

0 commit comments

Comments
 (0)