Cantaloupe offers a sophisticated and customizable caching subsystem that is capable of meeting a variety of needs while remaining easy to use. Several tiers of cache are available:
Cantaloupe can provide caching hints to clients using a
Cache-Control response header, which is configurable via the
cache.client.* keys in the configuration file. To enable this header, set the
cache.client.enabled key to
The default settings look something like this:
These are reasonable defaults that tell clients they can keep cached images for 2,592,000 seconds (30 days).
Cache-Control header will be returned only in HTTP 200-level responses.
Commonly, source images will be served from a local filesystem using FilesystemSource. There, they are already as local as they can be, so there would be no point in caching them—although a derivative cache could still be of great benefit.
As mentioned in the Sources section, though, images do not have to be served from a local filesystem—they can also be served from a remote web server, cloud storage, or wherever. The source cache can be beneficial when one of these non-filesystem sources performs poorer than ideal. By setting the stream retrieval strategy to
CacheStrategy and configuring FilesystemCache, all source images from non-FilesystemSources will be automatically downloaded into the source cache and read from there.
Another reason for a source cache is to work around the incompatibility between certain processors and sources. Some processors are only capable of reading source images located on the filesystem. By setting the fallback retrieval strategy to
CacheStrategy, and then configuring FilesystemCache, the source cache will be utilized to deal with incompatible processor/source situations by automatically pre-downloading source images, as a more robust alternative to
Note that there is only one available source cache implementation—FilesystemCache—and it is used independently of the derivative cache.
The derivative cache caches post-processed images in order to spare the computational expense of processing the same image over and over again. Derivative caches are pluggable, in order to enable different cache stores.
Derivative caching is recommended in production, as it will greatly reduce load on the server and improve response times accordingly. There are other ways of caching derivatives, such as by using a caching reverse proxy, but the built-in derivative cache is custom-tailored for this application and easy enough to set up.
Derivative caching is disabled by default. To enable it, set
true, and set
cache.server.derivative to the name of a cache, such as FilesystemCache.
The info cache caches image info objects in the Java heap, independently of the derivative cache. When both are enabled, the info cache acts as a "level 1" cache in front of the "level 2" derivative cache:
The info cache can be enabled or disabled via the
cache.server.info.enabled configuration key.
The info cache is cluster-safe: when multiple instances are sharing the same derivative cache, there will never (for more than a short period of time) be an info in an instance's info cache that isn't also present in the derivative cache.
The maximum size of the info cache is hard-coded to a reasonable percentage of the maximum heap size, and is not configurable. As infos are very small, the maximum size is unlikely to ever be reached, but if it is, the least-recently-accessed infos will be invalidated as necessary to accommodate fresher ones.
The info cache's content never expires, but it is not persisted, so it will be lost when the application exits.
The source and derivative caches can be configured to operate in one of two ways:
cache.server.resolve_first = true)
cache.server.resolve_first = false)
Because cached content is not automatically deleted after becoming invalid, there will likely be a certain amount of invalid content taking up space in the cache at any given time. Without periodic maintenance, the amount can only grow. If this is a problem, it can be dealt with manually via the HTTP API, or automatically, using a cache worker, which periodically cleans and purges invalid items. (See the
cache.server.worker.* configuration options.)
Most caches (with the exception of HeapCache) age-limit their content based on last-accessed or last-modified time. Depending on the amount of source content served, the varieties of derivatives generated, the time-to-live setting, and how often maintenance is performed, the cache may grow very large. Its size is not tracked, as this would be either expensive, or, for some cache implementations, impossible. Managing the cache size is therefore the responsibility of the administrator, and it can be accomplished by any combination of:
All implementations are thread-, process-, and cluster-safe, where applicable. Multiple application instances can be pointed at the same cache store without conflicting.
FilesystemCache caches content in a filesystem tree. The tree structure looks like:
Cache files are created with a .tmp extension and moved into place when closed for writing.
On macOS, files' last-modified time is used instead of their last-accessed time, as the latter is not reliable.
HeapCache caches derivative images and metadata in the Java heap, which is the main area of memory available to the JVM. This is the fastest of the caches, with the main drawback being that it cannot be shared across instances.
Unlike most of the other caches, this one does not age-limit content. When the target size (
HeapCache.target_size) has been exceeded, the minimum number of least-recently-accessed items are purged that will reduce it back down to this size. (The configured target size may be safely changed while the application is running.)
Because this cache is not time-limited,
cache.server.derivative.ttl_seconds does not apply, and, if enabled, the cache worker will remain idle.
When using this cache, ensure that your heap is able to grow large enough to accommodate the desired target size (using the
-Xmx VM option), and that you have enough RAM to accommodate this size.
This cache can persist its contents to disk using the
HeapCache.persist.filesystem.pathname configuration keys. When persistence is enabled, the contents of the cache will be written to a file at shutdown, and loaded back in at startup. If persistence is disabled, the cache contents will be lost when the application exits.
Some thought was given to storing cached data using the same on-disk format used by FilesystemCache, so that persisted data would be compatible between these caches. Unfortunately, this is not possible because of the one-way hashing used in the FilesystemCache format.
JdbcCache caches derivative images and metadata in relational database tables. To use this cache, a JDBC driver for your database must be installed on the classpath.
JdbcCache is tested with the H2 database. It is known not to work with the official PostgreSQL driver, as of version 9.4.1207. Other databases may work, but are untested.
JdbcCache can be configured with the following options:
JdbcCache will not create its schema automatically—this must be done manually using the following commands, which may have to be altered slightly for your particular database:
S3Cache caches derivative images and metadata in an Amazon Simple Storage Service (S3) bucket. It supports both AWS and non-AWS endpoints.
S3Cache is configured (excepting credentials) using the following configuration keys:
s3.us-east-2.amazonaws.com. (See the list of AWS S3 regions.)
See the Credentials Sources information for S3Source. S3Cache works the same way, except that the credentials-related configuration keys, if you choose to use them, are different:
S3 does not provide a last-accessed time in object metadata, so the time-to-live is on the basis of last-modified time instead.
AzureStorageCache caches derivative images and metadata into a Microsoft Azure Storage container. It can be configured with the following options:
Azure Storage does not provide a last-accessed time in object metadata, so the time-to-live is on the basis of last-modified time instead.
RedisCache, available since version 3.4, caches derivative images and metadata using the Redis data structure store. It supports the following configuration options:
Unlike with the other caches, cache policy is configured on the Redis side, and
cache.server.derivative.ttl_seconds will have no effect with this cache. Likewise, if enabled, the cache worker will remain idle.