In this post we will review NATS partitioning and how to use it to split load among multiple pods.
We've already reviewed the steps to setup a NATS cluster in kubernetes in this post. As part of the NATS statefulset template we have a config map, which is mounted into the NATS server container.
- name: nats
args:
- --config
- /etc/nats-config/nats.conf
volumeMounts:
- mountPath: /etc/nats-config
name: config
volumes:
- configMap:
name: nats-config
The ConfigMap is as follows:
apiVersion: v1
kind: ConfigMap
metadata:
name: nats-config
data:
nats.conf: |
{
"cluster": {
"name": "nats",
"no_advertise": true,
"port": 6222,
"routes": [
"nats://nats-0.nats-headless:6222",
"nats://nats-1.nats-headless:6222"
]
},
"http_port": 8222,
"lame_duck_duration": "30s",
"lame_duck_grace_period": "10s",
"pid_file": "/var/run/nats/nats.pid",
"port": 4222,
"server_name": $SERVER_NAME,
"mappings": {
"application.*": "application.{{partition(3,1)}}.{{wildcard(1)}}"
}
}
The NATS partitioning is configured by the mapping section in the config. In this case the producer publish messages to the NATS queue "application-<APPLICATION_ID>".
We want to split the load among 3 pods, and hence we configure the following:
"application.*": "application.{{partition(3,1)}}.{{wildcard(1)}}"
This provides the following instruction to the NATS:
Take the value used in the first wild card "application.*" , and use it to split into 3 partitions 0,1,2. Then publish the message in the following queue "application.<PARTITION_ID>.<APPLICATION ID>".
Now we can have 3 pods, each subsribing to the prefix: "application.<PARTITION_ID>.*", and the messages are split accordingly. Notice that a specific APPLICATION ID is always assigned to the same PARTITION_ID.
Also notice that this is a static assignment, regardless of the load on each application. In case we have hightly unbalanced applications load, this might not be a suitable method.
No comments:
Post a Comment