<p>I need to list all nodes from my Redis Cluster on attribute spring.redis.sentinel.nodes? Is it right?</p>
<p>I wanna run a Redis Cluster on K8s to use the autoscaling provided from K8s, How can I use autoscale is it necessary to inform all nodes on spring.redis.sentinel.nodes?</p>

Clayton K. N. Passos
<p>Good question 💯.</p>
<p>The short answer is that you typically don't do autoscaling with stateful apps like Redis since you have to be careful about not corrupting your data. Most of the time you migrate and <a href="https://en.wikipedia.org/wiki/Shard_(database_architecture)" rel="nofollow noreferrer">shard</a> your data, i.e multiple clusters, with different segments of your data, etc.</p>
<p>Having said that, there is no silver bullet redis autoscaling solution but it's doable with a lot of monitoring and <a href="https://aphyr.com/posts/307-jepsen-redis-redux" rel="nofollow noreferrer">testing</a> 🦄. A challenge here is that sentinels change the master in case of failover so your solution needs to be able to determine or monitor who the master is at a certain interval, this is very critical during downscales. <a href="https://redis.io/topics/sentinel-clients" rel="nofollow noreferrer">Redis has written a pretty good guide</a> on how to create clients which you will probably have to do/understand if you want a reliable autoscaling solution.</p>
<p>So the idea here 💡 is that you start with a set of sentinel/redis nodes managed by a <a href="https://github.com/spotahome/redis-operator" rel="nofollow noreferrer">Kubernetes Operator</a>. With some config like this:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: databases.spotahome.com/v1
kind: RedisFailover
metadata:
  name: redisfailover
spec:
  sentinel:
    replicas: 3
    resources:
      requests:
        cpu: 100m
      limits:
        memory: 100Mi
  redis:
    replicas: 3
    resources:
      requests:
        cpu: 100m
        memory: 100Mi
      limits:
        cpu: 400m
        memory: 500Mi
</code></pre>
<p>Then maybe modify the controller of this operator to do autoscale based on certain metrics (CPUs, Memory, Storage, etc).</p>
<p>The moment there is an autoscale operation you will have to do a configuration change in your Spring boot application to account for this change (say the <a href="https://kubernetes.io/docs/concepts/configuration/configmap/" rel="nofollow noreferrer">ConfigMap</a> of your application). For example, automatically change the value of this:</p>
<pre class="lang-yaml prettyprint-override"><code>spring:
  cache:
    type: redis
  redis:
    port: 6666
    password: 123pwd
    sentinel:
      master: masterredis
      nodes:
        - 10.0.0.16
        - 10.0.0.17
        - 10.0.0.18
    lettuce:
      shutdown-timeout: 200ms
</code></pre>
<p>Now after the config change, you need to do a rolling restart to prevent any downtime. The best thing, in my opinion, to do this in Kubernetes is just to have another <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/operator/#:%7E:text=Edit%20This%20Page-,Operator%20pattern,principles%2C%20notably%20the%20control%20loop." rel="nofollow noreferrer">Operator</a> (or extend the Redis operator) for your application, that has a controller, to automatically detect when there is scaling operation, does the ConfigMap change, and finally does the rolling restart of your app. Your scaling operations need to allow enough time for balancing of data and also the rolling restart to prevent any <a href="https://en.wikipedia.org/wiki/Thrashing_(computer_science)" rel="nofollow noreferrer">thrashing</a>/<a href="https://en.wikipedia.org/wiki/Starvation_(computer_science)" rel="nofollow noreferrer">starvation</a> and possible downtime/data corruption.</p>
<p>✌️☮️</p>
