Skip to content

Commit 03522b9

Browse files
authored
Clarified A/B/n tutorial and user guide (#60)
* clarified abn documentation Signed-off-by: Michael Kalantar <[email protected]> * clarified abn documentation Signed-off-by: Michael Kalantar <[email protected]> --------- Signed-off-by: Michael Kalantar <[email protected]>
1 parent b7c3220 commit 03522b9

File tree

4 files changed

+101
-139
lines changed

4 files changed

+101
-139
lines changed

docs/tutorials/abn/abn.md

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,7 @@ template: main.html
44

55
# A/B Experiments
66

7-
A/B testing an application's backend component is challenging.
8-
A/B testing typically relies on business metrics computed by a frontend, user-facing, service.
9-
Metric values often depend on one or more interactions with backend (not user-facing) components.
10-
To A/B test a backend component, it is necessary to be able to associate a metric value (computed by the frontend) to the version of the backend component that contributed to its computation.
11-
The challenge is that the frontend service often does not know which version of the backend component processed a given request.
12-
13-
To address this challenge, Iter8 introduces an A/B/n SDK which provides a frontend service with two APIs:
14-
15-
a. **Lookup()** - identifies a version of a backend component to send a request to
16-
17-
b. **WriteMetric()** - associates a metric with a backend component
18-
19-
This SDK, implemented using gRPC, can be used from a number of frontend implementation languages including *Node.js*, *Python*, *Ruby*, and *Go*, among others. Details of the Iter8 SDK are documented in the [gRPC protoc file](https://github.com/iter8-tools/iter8/blob/v0.13.0/abn/grpc/abn.proto).
20-
21-
This tutorial describes an A/B testing experiment for a backend component.
22-
Example implementations of frontend components are provided in *Node.js* and *Go*.
7+
This tutorial describes an [A/B testing](../../user-guide/topics/ab_testing.md) experiment for a backend component.
238

249
<p align='center'>
2510
<img alt-text="A/B/n experiment" src="../images/abn.png" />
@@ -32,7 +17,7 @@ Example implementations of frontend components are provided in *Node.js* and *Go
3217

3318
## Launch Iter8 A/B/n service
3419

35-
Deploy the Iter8 A/B/n service. When deploying the service, specify which Kubernetes resources to watch for each application. To watch for versions of the *backend* application in the *default* namespace, configure the service to watch for service and deployment resources:
20+
Deploy the Iter8 A/B/n service. When deploying the service, specify which Kubernetes resource types to watch for each application. To watch for versions of the *backend* application in the *default* namespace, configure the service to watch for Kubernetes service and deployment resources:
3621

3722
```shell
3823
helm install --repo https://iter8-tools.github.io/hub iter8-abn abn \
@@ -42,17 +27,20 @@ helm install --repo https://iter8-tools.github.io/hub iter8-abn abn \
4227
??? warn "Assumptions"
4328
To simplify specification, Iter8 assumes certain conventions:
4429

45-
- resources of all versions are deployed to the same namespace
46-
- there is only one resource of each resource type among the resources of a version
47-
- all resources that comprise the baseline version are named as: _&lt;application\_name&gt;_
48-
- all resources that comprise the i<sup>th</sup> candidate version are named as: _&lt;application\_name&gt;-candidate-&lt;i&gt;_
30+
- The baseline track identifier is the application name
31+
- Track identifiers associated with candidate versions are of the form `<application_name>-candidate-<index>`
32+
- All resource objects for all versions are deployed in the same namespace
33+
- There is only 1 resource object of a given type in each version
34+
- The name of each object in the version associated with the baseline track is the application name
35+
- The name of each object in the version associate with a candidate track is of the form `<application_name>-candidate-<index>` where index is 1, 2, etc.
36+
4937

5038
## Deploy the sample application
5139

5240
Deploy both the frontend and backend components of the application as described in each tab:
5341

5442
=== "frontend"
55-
Install the frontend service using an implementation in the language of your choice:
43+
Install the frontend component using an implementation in the language of your choice:
5644

5745
=== "node"
5846
```shell
@@ -66,10 +54,10 @@ Deploy both the frontend and backend components of the application as described
6654
kubectl expose deployment frontend --name=frontend --port=8090
6755
```
6856

69-
The frontend service is implemented to call **Lookup()** before each call to the backend service. It sends its request to the recommended backend service.
57+
The frontend component is implemented to call *Lookup()* before each call to the backend component. The frontend componet uses the returned track identifier to route the request to a version of the backend component.
7058

7159
=== "backend"
72-
Deploy version *v1* of the *backend* component as track *backend*.
60+
Deploy version *v1* of the *backend* component, associating it with the track identifier *backend*.
7361

7462
```shell
7563
kubectl create deployment backend --image=iter8/abn-sample-backend:0.13-v1
@@ -78,23 +66,19 @@ Deploy both the frontend and backend components of the application as described
7866
kubectl expose deployment backend --name=backend --port=8091
7967
```
8068

81-
Before calling the backend, the frontend uses *Lookup()* to identify the track to send requests to. Since there is only one version of the backend deployed, all requests will be sent to it.
82-
8369
## Generate load
8470

85-
Generate load. In separate shells, port-forward requests to the frontend service and generate load for multiple users. For example:
71+
Generate load. In separate shells, port-forward requests to the frontend component and generate load for multiple users. A [script](https://raw.githubusercontent.com/iter8-tools/docs/main/samples/abn-sample/generate_load.sh) is provided to do this. To use it:
8672
```shell
8773
kubectl port-forward service/frontend 8090:8090
8874
```
8975
```shell
9076
curl -s https://raw.githubusercontent.com/iter8-tools/docs/main/samples/abn-sample/generate_load.sh | sh -s --
9177
```
9278

93-
Note that the the names `foo` and `foobar` are examples. They may be mapped to the same track label -- since we are using
94-
9579
## Deploy a candidate version
9680

97-
Deploy version *v2* of the *backend* component as track *backend-candidate-1*.
81+
Deploy version *v2* of the *backend* component, associating it with the track identifier *backend-candidate-1*.
9882

9983
```shell
10084
kubectl create deployment backend-candidate-1 --image=iter8/abn-sample-backend:0.13-v2
@@ -103,8 +87,8 @@ kubectl label deployment backend-candidate-1 app.kubernetes.io/version=v2
10387
kubectl expose deployment backend-candidate-1 --name=backend-candidate-1 --port=8091
10488
```
10589

106-
Until the candidate version is ready; that is, until all expected resources are deployed and available, calls to *Lookup()* will continue to return only the *backend* track.
107-
Once the candidate version is ready, *Lookup()* will return both tracks so that requests will be distributed between them.
90+
Until the candidate version is ready; that is, until all expected resources are deployed and available, calls to *Lookup()* will return only the *backend* track identifier.
91+
Once the candidate version is ready, *Lookup()* will return both track identifiers so that requests will be distributed between versions.
10892

10993
## Launch experiment
11094

@@ -117,7 +101,7 @@ iter8 k launch \
117101
```
118102

119103
??? note "About this experiment"
120-
This experiment periodically (in this case, once a minute) reads the `abn` metrics associated with the *backend* application component in the *default* namespace. These metrics are written by the frontend service using the *WriteMetric()* interface as a part of processing user requests.
104+
This experiment periodically (in this case, once a minute) reads the `abn` metrics associated with the *backend* application component in the *default* namespace. These metrics are written by the frontend component using the *WriteMetric()* interface as a part of processing user requests.
121105

122106
## Inspect experiment report
123107

@@ -149,9 +133,9 @@ iter8 k report
149133
abn/sample_metric/min | 0.00 | 1.00
150134
abn/sample_metric/stddev | 28.52 | 31.91
151135
```
152-
The output allows you to compare the versions against each other and select a winner. Since the experiment runs periodically, you should expect the values in the report to change over time.
136+
The output allows you to compare the versions against each other and select a winner. Since the experiment runs periodically, the values in the report will change over time.
153137

154-
Once a winner is identified, the experiment can be terminated and the winner can be promoted and the candidate versions can be deleted.
138+
Once a winner is identified, the experiment can be terminated, the winner can be promoted, and the candidate version(s) can be deleted.
155139

156140
To delete the experiment:
157141

@@ -168,14 +152,11 @@ kubectl delete deployment backend-candidate-1
168152
kubectl delete service backend-candidate-1
169153
```
170154

171-
Update the version of the baseline track:
155+
Update the version associated with the baseline track identifier *backend*:
172156

173157
```shell
174158
kubectl set image deployment/backend abn-sample-backend=iter8/abn-sample-backend:0.13-v2
175159
kubectl label --overwrite deployment/backend app.kubernetes.io/version=v2
176-
177-
# no change in service
178-
# kubectl expose deployment backend --name=backend --port=8091
179160
```
180161

181162
## Cleanup

0 commit comments

Comments
 (0)