Session Affinity¶
Scenario: A/B testing with session affinity (sticky sessions)
Session affinity ensures that the version to which a particular user's request is routed remains consistent throughout the duration of the experiment. In this tutorial, you will use a FixedSplit deployment in conjunction with session affinity.
The experiment will involve two user groups, 1 and 2. Reqeusts from user group 1 will have a userhash
header value prefixed with 111
and will be routed to the baseline version. Requests from user group 2 will have a userhash
header value prefixed with 101
and will be routed to the candidate version.
The session affinity experiment is depicted below.
Before you begin...
This tutorial is available for the following K8s stacks.
Please choose the same K8s stack consistently throughout this tutorial. If you wish to switch K8s stacks between tutorials, start from a clean K8s cluster, so that your cluster is correctly setup.
Steps 1 to 3¶
Please follow steps 1 through 3 of the quick start tutorial.
4. Create versions and initialize routing rule¶
kubectl apply -f $ITER8/samples/kfserving/quickstart/baseline.yaml
kubectl apply -f $ITER8/samples/kfserving/quickstart/candidate.yaml
kubectl apply -f $ITER8/samples/kfserving/session-affinity/routing-rule.yaml
kubectl wait --for=condition=Ready isvc/flowers -n ns-baseline
kubectl wait --for=condition=Ready isvc/flowers -n ns-candidate
Virtual service with routing rule
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
5. Generate requests¶
Generate requests to your model as follows.
INGRESS_GATEWAY_SERVICE=$(kubectl get svc -n istio-system --selector="app=istio-ingressgateway" --output jsonpath='{.items[0].metadata.name}')
kubectl port-forward -n istio-system svc/${INGRESS_GATEWAY_SERVICE} 8080:80
curl -o /tmp/input.json https://raw.githubusercontent.com/kubeflow/kfserving/master/docs/samples/v1beta1/rollout/input.json
while true; do
curl -v -H "Host: example.com" -H "userhash: 1111100000" localhost:8080/v1/models/flowers:predict -d @/tmp/input.json
sleep 0.29
done
curl -o /tmp/input.json https://raw.githubusercontent.com/kubeflow/kfserving/master/docs/samples/v1beta1/rollout/input.json
while true; do
curl -v -H "Host: example.com" -H "userhash: 1010101010" localhost:8080/v1/models/flowers:predict -d @/tmp/input.json
sleep 2.0
done
6. Define metrics¶
Please follow Step 6 of the quick start tutorial.
7. Launch experiment¶
kubectl apply -f $ITER8/samples/kfserving/session-affinity/experiment.yaml
Look inside experiment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
The process automated by Iter8 during this experiment is depicted below.
8. Observe experiment¶
Please follow Step 8 of the quick start tutorial to observe the experiment in realtime. Note that the experiment in this tutorial uses a different name from the quick start one. Replace the experiment name quickstart-exp
with session-affinity-exp
in your commands. You can also observe traffic by suitably modifying the commands for observing traffic.
Understanding what happened
- You created two versions of your app/ML model.
- You generated requests for your app/ML model versions. Throughout the experiment, users from Group 1 (i.e., users whose requests had a
userhash
header value prefixed with111
) were routed to the baseline version; and users from Group 2 (i.e., users whose requests had auserhash
header value prefixed with101
) were routed to the candidate version. - You created an Iter8 experiment with A/B testing pattern and FixedSplit deployment pattern. In each iteration, Iter8 observed the latency and error-rate metrics collected by Prometheus, and the user-engagement metric from New Relic; Iter8 verified that the candidate satisfied all objectives, verified that the candidate improved over the baseline in terms of user-engagement, identified candidate as the winner, and finally promoted the candidate.
9. Cleanup¶
kubectl delete -f $ITER8/samples/kfserving/session-affinity/experiment.yaml
kubectl delete -f $ITER8/samples/kfserving/session-affinity/routing-rule.yaml
kubectl delete -f $ITER8/samples/kfserving/quickstart/candidate.yaml
kubectl delete -f $ITER8/samples/kfserving/quickstart/baseline.yaml