blob: 23879951ab4f09628d66cfa71a7e9b12b71b7139 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Apache Flink: Apache Flink Roadmap</title>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/flink.css">
<link rel="stylesheet" href="/css/syntax.css">
<!-- Blog RSS feed -->
<link href="/blog/feed.xml" rel="alternate" type="application/rss+xml" title="Apache Flink Blog: RSS feed" />
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<!-- We need to load Jquery in the header for custom google analytics event tracking-->
<script src="/js/jquery.min.js"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Main content. -->
<div class="container">
<div class="row">
<div id="sidebar" class="col-sm-3">
<!-- Top navbar. -->
<nav class="navbar navbar-default">
<!-- The logo. -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="navbar-logo">
<a href="/">
<img alt="Apache Flink" src="/img/flink-header-logo.svg" width="147px" height="73px">
</a>
</div>
</div><!-- /.navbar-header -->
<!-- The navigation links. -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-main">
<!-- First menu section explains visitors what Flink is -->
<!-- What is Stream Processing? -->
<!--
<li><a href="/streamprocessing1.html">What is Stream Processing?</a></li>
-->
<!-- What is Flink? -->
<li><a href="/flink-architecture.html">What is Apache Flink?</a></li>
<!-- What is Stateful Functions? -->
<li><a href="/stateful-functions.html">What is Stateful Functions?</a></li>
<!-- Use cases -->
<li><a href="/usecases.html">Use Cases</a></li>
<!-- Powered by -->
<li><a href="/poweredby.html">Powered By</a></li>
&nbsp;
<!-- Second menu section aims to support Flink users -->
<!-- Downloads -->
<li><a href="/downloads.html">Downloads</a></li>
<!-- Getting Started -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Getting Started<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11/getting-started/index.html" target="_blank">With Flink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1/getting-started/project-setup.html" target="_blank">With Flink Stateful Functions <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="/training.html">Training Course</a></li>
</ul>
</li>
<!-- Documentation -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Documentation<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="https://ci.apache.org/projects/flink/flink-docs-release-1.11" target="_blank">Flink 1.11 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-docs-master" target="_blank">Flink Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-release-2.1" target="_blank">Flink Stateful Functions 2.1 (Latest stable release) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li><a href="https://ci.apache.org/projects/flink/flink-statefun-docs-master" target="_blank">Flink Stateful Functions Master (Latest Snapshot) <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
</ul>
</li>
<!-- getting help -->
<li><a href="/gettinghelp.html">Getting Help</a></li>
<!-- Blog -->
<li><a href="/blog/"><b>Flink Blog</b></a></li>
<!-- Flink-packages -->
<li>
<a href="https://flink-packages.org" target="_blank">flink-packages.org <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Third menu section aim to support community and contributors -->
<!-- Community -->
<li><a href="/community.html">Community &amp; Project Info</a></li>
<!-- Roadmap -->
<li class="active"><a href="/roadmap.html">Roadmap</a></li>
<!-- Contribute -->
<li><a href="/contributing/how-to-contribute.html">How to Contribute</a></li>
<!-- GitHub -->
<li>
<a href="https://github.com/apache/flink" target="_blank">Flink on GitHub <small><span class="glyphicon glyphicon-new-window"></span></small></a>
</li>
&nbsp;
<!-- Language Switcher -->
<li>
<a href="/zh/roadmap.html">中文版</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-bottom">
<hr />
<!-- Twitter -->
<li><a href="https://twitter.com/apacheflink" target="_blank">@ApacheFlink <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<!-- Visualizer -->
<li class=" hidden-md hidden-sm"><a href="/visualizer/" target="_blank">Plan Visualizer <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<hr />
<li><a href="https://apache.org" target="_blank">Apache Software Foundation <small><span class="glyphicon glyphicon-new-window"></span></small></a></li>
<li>
<style>
.smalllinks:link {
display: inline-block !important; background: none; padding-top: 0px; padding-bottom: 0px; padding-right: 0px; min-width: 75px;
}
</style>
<a class="smalllinks" href="https://www.apache.org/licenses/" target="_blank">License</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/security/" target="_blank">Security</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/sponsorship.html" target="_blank">Donate</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
<a class="smalllinks" href="https://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a> <small><span class="glyphicon glyphicon-new-window"></span></small>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
</div>
<div class="col-sm-9">
<div class="row-fluid">
<div class="col-sm-12">
<h1>Apache Flink Roadmap</h1>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<hr />
<div class="page-toc">
<ul id="markdown-toc">
<li><a href="#analytics-applications-and-the-roles-of-datastream-dataset-and-table-api" id="markdown-toc-analytics-applications-and-the-roles-of-datastream-dataset-and-table-api">Analytics, Applications, and the roles of DataStream, DataSet, and Table API</a></li>
<li><a href="#batch-and-streaming-unification" id="markdown-toc-batch-and-streaming-unification">Batch and Streaming Unification</a></li>
<li><a href="#fast-batch-bounded-streams" id="markdown-toc-fast-batch-bounded-streams">Fast Batch (Bounded Streams)</a></li>
<li><a href="#stream-processing-use-cases" id="markdown-toc-stream-processing-use-cases">Stream Processing Use Cases</a></li>
<li><a href="#deployment-scaling-and-security" id="markdown-toc-deployment-scaling-and-security">Deployment, Scaling and Security</a></li>
<li><a href="#resource-management-and-configuration" id="markdown-toc-resource-management-and-configuration">Resource Management and Configuration</a></li>
<li><a href="#ecosystem" id="markdown-toc-ecosystem">Ecosystem</a></li>
<li><a href="#non-jvm-languages-python" id="markdown-toc-non-jvm-languages-python">Non-JVM Languages (Python)</a></li>
<li><a href="#connectors-and-formats" id="markdown-toc-connectors-and-formats">Connectors and Formats</a></li>
<li><a href="#miscellaneous" id="markdown-toc-miscellaneous">Miscellaneous</a></li>
</ul>
</div>
<p><strong>Preamble:</strong> This is not an authoritative roadmap in the sense of a strict plan with a specific
timeline. Rather, we — the community — share our vision for the future and give an overview of the bigger
initiatives that are going on and are receiving attention. This roadmap shall give users and
contributors an understanding where the project is going and what they can expect to come.</p>
<p>The roadmap is continuously updated. New features and efforts should be added to the roadmap once
there is consensus that they will happen and what they will roughly look like for the user.</p>
<p><strong>Last Update:</strong> 2019-09-04</p>
<h1 id="analytics-applications-and-the-roles-of-datastream-dataset-and-table-api">Analytics, Applications, and the roles of DataStream, DataSet, and Table API</h1>
<p>Flink views stream processing as a <a href="/flink-architecture.html">unifying paradigm for data processing</a>
(batch and real-time) and event-driven applications. The APIs are evolving to reflect that view:</p>
<ul>
<li>
<p>The <strong>Table API / SQL</strong> is becoming the primary API for analytical use cases, in a unified way
across batch and streaming. To support analytical use cases in a more streamlined fashion,
the API is being extended with more convenient multi-row/column operations (<a href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=97552739">FLIP-29</a>).</p>
<ul>
<li>
<p>Like SQL, the Table API is <em>declarative</em>, operates on a <em>logical schema</em>, and applies <em>automatic optimization</em>.
Because of these properties, that API does not give direct access to time and state.</p>
</li>
<li>
<p>The Table API is also the foundation for the Machine Learning (ML) efforts inititated in (<a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-39+Flink+ML+pipeline+and+ML+libs">FLIP-39</a>), that will allow users to easily build, persist and serve (<a href="https://issues.apache.org/jira/browse/FLINK-13167">FLINK-13167</a>) ML pipelines/workflows through a set of abstract core interfaces.</p>
</li>
</ul>
</li>
<li>
<p>The <strong>DataStream API</strong> is the primary API for data-driven applications and data pipelines.
It uses <em>physical data types</em> (Java/Scala classes) and there is no automatic rewriting.
The applications have explicit control over <em>time</em> and <em>state</em> (state, triggers, proc fun.).
In the long run, the DataStream API will fully subsume the DataSet API through <em>bounded streams</em>.</p>
</li>
</ul>
<h1 id="batch-and-streaming-unification">Batch and Streaming Unification</h1>
<p>Flink’s approach is to cover batch and streaming by the same APIs on a streaming runtime.
<a href="/news/2019/02/13/unified-batch-streaming-blink.html">This blog post</a>
gives an introduction to the unification effort.</p>
<p>The biggest user-facing parts currently ongoing are:</p>
<ul>
<li>
<p>Table API restructuring (<a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-32%3A+Restructure+flink-table+for+future+contributions">FLIP-32</a>)
that decouples the Table API from batch/streaming specific environments and dependencies. Some key parts of the FLIP are completed, such as the modular decoupling of expression parsing and the removal of Scala dependencies, and the next step is to unify the function stack (<a href="https://issues.apache.org/jira/browse/FLINK-12710">FLINK-12710</a>).</p>
</li>
<li>
<p>The new source interfaces generalize across batch and streaming, making every connector usable as a batch and streaming data source (<a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-27%3A+Refactor+Source+Interface">FLIP-27</a>).</p>
</li>
<li>
<p>The introduction of <em>upsert-</em> or <em>changelog-</em> sources will support more powerful streaming inputs to the Table API (<a href="https://issues.apache.org/jira/browse/FLINK-8545">FLINK-8545</a>).</p>
</li>
</ul>
<p>On the runtime level, the streaming operators were extended in Flink 1.9 to also support the data consumption patterns required for some batch operations — which is groundwork for upcoming features like efficient <a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-17+Side+Inputs+for+DataStream+API">side inputs</a>.</p>
<p>Once these unification efforts are completed, we can move on to unifying the DataStream API.</p>
<h1 id="fast-batch-bounded-streams">Fast Batch (Bounded Streams)</h1>
<p>The community’s goal is to make Flink’s performance on bounded streams (batch use cases) competitive with that
of dedicated batch processors. While Flink has been shown to handle some batch processing use cases faster than
widely-used batch processors, there are some ongoing efforts to make sure this the case for broader use cases:</p>
<ul>
<li>
<p>Faster and more complete SQL/Table API: The community is merging the Blink query processor which improves on
the current query processor by adding a much richer set of runtime operators, optimizer rules, and code generation.
The Blink-based query processor has full TPC-H support (with TPC-DS planned for the next release) and up to 10x performance improvement over the pre-1.9 Flink query processor (<a href="https://issues.apache.org/jira/browse/FLINK-11439">FLINK-11439</a>).</p>
</li>
<li>
<p>An application on bounded data can schedule operations after another, depending on how the operators
consume data (e.g., first build hash table, then probe hash table).
We are separating the scheduling strategy from the ExecutionGraph to support different strategies
on bounded data (<a href="https://issues.apache.org/jira/browse/FLINK-10429">FLINK-10429</a>).</p>
</li>
<li>
<p>Caching of intermediate results on bounded data, to support use cases like interactive data exploration.
The caching generally helps with applications where the client submits a series of jobs that build on
top of one another and reuse each others’ results (<a href="https://issues.apache.org/jira/browse/FLINK-11199">FLINK-11199</a>).</p>
</li>
</ul>
<p>Various of these enhancements can be integrated from the contributed code in the <a href="https://github.com/apache/flink/tree/blink">Blink fork</a>. To exploit these optimizations for bounded streams also in the DataStream API, we first need to break parts of the API and explicitly model bounded streams.</p>
<h1 id="stream-processing-use-cases">Stream Processing Use Cases</h1>
<p>The <em>new source interface</em> effort (<a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-27%3A+Refactor+Source+Interface">FLIP-27</a>)
aims to give simpler out-of-the box support for event time and watermark generation for sources.
Sources will have the option to align their consumption speed in event time, to reduce the
size of in-flight state when re-processing large data volumes in streaming
(<a href="https://issues.apache.org/jira/browse/FLINK-10886">FLINK-10887</a>).</p>
<p>To overcome the current pitfalls of checkpoint performance under backpressure scenarios, the community is introducing the concept of <a href="https://lists.apache.org/thread.html/fd5b6cceb4bffb635e26e7ec0787a8db454ddd64aadb40a0d08a90a8@%3Cdev.flink.apache.org%3E">unaligned checkpoints</a>. This will allow checkpoint barriers to overtake the output/input buffer queue to speed up alignment and snapshot the inflight data as part of checkpoint state.</p>
<p>We also plan to add first class support for
<a href="https://developers.google.com/protocol-buffers/">Protocol Buffers</a> to make evolution of streaming state simpler, similar to the way
Flink deeply supports Avro state evolution (<a href="https://issues.apache.org/jira/browse/FLINK-11333">FLINK-11333</a>).</p>
<h1 id="deployment-scaling-and-security">Deployment, Scaling and Security</h1>
<p>To provide downstream projects with a consistent way to programatically control Flink deployment submissions, the Client API is being <a href="https://lists.apache.org/thread.html/ce99cba4a10b9dc40eb729d39910f315ae41d80ec74f09a356c73938@%3Cdev.flink.apache.org%3E">refactored</a>. The goal is to unify the implementation of cluster deployment and job submission in Flink and allow more flexible job and cluster management — independent of cluster setup or deployment mode. <a href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=125308637">FLIP-52</a> proposes the deprecation and removal of the legacy Program interface.</p>
<p>The community is working on extending the interoperability with authentication and authorization services.
Under discussion are general extensions to the <a href="http://apache-flink-mailing-list-archive.1008284.n3.nabble.com/DISCUSS-Flink-security-improvements-td21068.html">security module abstraction</a>
as well as specific <a href="http://apache-flink-mailing-list-archive.1008284.n3.nabble.com/DISCUSS-Flink-Kerberos-Improvement-td25983.html">enhancements to the Kerberos support</a>.</p>
<h1 id="resource-management-and-configuration">Resource Management and Configuration</h1>
<p>There is a big effort to design a new way for Flink to interact with dynamic resource
pools and automatically adjust to resource availability and load.
Part of this is becoming a <em>reactive</em> way of adjusting to changing resources (like
containers/pods being started or removed) (<a href="https://issues.apache.org/jira/browse/FLINK-10407">FLINK-10407</a>),
while other parts are resulting in <em>active</em> scaling policies where Flink decides to add
or remove TaskManagers, based on internal metrics.</p>
<ul>
<li>
<p>The current TaskExecutor memory configuration in Flink has some shortcomings that make it hard to reason about or optimize resource utilization, such as: (1) different configuration models for memory footprint for Streaming and Batch; (2) complex and user-dependent configuration of off-heap state backends (typically RocksDB) in Streaming execution; (3) and sub-optimal memory utilization in Batch execution. <a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-49%3A+Unified+Memory+Configuration+for+TaskExecutors">FLIP-49</a> proposes to unify managed memory configuration for TaskExecutors to make this process more generic and intuitive for the user.</p>
</li>
<li>
<p>In a similar way, we are introducing changes to Flink’s resource management module with <a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-53%3A+Fine+Grained+Operator+Resource+Management">FLIP-53</a> to enable fine-grained control over Operator resource utilization according to known (or unknown) resource profiles. Since the requirements of this FLIP conflict with the existing static slot allocation model, this model first needs to be refactored to provide dynamic slot allocation (<a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-56%3A+Dynamic+Slot+Allocation">FLIP-56</a>).</p>
</li>
<li>
<p>To support the active resource management also in Kubernetes, we are working on a Kubernetes Resource Manager
(<a href="https://issues.apache.org/jira/browse/FLINK-9953">FLINK-9953</a>).</p>
</li>
</ul>
<p>Spillable Heap State Backend (<a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-50%3A+Spill-able+Heap+Keyed+State+Backend">FLIP-50</a>), a new state backend configuration, is being implemented to support spilling cold state data to disk before heap memory is exhausted and so reduce the chance of OOM errors in job execution. This is not meant as a replacement for RocksDB, but more of an enhancement to the existing Heap State Backend.</p>
<h1 id="ecosystem">Ecosystem</h1>
<p>The community is working on extending the support for catalogs, schema registries, and metadata stores, including support in the APIs and the SQL client (<a href="https://issues.apache.org/jira/browse/FLINK-11275">FLINK-11275</a>).
We have added DDL (Data Definition Language) support in Flink 1.9 to make it easy to add tables to catalogs (<a href="https://issues.apache.org/jira/browse/FLINK-10232">FLINK-10232</a>), and will extend the support to streaming use cases in the next release.</p>
<p>There is also an ongoing effort to fully integrate Flink with the Hive ecosystem. The latest release made headway in bringing Hive data and metadata interoperability to Flink, along with initial support for Hive UDFs. Moving forward, the community will stabilize and expand on the existing implementation to support Hive DDL syntax and types, as well as other desirable features and capabilities described in <a href="https://issues.apache.org/jira/browse/FLINK-10556">FLINK-10556</a>.</p>
<h1 id="non-jvm-languages-python">Non-JVM Languages (Python)</h1>
<p>The work initiated in Flink 1.9 to bring full Python support to the Table API (<a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-38%3A+Python+Table+API">FLIP-38</a>) will continue in the upcoming releases, also in close collaboration with the Apache Beam community. The next steps include:</p>
<ul>
<li>
<p>Adding support for Python UDFs (Scalar Functions (UDF), Tabular Functions (UDTF) and Aggregate Functions (UDAF)). The details of this implementation are defined in <a href="https://cwiki.apache.org/confluence/display/FLINK/FLIP-58%3A+Flink+Python+User-Defined+Function+for+Table+API">FLIP-58</a> and leverage the <a href="https://docs.google.com/document/d/1B9NmaBSKCnMJQp-ibkxvZ_U233Su67c1eYgBhrqWP24/edit#heading=h.khjybycus70">Apache Beam portability framework</a> as a basis for UDF execution.</p>
</li>
<li>
<p>Integrating Pandas as the final effort — that is, making functions in Pandas directly usable in the Python Table API.</p>
</li>
</ul>
<h1 id="connectors-and-formats">Connectors and Formats</h1>
<p>Support for additional connectors and formats is a continuous process.</p>
<h1 id="miscellaneous">Miscellaneous</h1>
<ul>
<li>
<p>The Flink code base has been updated to support Java 9 (<a href="https://issues.apache.org/jira/browse/FLINK-8033">FLINK-8033</a>) and Java 11 support is underway (<a href="https://issues.apache.org/jira/browse/FLINK-10725">FLINK-10725</a>).</p>
</li>
<li>
<p>To reduce compatibility issues with different Scala versions, we are working using Scala
only in the Scala APIs, but not in the runtime. That removes any Scala dependency for all
Java-only users, and makes it easier for Flink to support different Scala versions (<a href="https://issues.apache.org/jira/browse/FLINK-11063">FLINK-11063</a>).</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<hr />
<div class="row">
<div class="footer text-center col-sm-12">
<p>Copyright © 2014-2019 <a href="http://apache.org">The Apache Software Foundation</a>. All Rights Reserved.</p>
<p>Apache Flink, Flink®, Apache®, the squirrel logo, and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
<p><a href="/privacy-policy.html">Privacy Policy</a> &middot; <a href="/blog/feed.xml">RSS feed</a></p>
</div>
</div>
</div><!-- /.container -->
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.matchHeight/0.7.0/jquery.matchHeight-min.js"></script>
<script src="/js/codetabs.js"></script>
<script src="/js/stickysidebar.js"></script>
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-52545728-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>