InfluxDB 1.4 Now Available: InfluxQL Enhancements, Prometheus Read/Write, Better Compaction and a lot more!

Originally published at: InfluxDB 1.4 Now Available: InfluxQL Enhancements, Prometheus Read/Write, Better Compaction and a Lot More! | InfluxData

What’s new InfluxDB 1.4


We are announcing the new version of InfluxDB 1.4 in Open Source. This release, unlike our previous releases, is not paired with a corresponding InfluxDB Enterprise release. All of the features and changes described here are available in open source InfluxDB. This blog post is assembled largely from the pull requests and feature descriptions written by the InfluxDB platform team and community members. Thank you!

InfluxQL Enhancements

InfluxDB 1.4 includes new InfluxQL capabilities to make it easier to explore metadata and understand query execution. We’ve added SHOW CARDINALITY queries to make it much easier to query for series cardinality.

The SHOW CARDINALITY commands come in two flavors: estimated and exact. The estimated values are calculated using sketches and are a safe default for all cardinality sizes. The EXACT variations count directly from TSM data and are expensive to run for high cardinality data. We suggest preferring the estimates. We also started adding predicate support (WHERE clause support) to meta-queries. However, filtering by time is only currently supported with TSI. We will continue to improve these capabilities as we develop 1.5.

SHOW MEASUREMENT CARDINALITY β€” estimates the cardinality of the measurement set for the current database.

SHOW MEASUREMENT CARDINALITY ON db0 β€” estimates the cardinality of the measurement set on the provided database.

Note: SHOW MEASUREMENT CARDINALITY also supports GROUP BY tag and WHERE tag. However when using these options on the query, then the query falls back to an exact count. 

SHOW SERIES CARDINALITY β€” estimates the cardinality of the measurement set for the current database.

SHOW SERIES CARDINALITY ON db0 β€” estimates the cardinality of the measurement set on the provided database.

Note: SHOW SERIES CARDINALITY also supports FROM measurement, GROUP BY tag WHERE tag etc. However when using these options on the query, then the query falls back to an exact count. 

SHOW MEASUREMENT EXACT CARDINALITY β€”  counts exactly the number of measurements on the current database. 

SHOW SERIES EXACT CARDINALITY β€”  counts exactly the number of series exactly on the current database.

SHOW TAG KEY CARDINALITY β€”  estimates the number of tag keys on the current database. Note: this is currently implemented as an exact count.

SHOW TAG VALUES CARDINALITY WITH KEY = "X" β€”  estimates the number of tag values for the provide tag key, on the current database. Note: this is currently implemented as an exact count.

SHOW TAG KEY EXACT CARDINALITY β€”  counts exactly the number of tag keys on the current database.  

SHOW TAG VALUES EXACT CARDINALITY WITH KEY = "X" β€”  counts exactly the number of tag values for the provide tag key, on the current database. 

We’ve also added support for EXPLAIN and EXPLAIN ANALYZE to help understand query costs. EXPLAIN parses and plans the query and then prints a summary of estimated costs. Many SQL engines use EXPLAIN to show join order, join algorithms, and predicate and expression pushdown. InfluxQL doesn’t support joins. Instead, the cost of a query in InfluxQL is typically a function of total series accessed, number of iterator accesses to a TSM file, and number of TSM blocks that need to be scanned. Consequently, these are the elements of InfluxQL EXPLAIN:

> explain select sum(pointReq) from "_internal"."monitor"."write" group by hostname;
QUERY PLAN
------
EXPRESSION: sum(pointReq::integer)
NUMBER OF SHARDS: 2
NUMBER OF SERIES: 2
CACHED VALUES: 110
NUMBER OF FILES: 1
NUMBER OF BLOCKS: 1
SIZE OF BLOCKS: 931

Running EXPLAIN ANALYZE executes the query and counts the actual costs during runtime.

> explain analyze select sum(pointReq) from "_internal"."monitor"."write" group by hostname;
EXPLAIN ANALYZE
-----------
.
└── select
β”œβ”€β”€ execution_time: 242.167Β΅s
β”œβ”€β”€ planning_time: 2.165637ms
β”œβ”€β”€ total_time: 2.407804ms
└── field_iterators
β”œβ”€β”€ labels
β”‚   └── statement: SELECT sum(pointReq::integer) FROM "_internal"."monitor"."write" GROUP BY hostname
└── expression
β”œβ”€β”€ labels
β”‚   └── expr: sum(pointReq::integer)
β”œβ”€β”€ create_iterator
β”‚   β”œβ”€β”€ labels
β”‚   β”‚   β”œβ”€β”€ measurement: write
β”‚   β”‚   └── shard_id: 57
β”‚   β”œβ”€β”€ cursors_ref: 1
β”‚   β”œβ”€β”€ cursors_aux: 0
β”‚   β”œβ”€β”€ cursors_cond: 0
β”‚   β”œβ”€β”€ float_blocks_decoded: 0
β”‚   β”œβ”€β”€ float_blocks_size_bytes: 0
β”‚   β”œβ”€β”€ integer_blocks_decoded: 1
β”‚   β”œβ”€β”€ integer_blocks_size_bytes: 931
β”‚   β”œβ”€β”€ unsigned_blocks_decoded: 0
β”‚   β”œβ”€β”€ unsigned_blocks_size_bytes: 0
β”‚   β”œβ”€β”€ string_blocks_decoded: 0
β”‚   β”œβ”€β”€ string_blocks_size_bytes: 0
β”‚   β”œβ”€β”€ boolean_blocks_decoded: 0
β”‚   β”œβ”€β”€ boolean_blocks_size_bytes: 0
β”‚   └── planning_time: 1.401099ms
└── create_iterator
β”œβ”€β”€ labels
β”‚   β”œβ”€β”€ measurement: write
β”‚   └── shard_id: 58
β”œβ”€β”€ cursors_ref: 1
β”œβ”€β”€ cursors_aux: 0
β”œβ”€β”€ cursors_cond: 0
β”œβ”€β”€ float_blocks_decoded: 0
β”œβ”€β”€ float_blocks_size_bytes: 0
β”œβ”€β”€ integer_blocks_decoded: 0
β”œβ”€β”€ integer_blocks_size_bytes: 0
β”œβ”€β”€ unsigned_blocks_decoded: 0
β”œβ”€β”€ unsigned_blocks_size_bytes: 0
β”œβ”€β”€ string_blocks_decoded: 0
β”œβ”€β”€ string_blocks_size_bytes: 0
β”œβ”€β”€ boolean_blocks_decoded: 0
β”œβ”€β”€ boolean_blocks_size_bytes: 0
└── planning_time: 76.192Β΅s

For the moment, these statistics are provided to help users and our support team understand the β€œcost” of the queries being executed. It helps to explain what the query engine is actually doing and hopefully provides greater insight into the data set being accessed. Unfortunately, there isn’t much more you can do to act on these results other than confirming that the number of series being accessed make sense based on expected results. But, we believe the insight to be useful by itself.

Support for Prometheus Read and Write Endpoints

As announced earlier, we added Prometheus read and write endpoints. These have been available on master for a while and are shipping with InfluxDB 1.4.

Compaction Performance Improvements

TSM compactions have been improved in a few areas: performance, scheduling, and observability. Performance has improved to better handle higher cardinalities within a shard. These changes include using off-heap memory for TSM indexes, disk-based index buffering when creating TSM files, and reductions in allocations. These changes should reduce GC pressure which lowers CPU and memory utilization in almost all cases. It also prevents OOMs due to very high cardinality compactions.

Compaction scheduling has been improved to better coordinate resources across shards and adapt to changing workloads. Previously, each shard scheduled and limited compactions for the shard independently. The scheduler now uses a weighted queue approach instead of fixed limits on scheduling and works across shards better. This allows higher priority work to take advantage of available cores more dynamically. The max-concurrent-compactions limit that was added in 1.3 is now enabled by default to limit compactions to 50% of available cores. This better controls memory and CPU utilization when many shards are active.

Monitoring of compactions now has a metric for the depth of the queue for each level. Each shard now exposes a gauge style metrics such as tsmLevel3CompactionQueue that indicates how long the queue is for that level and shard. The sum of all levels in a shard indicates if compactions are backing up and you may need more CPU cores. The combination of the *Active, *Err and *Queue metrics provide basic utilization, saturation and error (USE) metrics. The existing *Duration metrics can be used to monitor compaction latencies if you use the four gold signals approach to monitoring.

Client and HTTP Enhancements

There are a number of features that make using the HTTP interface easier.

HTTP responses to the /query endpoint no longer force Connection: close. This allows re-use of HTTP connections by clients. The issue #8525 includes useful discussion of the change.

InfluxDB HTTP responses now include the InfluxDB version in the header X-Influxdb-Build for applications that need to distinguish database versions. Internally, Chronograf will use this to more easily manage combinations of open source and enterprise InfluxDB instances.

Errors from queries and writes are now available via the X-InfluxDB-Error header and 5xx error messages are written to server logs when log-enabled = true is enabled in the [httpd] configuration section.

InfluxDB now honors X-Request-Id header so that callers can pass a correlation id as part of the request. HTTP responses populate both X-Request-Id and Request-Id to maintain backwards compatibility with previous version, and to support the more common X-Request-Id header name. More details are recorded in the pull request.

Finally, thanks to @emluque, the InfuxDB CLI now supports Ctrl+C to cancel a running query.

Message Pack formats for responses

Message pack can now be used for responses by setting application/x-msgpack in the Accept header. The server will respond with message pack serialized responses.

Experimental and Preview Features

TSI Progress

A lot of work has gone into TSI over the course of developing 1.4. However, we are not yet ready to release TSI as the default production index. We’ll be writing more about our TSI progress as we work on 1.5.

This release does include a utility to generate TSI indexes from TSM data. This is allows TSI indexes to be rebuilt even when they are larger than in-memory support would allow; it also allows building TSI indexes for older shards for experimentation.

Further description and a usage example is available in the pull request: #8669.

Preview of uint64 Support

We have added unsigned 64 bit integer (aka uint64) support that can be enabled with an InfluxDB build flag. We are leaving this behind a build flag until we implement uint64 support through the rest of the TICK stack. Telgraf, Chronograf, and Kapacitor do not yet support this field type and there are some client libraries where unit64 values cannot be naturally expressed.

To enable uint64, build InfluxDB with go install -tags uint64 ./…. Write uint64 values by suffixing an integer with u in the write protocol.

create database u64ex
use u64ex
Using database u64ex
insert cpu v1=18446744073709551615u
select v1 from cpu
name: cpu
time                v1
----                --
1510620507267476000 18446744073709551615

IFQL Prototype Interfaces

InfluxDB OSS 1.4 includes the prototype RPC interface to support IFQL. This API will change as we advance the IFQL prototype and we are not establishing any compatibility promises for this new interface. However, you can enable and access storage if you want to explore the interface as an access point to the database. An ifql section is now available on the configuration file.
[ifql]
# Determines whether the RPC service is enabled.
enabled = true
# Determines whether additional logging is enabled.
log-enabled = true
# The bind address used by the ifql RPC service.
bind-address = ":8082"
The IFQL RPC interface is protobuf based; the protobuf file is available for your coding pleasure.

Other Changelog Tidbits

  • #8426: Add parse-multivalue-plugin to allow users to choose how multivalue plugins should be handled by the collectd service.
  • #8548: Allow panic recovery to be disabled when investigating server issues.
  • #8592: Mutex profiles are now available.
  • #8854: Report the task status for a query.
  • #8830: Separate importer log statements to stdout and stderr.
  • #8690: Implicitly decide on a lower limit for fill queries when none is present.
1 Like