# Configuration properties for Aerospike Connect for Trino

Use these configuration properties in the `aerospike.properties` file to specify how the Trino connector interacts with your Aerospike cluster.

::: note
Tuning Trino for performance improvements is outside the scope of this documentation.
:::

To use these configuration properties with Docker, you must use the `--volume` or `-v` option when you run the `docker run` command. Use this option to mount the `aerospike.properties` file by providing the path to the folder that contains this file. The default path is `trino-aerospike.docker/docker/etc/catalog`.

In general, when you use Docker, you cannot set environment variables and mount an `aerospike.properties` file at the same time. The only exception is when you use `TRINO_DISCOVERY_URI` and `TRINO_NODE_TYPE`. You can set those environment variables using the `-e` option and also mount the `aerospike.properties` file using the `-v` option in the same `docker run` command.

The following sets of configuration properties are available:

## Basic configuration properties

`aerospike.cache-ttl-ms`

**Description:** Number of milliseconds to keep the inferred schema cached. If you specify the schema, this property has no effect.

**Default value:** 1800000

---

`aerospike.clientpolicy.clusterName`

**Description:** Name of the Aerospike cluster, if a name has been configured for it.

**Default value:** `null`

---

`aerospike.clientpolicy.maxSocketIdle`

**Description:** Maximum socket idle in seconds. Socket connection pools discard sockets that have been idle longer than the maximum.

**Default value:** 55

---

`aerospike.clientpolicy.timeout`

**Description:** How long the connector waits (in milliseconds) for a response from your Aerospike cluster when making its initial connection.

**Default value:** 1000

---

`aerospike.clientpolicy.failIfNotConnected`

**Description:** Set to `true` for the connector to throw an exception if it is unable to connect to any seed nodes in an Aerospike cluster.

**Default value:** `true`

---

`aerospike.clientpolicy.sharedThreadPool`

**Description:** Whether `threadPool` is shared between other client instances or classes. If `threadPool` is not shared (default), `threadPool` shuts down when the client instance closes.

**Default value:** `false`

---

`aerospike.clientpolicy.useServicesAlternate`

**Description:** Use `services-alternate` instead of `services` in info request during cluster tending.

**Default value:** `false`

---

`aerospike.default-set-name`

**Description:** Table name for the default set. Use this environment variable when your namespace has a `null` set or no sets. If you have multiple namespaces with no sets in your cluster, you can query them as demonstrated in the following example:

```sql
select * from NAMESPACE_1.VALUE

select * from NAMESPACE_2.VALUE
```

Where `VALUE` is the value assigned to `DEFAULT_SET_NAME`.

**Default value:** `__default`

---

`aerospike.hostlist`

**Description:** Comma-separated list of seed nodes in the Aerospike cluster.

**Default value for non-container deployments:** `null`

**For standalone deployments in Dockerized environments:** On macOS, use `docker.for.mac.host.internal:3000`. On Linux operating systems, use `localhost:3000`

**For TLS-enabled Aerospike clusters:** Include the TLS configuration name in the hostlist using the format `hostname:TLS_NAME:port`. For example:

```properties
aerospike.hostlist=node1.company.com:TLS_NAME:4333,node2.company.com:TLS_NAME:4333,node3.company.com:TLS_NAME:4333
```

If your TLS config is named `cluster_tls`, the configuration looks like:

```properties
aerospike.hostlist=node1.company.com:cluster_tls:4333,node2.company.com:cluster_tls:4333,node3.company.com:cluster_tls:4333
```

---

`aerospike.insert-require-key`

**Description:** Require the primary key (PK) on INSERT queries. Although we recommend that you provide a primary key, you can choose not to by setting this property to `false`, in which case a UUID is generated for the PK. You can view PKs by setting `aerospike.record-key-hidden` to `false` for future queries.

**Default value:** `true`

---

`aerospike.record-key-name`

**Description:** Column name for the record’s primary key. You can use this name in the queries for projection and/or predicates.

**Default value:** `__key`

---

`aerospike.record-key-hidden`

**Description:** If set to `false`, the connector makes the primary key column available in the result set.

**Default value:** `true`

---

`aerospike.record-digest-name`

**Description:** Column name for the record’s digest. You can use this name in the queries for projection and/or predicates, and must be specified as a string.

**Default value:** `__digest`

---

`aerospike.record-digest-hidden`

**Description:** If set to `false`, the connector makes the record digest column available in the result set.

**Default value:** `true`

---

`aerospike.strict-schemas`

**Description:** Use a strict schema. See “[Strict schemas](#strict-schemas)”.

**Default value:** `false`

---

`aerospike.table-desc-dir`

**Description:** Path of the directory containing table description files. Do not use this configuration parameter for Dockerized environments; instead, use the `--volume` or `-v` option in the `docker run` command, as explained in [Deploy in standalone mode in Docker](https://aerospike.com/docs/connectors/trino/docker/standalone) and [Deploy in distributed mode in Docker](https://aerospike.com/docs/connectors/trino/docker/distributed).

**Default value:** `TRINO_DIRECTORY/etc/catalog`

---

`aerospike.case-insensitive-identifiers`

**Description:** Use this property when you have a namespace or set name with mixed case types in Aerospike. This property helps resolve the tables/schemas case-insensitivity issue inherent in Trino that converts all names to lowercase. If turned on, you can use supported SQL statements correctly against table names with mixed-case names, like `deepLearning`.

::: note
-   It does not support two sets having the same name but different case types within the same namespace. For example, sets named `deepLearning` and `deeplearning`.
-   It only works with Trino version 360 or later.
-   Using it may have some performance implications, so use it only when you have set names with mixed case types in Aerospike.
-   Although the output of SHOW TABLES and DESCRIBE statements are lower case names regardless of whether mixed case naming is used in Aerospike, you can correctly use SELECT and other statements with either mixed case or lower case names. For example, if deepLearning and Score are the names of the set and bin used in Aerospike, `SELECT Score FROM deepLearning;` works. That is despite the fact that set and the column names show up in lower case in the output for SHOW TABLES and DESCRIBE statements respectively.
:::

**Possible values:** `true`, `false`

**Default value:** `false`

---

`aerospike.case-insensitive-identifiers.config-file`

**Description:** If the `aerospike.case-insensitive-identifiers` option is set to `true`, you can use a mapping file to define how case-sensitive Aerospike names — referred to as `remoteSchema` and `remoteTable` — are translated into unique, case-insensitive names. This is important when your case-sensitive names would become identical when converted to a case-insensitive format. In such cases, the mapping file helps prevent naming conflicts and avoids exceptions in Starburst versions 443-e and later.

Example of a mapping file:

```json
{

  "schemas": [

    {

      "remoteSchema": "CaseSensitiveName",

      "mapping": "case_insensitive_1"

    },

    {

      "remoteSchema": "cASEsENSITIVEnAME",

      "mapping": "case_insensitive_2"

    }],

  "tables": [

    {

      "remoteSchema": "CaseSensitiveName",

      "remoteTable": "tablex",

      "mapping": "table_1"

    },

    {

      "remoteSchema": "CaseSensitiveName",

      "remoteTable": "TABLEX",

      "mapping": "table_2"

    }]

}
```

**Possible values:** A valid path to the configuration file.

**Default value:** `etc/catalog/identifiers.json`

---

`aerospike.client-cache-size`

**Description:** Aerospike Java client cache pool size.

**Default value:** 4

---

`aerospike.record-queue-capacity`

**Description:** Asynchronous command record queue capacity.

**Default value:** 8192

---

`aerospike.event-loop-timeout-ms`

**Description:** Asynchronous command event loop timeout in milliseconds.

**Default value:** 1000

---

`aerospike.domain-compaction-threshold`

**Description:** Domain compaction threshold.

**Default value:** 32

---

### Strict schemas

Because Trino is a SQL engine, it assumes that the underlying data store (Aerospike, in this case) follows a strict schema for all the records within a table. However, as a NoSQL database, Aerospike is schemaless.

Therefore, a single bin (mapped to a Trino column) within a set (mapped to a Trino table) can technically hold values of multiple [Aerospike supported types](https://aerospike.com/docs/develop/data-types/scalar).

The Trino connector reconciles this incompatibility with the help of the `aerospike.strict-schemas` configuration property:

1.  **`aerospike.strict-schemas` = `false` (default)**
    
    -   If none of the column types in the user-specified schema match the bin types of a record in Aerospike, the connector returns a record with NULLs in the result set.
    -   If this mismatch is limited to fewer columns in the user-specified schema, the connector returns NULL for those columns in the result set. There is no way to differentiate between a NULL due to a missing value in the original data set and a NULL due to a mismatch. Therefore, you must treat all NULLs as missing values. The connector automatically filters out columns that are not part of the schema in the result set.
2.  **`aerospike.strict-schemas` = `true`**
    
    -   If a mismatch between the user-specified schema and the schema of a record in Aerospike is detected at the bin/column level, your query fails with an error.
    -   Use the strict configuration of `aerospike.strict-schemas` = `true` when you have modeled your data in Aerospike to adhere to a strict schema where each record within the set has the same structure.

## Properties related to security

`aerospike.clientpolicy.user` and `aerospike.clientpolicy.password`

**Description:** Authenticates all Trino users to your Aerospike cluster with this single set of credentials. If you set `aerospike.clientpolicy.authMode` to `INTERNAL`, ensure that the user, password, and associated roles are configured in Aerospike. See [Configuring access control](https://aerospike.com/docs/database/manage/security/rbac) for more information.

To override the username and password that are set in this file, you can authenticate users in Trino sessions by running these commands in the Trino CLI:

```sql
SET SESSION CATALOG_NAME.client_policy_user = 'USERNAME'

SET SESSION CATALOG_NAME.client_policy_password = 'PASSWORD'
```

where `CATALOG_NAME` matches the catalog name of the Aerospike cluster being authenticated to.

::: note
When you use the `SET SESSION` command, the names of these two configuration properties use underscores, not periods, to separate the words that compose them. Also, these are the only properties that you can set with the `SET SESSION` command.
:::

**Default value:** `null`

---

`aerospike.clientpolicy.authMode`

**Description:** Authentication mode to use when values are set for `aerospike.clientpolicy.user` and `aerospike.clientpolicy.password`.

Possible values:

-   `INTERNAL` - Use internal authentication only. The server stores the hashed password. Does not send plaintext password. This is the default.
-   `EXTERNAL` - Use external authentication (such as LDAP). Configure specific external authentication on the server. If TLS is defined, sends plaintext password on node login using TLS. Throws an exception if TLS is not defined.
-   `EXTERNAL_INSECURE` - Use external authentication (such as LDAP). Configure specific external authentication on the server. Sends plaintext password on node login whether or not TLS is defined. Use this mode only for testing purposes because it does not provide secure authentication.
-   `PKI` - Authentication and authorization based on a certificate. No username or password needs to be configured. Requires TLS and a client certificate. Requires Aerospike Database 5.7 or later.

**Default value:** `INTERNAL`

---

`aerospike.clientpolicy.tls.enabled`

**Description:** Enable secure TLS connection.

**Default value:** `false`

---

`aerospike.clientpolicy.tls.storeType`

**Description:** Type of the keystore.

**Default value:** `jks`

---

`aerospike.clientpolicy.tls.keystorePath`

**Description:** Keystore file path.

**Default value:** `null`

---

`aerospike.clientpolicy.tls.keystorePassword`

**Description:** Keystore password.

**Default value:** `null`

---

`aerospike.clientpolicy.tls.keyPassword`

**Description:** Key password.

**Default value:** `null`

---

`aerospike.clientpolicy.tls.truststorePath`

**Description:** Truststore file path.

**Default value:** `null`

---

`aerospike.clientpolicy.tls.truststorePassword`

**Description:** Truststore password.

**Default value:** `null`

---

`aerospike.clientpolicy.tls.forLoginOnly`

**Description:** Use TLS connection only for login authentication.

**Default value:** `false`

---

`aerospike.clientpolicy.tls.allowedCiphers`

**Description:** Comma-separated list of allowable TLS ciphers to use for the secure connection.

**Default value:** Default ciphers defined by JVM

---

`aerospike.clientpolicy.tls.allowedProtocols`

**Description:** Comma-separated list of allowable TLS protocols to use for the secure connection.

**Default value:** `TLSv1.2`

---

## Properties related to performance

`aerospike.clientpolicy.connPoolsPerNode`

**Description:** Number of synchronous connection pools used for each node.

If each of your nodes has eight or fewer CPU cores, you can leave this value at the default. However, if each node has more CPU cores, use a higher value to create multiple connection pools per node. This helps avoid contention among CPU cores for pooled connections.

**Default value:** 1

---

`aerospike.clientpolicy.maxConnsPerNode`

**Description:** Maximum number of synchronous connections allowed per server node. Increasing this value can help prevent the connector from reaching the maximum number of connections if you run many queries that use parallel scans.

**Default value:** 300

---

`aerospike.enable-statistics`

**Description:** Generate statistics for Cost-Based Optimization (CBO). Currently, the Trino connector only supports the row count. Ensure that you turn on CBO in Trino.

**Default value:** `false`

---

`aerospike.scanpolicy.recordsPerSecond`

**Description:** Limit returned records per second (RPS) rate for each server. A value of 0 specifies that there is no limit. Setting this value higher than 0 throttles the rate at which records are returned.

**Default value:** 0

---

`aerospike.scanpolicy.maxConcurrentNodes`

**Description:** Maximum number of concurrent requests to server nodes at any point in time. Issue requests to all server nodes in parallel if maxConcurrentNodes is zero.

**Default value:** 0

---

`aerospike.split-number`

**Description:** Number of Trino splits. Update this property to align with the available resources (CPU threads) in your cluster. Aerospike connector supports up to `Integer.MAX_VALUE` splits, meaning 2^31-1 Trino splits, for parallel partition scans by Trino workers.

Splits are the unit of parallelism in Trino. Therefore, the connector can support up to ~2B Trino worker threads (configurable by setting `task.max-worker-threads` in Trino).

Setting this value too high may cause a drop in performance due to context switching. We recommend that you set the value of `aerospike.split-number` to the result of multiplying the number of cores by the number of threads per core.

**Default value:** 16

**Use a value of 4 for Dockerized environments**

---

`aerospike.policy.connectTimeout`

**Description:** Socket connect timeout in milliseconds.

**Default value:** 0

---

`aerospike.policy.socketTimeout`

**Description:** Aerospike socket idle timeout in milliseconds when processing a database command.

**Default value:** 300000

---

`aerospike.event-group-size`

**Description:** Aerospike Java client Netty event loop group size.

**Default value:** Number of available CPU cores

---

`aerospike.eventpolicy.maxCommandsInProcess`

**Description:** Maximum number of async commands that can be processed in each event loop at any point in time.

**Default value:** `0 (execute all async commands immediately)`

---

`aerospike.eventpolicy.maxCommandsInQueue`

**Description:** Maximum number of async commands that can be stored in each event loop’s delay queue for later execution.

**Default value:** `0 (no delay queue limit)`

---

`aerospike.eventpolicy.commandsPerEventLoop`

**Description:** Expected number of concurrent asynchronous commands in each event loop that are active at any point in time.

**Default value:** 256

---

## Properties related to audit trail

The Aerospike connector supports query audit logging by leveraging Trino event listener.

It currently logs timestamp, initiating user (name used in the Trino session or the user’s OS name if session name was unspecified), schema name and table name (format is schemaname.tablename), query ID, query status (success/failure), SQL statement, and the number of records that were read or written.

You can enable it by creating a configuration file `etc/event-listener.properties` with the following properties.

`event-listener.name`

**Description:** Set this name to `aerospike-audit-log`.

---

`audit-log.path`

**Description:** Path of the security audit log file. If you use the default path, make sure that the permissions to create the file in the specified location exist, otherwise the feature does not work.

**Default value:** etc/log/security.log

---

`audit-log.max-size`

**Description:** Maximum size of a single security audit log file that is specified in bytes. For example, 128MB is equal to 134217728.

**Default value:** 134217728

---

`audit-log.max-history`

**Description:** Maximum number of security audit log files the system can create.

**Default value:** 24

::: note
-   The log file contains one log entry per line, and the values are separated by a tab character. The timestamp is using ISO 8601 format.
-   The log files are stored in the Trino coordinator.
-   schemaname.tablename is not displayed if the query fails.
:::

---

## Properties related to backing off due to error conditions

::: note
These properties are available in Aerospike Connect for Trino versions 1.1.0 or later.
:::

When certain error conditions occur as the connector interacts with your Aerospike cluster, the connector can “back off” from the server. “Backing off” means not only retrying the actions that led to the error, but retrying them at exponentially increasing intervals of time.

The duration of the interval before the first attempt is specified by the configuration property `aerospike.retry-initial-millis`. If the database cannot service the request because it is busy, the connector continues attempting the same action after exponentially longer intervals. To compute the length of each successive interval, the connector multiplies the duration of the current interval by the value of the configuration parameter `aerospike.retry-multiplier`.

For example, if the initial wait time is 1s (1000 milliseconds) and the multiplier is 2, retries are attempted at 1s, 2s, 4s, 8s, 16s, 32s, and so on. The connector continues retrying the action until the database can service the request or until the connector reaches the maximum number of retries allowed, which you can specify with `aerospike.retry-max-attempts`.

The most important error condition that prompts the connector to back off from the server is the violation of a rate quota. The other error conditions are internal error conditions.

### Configuration properties

These three configuration properties determine the “back off” behavior of the connector when the connector encounters one of the error conditions:

`aerospike.retry-initial-millis`

**Description:** Time to wait (in milliseconds) before retrying for the first time the action that led to the error condition. If the error condition persists after the initial retry, subsequent retries are attempted at intervals that become exponentially longer.

**Default value:** 1000

---

`aerospike.retry-max-attempts`

**Description:** The maximum number of times to retry an action that led to an error condition. A value of 0 prevents the connector from retrying.

**Default value:** 3

---

`aerospike.retry-multiplier`

**Description:** The integer by which to multiply the duration of the current wait interval to determine the duration of the next wait interval.

**Default value:** 2

---

`aerospike.sindex-table-name`

**Description:** Name of the table that stores the list of available secondary indexes for a schema.

**Default value:** `__sindex`

---

### Back-offs for violations of one or both rate quotas

::: note
You can use rate quotas with Aerospike Connect for Trino version 1.1.0 or later only when your Aerospike Database Enterprise Edition cluster is at version 5.6 or later.
:::

In your Aerospike cluster, an administrator can set rate quotas for roles and then assign users to those roles. One rate quota limits the number of reads in terms of records per second, and the other rate quota limits the number of writes, also in terms of records per second. All record accesses are counted towards the quotas: updates, replaces, UDFs, background UDFs, reads, batch reads, and scans. Your Aerospike cluster consequently limits the user to a number of transactions per second. This number consists of the sum of the two rate quotas.

For example, you can set the rate quota of 40,000 records per second for reads and 40,000 records per second for writes for the role `analysts`. Then, you can assign the user `analyst_1` the role `analysts`. When a query issued against your Aerospike cluster by `analyst_1` results in a rate of transactions per second that breaches either of these rate quotas, the connector waits before attempting to re-run the stage of the query that violated a rate quota.

The connector may have to retry a query stage more than once because the database may be busy and not have the resources to service the request. If the query stage still does not run after the maximum number of retries, the connector fails the query. In this situation, you can retry the query at a later time.