BenchBase Documentation

repository·main·Indexed 20 days ago

https://github.com/cmu-db/benchbase

A multi-threaded SQL benchmarking framework for generating variable rate and mixture workloads against JDBC-enabled relational databases. It supports profiles for postgres, mysql, mariadb, sqlite, cockroachdb, phoenix, and spanner, providing detailed latency and throughput logs. The framework includes Docker-based environments for development and runtime, as well as tools for running benchmarks like TPC-C and TPC-H.

Tokens
15.4K
Snippets
46
Records
52
Agent score
68%

What's inside BenchBase

  1. Use Value Distributions in Templated Queries

    main

    Instead of static values, you can use distributions to substitute the ? placeholder with a value generated at runtime. This allows for more realistic workload modeling.

    Supported distributions depend on the parameter type:

    Typeuniformbinomialzipfianscrambled
    INTEGERXXXX
    FLOAT / REALXX--
    BIGINTXXXX
    VARCHARX---
    TIMESTAMPXXXX
    DATEXXXX
    TIMEXXXX

    Distribution Properties:

    • dist: The distribution type (uniform, binomial, zipfian, scrambled). Required.
    • min: The minimum value the generator can produce. Required.
    • max: The maximum value the generator can produce. Required.
    • seed: A seed for the generator to ensure consistency. Default is 0.
    <templates>
        <template name="MyTemplate">
            <query><![CDATA[SELECT * FROM MyTable WHERE id = ?]]></query>
            <types>
                <type>INTEGER</type>
            </types>
            <values>
                <value dist="uniform" min="0" max="1000" seed="1"/>
            </values>
             <values>
                <value dist="zipf" min="0" max="1000" seed="1"/>
            </values>
        </template>
    </templates>
  2. Understand the structure of a Benchmark implementation

    main

    Each benchmark implementation in BenchBase follows a standardized directory layout consisting of four main components:

    1. {Prefix}Benchmark.java: The BenchmarkModule implementation. It is responsible for setting up all the necessary class paths required for the benchmark to run.
    2. {Prefix}Loader.java: The Loader implementation. This component is responsible for populating the database with initial data.
    3. {Prefix}Worker.java: The Worker implementation. It receives a random TransactionType from the abstract Worker driver code and invokes the corresponding procedure.
    4. procedures/ directory: Contains the actual implementations for all transaction types defined within that specific benchmark.

    Additionally, benchmark-specific dialects and ddls files are located in the src/main/resources directory.

  3. Choose between throughput and advanced monitoring types

    main

    BenchBase supports two monitoring modes via the -mt flag:

    1. Throughput Monitoring (-mt=throughput):

      • This is the default setting if no type is explicitly set.
      • It tracks benchmark progress by logging updated throughput values directly to the system output.
    2. Advanced Monitoring (-mt=advanced):

      • Monitors query and system properties via system tables (supported for SQLServer and Postgres).
      • Records findings in CSV files located in the results/monitor/ directory.
      • Collects various data points:
        • One-off query info: e.g., query plans, query text.
        • Repeated query info: e.g., elapsed time per execution, worker time, execution count.
        • Repeated system info: e.g., cache hits, number of transactions.
      • The specific events collected depend on the database system and are handled by corresponding drivers.
  4. How value selection works in Templated Benchmarks

    main

    Values in templated benchmarks are selected using a Round-Robin access pattern. If you provide multiple <values> blocks, BenchBase will cycle through them sequentially for each query execution.

    Example pattern for query 'Q1' with two value sets: V1 --> V2 --> V1 --> V2 ...

    If you require more fine-grained control over the access pattern (e.g., specific weights), you should create separate queries for each value and adjust their relative weights in the main configuration file.

    <templates>
        <template name="Q1">
            <query><![CDATA[$SQLQuery]]></query>
            <types>
                <type>Type1</type>
            </types>
            <values>
                <value>V1</value>
            </values>
            <values>
                <value>V2</value>
            </values>
        </template>
    </templates>
  5. Quickstart: Build and run BenchBase with PostgreSQL

    main

    To quickly get started with BenchBase using the postgres profile, clone the repository, build it using the Maven wrapper, and extract the resulting artifact. You can then run a benchmark like tpcc using the generated benchbase.jar.

    Steps:

    1. Clone and build:
      git clone --depth 1 https://github.com/cmu-db/benchbase.git
      cd benchbase
      ./mvnw clean package -P postgres
    2. Extract the distribution:
      cd target
      tar xvzf benchbase-postgres.tgz
      cd benchbase-postgres
    3. Run the benchmark:
      java -jar benchbase.jar -b tpcc -c config/postgres/sample_tpcc_config.xml --create=true --load=true --execute=true
    git clone --depth 1 https://github.com/cmu-db/benchbase.git
    cd benchbase
    ./mvnw clean package -P postgres
    
    cd target
    tar xvzf benchbase-postgres.tgz
    cd benchbase-postgres
    
    java -jar benchbase.jar -b tpcc -c config/postgres/sample_tpcc_config.xml --create=true --load=true --execute=true
  6. Publish BenchBase containers to a registry

    main

    To publish images to a container registry, use the provided build scripts and then docker push. You can specify a custom registry by setting the CONTAINER_REGISTRY_NAME environment variable.

    export CONTAINER_REGISTRY_NAME='benchbasedev.azurecr.io'
    ./build-dev-image.sh
    ./build-full-image.sh
    
    docker push $CONTAINER_REGISTRY_NAME/benchbase-dev
    docker push $CONTAINER_REGISTRY_NAME/benchbase
  7. Use BenchBase with Docker

    main

    BenchBase supports Docker for both development and production-like execution.

    Development Images

    To build and run a development image from source:

    ./docker/benchbase/build-dev-image.sh
    ./docker/benchbase/run-dev-image.sh

    Full Images

    To build a full image with all profiles:

    ./docker/benchbase/build-full-image.sh

    To build an image with specific profiles (e.g., postgres and mysql):

    BENCHBASE_PROFILES='postgres mysql' ./docker/benchbase/build-full-image.sh

    Running a Profile via Docker

    To run a specific profile using the pre-built image:

    # Using the run script
    BENCHBASE_PROFILE='postgres' ./docker/benchbase/run-full-image.sh
    
    # Using docker run directly
    docker run -it --rm --env BENCHBASE_PROFILE='postgres' \
      -v results:/benchbase/results benchbase.azurecr.io/benchbase --help
    # build an image with all profiles
    ./docker/benchbase/build-full-image.sh
    
    # or if you only want to build some of them
    BENCHBASE_PROFILES='postgres mysql' ./docker/benchbase/build-full-image.sh
    
    # Run for a given profile
    BENCHBASE_PROFILE='postgres' ./docker/benchbase/run-full-image.sh
  8. Clean up Spanner Emulator resources

    main

    To remove the resources created for the emulator and return your gcloud environment to its original state, follow these steps: delete the Spanner instance, reactivate your default configuration, delete the emulator configuration, and stop the Docker container.

    # 1. Delete the Spanner instance
    gcloud spanner instances delete benchbase-instance
    
    # 2. Reactivate your default configuration
    gcloud config configurations activate default
    
    # 3. Delete the emulator-config
    gcloud config configurations delete emulator-config
    
    # 4. Stop the Docker container (e.g., via docker stop or docker-compose down)
  9. Run BenchBase directly with Maven

    main

    You can execute benchmarks directly against the source code without manually building and extracting a distribution by using the Maven exec:java goal. This is useful for rapid development.

    Example (TPC-C against PostgreSQL):

    mvn clean compile exec:java -P postgres -Dexec.args="-b tpcc -c config/postgres/sample_tpcc_config.xml --create=true --load=true --execute=true"
  10. Configure advanced monitoring for SQLServer and Postgres

    main

    To use advanced monitoring (-mt=advanced), the underlying database must meet specific requirements:

    • Postgres: The pg_stat_statements extension must be enabled.
    • SQLServer: The user must have sufficient permissions to access system tables.

    Important Considerations:

    • Graceful Failure: If monitoring queries fail, BenchBase will log an error but will not interrupt the benchmark execution.
    • Performance Impact: Frequent monitoring queries against the DBMS can increase system load and potentially distort benchmarking results by competing with the actual benchmark queries for resources.
  11. Build BenchBase distributions for specific databases

    main

    BenchBase uses Maven profiles to build distributions tailored for specific databases. Use the -P flag with ./mvnw clean package to specify the target database.

    Supported profiles: postgres, mysql, mariadb, sqlite, cockroachdb, phoenix, and spanner.

    Output: Build artifacts are placed in the ./target folder as:

    • benchbase-<profile name>.tgz
    • benchbase-<profile name>.zip
    ./mvnw clean package -P <profile name>
  12. Run BenchBase via CLI

    main

    After unpacking a distribution, run benchbase.jar with the required arguments. Note that you must run the command from the root of the expanded distribution folder to avoid java.lang.NoClassDefFoundError.

    Common usage:

    • Help: java -jar benchbase.jar -h
    • Single benchmark: java -jar benchbase.jar -b tpcc -c config/postgres/sample_tpcc_config.xml --create=true --load=true --execute=true
    • Composite benchmarks: For benchmarks requiring multiple schemas (e.g., chbenchmark), provide a comma-separated list to the -b flag: java -jar benchbase.jar -b tpcc,chbenchmark -c config/postgres/sample_chbenchmark_config.xml --create=true --load=true --execute=true
    java -jar benchbase.jar -b tpcc -c config/postgres/sample_tpcc_config.xml --create=true --load=true --execute=true