File system cache#
Trino accesses files directly on object storage and remote file system storage. This often involves the transfer of large amounts of data. The files are retrieved from HDFS, or any other supported object storage, by multiple workers and processed on these workers. Repeated queries with different parameters, or even different queries from different users, often access, and therefore transfer, the same objects.
Trino caches these files with a cache manager, configured on every node of the cluster. Two cache managers are available:
alluxiocaches files on local disks with the help of the open source Alluxio libraries, and is the cache manager to use for caching table data.memorycaches files on the Java heap, and is used by the coordinator to cache the metadata files it reads during query planning.
Caching of table data is available for catalogs using the following connectors:
Distributed caching#
File system caching is distributed in Trino as part of the mechanism of any other query processing. Query processing, detailed more in Trino concepts is broken up into different stages, where tasks and splits are processed by different nodes in the cluster. The lowest level splits retrieve data from the data source with the help of the connector of the specific catalog. For file system caching, these splits result in the retrieval of files from object storage.
Different nodes process splits with data from objects storage randomly over time, but with preference for using a fixed set of nodes for a given file. If the preferred nodes are too busy, the split, and hence the caching, takes place on a non-preferred, less busy node. File system caching keeps copies of the retrieved files on a local cache storage, separate for each node. Over time the same files from object storage are cached on any nodes that require the data file for processing a specific task. Each cache on each node is managed separately, following the TTL and size configuration, and cached files are evicted from the cache.
You can limit the number of hosts that are preferred to process these tasks with
the node-scheduler.cache-preferred-hosts-count property in the coordinator’s
etc/config.properties.
Query processing still uses all other nodes as required for the parallel
processing of tasks, and therefore potentially caches files on more nodes than
the preferred hosts only. A low setting, such as the default 2, can reduce the
overall size of the cache because it can reduce how often the same file is
cached on multiple nodes. A higher setting, up to the number of nodes in the
cluster, distributes the workload across more workers by default, and leads to
more resilience against node failures at the expense of effective cache size.
Benefits#
Enabling caching can result in the following significant benefits:
Reduced load on storage
Every retrieved and cached file avoids repeated retrieval from the storage in subsequent queries on the same worker. As a result the storage system does not have to provide the file again and again.
For example, if your query accesses 100MB of files from the storage, the first time the query runs 100MB are downloaded and cached. Any following query uses these files. If your users run another 100 queries accessing the same files, your storage system does not have to provide all data repeatedly. Without caching it has to provide the same files again and again, resulting in up to 10GB of total files to serve.
Increased query performance
Caching can provide significant performance benefits, by avoiding the repeated network transfers and instead accessing copies of the files from a local cache. Performance gains are more significant if the performance of directly accessing the storage is low compared to accessing the local cache.
For example, if you access storage in a different network, different data center, or even different cloud-provider region query performance is slow. Adding caching using fast, local storage has a significant impact and makes your queries much faster.
On the other hand, if your storage is already running at very high performance for I/O and network access, and your local cache storage is at similar speeds, or even slower, performance benefits can be minimal.
Reduced query costs
A result of the reduced load on the storage, mentioned earlier, is significantly reduced network traffic and access to storage. Network traffic and access, often in the form of API access, are often a considerable cost factor, specifically also when hosted in public cloud provider systems.
Configuration#
Configuring the cache takes two steps:
Configure one or more cache managers on every node of the cluster, as described in Cache managers. All nodes must use the same configuration.
Enable caching in each catalog that must use it, as described in Catalog configuration.
Cache managers#
Cache managers are configured per node, not per catalog. Set
cache-manager.config-files in the node’s etc/config.properties to a
comma-separated list of properties files, one per cache manager:
cache-manager.config-files=etc/cache-manager-alluxio.properties,etc/cache-manager-memory.properties
Every listed file must set cache-manager.name to the name of the cache
manager, followed by that manager’s own properties. For example
etc/cache-manager-alluxio.properties:
cache-manager.name=alluxio
fs.cache.directories=/tmp/trino-cache
fs.cache.max-sizes=500GB
A cluster can load at most one cache manager for each kind of caching. Loading
both alluxio and memory therefore uses alluxio for table data, since it is
the only one that can cache more data than fits on the heap, and memory for
coordinator metadata caching.
If cache-manager.config-files is not set, Trino loads the memory cache
manager with default configuration, so that the coordinator caches metadata
files. Once the property is set, only the listed cache managers are loaded, and
metadata caching requires listing a memory cache manager explicitly.
Property |
Description |
|---|---|
|
Required, comma-separated list of absolute paths to directories to use for
caching. All directories must exist on the coordinator and all workers.
Trino must have read and write permissions for files and nested directories.
A valid example with only one directory is All catalogs with caching enabled share these directories, and entries are separated by catalog within the cache. |
|
Comma-separated list of maximum data sizes for each
caching directory. Order of values must be identical to the directories
list. Configuring either |
|
Comma-separated list of maximum percentage values of the used disk for each
directory. Each value is an integer between 1 and 100. Order of values must
be identical to the directories list. If multiple directories use the same
disk, ensure that total percentages per drive remains below 100 percent.
Configuring either |
|
The maximum duration for objects to remain in the cache
before eviction. Defaults to |
|
The page data size used for caching data. Each transfer of files
uses at least this amount of data. Defaults to |
Property |
Description |
|---|---|
|
Maximum total data size of the cache on the heap. Defaults to two percent of the maximum heap size. |
|
Maximum data size of a single cached file. Larger
files are read directly from storage and never cached. Defaults to |
|
The maximum duration for files to remain in the cache
before eviction. Defaults to |
Catalog configuration#
Set fs.cache.enabled to true in the catalog properties file of every catalog
that must cache table data:
fs.cache.enabled=true
Every node must have a cache manager that can cache table data, alluxio, when
a catalog enables caching. Trino fails to start the catalog otherwise.
Enabling table data caching does not replace metadata caching on the
coordinator. If a memory cache manager is loaded as well, the coordinator
looks up that cache first and reads through to alluxio on a miss, so planning
keeps the lower latency of the heap cache.
Monitoring#
The Alluxio cache manager exposes the
Alluxio JMX client metrics
under the org.alluxio package, and metrics on external reads and cache reads
per catalog under io.trino.blob.cache.alluxio:type=AlluxioCacheStats,name=<catalog>.
The memory cache manager exposes per-catalog metrics under
io.trino.blob.cache.memory:type=MemoryBlobCacheStats,name=<catalog>, and metrics
for the shared cache under io.trino.blob.cache.memory:name=MemoryBlobCache.
The cache code uses OpenTelemetry tracing.
Migration from catalog-level caching#
In earlier versions the Alluxio cache was configured with fs.cache.*
properties in each catalog properties file. When upgrading:
Move
fs.cache.directories,fs.cache.max-sizes,fs.cache.max-disk-usage-percentages,fs.cache.ttl, andfs.cache.page-sizeout of the catalog properties files and into analluxiocache manager properties file on every node. Catalogs keep onlyfs.cache.enabled.Catalogs no longer need separate cache directories. All catalogs that enable caching share the directories of the node’s cache manager.
Existing cached data on disk is not reused, because cache entries are identified differently. The cache repopulates from storage on the first queries after the upgrade, and the previous cache directory contents are evicted by the configured size limit.
JMX object names changed. The Alluxio cache statistics moved from
io.trino.filesystem.alluxio:type=AlluxioCacheStats,name=<catalog>toio.trino.blob.cache.alluxio:type=AlluxioCacheStats,name=<catalog>, and the Hive connector’sio.trino.plugin.hive.fs:type=TrinoFileSystemCachebean no longer exists. Update dashboards and alerts accordingly.
Recommendations#
The speed of the local cache storage is crucial to the performance of the cache. The most common and cost-efficient approach is to attach high-performance SSD disks or equivalent storage. Fast cache performance can also be achieved with a RAM disk used as an in-memory cache.
In all cases, avoid using the root partition and disk of the node. Instead attach one or more dedicated storage devices for the cache on each node. Storage should be local, dedicated on each node, and not shared.
Your deployment method for Trino decides how to attach storage and create the directories for caching. Typically you need to connect a fast storage system, like an SSD drive, and ensure that it is mounted on the configured path.