Caching
Caching
refers to the process of storing the collected gNMI updates before sending them out to the intended output(s).
By default, gNMIc
outputs send out the received gNMI updates as they arrive (i.e without storing them).
A cache is used to store the received updates when the gnmi-server
functionality is enabled and (optionally) when influxdb
and prometheus
outputs are enabled to allow for advanced data pipeline processing.
Caching messages before writing them to a remote location allows implementing a few use cases like rate limiting, batch processing, data replication, etc.
Caching support for other outputs is planned.
How does it work?#
When caching is enabled for a certain output, the received gNMI updates are not written directly to the output remote server (for e.g: InfluxDB server), but rather cached locally until the cache-flush-timer
is reached (in the case of an influxdb
output) or when the output receives a Prometheus
scrape request (in the case of a prometheus
output).
The below diagram shows how an InfluxDB output works with and without cache enabled:
The cached gNMI updates are periodically retrieved from the cache in batch then converted to events.
If processors are defined under the output config section, they are applied to the whole list of events at once. This allows for augmentation of messages with values from other messages even if they where received in separate updates or collected from a different target/subscription.
Enable caching#
gnmi-server#
The gNMI server has caching enabled by default. The cache type and its behavior can be tweaked, see here
gnmi-server:
#
# other gnmi-server related attributes
#
cache: {}
outputs#
Caching can be enabled per output by populating the cache
attribute under the desired output:
outputs:
output1:
type: prometheus
#
# other output related attributes
#
cache: {}
This enables output1
to use a cache of type oc
.
Each output has its own cache. Using a single global cache will be implemented in a future release.
Distributed caches#
When running multiple instances of gNMIc
it's possible to synchronize the collected data between all the instances using a distributed cache.
Each output that is configured with a remote cache will write the collected gNMI updates to the remote cache first, then syncs back all the cached data to its local cache then eventually write it to the output.
(1) The received gNMI updates are written to the remote cache.
(2) The output syncs the remote cache data to its local cache.
(3) The locally cached data is written to the remote output periodically or on scape request.
This is useful when different instances collect data from different targets and/or subscriptions. A single instance can be responsible for writing all the collected data to the output or each instance would be writing to a different output.
Cache types#
gNMIc
supports 4 cache types. There is 1 local cache and 3 distributed caches "flavors".
The choice of cache to use depends on the use case you are trying to implement.
A local cache is local to the gNMIc
instance i.e not exposed externally, while a distributed cache is external to the gNMIc
instance, potentially shared by multiple gNMIc
instances and is always combined with a local cache to sync updates between gNMIc
instances.
gNMI cache (local)#
Is an in-memory gNMI cache based on the Openconfig gNMI cache published here
This type of cache is ideal when running a single gNMIc
instance. It is also the default cache type for the gNMI server and for an output when caching is enabled.
Configuration:
outputs:
output1:
type: prometheus # or influxdb
#
# other output related fields
#
cache:
type: oc
# duration, default: 60s.
# updates older than the expiration value will not be read from the cache.
expiration: 60s
# enable extra logging
debug: false
NATS cache (distributed)#
Is a cache type that relies on a NATS server to distribute the collected updates between gNMIc
instances.
This type of cache is useful when multiple gNMIc
instances are subscribed to different targets and/or different gNMI paths.
Configuration:
outputs:
output1:
type: prometheus # or influxdb
#
# other output related fields
#
cache:
type: nats
# string, address of the remote NATS server,
# if left empty an in memory NATS server will be created an used.
address:
# string, the NATS server username.
username:
# string, the NATS server password.
password:
# string, expiration period of received messages.
expiration: 60s
# enable extra logging
debug: false
JetStream cache (distributed)#
Is a cache type that relies on a JetStream server to distribute the collected updates between gNMIc
instances.
This type of cache is useful when multiple gNMIc
instances are subscribed to different targets and/or different gNMI paths.
It is planned to add gNMI historical subscriptions support using the jetstream
cache type.
Configuration:
outputs:
output1:
type: prometheus # or influxdb
#
# other output related fields
#
cache:
type: jetstream
# string, address of the remote NATS JetStream server,
# if left empty an in memory NATS JetStream server will be created an used.
address:
# string, the JetStream server username.
username:
# string, the JetStream server password.
password:
# duration, default: 60s.
# Expiration period of received messages.
expiration: 60s
# int64, default: 1073741824 (1 GiB).
# Max number of bytes stored in the cache per subscription.
max-bytes:
# int64, default: 1048576.
# Max number of messages stored per subscription.
max-msgs-per-subscription:
# int, default 100.
# Batch size used by the JetStream pull subscriber.
fetch-batch-size:
# duration, default 100ms.
# Wait time used by the JetStream pull subscriber.
fetch-wait-time:
# enable extra logging
debug: false
Redis cache (distributed)#
Is a cache type that relies on a Redis PUBSUB server to distribute the collected updates between gNMIc
instances.
This type of cache is useful when multiple gNMIc
instances are subscribed to different targets and/or different gNMI paths.
outputs:
output1:
type: prometheus # or influxdb
#
# other output related fields
#
cache:
type: redis
# string, redis server address
address:
# string, the Redis server username.
username:
# string, the Redis server password.
password:
# duration, default: 60s.
# Expiration period of received messages.
expiration: 60s
# enable extra logging
debug: false