Using a9s KeyValue
This topic describes how to use a9s KeyValue.
Compatibility between existing Redis®* client libraries with a9s KeyValue are not guaranteed. Please verify the existence of a Valkey client library for your programming language of choice, or use the Redis® client library with caution.
Use a9s KeyValue with an Application
To use a9s KeyValue with an application, create a Service Instance and bind the Service Instance to your app. For more information about managing Service Instances, see Managing Service Instances with the cf CLI.
View the a9s KeyValue Service
After the tile is installed, you can see a9s-keyvalue
and its service plans appear in your CF marketplace.
Run cf marketplace
to see the service listing:
$ cf marketplace
Getting services from marketplace in org test / space test as admin...
OK
service plans description
a9s-keyvalue keyvalue8-single-ssl, keyvalue8-replica-ssl, keyvalue8-single-no-logging-ssl This is the a9s KeyValue service.
Create a Service Instance
To provision a Valkey database, run cf create-service
. For example.
cf create-service a9s-keyvalue keyvalue8-single-ssl my-keyvalue-service
Depending on your infrastructure and service broker utilization, it might take several minutes to create the a9s service instance.
Run the cf services
command to view the creation status. This command displays a list of all your Service Instances.
To view the status of a specific Service Instance, run cf service NAME-OF-YOUR-SERVICE
.
Bind an Application to a Service Instance
After your database is created, run cf bind-service
to bind the service to your application:
cf bind-service a9s-keyvalue-app my-keyvalue-service
Restage or Restart Your Application
To enable your application to access the Service Instance, run cf restage
or cf restart
to restage or restart your
application.
Obtain Service Instance Access Credentials
After a Service Instance is bound to an application, the credentials of your Valkey database are stored in the
environment variables of the application. Run cf env APP-NAME
to display the environment variables.
You can find the credentials in the VCAP_SERVICES key.
cf env a9s-keyvalue-app
Getting env variables for app a9s-keyvalue-app in org test / space test as admin...
System-Provided:
{
"VCAP_SERVICES": {
"a9s-keyvalue": [
{
(...)
"credentials": {
"host": "EXAMPLE-master.service.dc1.a9ssvc",
"hosts": [
"EXAMPLE-valkey-0.node.dc1.a9ssvc",
"EXAMPLE-valkey-1.node.dc1.a9ssvc",
"EXAMPLE-valkey-2.node.dc1.a9ssvc"
],
"load_balanced_host": "EXAMPLE.service.dc1.a9ssvc",
"valkey": {
"password": "EXAMPLE-VALKEY-PASSWORD",
"port": 6379,
"username": "EXAMPLE-VALKEY-USERNAME"
},
"sentinel": {
"master_name": "EXAMPLE-master",
"password": "EXAMPLE-SENTINEL-PASSWORD",
"port": 26379,
"username": "EXAMPLE-SENTINEL-PASSWORD"
}
}
(...)
}
]
}
}
...
Check credentials for a9s KeyValue 8
$ cf env a9s-keyvalue-app
Getting env variables for app a9s-keyvalue-app in org test / space test as admin...
System-Provided:
{
"VCAP_SERVICES": {
"a9s-keyvalue": [
{
(...)
"credentials": {
"host": "EXAMPLE-master.service.dc1.consul",
"hosts": [
"EXAMPLE-valkey-0.node.dc1.consul",
"EXAMPLE-valkey-1.node.dc1.consul",
"EXAMPLE-valkey-2.node.dc1.consul"
],
"load_balanced_host": "EXAMPLE.service.dc1.consul",
"password": "EXAMPLE-PWD",
"port": 6379,
"sentinel_master_name": "EXAMPLE-master",
"sentinel_port": 26379
}
(...)
}
]
}
}
...
You can use the host
and password
values to connect to your database with a Valkey client, by using only the host
variable, your application does not need to know anything about Valkey Sentinel. However if you use the hosts
variable
or the load_balanced_host
, your application needs to know about Valkey Sentinel and being able to work with Valkey
Sentinel. This means, by using the host
variable, the failover is handled by the logic within our service and if you
use one of the other variables, the failover needs to be handled by your application.
The sentinel
information and its subfields are only present for Service Instances with cluster plans.
Access Credentials
The user access control is based on Valkey Access Control List (ACL). Each credential has some pre-configured permissions and does not have admin privileges.
Best Practices
There are some best practices for using service binding information in apps in a separate document.
Delete an a9s KeyValue Service Instance
Before deleting a Service Instance, you must backup data stored in your database. This operation cannot be undone and all the data is lost when the service is deleted.
Before you can delete a Service Instance, you must unbind it from all apps.
List Available Services
Run cf services
to list available services.
$ cf services
Getting services in org test / space test as admin...
OK
name service plan bound apps last operation
my-keyvalue-service a9s-keyvalue8 keyvalue8-single-ssl a9s-keyvalue-app create succeeded
This example shows that my-keyvalue-service
is bound to the a9s-keyvalue-app
application.
Unbind a Service Instance
Run cf unbind-service
to unbind the service from your app:
cf unbind-service a9s-keyvalue-app my-keyvalue-service
Delete a Service Instance
After unbinding the service, it is no longer bound to an app. Run cf delete-service
to delete the service:
cf delete-service my-keyvalue-service
It may take several minutes to delete the service. Deleting a service deprovisions the corresponding infrastructure
resources. Run the cf services
command to view the deletion status.
Upgrade the Service Instance to another Service Plan
Once created, you can upgrade your Service Instance to another, larger service plan. A larger service plan provides more CPU, RAM and storage. For more information, see the Update a Service Instance of the Managing Service Instances with the cf CLI topic.
cf update-service my-keyvalue-service -p a-bigger-plan
Change RDB Persistence Settings
a9s KeyValue supports RDB persistence with point in time snapshots. This setting can be changed by the user.
Default Behavior
By default, the persistency is disabled for a9s KeyValue Service Instances.
When persistency is disabled, the a9s KeyValue ensures state consistency, which means no RDB should exist. Therefore, manually creating an RDB via the API must be avoided, as it could lead to inconsistent behavior, such as recovering undesired data in some cases.
Please note that in a non-persistent scenario, if the Service Instance is a single plan and the Valkey process is restarted, data will be cleaned up. However, if the Service Instance is a replica plan, the replica will recover the data even if one of the nodes of the Service Instance has restarted the Valkey process.
Configuring RDB
You can configure RDB according to the needs of your apps by providing custom parameters as settings. This setting
must follow the original Valkey configuration for RDB -c "{\"snapshot\": \"['save 900 1','save 300 10']\"}
.
cf update-service my-keyvalue-service -c "{\"snapshot\": \"['save 900 1','save 300 10']\"}"
In this example, it configures to snapshot the Valkey database according to the following rules:
Setting | Effect |
---|---|
save 900 1 | Create a snapshot after 900 seconds if 1 write operations occurred. |
save 300 10 | Create a snapshot after 300 seconds if 10 write operations occurred. |
Cache Only
You can disable snapshots and use Valkey as cache only by creating the service with the following custom parameter:
-c "{\"snapshot\": \"[]\"}"
.
The command is:
cf update-service my-keyvalue-service -c "{\"snapshot\": \"[]\"}"
For more information, see the snapshot settings in the documentation of Valkey Persistence.
Change Maxmemory Policy
With the maxmemory_policy
, you can configure a9s KeyValue which key to remove when maxmemory
is reached. There are
several configurable behaviors.
Setting | Effect |
---|---|
volatile-lru | Remove the key with an expire set using an LRU algorithm This is the default value. |
allkeys-lru | Remove any key according to the LRU algorithm |
volatile-random | Remove a random key with an expire set |
allkeys-random | Remove a random key |
volatile-ttl | Remove the key with the nearest expire time (minor TTL) |
noeviction | Don't expire at all, just return an error on write operations |
You can use -c {"maxmemory-policy": "volatile-ttl"}
to update the maxmemory-policy.
cf update-service my-keyvalue-service -c {"maxmemory-policy": "volatile-ttl"}
For more information, see the maxmemory_policy
settings in the self documented valkey.conf.
HA Cluster with Valkey Sentinel
a9s KeyValue uses Valkey Sentinel to provide a high available replication set. Valkey Sentinel is monitoring several nodes, takes care of the automatic failover and is able to send notifications when something in the cluster is changing.
a9s KeyValue provides some settings to adjust the cluster behavior: min-slaves-max-lag
, down-after-milliseconds
, and
failover-timeout
.
Setting | Effect |
---|---|
min_replicas_max_lag | Time in seconds how long the master waits before he stops accepting write operations, when replicas are no more reachable. Default is 10 seconds . min-replicas-to-write can not be changed, it is fixed set to 1 .See valkey.conf |
down-after-milliseconds | Number of milliseconds the master is unreachable in order to mark it a S_DOWN state. Default is 10000 ms .See sentinel.conf |
failover-timeout | The failover timeout value in milliseconds. Default is 30000 ms .See sentinel.conf |
cf update-service my-keyvalue-service -c {"min_replicas_max_lag": "10"}
cf update-service my-keyvalue-service -c '{"down-after-milliseconds": "10000"}'
cf update-service my-keyvalue-service -c '{"failover-timeout": "30000"}'
Add a Graphite Endpoint
Streaming of logs and metrics might not be available for your plan! If unsure, please check your plan description.
If you want to monitor your service with Graphite, you can set the custom parameter graphite
. It expects the host and
port where the Graphite metrics should be sent to.
For example, in order to send Graphite metrics to an endpoint yourspace.your-graphite-endpoint.com:12345
, you can use
the following command:
cf update-service my-instance -c '{ "graphite": "yourspace.your-graphite-endpoint.com:12345" }'
The endpoint would then receive metrics in the format:
<service_guid>.<service_type>.<host>.<metric> <metric value> <metric timestamp>
Metrics Frequency
By default, metrics will be emitted every 10
seconds. You can change the interval via the custom parameter
metrics_frequency
.
For example, in order to send Graphite metrics to an endpoint every minute, you would set the custom parameter
metrics_frequency
to 60
using the following command:
cf update-service my-instance -c '{ "metrics_frequency": 60 }'
Metrics Prefix
Depending on your graphite provider, you might need to prefix the metrics with a certain value, like an API key for
example. In this case you can leverage the custom parameter metrics_prefix
.
cf update-service my-instance -c '{ "metrics_prefix": "my-api-key-for-a-certain-provider" }'
The resulting metric path would have the format:
<metrics_prefix>.<service_guid>.<service_type>.<host>.<metric>
Metrics
These are all metrics provided by a9s KeyValue.
Metric Id | Type | Description |
---|---|---|
blocked_clients | Integer | Number of clients pending on a blocking call (BLPOP, BRPOP, BRPOPLPUSH, BLMOVE, BZPOPMIN, BZPOPMAX). documentation |
connected_clients | Integer | Number of client connections (excluding connections from replicas). documentation |
connected_slaves | Integer | Number of connected replicas. documentation |
evicted_keys | Integer | Number of evicted keys due to maxmemory limit. documentation |
expired_keys | Integer | Total number of key expiration events. documentation |
instantaneous_ops_per_sec | Integer | Number of commands processed per second. documentation |
keyspace_hits | Integer | Number of successful lookup of keys in the main dictionary. documentation |
keyspace_misses | Integer | Number of failed lookup of keys in the main dictionary. documentation |
master_last_io_seconds_ago | Integer | Number of seconds since the last interaction with master. documentation |
master_link_down_since_seconds | Integer | Number of seconds since the link is down. documentation |
master_link_status | Text | Status of the link (up/down). documentation |
master_sync_last_io_seconds_ago | Integer | Number of seconds since last transfer I/O during a SYNC operation. documentation |
mem_fragmentation_ratio | Float | Ratio between used_memory_rss and used_memory . Note that this doesn't only includes fragmentation, but also other process overheads (see the allocator_* metrics), and also overheads like code, shared libraries, stack, etc. documentation |
min_slaves_good_slaves | Integer | Number of replicas currently considered good. documentation |
rejected_connections | Integer | Number of connections rejected because of maxclients limit. documentation |
role | Text | Value is "master" if the instance is replica of no one, or "slave" if the instance is a replica of some master instance. documentation |
slaveXX.lag | Integer | The read replication lag of the replica instance. documentation |
slaveXX.offset | Integer | The read replication offset of the replica instance. documentation |
total_commands_processed | Integer | Total number of commands processed by the server. documentation |
total_connections_received | Integer | Total number of connections accepted by the server. documentation |
used_memory | Integer | Total number of bytes allocated by Valkey using its allocator (either standard libc, jemalloc, or an alternative allocator such as tcmalloc) documentation |
used_memory_lua | Integer | Number of bytes used by the Lua engine. documentation |
used_memory_peak | Integer | Peak memory consumed by Valkey (in bytes). documentation |
used_memory_rss | Integer | Number of bytes that Valkey allocated as seen by the operating system (a.k.a resident set size). documentation |
*.valkey.*.*.*.blocked_clients
*.valkey.*.*.*.connected_clients
*.valkey.*.*.*.connected_slaves
*.valkey.*.*.*.evicted_keys
*.valkey.*.*.*.expired_keys
*.valkey.*.*.*.instantaneous_ops_per_sec
*.valkey.*.*.*.keyspace_hits
*.valkey.*.*.*.keyspace_misses
*.valkey.*.*.*.master_last_io_seconds_ago
*.valkey.*.*.*.master_link_down_since_seconds
*.valkey.*.*.*.master_link_status
*.valkey.*.*.*.master_sync_last_io_seconds_ago
*.valkey.*.*.*.mem_fragmentation_ratio 4
*.valkey.*.*.*.min_slaves_good_slaves
*.valkey.*.*.*.rejected_connections
*.valkey.*.*.*.role
*.valkey.*.*.*.slaveXX.lag
*.valkey.*.*.*.slaveXX.offset
*.valkey.*.*.*.total_commands_processed
*.valkey.*.*.*.total_connections_received
*.valkey.*.*.*.used_memory
*.valkey.*.*.*.used_memory_lua
*.valkey.*.*.*.used_memory_peak
*.valkey.*.*.*.used_memory_rss
System Metrics
Aside from the metrics shown above, this Data Service also provides system metrics, common to all a9s Data Services. They can be seen in the Graphite metrics documentation.
Cloud Foundry Org and Space Guid
The platform operators can enable support on a global level to prefix the Graphite metrics with the CloudFoundry organization and space. This means that all metrics of all Service Instances (not only yours!) contain that information.
In this case the Graphite metric paths have the following format:
<organization_guid>.<space_guid>.<service_guid>.<service_type>.<host>.<metric>
When you enable in addition the metrics_prefix
for your instance, you will end up with the metric path format:
<metrics_prefix>.<organization_guid>.<space_guid>.<service_guid>.<service_type>.<host>.<metric>
Add a Syslog Endpoint
The cf update-service
command used with the -c flag
can let you stream your syslog to a third-party service. In this case, the command expects a JSON string containing the
syslog
key. A single endpoint item for syslog
can be provided, as well as an array of endpoints.
host
and port
are mandatory parameters.
The protocol
parameter is optional. The accepted values are:
udp
setsrfc
by default torfc3164
.tcp
setsrfc
by default torfc3164
.ssl-tcp
setsrfc
by default torfc6587
.- For
ssl-tcp
;ssl_cert
andssl_key
are required parameters. - If
ssl_verify
is set totrue
, thenssl_cacert
must also be provided.
- For
To remove all endpoints, simply set syslog
to []
.
rfc
valuesOptionally, the rfc
parameter can be explicitly overwritten.
Valid values: rfc3164
, rfc5424
and rfc6587
.
cf update-service my-service \
-c '{
"syslog": [
{
"host": "logs4.your-syslog-endpoint.com",
"port": "6514",
"protocol": "ssl-tcp",
"rfc": "rfc6587",
"ssl_cert": "-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----",
"ssl_key": "-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----",
"ssl_cacert": "-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----",
"ssl_verify": "false"
}
]
}'
The legacy format to specify syslog endpoints (["hostname1:port1", "hostname2:port2"]
) is still supported.
Cloud Foundry Application Security Groups
This topic describes how to check whether a security group was created.
Each a9s Data Service will automatically create and update Cloud Foundry security groups in order to protected service instances to be accessed by applications not running in the same Cloud Foundry applications space. To get a better understanding about Security Groups you can have a look on the Understanding Application Security Groups topic.
Get Service Instance GUID
Run cf service INSTANCE_NAME --guid
to get the guid of the Service Instance.
$ cf service my-keyvalue-service --guid
ca16f111-5073-40b7-973a-156c75dd3028
Check available Security Groups
To see all available security groups use cf security-groups
.
$ cf security-groups
Getting security groups as demo@anynines.com
OK
Name Organization Space
#0 public_networks
#1 dns
#2 tcp_open
#3 guard_432fb752-876d-443b-a311-a075f4df2237 demonstrations demo
#4 guard_ca16f111-5073-40b7-973a-156c75dd3028 demonstrations demo
There we can see a security group with the named guard_ca16f111-5073-40b7-973a-156c75dd3028
was successfully created.
In some circumstances the connection between the application and the Service Instance is not possible, in this case check if a security group was created.
a9s KeyValue Custom Parameters
As an end user you have the opportunity to customize your Service Instance by using custom parameters. Custom parameters
are passed on to a Service Instance by using the -c
switch of the cf CLI commands cf create-service
and
cf update-service
. For example
cf update-service mykeyvalue -c '{"maxclients": 1000}'
would set the maxclients
limit to the value 1000
for the Service Instance mykeyvalue
.
You don't have to utilize those settings. There are sane defaults in place that fit your service plan well.
Every parameter corresponds to a property in the configuration file for the respective Valkey version.
lazyfree-lazy-eviction
The default value is no
.
The allowed values are yes
and no
.
lazyfree-lazy-expire
The default value is no
.
The allowed values are yes
and no
.
lua-time-limit
The default value is 5000
.
The value must be an integer
.
maxclients
The default value is 10000
.
The value must be an integer
> 0
.
maxmemory-policy
The default value is volatile-lru
.
The allowed string values are:
volatile-lru
volatile-lfu
volatile-random
volatile-ttl
allkeys-lru
allkeys-lfu
allkeys-random
noeviction
For an explanation, see here.
maxmemory-samples
The default value is 5
.
The value must be an integer
>= 0
.
notify-keyspace-events
This parameter allows to configure the Valkey Keyspace Notifications.
The default value is ''
which means by default keyspace events are disabled.
failover-timeout
It is a Valkey sentinel property that specifies the failover timeout in milliseconds. The default is 30 seconds.
The default value is 30000
.
The value must be an integer
>= 0
.
down-after-milliseconds
It is a Valkey sentinel property that specifies the milliseconds a node is unreacheable in order to consider it subjectively down. The default is 10 seconds.
The default value is 10000
.
The value must be an integer
>= 0
.
tls-protocols
You can explicitly specify TLS versions to support. Allowed values are "TLSv1.2" and "TLSv1.3" or any combination.
- Improper changes to this value can easily break existing instances.
- When using TLSv1.3 only, Valkey specific metrics will not be provided.
The default value is null
. In this case Valkey uses TLSv1.2 and TLSv1.3.
tls-ciphers
Configure allowed ciphers. See the ciphers(1ssl) manpage for more information about the syntax of this string.
There is no validation enabled for the user provided values and therefore existing instances can break when applying this parameter.
The default value is null
which comments out the Valkey config tls-ciphers
in the Valkey and Sentinel configuration
files.
tls-ciphersuites
Configure allowed ciphersuites. See the ciphers(1ssl) manpage for more information about the syntax of this string, and specifically for TLSv1.3 ciphersuites.
There is no validation enabled for the user provided values and therefore existing instances can break when applying this parameter.
The default value is null
which comments out the Valkey config tls-ciphersuites
in the Valkey and Sentinel
configuration files.
hostname-resolution
- This feature specifically applies to a9s KeyValue Cluster instances.
- When enabling or disabling the feature in an existing a9s Service Instance, there might be an increased downtime during the first cluster update due to a temporary divergence in Sentinel's settings when switching between IP address and hostname.
- When enabled, unexpected delays in address resolution may have a negative impact on Sentinel. For more information, refer to the Valkey documentation.
The feature provides the option to enable and disable DNS/hostname support in Valkey and Sentinel. When enabled, it will utilize the hostname for internal cluster communication and announce Valkey and Sentinel node information using the hostname instead of the typical IP address.
Using this feature is useful when Valkey clients use TLS to connect to Service Instances and require a hostname rather than an IP address in order to perform certificate ASN matching.
Using it
To enable or disable hostname-resolution
, it is important to follow a series of steps to ensure safety and prevent
significant downtime or data loss. Depending on its current state, the process may require adjusting a custom parameter
in two steps. See the cases below:
- To enable it in an existing Service Instance, follow these steps:
disabled → resolve-only → enabled
. - To disable it in an existing Service Instance, follow these steps:
enabled → resolve-only → disabled
. - When you create a new Service Instance, you can set any value directly. We suggest using either
enabled
ordisabled
.
Please note that transitioning directly from disabled
to enabled
, and vice versa, is not possible in an existing
Service Instance.
States/Values | Description |
---|---|
disabled | Hostname resolution and announcement are fully disabled. |
resolve-only | Hostname resolution is enabled but announcement is disabled. |
enabled | Hostname resolution and announcement are fully enabled. |
The default value is disabled
.
Backup and Restore Service Instances
a9s KeyValue provides an easy way to create backups and restore if needed. For a more detailed description, please see the a9s Service Dashboard documentation.
Make a Service Instance Locally Available
It is possible to access any of the a9s Data Services locally. That means you can connect with a local client to the service for any purpose such as debugging. CF provides a smart way to create SSH forward tunnels via a pushed application. For more information about this feature see the Accessing Apps with SSH section of the CF documentation.
First of all you must have an application bound to the service. How to do this see Bind an Application to a Service Instance.
cf ssh
support must be enabled in the platform. Ask your administrator if you are not sure.
Get The Service URL and Credentials
When you follow this instructions Obtain Service Instance Access Credentials you will get the hostname of the service and the user credentials.
$ cf env a9s-keyvalue-app
Getting env variables for app a9s-keyvalue-app in org test / space test as admin...
OK
System-Provided:
{
"VCAP_SERVICES": {
"a9s-keyvalue8": [
{
(...)
"credentials": {
"cacrt": "-----BEGIN CERTIFICATE-----\nMIIDGzszfasde....8tn9ebYK0k2Qt\n-----END CERTIFICATE-----\n",
"host": "EXAMPLE-master.service.dc1.a9ssvc",
"valkey": {
"password": "EXAMPLE-VALKEY-PASSWORD",
"port": 6379,
"username": "EXAMPLE-VALKEY-USERNAME"
},
"sentinel": {
"master_name": "EXAMPLE-master",
"password": "EXAMPLE-SENTINEL-PASSWORD",
"port": 26379,
"username": "EXAMPLE-SENTINEL-PASSWORD"
}
}
(...)
}
]
}
}
...
Notice the host EXAMPLE.service.dc1.a9svs
, the username EXAMPLE-VALKEY-USERNAME
and the password
EXAMPLE-VALKEY-PASSWORD
. You will need this in the next step.
Create a Tunnel to The Service
With the cf ssh
as mentioned before you can create a ssh forward tunnel to the management dashboard. Use port 6379 to
connect to the a9s KeyValue Instance.
$ cf ssh a9s-keyvalue-app -L 6379:EXAMPLE.service.dc1.a9svs:6379
vcap@956aaf4e-6da9-4f69-4b1d-8e631a403312:~$
When the ssh tunnel is open you can access the instance over the address localhost:6379
.
If the instance you have created is based on an SSL-plan, then you would need to provide a CA certificate when
connecting to it using the tunnel approach. To do so you can rely on the certificate shown when executing cf env
, as
shown above.
You should save the certificate from the credentials.cacrt
value of the VCAP_SERVICES
object into some local file.
Then, while the tunnel is open you can use the valkey-cli
to interact with your KeyValue instance from your local
machine:
valkey-cli -h 127.0.0.1 -p 6379 --user <user> --pass <password> --tls --cacert "$LOCAL_CA_CERT_FILE"
Don't forget to close the session with exit
.
Setup Disk Usage Alerts
Each service comes with the a9s Parachute. This component monitors ephemeral and persistent disk usage. See the a9s Parachute documentation how to configure the component.
*Redis is a registered trademark of Redis Ltd. Any rights therein are reserved to Redis Ltd. Any use by anynines GmbH is for referential purposes only and does not indicate any sponsorship, endorsement or affiliation between Redis and anynines GmbH.