EDXRedis Function
17 minute read
Overview
Redis is an open-source, in-memory data structure store that serves as a database, cache, message broker, and streaming engine. It supports diverse data structures including strings, hashes, lists, sets, sorted sets, bitmaps, hyperloglogs, and geospatial indexes. With sub-millisecond latency and support for millions of operations per second, Redis excels at real-time use cases such as session caching, rate limiting, leaderboards, and distributed locks, making it the de facto standard for high-performance data operations in modern architectures.
The EDXRedis
function brings Redis’s power directly into Edge Delta’s OTTL pipelines as a converter function, enabling real-time data enrichment, caching, and stateful processing of telemetry data. By integrating with Redis, pipelines can perform dynamic lookups to enrich logs with user metadata, implement deduplication to track unique events, maintain rolling counters for rate limiting, and correlate distributed traces across services. The function returns results from any Redis command and supports all deployment modes including Standalone for simplicity, Cluster for horizontal scaling across multiple nodes, and Sentinel for automatic failover and high availability, ensuring your enrichment layer scales seamlessly with your telemetry volume.
Minimum Agent Version: v2.5.0
Key Features
- Support for Redis Standalone, Cluster, and Sentinel deployments
- Universal command support - executes any valid Redis command
- Batch operations for performance optimization
- Automatic connection pooling and reuse
- Full TLS/mTLS support with certificate validation
- Client-side caching support
- Thread-safe client management
Syntax
EDXRedis(connection_config, commands)
connection_config
The connection_config
parameter is a map containing Redis connection details. This configuration object determines how EDXRedis connects to your Redis deployment, including the server URL, authentication method, and TLS settings.
url
Required. The Redis connection string that specifies the server endpoint(s). The format varies based on your deployment type:
- Standalone:
"redis://localhost:6379"
or"redis://default:password@host:port"
- Cluster:
"redis://node1:6379,node2:6379,node3:6379"
- Sentinel:
"redis://sentinel1:26379,sentinel2:26379,sentinel3:26379"
- With TLS:
"rediss://host:port"
(note the double ’s’ in rediss)
deploymentType
Optional. Specifies the Redis deployment architecture as "Standalone"
, "Cluster"
, or "Sentinel"
. Defaults to "Standalone"
if not specified. This setting ensures proper handling of cluster redirects and sentinel failovers.
sentinelMasterName
Required for Sentinel. The name of the Redis master as configured in your Sentinel setup. This parameter is mandatory when using Sentinel deployment type to enable proper master discovery.
auth
Optional. Authentication configuration for password-protected Redis instances. Currently supports only the "Manual"
method with the following fields:
method
: Must be"Manual"
(Note: UserSecret method is not yet implemented)username
: Redis username for ACL-based authenticationpassword
: Redis password for authentication
tls
Optional. TLS/SSL configuration for encrypted connections. When enabled, this secures the communication channel between Edge Delta and Redis:
enabled
: Boolean flag to enable TLSvalidateCerts
: Boolean flag to validate server certificatescaCertPath
: Path to the CA certificate file for server verificationcertPath
: Path to the client certificate file (required for mTLS)keyPath
: Path to the client private key file (required for mTLS)serverName
: Server name for TLS verification
Important: Certificates MUST include Subject Alternative Names (SANs) for successful TLS handshakes. Common Name (CN) alone is insufficient and will cause “certificate verify failed” errors. When using mTLS, the Edge Delta deployment scripts create Kubernetes secrets that mount certificates at /certs/
. Both agent runtime and platform API configurations assume these certificate files are present at the specified paths.
blockingTimeout
Optional. Timeout for blocking operations in seconds. Defaults to 60 seconds. This applies to blocking commands like BLPOP or BRPOP.
clientSideCache
Optional. Boolean flag to enable client-side caching for improved performance on frequently accessed keys.
options
Optional. A map of additional Redis-specific options as key-value pairs for advanced configurations.
commands
The commands
parameter is an array of command objects that specify the Redis operations to execute. Each command object in the array contains the following fields:
outField
Required. The field name where the command result will be stored. This is mandatory for all commands and determines how you access the result in subsequent pipeline statements.
command
Required. The Redis command name to execute (case-insensitive). Any valid Redis command can be used, such as GET, SET, HGET, INCR, etc.
key
Optional. The Redis key to operate on. Required for most commands except server commands like PING or INFO.
args
Optional. An array of additional arguments specific to the command. For example, SET command might include expiration time, HGET requires the field name, etc.
Important: The outField
parameter is mandatory for EDXRedis to return results. Without it, operations may execute but results will not be accessible in your pipeline.
Supported Redis Commands
EDXRedis supports all Redis commands through a generic command interface. Any valid Redis command can be executed.
Category | Commands | Description |
---|---|---|
String Operations | GET, SET, SETEX, SETNX | Basic string get/set operations with optional expiration and conditional setting |
MGET, MSET | Multiple key operations for batch get/set | |
INCR, INCRBY, DECR, DECRBY | Atomic increment/decrement operations for counters | |
APPEND, STRLEN | String manipulation - append content and get length | |
GETSET, GETRANGE, SETRANGE | Advanced string operations - atomic get+set, substring operations | |
Key Management | EXISTS, DEL | Check key existence and delete keys |
EXPIRE, EXPIREAT, TTL, PTTL | Set and query key expiration times | |
PERSIST, RENAME, RENAMENX | Remove expiration, rename keys (with conditional rename) | |
TYPE, KEYS, SCAN, RANDOMKEY | Key inspection, pattern matching, and iteration | |
List Operations | LPUSH, RPUSH, LPOP, RPOP | Add/remove elements from list heads and tails |
LLEN, LRANGE, LINDEX | Get list length, range of elements, or element at index | |
LSET, LTRIM, LREM, LINSERT | Modify lists - set by index, trim, remove, or insert elements | |
Set Operations | SADD, SREM | Add/remove members from sets |
SISMEMBER, SMEMBERS | Check membership and get all members | |
SCARD, SPOP, SRANDMEMBER | Get set size, pop random member, or get random member | |
SUNION, SINTER, SDIFF | Set operations - union, intersection, and difference | |
Hash Operations | HSET, HGET, HMGET | Set/get hash fields (single or multiple) |
HGETALL, HKEYS, HVALS | Get all fields+values, all keys, or all values | |
HDEL, HEXISTS | Delete fields and check field existence | |
HLEN, HINCRBY, HSETNX | Get hash size, increment field, conditional set | |
Sorted Set Operations | ZADD, ZREM | Add/remove members with scores |
ZSCORE, ZRANK | Get member score or rank | |
ZRANGE, ZRANGEBYSCORE | Get members by rank or score range | |
ZCOUNT, ZCARD, ZINCRBY | Count members, get size, increment scores |
Examples
Simple GET Operation
This example retrieves a value from Redis using the GET command, which fetches the string value associated with a given key.
Consider this log:
{
"timestamp": "2025-09-18T10:30:45Z",
"level": "INFO",
"message": "User login attempt",
"event_id": "evt_001",
"user_id": "user_1"
}
Assume it is passed through the Edge Delta pipeline with this configuration:
- name: redis_get
type: ottl_transform
statements: |-
set(cache["cmd"], [{"command": "get", "key": "user:123", "outField": "user_data"}])
set(cache["result"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmd"]))
set(attributes["user"], cache["result"]["user_data"]) where cache["result"]["user_data"] != nil
In this processor, the first statement creates a Redis GET command for the key “user:123” and stores it in the cache. The second statement executes this command against Redis at localhost:6379 and stores the full response. The third statement extracts the user data from the result and adds it as an attribute, but only if the value is not nil.
The following output log would be generated (assuming Redis key “user:123” contains “John Doe”):
{
"timestamp": "2025-09-18T10:30:45Z",
"level": "INFO",
"message": "User login attempt",
"event_id": "evt_001",
"user_id": "user_1",
"attributes": {
"user": "John Doe"
}
}
In the output, the user attribute has been added with the value “John Doe” that was retrieved from Redis, enriching the original log with additional context about the user.
Note: If the key doesn’t exist in Redis, the user
attribute will not be added due to the where
condition checking for nil.
SET with Expiration
This example stores a value in Redis with an expiration time using the SET command with the EX (expire in seconds) option.
Consider this log:
{
"timestamp": "2025-09-18T04:00:00Z",
"sequence": 1,
"event_id": "evt_001",
"user_id": "user_1",
"action": "test_action",
"data": "test_data_1"
}
Assume it is passed through the Edge Delta pipeline with this configuration:
- name: redis_set_with_ttl
type: ottl_transform
statements: |-
set(cache["value"], String(attributes["data"]))
set(cache["cmd"], [{"command": "set", "key": "temp:data", "args": [cache["value"], "EX", "60"], "outField": "result"}])
set(cache["response"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmd"]))
set(attributes["redis.set.result"], cache["response"]["result"])
In this processor, the first statement converts the data attribute to a string. The second statement creates a Redis SET command with a 60-second expiration time. The third statement executes the command against Redis. The fourth statement adds the operation result as an attribute.
The following output log would be generated:
{
"timestamp": "2025-09-18T04:00:00Z",
"sequence": 1,
"event_id": "evt_001",
"user_id": "user_1",
"action": "test_action",
"data": "test_data_1",
"attributes": {
"redis.set.result": "OK"
}
}
In the output, the redis.set.result attribute contains “OK”, confirming that the value was successfully stored in Redis with a 60-second TTL. The key “temp:data” now contains “test_data_1” and will automatically expire after 60 seconds.
Note: The SET command returns “OK” when successful. You can verify the TTL using the TTL command, which would return the remaining seconds (e.g., 59 if checked immediately after setting).
Manual Authentication
This example demonstrates connecting to a password-protected Redis instance using manual authentication credentials.
Consider this log:
{
"timestamp": "2025-09-18T06:30:00Z",
"level": "INFO",
"message": "Secure data access request",
"request_id": "req_456",
"user": "admin"
}
Assume it is passed through the Edge Delta pipeline with this configuration:
- name: redis_with_auth
type: ottl_transform
statements: |-
set(cache["config"], {"url": "redis://redis-auth.test-destination.svc.cluster.local:6379", "auth": {"method": "Manual", "username": "myuser", "password": "mypassword"}})
set(cache["cmd"], [{"command": "get", "key": "secure:data", "outField": "data"}])
set(cache["result"], EDXRedis(cache["config"], cache["cmd"]))
set(attributes["secure_value"], cache["result"]["data"]) where cache["result"]["data"] != nil
In this processor, the first statement creates a configuration object with Redis connection details including manual authentication. The second statement prepares a GET command for the key “secure:data”. The third statement executes the authenticated command against Redis. The fourth statement adds the retrieved value as an attribute if it exists.
The following output log would be generated (assuming Redis key “secure:data” contains “confidential_info”):
{
"timestamp": "2025-09-18T06:30:00Z",
"level": "INFO",
"message": "Secure data access request",
"request_id": "req_456",
"user": "admin",
"attributes": {
"secure_value": "confidential_info"
}
}
In the output, the secure_value attribute contains the data retrieved from the authenticated Redis instance, demonstrating successful authentication and data retrieval.
Note: Manual authentication is currently the only supported authentication method. The UserSecret method is not yet implemented and will return an error if attempted.
TLS Configuration
This example shows the configuration for connecting to Redis over TLS using server certificate validation.
Consider this log:
{
"timestamp": "2025-09-18T08:45:00Z",
"level": "INFO",
"message": "Encrypted channel request",
"transaction_id": "txn_789",
"service": "payment"
}
The following configuration is intended for TLS connections:
- name: redis_with_tls
type: ottl_transform
statements: |-
set(cache["config"], {"url": "rediss://redis-tls.test-destination.svc.cluster.local:6379", "tls": {"enabled": true, "validateCerts": true, "caCertPath": "/certs/ca.crt"}})
set(cache["cmd"], [{"command": "get", "key": "secure:config", "outField": "config_data"}])
set(cache["result"], EDXRedis(cache["config"], cache["cmd"]))
set(attributes["config"], cache["result"]["config_data"]) where cache["result"]["config_data"] != nil
Important Note: During testing (September 2025), this TLS-only configuration exhibited silent failures with no TLS handshake attempts or data retrieval. The issue appears related to certificate validation requirements. For production use, we recommend using the mTLS configuration (Example 4b) which has been thoroughly validated, or ensure your server certificate includes proper Subject Alternative Names (SANs) that match the hostname used in the connection URL.
Known Requirements:
- Server certificate MUST include Subject Alternative Names (SANs)
- The SAN must match the hostname in the connection URL
- Common Name (CN) alone is insufficient and will cause connection failures
For a working encrypted connection, see Example 4b (mTLS) which has been validated in production environments.
mTLS Configuration (Mutual TLS)
This example demonstrates mutual TLS authentication where both the client and server validate each other’s certificates.
Consider this log:
{
"level": "INFO",
"message": "Test log from telemetry generator",
"test_id": "11526",
"timestamp": "2025-09-19T00:31:09+00:00"
}
Assume it is passed through the Edge Delta pipeline with this configuration:
- name: redis_with_mtls
type: ottl_transform
statements: |-
# Configure mTLS connection with client certificates
set(cache["config"], {
"url": "rediss://redis-mtls.test-destination.svc.cluster.local:6379",
"tls": {
"enabled": true,
"validateCerts": true,
"caCertPath": "/certs/ca.crt",
"certPath": "/certs/client.crt",
"keyPath": "/certs/client.key"
}
})
# Test connection with PING
set(cache["ping_cmd"], [{"command": "ping", "outField": "ping_result"}])
set(cache["ping_result"], EDXRedis(cache["config"], cache["ping_cmd"]))
set(attributes["redis.mtls.ping"], cache["ping_result"]["ping_result"])
# SET operation over mTLS
set(cache["set_cmd"], [{"command": "set", "key": "secure:key", "args": ["secure_data"], "outField": "set_result"}])
set(cache["set_result"], EDXRedis(cache["config"], cache["set_cmd"]))
set(attributes["redis.mtls.set"], cache["set_result"]["set_result"])
# GET operation over mTLS
set(cache["get_cmd"], [{"command": "get", "key": "secure:key", "outField": "get_result"}])
set(cache["get_result"], EDXRedis(cache["config"], cache["get_cmd"]))
set(attributes["redis.mtls.get"], cache["get_result"]["get_result"])
In this processor, the first statement creates a complete mTLS configuration with CA certificate for server validation and client certificate/key for client authentication. The subsequent statements execute PING to verify connectivity, SET to store data, and GET to retrieve it, all over the mutually authenticated TLS connection.
The following output log would be generated:
{
"level": "INFO",
"message": "Test log from telemetry generator",
"test_id": "11526",
"timestamp": "2025-09-19T00:31:09+00:00",
"attributes": {
"redis.mtls.ping": "PONG",
"redis.mtls.set": "OK",
"redis.mtls.get": "secure_data"
}
}
In the output, the redis.mtls.ping confirms connectivity with “PONG”, redis.mtls.set shows successful storage with “OK”, and redis.mtls.get contains the retrieved value “secure_data”, all demonstrating successful mutual TLS authentication and encrypted operations.
Critical Requirements:
- Both server and client certificates MUST include Subject Alternative Names (SANs)
- The Edge Delta deployment automatically mounts certificates at
/certs/
from Kubernetes secrets - Ensure the same CA signs both server and client certificates for successful mutual authentication
Batch Operations
This example demonstrates executing multiple Redis commands in a single call for improved performance.
Consider this log:
{
"timestamp": "2025-09-18T10:45:00Z",
"level": "INFO",
"message": "Application status check",
"service": "monitoring",
"check_id": "chk_123"
}
Assume it is passed through the Edge Delta pipeline with this configuration:
- name: batch_operations
type: ottl_transform
statements: |-
# Execute multiple commands in one call
set(cache["cmds"], [
{"command": "get", "key": "config:app", "outField": "app_config"},
{"command": "incr", "key": "counters:requests", "outField": "request_count"},
{"command": "hget", "key": "server:status", "args": ["health"], "outField": "health"}
])
set(cache["results"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmds"]))
# Access individual results
set(attributes["app_config"], cache["results"]["app_config"]) where cache["results"]["app_config"] != nil
set(attributes["requests"], cache["results"]["request_count"]) where cache["results"]["request_count"] != nil
set(attributes["health"], cache["results"]["health"]) where cache["results"]["health"] != nil
In this processor, the first statement creates an array of three Redis commands: GET to retrieve configuration, INCR to increment a counter, and HGET to fetch a hash field. The second statement executes all three commands in a single EDXRedis call. The remaining statements extract each result and add them as attributes.
The following output log would be generated (assuming the keys exist with appropriate values):
{
"timestamp": "2025-09-18T10:45:00Z",
"level": "INFO",
"message": "Application status check",
"service": "monitoring",
"check_id": "chk_123",
"attributes": {
"app_config": "production_v2.1",
"requests": 1250,
"health": "healthy"
}
}
In the output, three attributes are added from the batch operation: app_config contains the configuration string, requests shows the incremented counter value, and health displays the status from the hash.
Performance Note: Batch operations reduce network round trips by sending multiple commands together. This is particularly beneficial when enriching logs with multiple Redis lookups or when performing related operations that can be grouped.
Hash Operations
This example demonstrates storing and retrieving multiple fields in a Redis hash structure.
Consider this log:
{
"timestamp": "2025-09-18T05:32:52+00:00",
"sequence": 20298,
"server_id": "srv_0",
"metrics": {"cpu": 45, "memory": 78, "disk": 62},
"status": "active"
}
Assume it is passed through the Edge Delta pipeline with this configuration:
- name: hash_operations
type: ottl_transform
statements: |-
# Store multiple fields in a hash
set(cache["cmd"], [{"command": "hset", "key": "server:metrics", "args": ["cpu", "45", "memory", "78", "disk", "62"], "outField": "fields_added"}])
set(cache["result"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmd"]))
set(attributes["fields_stored"], cache["result"]["fields_added"])
# Retrieve all hash fields
set(cache["get_cmd"], [{"command": "hgetall", "key": "server:metrics", "outField": "metrics"}])
set(cache["metrics"], EDXRedis({"url": "redis://localhost:6379"}, cache["get_cmd"]))
set(attributes["server_metrics"], cache["metrics"]["metrics"])
In this processor, the first statement creates an HSET command to store three field-value pairs in a hash. The second statement executes the command. The third statement captures the number of fields added. The fourth statement prepares an HGETALL command to retrieve all fields. The fifth statement executes the retrieval. The sixth statement adds the metrics as an attribute.
The following output log would be generated:
{
"timestamp": "2025-09-18T05:32:52+00:00",
"sequence": 20298,
"server_id": "srv_0",
"metrics": {"cpu": 45, "memory": 78, "disk": 62},
"status": "active",
"attributes": {
"fields_stored": 3,
"server_metrics": ["cpu", "45", "memory", "78", "disk", "62"]
}
}
In the output, fields_stored shows that 3 fields were added to the hash, and server_metrics contains the retrieved data as a flat array in Redis format [key1, value1, key2, value2…].
Important Note: HGETALL returns data as a flat array rather than a map/object. To work with individual fields, consider using HGET commands for specific fields or post-process the array in OTTL to convert it to a map structure.
Deduplication Pattern
This example demonstrates using SETNX (SET if Not eXists) to detect and prevent duplicate event processing.
Common Use Cases:
- Use SETNX for exactly-once semantics
- Track processed event IDs with TTL
- Implement idempotency keys
- Maintain processing history
Consider this log:
{
"timestamp": "2025-09-18T11:00:00Z",
"level": "INFO",
"message": "Payment processed",
"event_id": "evt_12345",
"amount": 99.99,
"user_id": "user_789"
}
Assume it is passed through the Edge Delta pipeline with this configuration:
- name: event_deduplication
type: ottl_transform
statements: |-
# Create unique event key
set(cache["event_key"], Concat(["event:", attributes["event_id"]], ""))
# Use SETNX to detect duplicates (returns 1 if new, 0 if exists)
set(cache["cmd"], [{"command": "setnx", "key": cache["event_key"], "args": ["1"], "outField": "is_new"}])
set(cache["result"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmd"]))
# Set TTL on new events (expire after 1 hour)
set(cache["expire_cmd"], [{"command": "expire", "key": cache["event_key"], "args": ["3600"], "outField": "expire_result"}]) where cache["result"]["is_new"] == 1
set(cache["expire_result"], EDXRedis({"url": "redis://localhost:6379"}, cache["expire_cmd"])) where cache["result"]["is_new"] == 1
# Mark as duplicate or new
set(attributes["is_duplicate"], cache["result"]["is_new"] == 0)
set(attributes["dedup_key"], cache["event_key"])
In this processor, the first statement creates a unique key from the event ID. The second and third statements use SETNX to atomically check and set the key. The fourth and fifth statements set an expiration time only for new events. The final statements add attributes indicating whether this is a duplicate.
First occurrence output (new event):
{
"timestamp": "2025-09-18T11:00:00Z",
"level": "INFO",
"message": "Payment processed",
"event_id": "evt_12345",
"amount": 99.99,
"user_id": "user_789",
"attributes": {
"is_duplicate": false,
"dedup_key": "event:evt_12345"
}
}
Subsequent occurrence output (duplicate within 1 hour):
{
"timestamp": "2025-09-18T11:05:00Z",
"level": "INFO",
"message": "Payment processed",
"event_id": "evt_12345",
"amount": 99.99,
"user_id": "user_789",
"attributes": {
"is_duplicate": true,
"dedup_key": "event:evt_12345"
}
}
In the output, is_duplicate is false for the first occurrence (SETNX returned 1) and true for any duplicates within the TTL window (SETNX returned 0).
Note: This pattern provides exactly-once semantics within the TTL window. The EXPIRE command ensures automatic cleanup of deduplication keys to prevent memory growth.
CMDB Enrichment
Common Use Cases:
- Store asset information from ServiceNow, Jira Assets, or custom CMDBs
- Perform priority-based lookups (asset tag → hostname → IP)
- Cache enrichment data with appropriate TTLs
- Track enrichment success rates
- name: cmdb_enrichment
type: ottl_transform
statements: |-
# Extract identifiers
set(cache["asset_tag"], EDXExtractPatterns(body, "asset_tag=(?P<tag>[A-Z0-9-]+)")["tag"])
set(cache["hostname"], EDXExtractPatterns(body, "host=(?P<host>[\\w\\.-]+)")["host"])
# Batch lookup multiple keys
set(cache["cmds"], [{"command": "get", "key": Concat(["cmdb:asset:", cache["asset_tag"]], ""), "outField": "by_asset"}, {"command": "get", "key": Concat(["cmdb:host:", cache["hostname"]], ""), "outField": "by_host"}])
set(cache["lookups"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmds"]))
# Use first available match
set(cache["cmdb_data"], cache["lookups"]["by_asset"]) where cache["lookups"]["by_asset"] != nil
set(cache["cmdb_data"], cache["lookups"]["by_host"]) where cache["cmdb_data"] == nil and cache["lookups"]["by_host"] != nil
# Parse and enrich
set(cache["cmdb"], ParseJSON(cache["cmdb_data"])) where cache["cmdb_data"] != nil
merge_maps(attributes, cache["cmdb"], "insert") where cache["cmdb"] != nil
Redis Cluster
- name: cluster_operation
type: ottl_transform
statements: |-
set(cache["config"], {"url": "redis://node1:6379,node2:6379,node3:6379", "deploymentType": "Cluster"})
set(cache["cmd"], [{"command": "get", "key": "distributed:data", "outField": "data"}])
set(cache["result"], EDXRedis(cache["config"], cache["cmd"]))
Redis Sentinel
- name: sentinel_operation
type: ottl_transform
statements: |-
set(cache["config"], {"url": "redis://sentinel1:26379,sentinel2:26379", "deploymentType": "Sentinel", "sentinelMasterName": "mymaster"})
set(cache["cmd"], [{"command": "get", "key": "ha:data", "outField": "data"}])
set(cache["result"], EDXRedis(cache["config"], cache["cmd"]))
Error Handling
Nil Responses
- name: handle_nil
type: ottl_transform
statements: |-
set(cache["cmd"], [{"command": "get", "key": "missing:key", "outField": "data"}])
set(cache["result"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmd"]))
# Nil is normal for non-existent keys
set(attributes["data"], cache["result"]["data"]) where cache["result"]["data"] != nil
set(attributes["data"], "default_value") where cache["result"]["data"] == nil
Connection Failures
- name: handle_failure
type: ottl_transform
statements: |-
set(cache["result"], EDXRedis({"url": "redis://localhost:6379"}, cache["cmd"]))
# Connection errors are logged but don't stop the pipeline
set(attributes["source"], "redis") where cache["result"] != nil
set(attributes["source"], "fallback") where cache["result"] == nil
Performance Optimization
Connection Pooling
The EDXRedis function automatically manages a connection pool:
- Clients are cached and reused based on connection configuration
- Connection configurations are hashed for efficient lookups
- Unhealthy clients are automatically detected and replaced
- Memory-efficient sharing of client instances
Batch Operations
Execute multiple commands in a single call to reduce round trips:
set(cache["cmds"], [{"command": "get", "key": "k1", "outField": "v1"}, {"command": "get", "key": "k2", "outField": "v2"}, {"command": "get", "key": "k3", "outField": "v3"}])
set(cache["results"], EDXRedis(config, cache["cmds"]))
Key Design Best Practices
- Use consistent key naming:
namespace:type:id
- Keep keys short but descriptive
- Use hash tags for cluster slot control:
{user:123}:session
- Implement key expiration strategy
Troubleshooting
For a comprehensive troubleshooting guide with detailed solutions, see the EDXRedis Troubleshooting Guide.
Common Issues
Issue | Cause | Solution |
---|---|---|
No results returned | Missing outField |
Always include outField in command objects |
Connection refused | Wrong host/port | Verify Redis is running and accessible |
AUTH failed | Invalid credentials | Check username/password with Manual auth method |
TLS handshake failed | Certificate issues | Ensure certificates include SANs; verify CA cert path and server name |
“certificate verify failed” | Missing SANs in certificates | Regenerate certificates with proper Subject Alternative Names |
Cluster redirect | Wrong deployment type | Set deploymentType: "Cluster" for Redis Cluster |
Sentinel can’t find master | Wrong master name | Verify sentinelMasterName matches Sentinel config |
High latency | Network or blocking timeout | Adjust blockingTimeout parameter |
Memory errors | Redis full | Implement eviction policy or increase memory |
Debug Techniques
- name: debug_redis
type: ottl_transform
statements: |-
# Test connectivity
set(cache["ping_cmd"], [{"command": "ping", "key": "", "outField": "pong"}])
set(cache["ping_result"], EDXRedis({"url": "redis://localhost:6379"}, cache["ping_cmd"]))
set(attributes["redis.connected"], cache["ping_result"]["pong"] == "PONG")
# Log for debugging
set(attributes["debug.cmd"], String(cache["cmd"]))
set(attributes["debug.result"], String(cache["result"]))
Additional Resources
Edge Delta Documentation
- EDXRedis in OTTL Extensions - Quick reference and comparison with other OTTL functions
- EDXRedis Troubleshooting Guide - Common issues and solutions
- Edge Delta OTTL Guide - Complete OTTL language reference
- Edge Delta Performance Tuning - Optimize your pipelines