Table Of Contents

7.5. Performance profiling

Note

The performance profiling API is available starting with QuasarDB 3.0

7.5.1. Introduction

The goal of the performance API is to provide a cross-platform, accurate, and lightweight timing API enabling users to identify performance bottlenecks in their QuasarDB cluster.

When enabled, each call has a precise breakdown on how the time was spent for each call.

Features:

  • Lightweight - Low CPU and memory overhead on the server, compact footprint on the wire
  • Convenient - The client receives all metric information with every call made
  • Precise - The API uses the most accurate clock available on the platform for precise timing
  • Detailed - A precise breakdown on every call is made, dispatching, serialization, disks I/O…

7.5.2. When to use?

Performance collection does not need to be enabled all the time and is mostly useful for troubleshooting performance issues.

7.5.3. Design

The performance API is made of two parts:

  • A server part where calls are instruments, data collected, and sent back to the client
  • A client part that collects the data from the server and makes it available to the client

For performance and security reasons the performance API is disabled by default both on the server and the client API.

7.5.4. Usage

Enabling the collection on the server

To use the performance API you need to first enable it on the server. In the network section, the “performance” entry must be set to true (see _qdbd-config-file-reference).

When active, the node will return performance metrics for every call made.

Enabling the collection on the client

By default the client will discard all performance data returned by the server.

You must thus enable performance collection with an API call:

Note

The handle must be connected as the client will check that performance data is indeed being sent by the remote nodes.

After this call, the client API will accumulate the performance data for all calls made from this handle.

Warning

Performance data will accumulate in the handle until it’s retrieved, cleared, or the handle is closed.

You can disable collection at any moment:

error = qdb_perf_enable_client_tracking(handle);
if (QDB_FAILURE(error))
{
    // error management
}

Retrieving performance data

Once data collection is enabled, any thread accessing the handle can gather the previously accumulated data:

qdb_perf_profile_t * profiles = NULL;
qdb_size_t count              = 0;

error = qdb_perf_get_profiles(handle, &profiles, &count);
if (QDB_SUCCESS(error))
{
    // use the performance data

    // release memory
    qdb_release(handle, profiles);
}

This call will:

  • Allocate a dedicated structure to store all accumulated performance data
  • Copy the accumulated data in the handle for the calling thread into the structure
  • Release the data in the handle so that it is no longer returned in subsequent calls
  • Return the allocated dedicated structure to the caller

The caller must thus release the performance data structure with qdb_release().

What does a performance profile contain?

A performance profile is a collection of timestamps, in nanoseconds, relative to when the request arrived on the server. Each timestamp has an associated label describing the moment at which the timestamp was collected. The timestamps are ordered in time, as they were collected on the server.

The performance profile is named after the function that was running when collected.

A single API call can result in multiple functions being executed on the server, thus, the number of performance profiles can be much greater than the number of API calls.

Note

Although the timestamps are measured in nanoseconds, this does not mean that the timestamps are nanosecond accurate. The exact accuracy of the timestamp is platform dependent.

Clearing all performance data

When performance data collection is no longer necessary, after disabling data collection, it is advised to purge all accumulated performance data.

error = qdb_perf_clear_all_profiles(handle);
if (QDB_FAILURE(error))
{
    // error management
}

This step is not always required as when closing the handle, all performance data will be freed.

Note that this call will not release memory associated to data returned to qdb_perf_get_profiles(). You still need to call qdb_release() on the returned profiles.