# Benchmark MongoDB with YCSB

## In this learning path

- [Introduction](https://learn.arm.com/learning-paths/servers-and-cloud-computing/glibc-with-lse/)
- [Build Glibc with LSE](https://learn.arm.com/learning-paths/servers-and-cloud-computing/glibc-with-lse/build_glibc_with_lse/)
- [Start MongoDB utilizing the newly built Glibc with LSE](https://learn.arm.com/learning-paths/servers-and-cloud-computing/glibc-with-lse/mongo_start/)
- [Benchmark MongoDB with YCSB](https://learn.arm.com/learning-paths/servers-and-cloud-computing/glibc-with-lse/mongo_benchmark/)
- [Compare the results with LSE and NoLSE](https://learn.arm.com/learning-paths/servers-and-cloud-computing/glibc-with-lse/compare_result/)
- [Next Steps](https://learn.arm.com/learning-paths/servers-and-cloud-computing/glibc-with-lse/_next-steps/)

YCSB (Yahoo! Cloud Serving Benchmark) is a widely adopted open-source benchmarking tool designed to evaluate the performance of cloud-based or distributed data-serving systems. It was developed by Yahoo! and is now maintained by the open-source community.

The primary goal of YCSB is to simulate different types of workloads commonly encountered in real-world cloud applications, such as read-heavy or write-heavy workloads. It provides a standardized framework for testing and comparing the performance of various data-serving systems, including databases, key-value stores, and distributed storage systems.

YCSB supports a variety of popular data-serving systems, including Apache Cassandra, MongoDB, Redis, HBase, Amazon DynamoDB, and more. It provides a set of workload scenarios that can be customized to simulate specific application patterns and data access patterns.

Using YCSB, you can measure key performance metrics like throughput, latency, and scalability of the target data-serving system under different workloads. This helps in evaluating the system’s suitability for specific use cases, comparing different systems, and identifying performance bottlenecks or areas for optimization.

YCSB is a command-line tool that provides a simple and extensible framework for benchmarking. It allows users to define their own workloads, extend it for new systems, and customize parameters such as the data distribution, request rate, and operation mix.

Overall, YCSB has become a standard benchmarking tool in the cloud and distributed systems community, facilitating performance evaluations and enabling fair comparisons between various data-serving solutions.

You are now ready to benchmark MongoDB with YCSB on your Arm server!

## YCSB Setup

Install Java on your machine:

```bash
sudo apt-get install -y openjdk-11-jdk
```

Download and uncompress the YCSB Benchmark source:

```bash
cd ~
wget -c https://github.com/brianfrankcooper/YCSB/releases/download/0.17.0/ycsb-0.17.0.tar.gz
tar xfvz ycsb-0.17.0.tar.gz
```

Using a file editor of your choice, create a workload file `~/ycsb-0.17.0/workloads/iworkload`. Copy and save the following content into this file:

```
recordcount=1000
operationcount=1000
workload=site.ycsb.workloads.CoreWorkload
readallfields=true
readproportion=0.2
updateproportion=0.3
scanproportion=0.3
insertproportion=0
readmodifywriteproportion=0.2
requestdistribution=zipfian
```

## Run YCSB

To run YCSB, you need to follow the `load` command first:

```bash
~/ycsb-0.17.0/bin/ycsb.sh load mongodb -s -P ~/ycsb-0.17.0/workloads/iworkload -p recordcount=10000000 -threads 256 -p mongodb.url="mongodb://${mongo_ip}:${mongo_port}/mymongodb"
```

Replace `mongo_ip` and `mongo_port` in the command above with the IP address and port number of the machine you are running MongoDB on.

You should see the result from the benchmark after the `load` command finishes:

```
__output__ /usr/bin/java  -classpath /root/workload/tools/ycsb-0.17.0/conf:/root/workload/tools/ycsb-0.17.0/lib/core-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/lib/HdrHistogram-2.1.4.jar:/root/workload/tools/ycsb-0.17.0/lib/htrace-core4-4.1.0-incubating.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-core-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-mapper-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-classic-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-core-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-async-driver-2.0.1.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-binding-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongo-java-driver-3.8.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/slf4j-api-1.7.25.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/snappy-java-1.1.7.1.jar site.ycsb.Client -load -db site.ycsb.db.MongoDbClient -s -P /root/workload/tools/ycsb-0.17.0/workloads/iworkload -p recordcount=10000000 -threads 256 -p mongodb.url=mongodb://172.26.202.189:27017/mymongodb
__output__ mongo client connection created with mongodb://172.26.202.189:27017/mymongodb
__output__ [OVERALL], RunTime(ms), 241978
__output__ [OVERALL], Throughput(ops/sec), 41326.07096512906
__output__ [TOTAL_GCS_G1_Young_Generation], Count, 334
__output__ [TOTAL_GC_TIME_G1_Young_Generation], Time(ms), 723
__output__ [TOTAL_GC_TIME_%_G1_Young_Generation], Time(%), 0.2987874930778831
__output__ [TOTAL_GCS_G1_Old_Generation], Count, 0
__output__ [TOTAL_GC_TIME_G1_Old_Generation], Time(ms), 0
__output__ [TOTAL_GC_TIME_%_G1_Old_Generation], Time(%), 0.0
__output__ [TOTAL_GCs], Count, 334
__output__ [TOTAL_GC_TIME], Time(ms), 723
__output__ [TOTAL_GC_TIME_%], Time(%), 0.2987874930778831
__output__ [CLEANUP], Operations, 256
__output__ [CLEANUP], AverageLatency(us), 14.421875
__output__ [CLEANUP], MinLatency(us), 0
__output__ [CLEANUP], MaxLatency(us), 3581
__output__ [CLEANUP], 95thPercentileLatency(us), 2
__output__ [CLEANUP], 99thPercentileLatency(us), 2
__output__ [INSERT], Operations, 10000000
__output__ [INSERT], AverageLatency(us), 6153.2624904
__output__ [INSERT], MinLatency(us), 183
__output__ [INSERT], MaxLatency(us), 969215
__output__ [INSERT], 95thPercentileLatency(us), 7563
__output__ [INSERT], 99thPercentileLatency(us), 14991
__output__ [INSERT], Return=OK, 10000000
```

You can now benchmark the performance of MongoDB following the `run` command:

```bash
~/ycsb-0.17.0/bin/ycsb.sh run mongodb -s -P ~/ycsb-0.17.0/workloads/iworkload -p operationcount=5000000 -threads 256 -p mongodb.url="mongodb://${mongo_ip}:${mongo_port}/mymongodb"
```

Replace `mongo_ip` and `mongo_port` in the command above with the IP address and port number of the machine you are running MongoDB on.

**Note**

Please ensure that you have sufficient disk space available (60GB as a minimum requirement).

You can see the performance data after the `run` command execution is finished:

```
__output__ /usr/bin/java  -classpath /root/workload/tools/ycsb-0.17.0/conf:/root/workload/tools/ycsb-0.17.0/lib/core-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/lib/HdrHistogram-2.1.4.jar:/root/workload/tools/ycsb-0.17.0/lib/htrace-core4-4.1.0-incubating.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-core-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-mapper-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-classic-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-core-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-async-driver-2.0.1.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-binding-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongo-java-driver-3.8.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/slf4j-api-1.7.25.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/snappy-java-1.1.7.1.jar site.ycsb.Client -t -db site.ycsb.db.MongoDbClient -s -P /root/workload/tools/ycsb-0.17.0/workloads/iworkloadf -p operationcount=5000000 -threads 256 -p mongodb.url=mongodb://172.26.202.189:27017/mymongodb
__output__ mongo client connection created with mongodb://172.26.202.189:27017/mymongodb
__output__ [OVERALL], RunTime(ms), 774685
__output__ [OVERALL], Throughput(ops/sec), 6454.236237954781
__output__ [TOTAL_GCS_G1_Young_Generation], Count, 2889
__output__ [TOTAL_GC_TIME_G1_Young_Generation], Time(ms), 27004
__output__ [TOTAL_GC_TIME_%_G1_Young_Generation], Time(%), 3.4858039073946183
__output__ [TOTAL_GCS_G1_Old_Generation], Count, 0
__output__ [TOTAL_GC_TIME_G1_Old_Generation], Time(ms), 0
__output__ [TOTAL_GC_TIME_%_G1_Old_Generation], Time(%), 0.0
__output__ [TOTAL_GCs], Count, 2889
__output__ [TOTAL_GC_TIME], Time(ms), 27004
__output__ [TOTAL_GC_TIME_%], Time(%), 3.4858039073946183
__output__ [READ], Operations, 2000633
__output__ [READ], AverageLatency(us), 23745.636704982873
__output__ [READ], MinLatency(us), 257
__output__ [READ], MaxLatency(us), 242047
__output__ [READ], 95thPercentileLatency(us), 43423
__output__ [READ], 99thPercentileLatency(us), 63551
__output__ [READ], Return=OK, 2000633
__output__ [READ-MODIFY-WRITE], Operations, 1000524
__output__ [READ-MODIFY-WRITE], AverageLatency(us), 47604.22748279901
__output__ [READ-MODIFY-WRITE], MinLatency(us), 496
__output__ [READ-MODIFY-WRITE], MaxLatency(us), 389631
__output__ [READ-MODIFY-WRITE], 95thPercentileLatency(us), 75647
__output__ [READ-MODIFY-WRITE], 99thPercentileLatency(us), 97343
__output__ [CLEANUP], Operations, 256
__output__ [CLEANUP], AverageLatency(us), 17.16015625
__output__ [CLEANUP], MinLatency(us), 0
__output__ [CLEANUP], MaxLatency(us), 4035
__output__ [CLEANUP], 95thPercentileLatency(us), 2
__output__ [CLEANUP], 99thPercentileLatency(us), 3
__output__ [UPDATE], Operations, 2500512
__output__ [UPDATE], AverageLatency(us), 23774.697541143574
__output__ [UPDATE], MinLatency(us), 219
__output__ [UPDATE], MaxLatency(us), 254847
__output__ [UPDATE], 95thPercentileLatency(us), 43551
__output__ [UPDATE], 99thPercentileLatency(us), 63775
__output__ [UPDATE], Return=OK, 2500512
__output__ [SCAN], Operations, 1499379
__output__ [SCAN], AverageLatency(us), 60546.94498655777
__output__ [SCAN], MinLatency(us), 455
__output__ [SCAN], MaxLatency(us), 547327
__output__ [SCAN], 95thPercentileLatency(us), 101183
__output__ [SCAN], 99thPercentileLatency(us), 125375
__output__ [SCAN], Return=OK, 1499379
```
