blob: ac5affa426c2add76c5f78520e5dbee9a9c844a4 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en" dir=ZgotmplZ>
<head>
<link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
<script src="/bootstrap/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" type="text/css" href="/font-awesome/css/font-awesome.min.css">
<script src="/js/anchor.min.js"></script>
<script src="/js/flink.js"></script>
<link rel="canonical" href="https://flink.apache.org/2020/10/13/stateful-functions-internals-behind-the-scenes-of-stateful-serverless/">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Stateful Functions (StateFun) simplifies the building of distributed stateful applications by combining the best of two worlds: the strong messaging and state consistency guarantees of stateful stream processing, and the elasticity and serverless experience of today&rsquo;s cloud-native architectures and popular event-driven FaaS platforms. Typical StateFun applications consist of functions deployed behind simple services using these modern platforms, with a separate StateFun cluster playing the role of an “event-driven database” that provides consistency and fault-tolerance for the functions&rsquo; state and messaging.">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="Stateful Functions Internals: Behind the scenes of Stateful Serverless" />
<meta property="og:description" content="Stateful Functions (StateFun) simplifies the building of distributed stateful applications by combining the best of two worlds: the strong messaging and state consistency guarantees of stateful stream processing, and the elasticity and serverless experience of today&rsquo;s cloud-native architectures and popular event-driven FaaS platforms. Typical StateFun applications consist of functions deployed behind simple services using these modern platforms, with a separate StateFun cluster playing the role of an “event-driven database” that provides consistency and fault-tolerance for the functions&rsquo; state and messaging." />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://flink.apache.org/2020/10/13/stateful-functions-internals-behind-the-scenes-of-stateful-serverless/" /><meta property="article:section" content="posts" />
<meta property="article:published_time" content="2020-10-13T00:00:00+00:00" />
<meta property="article:modified_time" content="2020-10-13T00:00:00+00:00" />
<title>Stateful Functions Internals: Behind the scenes of Stateful Serverless | Apache Flink</title>
<link rel="manifest" href="/manifest.json">
<link rel="icon" href="/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/book.min.22eceb4d17baa9cdc0f57345edd6f215a40474022dfee39b63befb5fb3c596b5.css" integrity="sha256-IuzrTRe6qc3A9XNF7dbyFaQEdAIt/uObY777X7PFlrU=">
<script defer src="/en.search.min.2698f0d1b683dae4d6cb071668b310a55ebcf1c48d11410a015a51d90105b53e.js" integrity="sha256-Jpjw0baD2uTWywcWaLMQpV688cSNEUEKAVpR2QEFtT4="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
<meta name="generator" content="Hugo 0.124.1">
<script>
var _paq = window._paq = window._paq || [];
_paq.push(['disableCookies']);
_paq.push(["setDomains", ["*.flink.apache.org","*.nightlies.apache.org/flink"]]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
</head>
<body dir=ZgotmplZ>
<header>
<nav class="navbar navbar-expand-xl">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<img src="/img/logo/png/100/flink_squirrel_100_color.png" alt="Apache Flink" height="47" width="47" class="d-inline-block align-text-middle">
<span>Apache Flink</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<i class="fa fa-bars navbar-toggler-icon"></i>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">About</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="/what-is-flink/flink-architecture/">Architecture</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/flink-applications/">Applications</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/flink-operations/">Operations</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/use-cases/">Use Cases</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/powered-by/">Powered By</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/roadmap/">Roadmap</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/community/">Community & Project Info</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/security/">Security</a>
</li>
<li>
<a class="dropdown-item" href="/what-is-flink/special-thanks/">Special Thanks</a>
</li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">Getting Started</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-docs-stable/docs/try-flink/local_installation/">With Flink<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-stable/docs/try-flink-kubernetes-operator/quick-start/">With Flink Kubernetes Operator<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-cdc-docs-stable/docs/get-started/introduction/">With Flink CDC<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-ml-docs-stable/docs/try-flink-ml/quick-start/">With Flink ML<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-statefun-docs-stable/getting-started/project-setup.html">With Flink Stateful Functions<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-docs-stable/docs/learn-flink/overview/">Training Course<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">Documentation</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-docs-stable/">Flink 1.19 (stable)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-docs-master/">Flink Master (snapshot)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-stable/">Kubernetes Operator 1.8 (latest)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-main">Kubernetes Operator Main (snapshot)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-cdc-docs-stable">CDC 3.0 (stable)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-cdc-docs-master">CDC Master (snapshot)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-ml-docs-stable/">ML 2.3 (stable)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-ml-docs-master">ML Master (snapshot)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-statefun-docs-stable/">Stateful Functions 3.3 (stable)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
<li>
<a class="dropdown-item" href="https://nightlies.apache.org/flink/flink-statefun-docs-master">Stateful Functions Master (snapshot)<i class="link fa fa-external-link title" aria-hidden="true"></i>
</a>
</li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">How to Contribute</a>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item" href="/how-to-contribute/overview/">Overview</a>
</li>
<li>
<a class="dropdown-item" href="/how-to-contribute/contribute-code/">Contribute Code</a>
</li>
<li>
<a class="dropdown-item" href="/how-to-contribute/reviewing-prs/">Review Pull Requests</a>
</li>
<li>
<a class="dropdown-item" href="/how-to-contribute/code-style-and-quality-preamble/">Code Style and Quality Guide</a>
</li>
<li>
<a class="dropdown-item" href="/how-to-contribute/contribute-documentation/">Contribute Documentation</a>
</li>
<li>
<a class="dropdown-item" href="/how-to-contribute/documentation-style-guide/">Documentation Style Guide</a>
</li>
<li>
<a class="dropdown-item" href="/how-to-contribute/improve-website/">Contribute to the Website</a>
</li>
<li>
<a class="dropdown-item" href="/how-to-contribute/getting-help/">Getting Help</a>
</li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link" href="/posts/">Flink Blog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/downloads/">Downloads</a>
</li>
</ul>
<div class="book-search">
<div class="book-search-spinner hidden">
<i class="fa fa-refresh fa-spin"></i>
</div>
<form class="search-bar d-flex" onsubmit="return false;"su>
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/">
<i class="fa fa-search search"></i>
<i class="fa fa-circle-o-notch fa-spin spinner"></i>
</form>
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
</div>
</div>
</nav>
<div class="navbar-clearfix"></div>
</header>
<main class="flex">
<section class="container book-page">
<article class="markdown">
<h1>
<a href="/2020/10/13/stateful-functions-internals-behind-the-scenes-of-stateful-serverless/">Stateful Functions Internals: Behind the scenes of Stateful Serverless</a>
</h1>
October 13, 2020 -
Tzu-Li (Gordon) Tai
<a href="https://twitter.com/tzulitai">(@tzulitai)</a>
<p><p>Stateful Functions (StateFun) simplifies the building of distributed stateful applications by combining the best of two worlds:
the strong messaging and state consistency guarantees of stateful stream processing, and the elasticity and serverless experience of today&rsquo;s cloud-native architectures and
popular event-driven FaaS platforms. Typical StateFun applications consist of functions deployed behind simple services
using these modern platforms, with a separate StateFun cluster playing the role of an “<a href="https://flink.apache.org/news/2020/04/07/release-statefun-2.0.0.html">event-driven database</a>
that provides consistency and fault-tolerance for the functions&rsquo; state and messaging.</p>
<p>But how exactly does StateFun achieve that? How does the StateFun cluster communicate with the functions?</p>
<p>This blog dives deep into the internals of the StateFun runtime. The entire walkthrough is complemented by a
<a href="https://github.com/tzulitai/statefun-aws-demo/">demo application</a> which can be completely deployed on AWS services.
Most significantly, in the demo, the stateful functions are deployed and serviced using <a href="https://aws.amazon.com/lambda/">AWS Lambda</a>,
a popular FaaS platform among many others. The goal here is to allow readers to have a good grasp of the interaction between
the StateFun runtime and the functions, how that works cohesively to provide a Stateful Serverless experience, and how they can apply
what they&rsquo;ve learnt to deploy their StateFun applications on other public cloud offerings such as GCP or Microsoft Azure.</p>
<h2 id="introducing-the-example-shopping-cart">
Introducing the example: Shopping Cart
<a class="anchor" href="#introducing-the-example-shopping-cart">#</a>
</h2>
<div class="alert alert-info" markdown="1">
<span class="label label-info" style="display: inline-block"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> Note</span>
You can find the full code [here](https://github.com/tzulitai/statefun-aws-demo/blob/master/app/shopping_cart.py), which
uses StateFun's [Python SDK](//nightlies.apache.org/flink/flink-statefun-docs-master/sdk/python.html). Alternatively, if you are
unfamiliar with StateFun's API, you can check out this [earlier blog](https://flink.apache.org/2020/08/19/statefun.html)
on modeling applications and stateful entities using [StateFun's programming constructs](//nightlies.apache.org/flink/flink-statefun-docs-master/concepts/application-building-blocks.html).
</div>
<p>Let’s first take a look at a high-level overview of the motivating demo for this blog post: a shopping cart application.
The diagram below covers the functions that build up the application, the state that the functions would keep, and the messages
that flow between them. We’ll be referencing this example throughout the blog post.</p>
<center>
<figure>
<img src="/img/blog/2020-10-13-stateful-serverless-internals/shopping-cart-overview.png" width="600px" alt="Shopping cart application"/>
<figcaption><i><b>Fig.1:</b> An overly simplified shopping cart application.</i></figcaption>
</figure>
</center>
<br>
<p>The application consists of two function types: a <code>cart</code> function and an <code>inventory</code> function.
Each instance of the <code>cart</code> function is associated with a single user entity, with its state being the items in the cart
for that user (<code>ItemsInCart</code>). In the same way, each instance of the <code>inventory</code> function represents a single inventory,
maintaining as state the number of items in stock (<code>NumInStock</code>) as well as the number of items reserved across all
user carts (<code>NumReserved</code>). Messages can be sent to function instances using their logical addresses, which consists
of the function type and the instance&rsquo;s entity ID, e.g. <code>(cart:Kim)</code> or <code>(inventory:socks)</code>.</p>
<p>There are two external messages being sent to and from the shopping cart application via ingresses and egresses:
<code>AddToCart</code>, which is sent to the ingress when an item is added to a user’s cart (e.g. sent by a front-end web application),
and <code>AddToCartResult</code>, which is sent back from our application to acknowledge the action.</p>
<p><code>AddToCart</code> messages are handled by the <code>cart</code> function, which in turn invokes other functions to form the main logic of the application.
To keep things simple, only two messages between functions are demonstrated: <code>RequestItem</code>, sent from the <code>cart</code> function to the <code>inventory</code>
function, representing a request to reserve an item, and <code>ItemReserved</code>, which is a response from the inventory function to acknowledge the request.</p>
<h2 id="what-happens-in-the-stateful-functions-runtime">
What happens in the Stateful Functions runtime?
<a class="anchor" href="#what-happens-in-the-stateful-functions-runtime">#</a>
</h2>
<p>Now that we understand the business logic of the shopping cart application, let&rsquo;s take a closer look at what keeps the state
of the functions and messages sent between them consistent and fault-tolerant: the StateFun cluster.</p>
<figure style="float:right;padding-left:1px;padding-top: 0px">
<img src="/img/blog/2020-10-13-stateful-serverless-internals/abstract-deployment.png" width="400px">
<figcaption style="padding-top: 10px;text-align:center"><i><b>Fig.2:</b> Simplified view of a StateFun app deployment.</i></figcaption>
</figure>
<p>The StateFun runtime is built on-top of Apache Flink, and applies the same battle-tested technique that Flink uses as the
basis for strongly consistent stateful streaming applications - <i><b>co-location of state and messaging</b></i>.
In a StateFun application, all messages are routed through the StateFun cluster, including messages sent from ingresses,
messages sent between functions, and messages sent from functions to egresses. Moreover, the state of all functions is
maintained in the StateFun cluster as well. Like Flink, the message streams flowing through the StateFun cluster and
function state are co-partitioned so that compute has local state access, and any updates to the state can be handled
atomically with computed side-effects, i.e. messages to send to other functions.</p>
<p>In more solid terms, take for example a message that is targeted for the logical address <code>(cart, &quot;Kim&quot;)</code> being routed
through StateFun. Logical addresses are used in StateFun as the partitioning key for both message streams and state, so
that the resulting StateFun cluster partition that this message ends up in will have the state for <code>(cart, &quot;Kim&quot;)</code>
locally available.</p>
<p>The only difference here for StateFun, compared to Flink, is that the actual compute doesn&rsquo;t happen within the StateFun
cluster partitions - <i><b>computation happens remotely in the function services</b></i>. So how does StateFun
route input messages to the remote function services and provide them with state access, all the while
preserving the same consistency guarantees as if state and compute were co-located?</p>
<h3 id="remote-invocation-request-reply-protocol">
Remote Invocation Request-Reply Protocol
<a class="anchor" href="#remote-invocation-request-reply-protocol">#</a>
</h3>
<p>A StateFun cluster partition communicates with the functions using a slim and well-defined request-reply protocol, as
illustrated in <strong>Fig. 3</strong>. Upon receiving an input message, the cluster partition invokes the target functions via their
HTTP service endpoint. The service request body carries input events and current state for the functions, retrieved from
local state. Any outgoing messages and state mutations as a result of invocations are sent back through StateFun as part
of the service response. When the StateFun cluster partition receives the response, all state mutations are written back
to local state and outgoing messages are routed to other cluster partitions, which in turn invokes other function
services.</p>
<center>
<figure>
<img src="/img/blog/2020-10-13-stateful-serverless-internals/request-reply-protocol.png" width="750px"/>
<figcaption><i><b>Fig.3:</b> The remote invocation request/reply protocol.</i></figcaption>
</figure>
</center>
<br>
<p>Under the hood, StateFun SDKs like the Python SDK and other <a href="//nightlies.apache.org/flink/flink-statefun-docs-master/sdk/external.html">3rd party SDKs for other languages</a>
all implement this protocol. From the user&rsquo;s perspective, they are programming with state local to their function deployment,
whereas in reality, state is maintained in StateFun and supplied through this protocol. It is easy to add more language SDKs,
as long as the language can handle HTTP requests and responses.</p>
<h3 id="function-state-consistency-and-fault-tolerance">
Function state consistency and fault-tolerance
<a class="anchor" href="#function-state-consistency-and-fault-tolerance">#</a>
</h3>
<p>The runtime makes sure that only one invocation per function instance (e.g. <code>(cart, &quot;Kim&quot;)</code>) is ongoing at any point in
time (i.e. invocations per entity are serial). If an invocation is ongoing while new messages for the same function
instance arrives, the messages are buffered in state and sent as a single batch as soon as the ongoing invocation completes.</p>
<p>In addition, since each request happens in complete isolation and all relevant information is encapsulated in each
request and response, <i><b>function invocations are effectively idempotent</b></i>
(i.e. results depend purely on the provided context of the invocation) and can be retried. This naturally avoids
violating consistency in case any function service hiccups occur.</p>
<p>For fault tolerance, all function state managed in the StateFun cluster is periodically and asynchronously checkpointed
to a blob storage (e.g. HDFS, S3, GCS) using Flink’s <a href="//nightlies.apache.org/flink/flink-docs-master/concepts/stateful-stream-processing.html#checkpointing">original distributed snapshot mechanism</a>.
These checkpoints contain <i><b>a globally consistent view of state across all functions of the application</b></i>,
including the offset positions in ingresses and the ongoing transaction state in egresses. In the case of an abrupt failure,
the system may restore from the latest available checkpoint: all function states will be restored and all events between
the checkpoint and the crash will be re-processed (and the functions re-invoked) with identical routing, all as if the failure
never happened.</p>
<h3 id="step-by-step-walkthrough-of-function-invocations">
Step-by-step walkthrough of function invocations
<a class="anchor" href="#step-by-step-walkthrough-of-function-invocations">#</a>
</h3>
<p>Let&rsquo;s conclude this section by going through the actual messages that flow between StateFun and the functions in our shopping
cart demo application!</p>
<p><strong>Customer &ldquo;Kim&rdquo; puts 2 socks into his shopping cart (Fig. 4):</strong></p>
<center>
<figure>
<img src="/img/blog/2020-10-13-stateful-serverless-internals/protocol-walkthrough-1.png" width="750px"/>
<figcaption><i><b>Fig.4:</b> Message flow walkthrough.</i></figcaption>
</figure>
</center>
<br>
<ul>
<li>
<p>An event <code>AddToCart(&quot;Kim&quot;, &quot;socks&quot;, 2)</code> comes through one of the ingress partitions <b><code>(1)</code></b>. The ingress event router is
configured to route <code>AddToCart</code> events to the function type <code>cart</code>, taking the user ID (<code>&quot;Kim&quot;</code>) as the instance ID. The
function type and instance ID together define the logical address of the target function instance for the event <code>(cart:Kim)</code>.</p>
</li>
<li>
<p>Let&rsquo;s assume the event is read by StateFun partition B, but the <code>(cart:Kim)</code> address is owned by partition A.
The event is thus routed to partition A <b><code>(2)</code></b>.</p>
</li>
<li>
<p>StateFun Partition A receives the event and processes it:</p>
<ul>
<li>First, the runtime fetches the state for <code>(cart:Kim)</code> from the local state store, i.e. the existing items in Kim’s cart <b><code>(3)</code></b>.</li>
<li>Next, it marks <code>(cart:Kim)</code> as <i>&ldquo;busy&rdquo;</i>, meaning an invocation is happening. This buffers other messages targeted for
<code>(cart:Kim)</code> in state until this invocation is completed.</li>
<li>The runtime grabs a free HTTP client connection and sends a request to the <code>cart</code> function type&rsquo;s service endpoint.
The request contains the <code>AddToCart(&quot;Kim&quot;, &quot;socks&quot;, 2)</code> message and the current state for <code>(cart:Kim)</code> <b><code>(4)</code></b>.</li>
<li>The remote <code>cart</code> function service receives the event and attempts to reserve socks with the <code>inventory</code> function.
Therefore, it replies to the invocation with a new message <code>RequestItem(&quot;socks&quot;, 2)</code> targeted at the address <code>(inventory:socks)</code>.
Any state modifications will be included in the response as well, but in this case there aren’t any state modifications yet
(i.e. Kim’s cart is still empty until a reservation acknowledgement is received from the inventory service) <b><code>(5)</code></b>.</li>
<li>The StateFun runtime receives the response, routes the <code>RequestItem</code> message to other partitions,
and marks <code>(cart:Kim)</code> as <i>&ldquo;available&rdquo;</i> again for invocation.</li>
</ul>
</li>
<li>
<p>Assuming that the <code>(inventory:socks)</code> address is owned by partition B, the message is routed to partition B <b><code>(6)</code></b>.</p>
</li>
<li>
<p>Once partition B receives the <code>RequestItem</code> message, the runtime invokes the function <code>(inventory:socks)</code> in the same
way as described above, and receives a reply with a modification of the state of the inventory (the number of reserved socks is now increased by 2).
<code>(inventory:socks)</code> now also wants to reply reservation of 2 socks for Kim, so an <code>ItemReserved(&quot;socks&quot;, 2)</code>
message targeted for <code>(cart:Kim)</code> is also included in the response <b><code>(7)</code></b>, which will again be routed by the StateFun runtime.</p>
</li>
</ul>
<h2 id="stateful-serverless-in-the-cloud-with-faas-and-statefun">
Stateful Serverless in the Cloud with FaaS and StateFun
<a class="anchor" href="#stateful-serverless-in-the-cloud-with-faas-and-statefun">#</a>
</h2>
<p>We&rsquo;d like to wrap up this blog by re-emphasizing how the StateFun runtime works well with cloud-native
architectures, and provide an overview of what your complete StateFun application deployment would look like
using public cloud services.</p>
<p>As you&rsquo;ve already learnt in previous sections, invocation requests themselves are stateless, with all necessary information
for an invocation included in the HTTP request (i.e. input events and state access), and all side-effects of the invocation
included in the HTTP response (i.e. outgoing messages and state modifications).</p>
<figure style="float:right;padding-left:1px;padding-top: 0px">
<img src="/img/blog/2020-10-13-stateful-serverless-internals/aws-deployment.png" width="450px">
<figcaption style="padding-top: 10px;text-align:center"><i><b>Fig.5:</b> Complete deployment example on AWS.</i></figcaption>
</figure>
<p>A natural consequence of this characteristic is that there is no session-related dependency between individual HTTP
requests, making it very easy to horizontally scale the function deployments. This makes it very easy to deploy your
stateful functions using FaaS platforms solutions, allowing them to rapidly scale out, scale to zero, or be upgraded
with zero-downtime.</p>
<p>In our complementary demo code, you can find <a href="https://github.com/tzulitai/statefun-aws-demo/blob/master/app/shopping_cart.py#L49">here</a>
the exact code on how to expose and service StateFun functions through AWS Lambda. Likewise, this is possible for any other
FaaS platform that supports triggering the functions using HTTP endpoints (and other transports as well in the future).</p>
<p><strong>Fig. 5</strong> on the right illustrates what a complete AWS deployment of a StateFun application would look like, with functions
serviced via AWS Lambda, AWS Kinesis streams as ingresses and egresses, AWS EKS managed Kubernetes cluster to run the
StateFun cluster, and an AWS S3 bucket to store the periodic checkpoints. You can also follow the
<a href="https://github.com/tzulitai/statefun-aws-demo#running-the-demo">instructions</a> in the demo code to try it out and deploy this yourself right away!</p>
<hr>
<p>If you’d like to learn more about Stateful Functions, head over to the <a href="//nightlies.apache.org/flink/flink-statefun-docs-master/">official documentation</a>, where you can also find more hands-on tutorials to try out yourself!</p>
</p>
</article>
<div class="edit-this-page">
<p>
<a href="https://cwiki.apache.org/confluence/display/FLINK/Flink+Translation+Specifications">Want to contribute translation?</a>
</p>
<p>
<a href="//github.com/apache/flink-web/edit/asf-site/docs/content/posts/2020-10-13-stateful-serverless-internals.md">
Edit This Page<i class="fa fa-edit fa-fw"></i>
</a>
</p>
</div>
</section>
<aside class="book-toc">
<nav id="TableOfContents"><h3>On This Page <a href="javascript:void(0)" class="toc" onclick="collapseToc()"><i class="fa fa-times" aria-hidden="true"></i></a></h3>
<ul>
<li>
<ul>
<li><a href="#introducing-the-example-shopping-cart">Introducing the example: Shopping Cart</a></li>
<li><a href="#what-happens-in-the-stateful-functions-runtime">What happens in the Stateful Functions runtime?</a>
<ul>
<li><a href="#remote-invocation-request-reply-protocol">Remote Invocation Request-Reply Protocol</a></li>
<li><a href="#function-state-consistency-and-fault-tolerance">Function state consistency and fault-tolerance</a></li>
<li><a href="#step-by-step-walkthrough-of-function-invocations">Step-by-step walkthrough of function invocations</a></li>
</ul>
</li>
<li><a href="#stateful-serverless-in-the-cloud-with-faas-and-statefun">Stateful Serverless in the Cloud with FaaS and StateFun</a></li>
</ul>
</li>
</ul>
</nav>
</aside>
<aside class="expand-toc hidden">
<a class="toc" onclick="expandToc()" href="javascript:void(0)">
<i class="fa fa-bars" aria-hidden="true"></i>
</a>
</aside>
</main>
<footer>
<div class="separator"></div>
<div class="panels">
<div class="wrapper">
<div class="panel">
<ul>
<li>
<a href="https://flink-packages.org/">flink-packages.org</a>
</li>
<li>
<a href="https://www.apache.org/">Apache Software Foundation</a>
</li>
<li>
<a href="https://www.apache.org/licenses/">License</a>
</li>
<li>
<a href="/zh/">
<i class="fa fa-globe" aria-hidden="true"></i>&nbsp;中文版
</a>
</li>
</ul>
</div>
<div class="panel">
<ul>
<li>
<a href="/what-is-flink/security">Security</a-->
</li>
<li>
<a href="https://www.apache.org/foundation/sponsorship.html">Donate</a>
</li>
<li>
<a href="https://www.apache.org/foundation/thanks.html">Thanks</a>
</li>
</ul>
</div>
<div class="panel icons">
<div>
<a href="/posts">
<div class="icon flink-blog-icon"></div>
<span>Flink blog</span>
</a>
</div>
<div>
<a href="https://github.com/apache/flink">
<div class="icon flink-github-icon"></div>
<span>Github</span>
</a>
</div>
<div>
<a href="https://twitter.com/apacheflink">
<div class="icon flink-twitter-icon"></div>
<span>Twitter</span>
</a>
</div>
</div>
</div>
</div>
<hr/>
<div class="container disclaimer">
<p>The contents of this website are © 2024 Apache Software Foundation under the terms of the Apache License v2. Apache Flink, Flink, and the Flink logo are either registered trademarks or trademarks of The Apache Software Foundation in the United States and other countries.</p>
</div>
</footer>
</body>
</html>