Performance Certification of Couchbase Autonomous Operator on Kubernetes
Take a look at detailed performance results from running YCSB Performance benchmark tests on Couchbase Server 5.5.
Join the DZone community and get the full member experience.
Join For FreeAt Couchbase, we take performance very seriously, and with the launch of our new product, Couchbase Autonomous Operator 1.0, we wanted to make sure it’s Enterprise-grade and production ready for customers.
In this post, we will discuss the detailed performance results from running YCSB Performance Benchmark tests on Couchbase Server 5.5 using the Autonomous Operator to deploy on Kubernetes platform. One of the big concerns for Enterprises planning to run a database on Kubernetes is "performance."
This document gives a quick comparison of two workloads, namely YCSB A & E with Couchbase Server 5.5 on Kubernetes vs. bare metal.
YCSB Workload A: This workload has a mix of 50/50 reads and writes. An application example is a session store recording recent actions.
Workload E: Short ranges: In this workload, short ranges of records are queried, instead of individual records. Application example: threaded conversations, where each scan is for the posts in a given thread (assumed to be clustered by thread id).
In general, we observed no significant performance degradation in running Couchbase Cluster on Kubernetes, Workload A had on par performance compared to bare metal and Workload E had approximately less than 10% degradation.
Setup
For the setup, Couchbase was installed using the Operator deployment as stated below. For more details on the setup, please refer here.
Files
Operator deployment: deployment.yaml (See Appendix)
Couchbase deployment: couchbase-cluster-simple-selector.yaml (See Appendix)
Client / workload generator deployment: pillowfight-ycsb.yaml (See Appendix) (Official pillowfight docker image from dockerhub and installed java and YCSB manually on top of it)
Hardware
7 servers
24 CPU x 64GB RAM per server
Couchbase Setup
4 servers: 2 data nodes, 2 index+query nodes
40GB RAM quota for data service
40GB RAM quota for index services
1 data/bucket replica
1 primary index replica
Tests
YCSB WorkloadA and WorkloadE
10M docs
Workflow after new empty k8s cluster is initialized on 7 servers:
# assign labels to the nodes so all services/pods will be assigned to right servers: kubectl label nodes arke06-sa09 type=power kubectl label nodes arke07-sa10 type=client kubectl label nodes ark08-sa11 type=client kubectl label nodes arke01-sa04 type=kv kubectl label nodes arke00-sa03 type=kv kubectl label nodes arke02-sa05 type=kv kubectl label nodes arke03-sa06 type=kv |
#deploy Operator: kubectl create -f deployment.yaml #deploy Couchbase kubectl create -f couchbase-cluster-simple-selector.yaml #deploy Client(s): kubectl create -f pillowfight-ycsb.yaml I ran my tests directly from the client node by logging into the docker image of the client pod: docker exec -it --user root <pillowfight-yscb container id> bash And installing YCSB environment there manually: apt-get upgrade apt-get update apt-get install -y software-properties-common apt-get install python sudo apt-add-repository ppa:webupd8team/java sudo apt-get update sudo apt-get install oracle-java8-installer export JAVA_HOME=/usr/lib/jvm/java-8-oracle cd /opt wget http://download.nextag.com/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz sudo tar -xvzf apache-maven-3.5.4-bin.tar.gz export M2_HOME="/opt/apache-maven-3.5.4" export PATH=$PATH:/opt/apache-maven-3.5.4/bin sudo update-alternatives --install "/usr/bin/mvn" "mvn" "/opt/apache-maven-3.5.4/bin/mvn" 0 sudo update-alternatives --set mvn /opt/apache-maven-3.5.4/bin/mvn git clone http://github.com/couchbaselabs/YCSB |
Running the workloads:
Examples of YCSB commands used in this exercise: Workload A Load: ./bin/ycsb load couchbase2 -P workloads/workloade -p couchbase.password=password -p couchbase.host=10.44.0.2 -p couchbase.bucket=default -p couchbase.upsert=true -p couchbase.epoll=true -p couchbase.boost=48 -p couchbase.persistTo=0 -p couchbase.replicateTo=0 -p couchbase.sslMode=none -p writeallfields=true -p recordcount=10000000 -threads 50 -p maxexecutiontime=3600 -p operationcount=1000000000 Run: ./bin/ycsb run couchbase2 -P workloads/workloada -p couchbase.password=password -p couchbase.host=10.44.0.2 -p couchbase.bucket=default -p couchbase.upsert=true -p couchbase.epoll=true -p couchbase.boost=48 -p couchbase.persistTo=0 -p couchbase.replicateTo=0 -p couchbase.sslMode=none -p writeallfields=true -p recordcount=10000000 -threads 50 -p operationcount=1000000000 -p maxexecutiontime=600 -p exportfile=ycsb_workloadA_22vCPU.log |
Test results:
Env | Direct setup | Kubernetes pod resources | Test | Bare metal | Kubernetes | Delta |
Env 1 | 22 vCPU, 48 GB RAM (cpu cores and RAM available are set on OS core level) |
Limit to: cpu: 22000m = ~22vCPU mem: 48GB All pods are on dedicated nodes |
WorkloadA 50/50 get/upsert |
Throughput: 194,158req/sec CPU usage avg: 86% of all 22 cores |
Throughput: 192,190req/sec CPU usage avg: 94% of the cpu quota |
– 1% |
Env 2 | 16 vCPU, 48 GB RAM (cpu cores and RAM available are set on OS core level) |
Limit to: cpu: 16000m = ~16vCPU mem: 48GB All pods are on dedicated nodes |
WorkloadA 50/50 get/upsert |
Throughput: 141,909req/sec CPU usage avg: 89% of all 16 cores |
Throughput: 145,430req/sec CPU usage avg: 100% of the cpu quota |
+ 2.5% |
Workload E: Load: ./bin/ycsb load couchbase2 -P workloads/workloade -p couchbase.password=password -p couchbase.host=10.44.0.2 -p couchbase.bucket=default -p couchbase.upsert=true -p couchbase.epoll=true -p couchbase.boost=48 -p couchbase.persistTo=0 -p couchbase.replicateTo=0 -p couchbase.sslMode=none -p writeallfields=true -p recordcount=10000000 -threads 50 -p maxexecutiontime=3600 -p operationcount=1000000000 Run: ./bin/ycsb run couchbase2 -P workloads/workloade -p couchbase.password=password -p couchbase.host=10.44.0.2 -p couchbase.bucket=default -p couchbase.upsert=true -p couchbase.epoll=true -p couchbase.boost=48 -p couchbase.persistTo=0 -p couchbase.replicateTo=0 -p couchbase.sslMode=none -p writeallfields=true -p recordcount=10000000 -threads 50 -p operationcount=1000000000 -p maxexecutiontime=600 -p exportfile=ycsb_workloadE_22vCPU.log |
Env | Direct setup | Kubernetes pod resources | Test | Bare metal | Kubernetes | Delta |
Env 1 | 22 vCPU, 48 GB RAM (cpu cores and RAM available are set on OS core level) |
Limit to: cpu: 22000m = ~22vCPU mem: 48GB All pods are on dedicated nodes |
WorkloadE 95/5 scan/insert |
Throughput: 15,823req/sec CPU usage avg: 85% of all 22 cores |
Throughput: 14,281req/sec CPU usage avg: 87% of the cpu quota |
– 9.7% |
Env 2 | 16 vCPU, 48 GB RAM (cpu cores and RAM available are set on OS core level) |
Limit to: cpu: 16000m = ~16vCPU mem: 48GB All pods are on dedicated nodes |
WorkloadE 95/5 scan/insert |
Throughput: 13,014req/sec CPU usage avg: 91% of all 16 cores |
Throughput: 12,579req/sec CPU usage avg: 100% of the cpu quota |
– 3.3% |
Conclusions
Couchbase Server 5.5 is production ready to be deployed on Kubernetes with the Autonomous Operator. Performance of Couchbase Server 5.5 on Kubernetes comparable to running on bare metal. There is little performance penalty in running Couchbase Server on Kubernetes platform. Looking at the results Workload A had on par performance compared to bare metal and Workload E had approximately less than 10% degradation.
References
- YCSB Workloads https://github.com/brianfrankcooper/YCSB/wiki/Core-Workloads
- Couchbase Kubernetes page https://www.couchbase.com/products/cloud/kubernetes
- Download Couchbase Autonomous Operator https://www.couchbase.com/downloads
- Introducing Couchbase Operator https://blog.couchbase.com/couchbase-autonomous-operator-1-0-for-kubernetes-and-openshift/
Appendix
My deployment.yaml file:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: couchbase-operator
spec:
replicas: 1
template:
metadata:
labels:
name: couchbase-operator
spec:
nodeSelector:
type: power
containers:
- name: couchbase-operator
image: couchbase/couchbase-operator-internal:1.0.0-292
command:
- couchbase-operator
# Remove the arguments section if you are installing the CRD manually
args:
- -create-crd
- -enable-upgrades=false
env:
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- name: readiness-port
containerPort: 8080
readinessProbe:
httpGet:
path: /readyz
port: readiness-port
initialDelaySeconds: 3
periodSeconds: 3
failureThreshold: 19
My couchbase-cluster-simple-selector.yaml file:
apiVersion: couchbase.database.couchbase.com/v1
kind: CouchbaseCluster
metadata:
name: cb-example
spec:
baseImage: couchbase/server
version: enterprise-5.5.0
authSecret: cb-example-auth
exposeAdminConsole: true
antiAffinity: true
exposedFeatures:
- xdcr
cluster:
dataServiceMemoryQuota: 40000
indexServiceMemoryQuota: 40000
searchServiceMemoryQuota: 1000
eventingServiceMemoryQuota: 1024
analyticsServiceMemoryQuota: 1024
indexStorageSetting: memory_optimized
autoFailoverTimeout: 120
autoFailoverMaxCount: 3
autoFailoverOnDataDiskIssues: true
autoFailoverOnDataDiskIssuesTimePeriod: 120
autoFailoverServerGroup: false
buckets:
- name: default
type: couchbase
memoryQuota: 20000
replicas: 1
ioPriority: high
evictionPolicy: fullEviction
conflictResolution: seqno
enableFlush: true
enableIndexReplica: false
servers:
- size: 2
name: data
services:
- data
pod:
nodeSelector:
type: kv
resources:
limits:
cpu: 22000m
memory: 48Gi
requests:
cpu: 22000m
memory: 48Gi
- size: 2
name: qi
services:
- index
- query
pod:
nodeSelector:
type: kv
resources:
limits:
cpu: 22000m
memory: 48Gi
requests:
cpu: 22000m
memory: 48Gi
My pillowfight-ycsb.yaml file:
apiVersion: batch/v1
kind: Job
metadata:
name: pillowfight
spec:
template:
metadata:
name: pillowfight
spec:
containers:
- name: pillowfight
image: sequoiatools/pillowfight:v5.0.1
command: ["sh", "-c", "tail -f /dev/null"]
restartPolicy: Never
nodeSelector:
type: client
Published at DZone with permission of Raju Suravarjjala. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments