Skip to main content
Discover Packs Jobs Registries Requests Docs About GitHub

Community Requests

Request new packs or jobs you'd like to see created

job Open

Replicating Redis Cluster with Sentinel

Hi *, I'm still trying to wrap my head around the above setup. There is a github repo (https://github.com/tritonDataCenter/triton-redis-cluster), that sets up a replicating redis sentinel cluster on Triton Datacenter. It basically patches the redis.conf depending from the fact, that a master already exists (or not). As I understand, sentinel is managing the cluster after the initial setup. Thus you just create one node first (count = 1) and then scale up afterwards. I guess, that should be somehow be doable maybe with lifecycle tasks and templates. I don't know, wether (consul?) DNS is even needed. If that works, you might even be able to use autoscaling to expand the number of cluster nodes dynamically. I tried to get Qwen3.6 to spit something out along those lines. But obviously there is no such thing as Nomad DNS but maybe one could use IP addresses, too: # redis-sentinel-replicated.nomad # Enhanced Nomad job: 3 Redis nodes (1 master + 2 replicas) + 3 Sentinel nodes # Inspired by tritonDataCenter/triton-redis-cluster replication pattern job "redis-sentinel-replicated" { datacenters = ["dc1"] type = "service" # ────────────────────────────────────────────────────────────────────────────── # REDIS CLUSTER (Master + Replicas) # ────────────────────────────────────────────────────────────────────────────── group "redis" { count = 3 restart { attempts = 3 interval = "5m" delay = "15s" mode = "delay" } task "redis" { driver = "docker" config { image = "redis:7-alpine" network_mode = "bridge" port_map = { redis = 6379 } } ports = ["redis"] # Persistent volume for replication durability volume "redis_data" { source = "redis_data" target = "/data" } # Dynamic config: Index 0 → Master, Others → Replica template { data = <<-EOT port 6379 bind 0.0.0.0 protected-mode no requirepass {{ env "REDIS_PASSWORD" | default "SecureRedisPass123!" }} masterauth {{ env "REDIS_PASSWORD" | default "SecureRedisPass123!" }} dir /data appendonly yes save 900 1 save 300 10 save 60 10000 replica-announce-ip {{ env "NOMAD_ADDR_redis" }} {{ if eq (env "NOMAD_ALLOC_INDEX") "0" }} # I am the master {{ else }} replicaof redis-master.service.redis.dc1.nomad.local 6379 {{ end }} EOT destination = "tmp/redis.conf" env = true } command = "redis-server" args = ["/tmp/redis.conf"] service { name = "redis-master" port = "redis" } check { type = "tcp" port = "redis" interval = "10s" timeout = "2s" } resources { cpu = 500 memory = 512 } } volume "redis_data" { type = "host" source = "/opt/redis/data" # Replace with CSI path for production } } # ────────────────────────────────────────────────────────────────────────────── # SENTINEL NODES # ────────────────────────────────────────────────────────────────────────────── group "sentinel" { count = 3 restart { attempts = 3 interval = "5m" delay = "15s" mode = "delay" } task "sentinel" { driver = "docker" config { image = "redis:7-alpine" network_mode = "bridge" port_map = { sentinel = 26379 } } ports = ["sentinel"] # Sentinel config: monitors master via Nomad DNS, re-resolves on failover template { data = <<-EOT port 26379 bind 0.0.0.0 sentinel monitor mymaster redis-master.service.redis.dc1.nomad.local 6379 2 sentinel auth-pass mymaster {{ env "REDIS_PASSWORD" | default "SecureRedisPass123!" }} sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1 sentinel deny-scripts-reconfig yes sentinel resolve-hostnames yes EOT destination = "tmp/sentinel.conf" env = true } command = "redis-sentinel" args = ["/tmp/sentinel.conf"] service { name = "sentinel" port = "sentinel" } check { type = "tcp" port = "sentinel" interval = "10s" timeout = "2s" } resources { cpu = 250 memory = 128 } } } }

neuroserve #2