<p>My application has some aggregation/window operation, so it has some state store which stores in the <code>state.dir</code>. AFAIK, it also writes the changelog of state store to the broker, 
so is that OK to consider the Kafka Stream application as a stateless POD?</p>

<blockquote>
  <p>My application has some aggregation/window operation, so it has some state store which stores in the <code>state.dir</code>. AFAIK, it also writes the changelog of state store to the broker, so is that OK to consider the Kafka Stream application as a stateless POD?</p>
</blockquote>

<p><strong>Stateless pod and data safety (= no data loss):</strong> Yes, you can consider the application as a stateless pod as far as <em>data safety</em> is concerned; i.e. regardless of what happens to the pod Kafka and Kafka Streams guarantee that you will not lose data (and if you have enabled exactly-once processing, they will also guarantee the latter).</p>

<p>That's because, as you already said, state changes in your application are always continuously backed up to Kafka (brokers) via changelogs of the respective state stores -- unless you explicitly disabled this changelog functionality (it is enabled by default).</p>

<p>Note: The above is even true when you are not using Kafka's Streams default storage engine (RocksDB) but the alternative in-memory storage engine. Many people don't realize this because they read "in-memory" and (falsely) conclude "data will be lost when a machine crashes, restarts, etc.".</p>

<p><strong>Stateless pod and application restoration/recovery time:</strong> The above being said, you should understand how having vs. not-having local state available after pod restarts will impact restoration/recovery time of your application (or rather: application instance) until it is fully operational again.</p>

<p>Imagine that one instance of your stateful application runs on a machine. It will store its local state under <code>state.dir</code>, and it will also continuously backup any changes to its local state to the remote Kafka cluster (brokers).</p>

<ul>
<li>If the app instance is being restarted and <em>does not</em> have access to its previous <code>state.dir</code> (probably because it is restarted on a different machine), it will fully reconstruct its state by restoring from the associated changelog(s) in Kafka. Depending on the size of your state this may take milliseconds, seconds, minutes, or more. Only once its state is fully restored it will begin processing new data.</li>
<li>If the app instance is being restarted and <em>does</em> have access to its previous <code>state.dir</code> (probably because it is restarted on the same, original machine), it can recover much more quickly because it can re-use all or most of the existing local state, so only a small delta needs to restored from the associated changelog(s).  Only once its state is fully restored it will begin processing new data.</li>
</ul>

<p>In other words, if your application is able to re-use existing local state then this is good because it will minimize application recovery time.</p>

<p><strong>Standby replicas to the rescue in stateless environments:</strong> But even if you are running stateless pods you have options to minimize application recovery times by configuring your application to use <a href="https://kafka.apache.org/documentation/streams/developer-guide/config-streams.html#num-standby-replicas" rel="noreferrer">standby replicas</a> via the <code>num.standby.replicas</code> setting:</p>

<blockquote>
  <p><strong>num.standby.replicas</strong></p>
  
  <p>The number of standby replicas.  Standby replicas are shadow copies of local state stores. Kafka Streams attempts to create the specified number of replicas and keep them up to date as long as there are enough instances running. Standby replicas are used to minimize the latency of task failover. A task that was previously running on a failed instance is preferred to restart on an instance that has standby replicas so that the local state store restoration process from its changelog can be minimized.</p>
</blockquote>

<p>See also the documentation section <a href="https://kafka.apache.org/documentation/streams/developer-guide/running-app.html#state-restoration-during-workload-rebalance" rel="noreferrer">State restoration during workload rebalance</a></p>

<p><strong>Update 2018-08-29</strong>: Arguably the most convenient option to run Kafka/Kafka Streams/KSQL on Kubernetes is to use Confluent Operator or the Helm Charts provided by Confluent, see <a href="https://www.confluent.io/confluent-operator/" rel="noreferrer">https://www.confluent.io/confluent-operator/</a>. (Disclaimer: I work for Confluent.)</p>

<p><strong>Update 2019-01-10</strong>: There's also a Youtube video that demoes how to <a href="https://www.youtube.com/watch?v=4hAVEy01dGY" rel="noreferrer">Scale Kafka Streams with Kubernetes</a>.</p>
