Several days ago, I saw a tweet fly by in my stream. The creator of Node.js, Ryan Dahl, was recommending Golang for any new server-side projects. While Node.js is still very popular, the growth in microservices has been driving a more wide-spread adoption of Golang for these projects.
Golang is becoming more and more appealing due to its ease of use, high performance, and lightweight architecture. Whether you are writing a simple script for a single task, a microservice in a pipeline, or a full-fledged enterprise service, Golang can do the job, quickly and efficiently. That’s why we are seeing more interest in using Golang to operate and communicate with Volt Active Data.
Volt Active Data has had a Golang driver using the native wire protocol for several years. It started out as an innovation week project by one of our developers. As our customers began to use it, we started supporting it officially and added enterprise features like client affinity and SSL to the driver.
We recently updated the Golang driver again. This latest release provides a significant performance boost, as well as many other improvements. To do that, we called on a Golang expert who lives half a world away in Tanzania, software engineer Geofrey Ernest.
Geofrey identified some bottlenecks and optimized the driver from the bottom up. The end result is very promising. It dramatically improves the throughput for both the blocking mode and the non-blocking mode. Not only that, it also reduces the memory consumption of the driver by up to 200 fold. The following table summarizes the performance improvements.
The following test results were produced using the Voter sample application running on a single node Volt Active Data and a different node for the Golang test application. Both nodes have 16 physical CPU cores. The Golang application calls a single read-write stored procedure repeatedly with different parameters each time.
Blocking |
Non-Blocking | |||
Throughput |
Memory |
Throughput |
Memory | |
Before | 130,000 tps | 6,656MB | 260,000 tps | 5,324MB |
After | 240,000 tps | 33MB | 450,000 tps | 770MB |
With Geofrey’s optimizations, the non-blocking mode achieved 450,000 stored procedure calls per second! Each stored procedure call is a fully serializable transaction with at least three SQL statements.
The Volt Active Data Golang driver implements the interfaces specified in the Golang database/sql/driver package. If you are familiar with the usage of the database/sql package, then using the Volt Active Data Golang driver will be a breeze. The following code snippet connects to the Volt Active Data server, calls a stored procedure and handles the result.
The database/sql/driver package defines a blocking interface for interacting with databases. It is sufficient for the majority use case. You can easily create goroutines to make database requests without blocking the main thread of execution.
However, it may be hard to write a highly concurrent program that interacts with the database with limited resources (CPU & memory) using this model. An alternative is to use a non-blocking model to interact with the database and limit the number of goroutines running at the same time.
To do this, the Volt Active Data driver comes with a non-blocking mode. All you need to do is to create an object that implements the callback interface defined here. The following code snippet shows how to call the same “HELLOWORLD.select” stored procedure shown above in non-blocking mode.
If you are interested in the Golang driver or have used the old driver, I strongly encourage you to try the new driver out at https://github.com/Volt Active Data/voltdb-client-go. Thanks to Geofrey’s great work, there are other stability and usability improvements besides performance. Any feedback is welcome.