Modified: flink/site/docs/0.6-incubating/iterations.html URL: http://svn.apache.org/viewvc/flink/site/docs/0.6-incubating/iterations.html?rev=1657551&r1=1657550&r2=1657551&view=diff ============================================================================== --- flink/site/docs/0.6-incubating/iterations.html (original) +++ flink/site/docs/0.6-incubating/iterations.html Thu Feb 5 12:21:38 2015 @@ -5,296 +5,327 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Apache Flink (incubating): Iterations</title> - <link rel="stylesheet" href="/css/bootstrap.css"> - <link rel="stylesheet" href="/css/bootstrap-lumen-custom.css"> - <link rel="stylesheet" href="/css/syntax.css"> - <link rel="/css/custom.css"> - <link rel="css/codetabs.css"> - <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> + <link rel="icon" href="favicon.ico" type="image/x-icon"> + <link rel="stylesheet" href="css/bootstrap.css"> + <link rel="stylesheet" href="css/bootstrap-lumen-custom.css"> + <link rel="stylesheet" href="css/syntax.css"> + <link rel="stylesheet" href="css/custom.css"> + <link href="css/main/main.css" rel="stylesheet"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> - <script src="/js/bootstrap.min.js"></script> + <script src="js/bootstrap.min.js"></script> <script src="js/codetabs.js"></script> </head> <body> <nav class="navbar navbar-default navbar-fixed-top" role="navigation"> <div class="container"> - <div class="navbar-header"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> - <span class="sr-only">Toggle navigation</span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="http://flink.incubator.apache.org">Apache Flink</a> - </div> - - <div class="collapse navbar-collapse" id="navbar-collapse-1"> - <ul class="nav navbar-nav"> + <div class="row"> + <div class="col-md-1 af-mobile-nav-bar"> + <a href="index.html" title="Home"> + <img class="hidden-xs hidden-sm img-responsive" + src="img/logo.png" alt="Apache Flink Logo"> + </a> + <div class="row visible-xs"> + <div class="col-xs-3"> + <a href="index.html" title="Home"> + <img class="hidden-x hidden-sm img-responsive" + src="img/logo.png" alt="Apache Flink Logo"> + </a> + </div> + <div class="col-xs-5"></div> + <div class="col-xs-4"> + <div class="af-mobile-btn"> + <span class="glyphicon glyphicon-plus"></span> + </div> + </div> + </div> + </div> + <!-- Navigation --> + <div class="col-md-11"> + <div class="collapse navbar-collapse" id="navbar-collapse-1"> + <ul class="nav navbar-nav"> + + <li> + <a href="index.html" class="">Documentation</a> + </li> + + <li> + <a href="api/java/index.html">Javadoc</a> + </li> + + <li> + <a href="api/scala/index.html#org.apache.flink.api.scala.package">Scaladoc</a> + </li> - <li> - <a href="index.html" class="">Documentation</a> - </li> - - <li> - <a href="api/java/index.html">Javadoc</a> - </li> - </ul> + </ul> + </div> + </div> </div> </div> </nav> - <div style="padding-top:70px" class="container"> + + <div style="padding-top:120px" class="container"> <div class="row"> <div class="col-md-3"> <ul> - <li>Quickstart - <ul> - <li><a href="setup_quickstart.html">Install</a></li> - <li><a href="run_example_quickstart.html">Run Example</a></li> - <li><a href="java_api_quickstart.html">Java API</a></li> - <li><a href="scala_api_quickstart.html">Scala API</a></li> - <li><a href="faq.html">FAQ</a></li> - </ul> - </li> - - <li>Setup & Configuration - <ul> - <li><a href="building.html">Build Instructions</a></li> - <li><a href="local_setup.html">Local Setup</a></li> - <li><a href="cluster_setup.html">Cluster Setup</a></li> - <li><a href="yarn_setup.html">YARN Setup</a></li> - <li><a href="config.html">Configuration</a></li> - </ul> - </li> - - <li>Programming Guides - <ul> - <li><a href="java_api_guide.html">Java API</a></li> - <li><a href="java_api_transformations.html">Java API Transformations</a></li> - <li><a href="scala_api_guide.html">Scala API</a></li> - <li><a href="iterations.html">Iterations</a></li> - <li><a href="spargel_guide.html">Spargel Graph API</a></li> - </ul> - </li> - - <li>Examples - <ul> - <li><a href="java_api_examples.html">Java API</a></li> - <li><a href="scala_api_examples.html">Scala API</a></li> - <li><a href="example_connectors.html">Connecting to other systems</a></li> - </ul> - </li> - - <li>Execution - <ul> - <li><a href="local_execution.html">Local/Debugging</a></li> - <li><a href="cluster_execution.html">Cluster</a></li> - <li><a href="cli.html">Command-Line Interface</a></li> - <li><a href="web_client.html">Web Interface</a></li> - </ul> - </li> - - <li>Internals - <ul> - <li><a href="internal_overview.html">Overview</a></li> - <li><a href="internal_general_arch.html">General Architecture</a></li> - <li><a href="internal_add_operator.html">How-to: Adding a new Operator</a></li> - </ul> - </li> + <li><a href="faq.html">FAQ</a></li> + <li>Quickstart + <ul> + <li><a href="setup_quickstart.html">Setup</a></li> + <li><a href="run_example_quickstart.html">Run Example</a></li> + <li><a href="java_api_quickstart.html">Java API</a></li> + <li><a href="scala_api_quickstart.html">Scala API</a></li> + </ul> + </li> + + <li>Setup & Configuration + <ul> + <li><a href="local_setup.html">Local Setup</a></li> + <li><a href="building.html">Build Flink</a></li> + <li><a href="cluster_setup.html">Cluster Setup</a></li> + <li><a href="yarn_setup.html">YARN Setup</a></li> + <li><a href="config.html">Configuration</a></li> + </ul> + </li> + + <li>Programming Guides + <ul> + <li><a href="programming_guide.html">Programming Guide</a></li> + <li><a href="dataset_transformations.html">DataSet Transformations</a></li> + <li><a href="java8_programming_guide.html">Java 8 Programming Guide</a></li> + <li><a href="streaming_guide.html">Streaming Guide</a></li> + <li><a href="iterations.html">Iterations</a></li> + <li><a href="spargel_guide.html">Spargel Graph API</a></li> + <li><a href="hadoop_compatibility.html">Hadoop Compatibility</a></li> + </ul> + </li> + + <li>Examples + <ul> + <li><a href="examples.html">Bundled Examples</a></li> + <li><a href="example_connectors.html">Connecting to other systems</a></li> + </ul> + </li> + + <li>Execution + <ul> + <li><a href="local_execution.html">Local/Debugging</a></li> + <li><a href="cluster_execution.html">Cluster</a></li> + <li><a href="cli.html">Command-Line Interface</a></li> + <li><a href="web_client.html">Web Interface</a></li> + </ul> + </li> + + <li>Internals + <ul> + <li><a href="internal_overview.html">Overview</a></li> + </ul> + </li> </ul> + </div> <div class="col-md-9"> <h1>Iterations</h1> + + <ul id="markdown-toc"> + <li><a href="#iterate-operator">Iterate Operator</a> <ul> + <li><a href="#example-incrementing-numbers">Example: Incrementing Numbers</a></li> + </ul> + </li> + <li><a href="#delta-iterate-operator">Delta Iterate Operator</a> <ul> + <li><a href="#example-propagate-minimum-in-graph">Example: Propagate Minimum in Graph</a></li> + </ul> + </li> + <li><a href="#superstep-synchronization">Superstep Synchronization</a></li> +</ul> - <p>Iterative algorithms occur in many domains of data analysis, such as <em>machine learning</em> or <em>graph analysis</em>. Such algorithms are crucial in order to realize the promise of Big Data to extract meaningful information out of your data. With increasing interest to run these kinds of algorithms on very large data sets, there is a need to execute iterations in a massively parallel fashion.</p> +<p>Iterative algorithms occur in many domains of data analysis, such as <em>machine learning</em> or <em>graph analysis</em>. Such algorithms are crucial in order to realize the promise of Big Data to extract meaningful information out of your data. With increasing interest to run these kinds of algorithms on very large data sets, there is a need to execute iterations in a massively parallel fashion.</p> <p>Flink programs implement iterative algorithms by defining a <strong>step function</strong> and embedding it into a special iteration operator. There are two variants of this operator: <strong>Iterate</strong> and <strong>Delta Iterate</strong>. Both operators repeatedly invoke the step function on the current iteration state until a certain termination condition is reached.</p> -<p>Here, we provide background on both operator variants and outline their usage. The <a href="java_api_guide.html">programming guides</a> explain how to implement the operators in both <a href="scala_api_guide.html">Scala</a> and <a href="java_api_guide.html#iterations">Java</a>. We also provide a <strong>vertex-centric graph processing API</strong> called <a href="spargel_guide.html">Spargel</a>.</p> +<p>Here, we provide background on both operator variants and outline their usage. The <a href="programming_guide.html">programming guide</a> explain how to implement the operators in both Scala and Java. We also provide a <strong>vertex-centric graph processing API</strong> called <a href="spargel_guide.html">Spargel</a>.</p> <p>The following table provides an overview of both operators:</p> <table class="table table-striped table-hover table-bordered"> - <thead> - <th></th> - <th class="text-center">Iterate</th> - <th class="text-center">Delta Iterate</th> - </thead> - <tr> - <td class="text-center" width="20%"><strong>Iteration Input</strong></td> - <td class="text-center" width="40%"><strong>Partial Solution</strong></td> - <td class="text-center" width="40%"><strong>Workset</strong> and <strong>Solution Set</strong></td> - </tr> - <tr> - <td class="text-center"><strong>Step Function</strong></td> - <td colspan="2" class="text-center">Arbitrary Data Flows</td> - </tr> - <tr> - <td class="text-center"><strong>State Update</strong></td> - <td class="text-center">Next <strong>partial solution</strong></td> - <td> - <ul> - <li>Next workset</li> - <li><strong>Changes to solution set</strong></li> - </ul> - </td> - </tr> - <tr> - <td class="text-center"><strong>Iteration Result</strong></td> - <td class="text-center">Last partial solution</td> - <td class="text-center">Solution set state after last iteration</td> - </tr> - <tr> - <td class="text-center"><strong>Termination</strong></td> - <td> - <ul> - <li><strong>Maximum number of iterations</strong> (default)</li> - <li>Custom aggregator convergence</li> - </ul> - </td> - <td> - <ul> - <li><strong>Maximum number of iterations or empty workset</strong> (default)</li> - <li>Custom aggregator convergence</li> - </ul> - </td> - </tr> + <thead> + <th></th> + <th class="text-center">Iterate</th> + <th class="text-center">Delta Iterate</th> + </thead> + <tr> + <td class="text-center" width="20%"><strong>Iteration Input</strong></td> + <td class="text-center" width="40%"><strong>Partial Solution</strong></td> + <td class="text-center" width="40%"><strong>Workset</strong> and <strong>Solution Set</strong></td> + </tr> + <tr> + <td class="text-center"><strong>Step Function</strong></td> + <td colspan="2" class="text-center">Arbitrary Data Flows</td> + </tr> + <tr> + <td class="text-center"><strong>State Update</strong></td> + <td class="text-center">Next <strong>partial solution</strong></td> + <td> + <ul> + <li>Next workset</li> + <li><strong>Changes to solution set</strong></li> + </ul> + </td> + </tr> + <tr> + <td class="text-center"><strong>Iteration Result</strong></td> + <td class="text-center">Last partial solution</td> + <td class="text-center">Solution set state after last iteration</td> + </tr> + <tr> + <td class="text-center"><strong>Termination</strong></td> + <td> + <ul> + <li><strong>Maximum number of iterations</strong> (default)</li> + <li>Custom aggregator convergence</li> + </ul> + </td> + <td> + <ul> + <li><strong>Maximum number of iterations or empty workset</strong> (default)</li> + <li>Custom aggregator convergence</li> + </ul> + </td> + </tr> </table> -<section id="iterate"> -Iterate Operator ----------------- +<h2 id="iterate-operator">Iterate Operator</h2> -The **iterate operator** covers the *simple form of iterations*: in each iteration, the **step function** consumes the **entire input** (the *result of the previous iteration*, or the *initial data set*), and computes the **next version of the partial solution** (e.g. `map`, `reduce`, `join`, etc.). +<p>The <strong>iterate operator</strong> covers the <em>simple form of iterations</em>: in each iteration, the <strong>step function</strong> consumes the <strong>entire input</strong> (the <em>result of the previous iteration</em>, or the <em>initial data set</em>), and computes the <strong>next version of the partial solution</strong> (e.g. <code>map</code>, <code>reduce</code>, <code>join</code>, etc.).</p> <p class="text-center"> <img alt="Iterate Operator" width="60%" src="img/iterations_iterate_operator.png" /> </p> - 1. **Iteration Input**: Initial input for the *first iteration* from a *data source* or *previous operators*. - 2. **Step Function**: The step function will be executed in each iteration. It is an arbitrary data flow consisting of operators like `map`, `reduce`, `join`, etc. and depends on your specific task at hand. - 3. **Next Partial Solution**: In each iteration, the output of the step function will be fed back into the *next iteration*. - 4. **Iteration Result**: Output of the *last iteration* is written to a *data sink* or used as input to the *following operators*. - -There are multiple options to specify **termination conditions** for an iteration: - - - **Maximum number of iterations**: Without any further conditions, the iteration will be executed this many times. - - **Custom aggregator convergence**: Iterations allow to specify *custom aggregators* and *convergence criteria* like sum aggregate the number of emitted records (aggregator) and terminate if this number is zero (convergence criterion). +<ol> + <li><strong>Iteration Input</strong>: Initial input for the <em>first iteration</em> from a <em>data source</em> or <em>previous operators</em>.</li> + <li><strong>Step Function</strong>: The step function will be executed in each iteration. It is an arbitrary data flow consisting of operators like <code>map</code>, <code>reduce</code>, <code>join</code>, etc. and depends on your specific task at hand.</li> + <li><strong>Next Partial Solution</strong>: In each iteration, the output of the step function will be fed back into the <em>next iteration</em>.</li> + <li><strong>Iteration Result</strong>: Output of the <em>last iteration</em> is written to a <em>data sink</em> or used as input to the <em>following operators</em>.</li> +</ol> + +<p>There are multiple options to specify <strong>termination conditions</strong> for an iteration:</p> + +<ul> + <li><strong>Maximum number of iterations</strong>: Without any further conditions, the iteration will be executed this many times.</li> + <li><strong>Custom aggregator convergence</strong>: Iterations allow to specify <em>custom aggregators</em> and <em>convergence criteria</em> like sum aggregate the number of emitted records (aggregator) and terminate if this number is zero (convergence criterion).</li> +</ul> -You can also think about the iterate operator in pseudo-code: +<p>You can also think about the iterate operator in pseudo-code:</p> -```java -IterationState state = getInitialState(); +<div class="highlight"><pre><code class="language-java"><span class="n">IterationState</span> <span class="n">state</span> <span class="o">=</span> <span class="n">getInitialState</span><span class="o">();</span> -while (!terminationCriterion()) { - state = step(state); -} +<span class="k">while</span> <span class="o">(!</span><span class="n">terminationCriterion</span><span class="o">())</span> <span class="o">{</span> + <span class="n">state</span> <span class="o">=</span> <span class="n">step</span><span class="o">(</span><span class="n">state</span><span class="o">);</span> +<span class="o">}</span> -setFinalState(state); -``` +<span class="n">setFinalState</span><span class="o">(</span><span class="n">state</span><span class="o">);</span></code></pre></div> <div class="panel panel-default"> - <div class="panel-body"> - See the <strong><a href="scala_api_guide.html">Scala</a> and <a href="java_api_guide.html#iterations">Java</a> programming guides</strong> for details and code examples.</div> + <div class="panel-body"> + See the <strong><a href="programming_guide.html">Programming Guide</a> </strong> for details and code examples.</div> </div> -### Example: Incrementing Numbers +<h3 id="example-incrementing-numbers">Example: Incrementing Numbers</h3> -In the following example, we **iteratively incremenet a set numbers**: +<p>In the following example, we <strong>iteratively incremenet a set numbers</strong>:</p> <p class="text-center"> <img alt="Iterate Operator Example" width="60%" src="img/iterations_iterate_operator_example.png" /> </p> - 1. **Iteration Input**: The inital input is read from a data source and consists of five single-field records (integers `1` to `5`). - 2. **Step function**: The step function is a single `map` operator, which increments the integer field from `i` to `i+1`. It will be applied to every record of the input. - 3. **Next Partial Solution**: The output of the step function will be the output of the map operator, i.e. records with incremented integers. - 4. **Iteration Result**: After ten iterations, the initial numbers will have been incremented ten times, resulting in integers `11` to `15`. - -``` -// 1st 2nd 10th -map(1) -> 2 map(2) -> 3 ... map(10) -> 11 -map(2) -> 3 map(3) -> 4 ... map(11) -> 12 -map(3) -> 4 map(4) -> 5 ... map(12) -> 13 -map(4) -> 5 map(5) -> 6 ... map(13) -> 14 -map(5) -> 6 map(6) -> 7 ... map(14) -> 15 -``` - -Note that **1**, **2**, and **4** can be arbitrary data flows. -</section> - -<section id="delta_iterate"> -Delta Iterate Operator ----------------------- +<ol> + <li><strong>Iteration Input</strong>: The inital input is read from a data source and consists of five single-field records (integers <code>1</code> to <code>5</code>).</li> + <li><strong>Step function</strong>: The step function is a single <code>map</code> operator, which increments the integer field from <code>i</code> to <code>i+1</code>. It will be applied to every record of the input.</li> + <li><strong>Next Partial Solution</strong>: The output of the step function will be the output of the map operator, i.e. records with incremented integers.</li> + <li><strong>Iteration Result</strong>: After ten iterations, the initial numbers will have been incremented ten times, resulting in integers <code>11</code> to <code>15</code>.</li> +</ol> + +<div class="highlight"><pre><code>// 1st 2nd 10th +map(1) -> 2 map(2) -> 3 ... map(10) -> 11 +map(2) -> 3 map(3) -> 4 ... map(11) -> 12 +map(3) -> 4 map(4) -> 5 ... map(12) -> 13 +map(4) -> 5 map(5) -> 6 ... map(13) -> 14 +map(5) -> 6 map(6) -> 7 ... map(14) -> 15 +</code></pre></div> + +<p>Note that <strong>1</strong>, <strong>2</strong>, and <strong>4</strong> can be arbitrary data flows.</p> + +<h2 id="delta-iterate-operator">Delta Iterate Operator</h2> -The **delta iterate operator** covers the case of **incremental iterations**. Incremental iterations **selectively modify elements** of their **solution solution** and evolve the solution rather than fully recompute it. +<p>The <strong>delta iterate operator</strong> covers the case of <strong>incremental iterations</strong>. Incremental iterations <strong>selectively modify elements</strong> of their <strong>solution solution</strong> and evolve the solution rather than fully recompute it.</p> -Where applicable, this leads to **more efficient algorithms**, because not every element in the solution set changes in each iteration. This allows to **focus on the hot parts** of the solution and leave the **cold parts untouched**. Frequently, the majority of the solution cools down comparatively fast and the later iterations operate only on a small subset of the data. +<p>Where applicable, this leads to <strong>more efficient algorithms</strong>, because not every element in the solution set changes in each iteration. This allows to <strong>focus on the hot parts</strong> of the solution and leave the <strong>cold parts untouched</strong>. Frequently, the majority of the solution cools down comparatively fast and the later iterations operate only on a small subset of the data.</p> <p class="text-center"> <img alt="Delta Iterate Operator" width="60%" src="img/iterations_delta_iterate_operator.png" /> </p> - 1. **Iteration Input**: The initial workset and solution set are read from *data sources* or *previous operators* as input to the first iteration. - 2. **Step Function**: The step function will be executed in each iteration. It is an arbitrary data flow consisting of operators like `map`, `reduce`, `join`, etc. and depends on your specific task at hand. - 3. **Next Workset/Update Solution Set**: The *next workset* drives the iterative computation and will be fed back into the *next iteration*. Furthermore, the solution set will be updated and implicitly forwarded (it is not required to be rebuild). Both data sets can be updated by different operators of the step function. - 4. **Iteration Result**: After the *last iteration*, the *solution set* is written to a *data sink* or used as input to the *following operators*. +<ol> + <li><strong>Iteration Input</strong>: The initial workset and solution set are read from <em>data sources</em> or <em>previous operators</em> as input to the first iteration.</li> + <li><strong>Step Function</strong>: The step function will be executed in each iteration. It is an arbitrary data flow consisting of operators like <code>map</code>, <code>reduce</code>, <code>join</code>, etc. and depends on your specific task at hand.</li> + <li><strong>Next Workset/Update Solution Set</strong>: The <em>next workset</em> drives the iterative computation and will be fed back into the <em>next iteration</em>. Furthermore, the solution set will be updated and implicitly forwarded (it is not required to be rebuild). Both data sets can be updated by different operators of the step function.</li> + <li><strong>Iteration Result</strong>: After the <em>last iteration</em>, the <em>solution set</em> is written to a <em>data sink</em> or used as input to the <em>following operators</em>.</li> +</ol> -The default **termination condition** for delta iterations is specified by the **empty workset convergence criterion** and a **maximum number of iterations**. The iteration will terminate when a produced *next workset* is empty or when the maximum number of iterations is reached. It is also possible to specify a **custom aggregator** and **convergence criterion**. +<p>The default <strong>termination condition</strong> for delta iterations is specified by the <strong>empty workset convergence criterion</strong> and a <strong>maximum number of iterations</strong>. The iteration will terminate when a produced <em>next workset</em> is empty or when the maximum number of iterations is reached. It is also possible to specify a <strong>custom aggregator</strong> and <strong>convergence criterion</strong>.</p> -You can also think about the iterate operator in pseudo-code: +<p>You can also think about the iterate operator in pseudo-code:</p> -```java -IterationState workset = getInitialState(); -IterationState solution = getInitialSolution(); +<div class="highlight"><pre><code class="language-java"><span class="n">IterationState</span> <span class="n">workset</span> <span class="o">=</span> <span class="n">getInitialState</span><span class="o">();</span> +<span class="n">IterationState</span> <span class="n">solution</span> <span class="o">=</span> <span class="n">getInitialSolution</span><span class="o">();</span> -while (!terminationCriterion()) { - (delta, workset) = step(workset, solution); +<span class="k">while</span> <span class="o">(!</span><span class="n">terminationCriterion</span><span class="o">())</span> <span class="o">{</span> + <span class="o">(</span><span class="n">delta</span><span class="o">,</span> <span class="n">workset</span><span class="o">)</span> <span class="o">=</span> <span class="n">step</span><span class="o">(</span><span class="n">workset</span><span class="o">,</span> <span class="n">solution</span><span class="o">);</span> - solution.update(delta) -} + <span class="n">solution</span><span class="o">.</span><span class="na">update</span><span class="o">(</span><span class="n">delta</span><span class="o">)</span> +<span class="o">}</span> -setFinalState(solution); -``` +<span class="n">setFinalState</span><span class="o">(</span><span class="n">solution</span><span class="o">);</span></code></pre></div> <div class="panel panel-default"> - <div class="panel-body"> - See the <strong><a href="scala_api_guide.html">Scala</a> and <a href="java_api_guide.html#iterations">Java</a> programming guides</strong> for details and code examples.</div> + <div class="panel-body"> + See the <strong><a href="scala_api_guide.html">Scala</a> and <a href="java_api_guide.html#iterations">Java</a> programming guides</strong> for details and code examples.</div> </div> -### Example: Propagate Minimum in Graph +<h3 id="example-propagate-minimum-in-graph">Example: Propagate Minimum in Graph</h3> -In the following example, every vertex has an **ID** and a **coloring**. Each vertex will propagete its vertex ID to neighboring vertices. The **goal** is to *assign the minimum ID to every vertex in a subgraph*. If a received ID is smaller then the current one, it changes to the color of the vertex with the received ID. One application of this can be found in *community analysis* or *connected components* computation. +<p>In the following example, every vertex has an <strong>ID</strong> and a <strong>coloring</strong>. Each vertex will propagete its vertex ID to neighboring vertices. The <strong>goal</strong> is to <em>assign the minimum ID to every vertex in a subgraph</em>. If a received ID is smaller then the current one, it changes to the color of the vertex with the received ID. One application of this can be found in <em>community analysis</em> or <em>connected components</em> computation.</p> <p class="text-center"> <img alt="Delta Iterate Operator Example" width="100%" src="img/iterations_delta_iterate_operator_example.png" /> </p> -The **intial input** is set as **both workset and solution set.** In the above figure, the colors visualize the **evolution of the solution set**. With each iteration, the color of the minimum ID is spreading in the respective subgraph. At the same time, the amount of work (exchanged and compared vertex IDs) decreases with each iteration. This corresponds to the **decreasing size of the workset**, which goes from all seven vertices to zero after three iterations, at which time the iteration terminates. The **important observation** is that *the lower subgraph converges before the upper half* does and the delta iteration is able to capture this with the workset abstraction. +<p>The <strong>intial input</strong> is set as <strong>both workset and solution set.</strong> In the above figure, the colors visualize the <strong>evolution of the solution set</strong>. With each iteration, the color of the minimum ID is spreading in the respective subgraph. At the same time, the amount of work (exchanged and compared vertex IDs) decreases with each iteration. This corresponds to the <strong>decreasing size of the workset</strong>, which goes from all seven vertices to zero after three iterations, at which time the iteration terminates. The <strong>important observation</strong> is that <em>the lower subgraph converges before the upper half</em> does and the delta iteration is able to capture this with the workset abstraction.</p> -In the upper subgraph **ID 1** (*orange*) is the **minimum ID**. In the **first iteration**, it will get propagated to vertex 2, which will subsequently change its color to orange. Vertices 3 and 4 will receive **ID 2** (in *yellow*) as their current minimum ID and change to yellow. Because the color of *vertex 1* didn't change in the first iteration, it can be skipped it in the next workset. +<p>In the upper subgraph <strong>ID 1</strong> (<em>orange</em>) is the <strong>minimum ID</strong>. In the <strong>first iteration</strong>, it will get propagated to vertex 2, which will subsequently change its color to orange. Vertices 3 and 4 will receive <strong>ID 2</strong> (in <em>yellow</em>) as their current minimum ID and change to yellow. Because the color of <em>vertex 1</em> didnât change in the first iteration, it can be skipped it in the next workset.</p> -In the lower subgraph **ID 5** (*cyan*) is the **minimum ID**. All vertices of the lower subgraph will receive it in the first iteration. Again, we can skip the unchanged vertices (*vertex 5*) for the next workset. +<p>In the lower subgraph <strong>ID 5</strong> (<em>cyan</em>) is the <strong>minimum ID</strong>. All vertices of the lower subgraph will receive it in the first iteration. Again, we can skip the unchanged vertices (<em>vertex 5</em>) for the next workset.</p> -In the **2nd iteration**, the workset size has already decreased from seven to five elements (vertices 2, 3, 4, 6, and 7). These are part of the iteration and further propagate their current minimum IDs. After this iteration, the lower subgraph has already converged (**cold part** of the graph), as it has no elements in the workset, whereas the upper half needs a further iteration (**hot part** of the graph) for the two remaining workset elements (vertices 3 and 4). +<p>In the <strong>2nd iteration</strong>, the workset size has already decreased from seven to five elements (vertices 2, 3, 4, 6, and 7). These are part of the iteration and further propagate their current minimum IDs. After this iteration, the lower subgraph has already converged (<strong>cold part</strong> of the graph), as it has no elements in the workset, whereas the upper half needs a further iteration (<strong>hot part</strong> of the graph) for the two remaining workset elements (vertices 3 and 4).</p> -The iteration **terminates**, when the workset is empty after the **3rd iteration**. -</section> +<p>The iteration <strong>terminates</strong>, when the workset is empty after the <strong>3rd iteration</strong>.</p> -<section id="supersteps"> -Superstep Synchronization -------------------------- +<p><a href="#supersteps"></a></p> -We referred to each execution of the step function of an iteration operator as *a single iteration*. In parallel setups, **multiple instances of the step function are evaluated in parallel** on different partitions of the iteration state. In many settings, one evaluation of the step function on all parallel instances forms a so called **superstep**, which is also the granularity of synchronization. Therefore, *all* parallel tasks of an iteration need to complete the superstep, before a next superstep will be initialized. **Termination criteria** will also be evaluated at superstep barriers. +<h2 id="superstep-synchronization">Superstep Synchronization</h2> + +<p>We referred to each execution of the step function of an iteration operator as <em>a single iteration</em>. In parallel setups, <strong>multiple instances of the step function are evaluated in parallel</strong> on different partitions of the iteration state. In many settings, one evaluation of the step function on all parallel instances forms a so called <strong>superstep</strong>, which is also the granularity of synchronization. Therefore, <em>all</em> parallel tasks of an iteration need to complete the superstep, before a next superstep will be initialized. <strong>Termination criteria</strong> will also be evaluated at superstep barriers.</p> <p class="text-center"> <img alt="Supersteps" width="50%" src="img/iterations_supersteps.png" /> </p> -</section> - + + <!-- Disqus Area --> <div style="padding-top:30px" id="disqus_thread"></div> <script type="text/javascript"> @@ -309,14 +340,12 @@ We referred to each execution of the ste })(); </script> <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> - <a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a> - </div> </div> <div class="footer"> - <p><hr class="divider"></p> + <hr class="divider" /> <p><small>Apache Flink is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC. Incubation is @@ -327,9 +356,10 @@ incubation status is not necessarily a r stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.</small></p> -<p><a href="http://incubator.apache.org/"><img src="/img/apache-incubator-logo.png" alt="Incubator Logo"></a></p> +<p><a href="http://incubator.apache.org/"><img src="/img/apache-incubator-logo.png" alt="Incubator Logo" /></a></p> -<p class="text-center"><a href="/privacy-policy.html">Privacy Policy<a></p> +<p class="text-center"><a href="privacy-policy.html">Privacy Policy<a> +</a></a></p> </div> </div>
Modified: flink/site/docs/0.6-incubating/java_api_quickstart.html URL: http://svn.apache.org/viewvc/flink/site/docs/0.6-incubating/java_api_quickstart.html?rev=1657551&r1=1657550&r2=1657551&view=diff ============================================================================== --- flink/site/docs/0.6-incubating/java_api_quickstart.html (original) +++ flink/site/docs/0.6-incubating/java_api_quickstart.html Thu Feb 5 12:21:38 2015 @@ -5,116 +5,146 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Apache Flink (incubating): Quickstart: Java API</title> - <link rel="stylesheet" href="/css/bootstrap.css"> - <link rel="stylesheet" href="/css/bootstrap-lumen-custom.css"> - <link rel="stylesheet" href="/css/syntax.css"> - <link rel="/css/custom.css"> - <link rel="css/codetabs.css"> - <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> + <link rel="icon" href="favicon.ico" type="image/x-icon"> + <link rel="stylesheet" href="css/bootstrap.css"> + <link rel="stylesheet" href="css/bootstrap-lumen-custom.css"> + <link rel="stylesheet" href="css/syntax.css"> + <link rel="stylesheet" href="css/custom.css"> + <link href="css/main/main.css" rel="stylesheet"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> - <script src="/js/bootstrap.min.js"></script> + <script src="js/bootstrap.min.js"></script> <script src="js/codetabs.js"></script> </head> <body> <nav class="navbar navbar-default navbar-fixed-top" role="navigation"> <div class="container"> - <div class="navbar-header"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> - <span class="sr-only">Toggle navigation</span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="http://flink.incubator.apache.org">Apache Flink</a> - </div> - - <div class="collapse navbar-collapse" id="navbar-collapse-1"> - <ul class="nav navbar-nav"> + <div class="row"> + <div class="col-md-1 af-mobile-nav-bar"> + <a href="index.html" title="Home"> + <img class="hidden-xs hidden-sm img-responsive" + src="img/logo.png" alt="Apache Flink Logo"> + </a> + <div class="row visible-xs"> + <div class="col-xs-3"> + <a href="index.html" title="Home"> + <img class="hidden-x hidden-sm img-responsive" + src="img/logo.png" alt="Apache Flink Logo"> + </a> + </div> + <div class="col-xs-5"></div> + <div class="col-xs-4"> + <div class="af-mobile-btn"> + <span class="glyphicon glyphicon-plus"></span> + </div> + </div> + </div> + </div> + <!-- Navigation --> + <div class="col-md-11"> + <div class="collapse navbar-collapse" id="navbar-collapse-1"> + <ul class="nav navbar-nav"> + + <li> + <a href="index.html" class="">Documentation</a> + </li> + + <li> + <a href="api/java/index.html">Javadoc</a> + </li> + + <li> + <a href="api/scala/index.html#org.apache.flink.api.scala.package">Scaladoc</a> + </li> - <li> - <a href="index.html" class="">Documentation</a> - </li> - - <li> - <a href="api/java/index.html">Javadoc</a> - </li> - </ul> + </ul> + </div> + </div> </div> </div> </nav> - <div style="padding-top:70px" class="container"> + + <div style="padding-top:120px" class="container"> <div class="row"> <div class="col-md-3"> <ul> - <li>Quickstart - <ul> - <li><a href="setup_quickstart.html">Install</a></li> - <li><a href="run_example_quickstart.html">Run Example</a></li> - <li><a href="java_api_quickstart.html">Java API</a></li> - <li><a href="scala_api_quickstart.html">Scala API</a></li> - <li><a href="faq.html">FAQ</a></li> - </ul> - </li> - - <li>Setup & Configuration - <ul> - <li><a href="building.html">Build Instructions</a></li> - <li><a href="local_setup.html">Local Setup</a></li> - <li><a href="cluster_setup.html">Cluster Setup</a></li> - <li><a href="yarn_setup.html">YARN Setup</a></li> - <li><a href="config.html">Configuration</a></li> - </ul> - </li> - - <li>Programming Guides - <ul> - <li><a href="java_api_guide.html">Java API</a></li> - <li><a href="java_api_transformations.html">Java API Transformations</a></li> - <li><a href="scala_api_guide.html">Scala API</a></li> - <li><a href="iterations.html">Iterations</a></li> - <li><a href="spargel_guide.html">Spargel Graph API</a></li> - </ul> - </li> - - <li>Examples - <ul> - <li><a href="java_api_examples.html">Java API</a></li> - <li><a href="scala_api_examples.html">Scala API</a></li> - <li><a href="example_connectors.html">Connecting to other systems</a></li> - </ul> - </li> - - <li>Execution - <ul> - <li><a href="local_execution.html">Local/Debugging</a></li> - <li><a href="cluster_execution.html">Cluster</a></li> - <li><a href="cli.html">Command-Line Interface</a></li> - <li><a href="web_client.html">Web Interface</a></li> - </ul> - </li> - - <li>Internals - <ul> - <li><a href="internal_overview.html">Overview</a></li> - <li><a href="internal_general_arch.html">General Architecture</a></li> - <li><a href="internal_add_operator.html">How-to: Adding a new Operator</a></li> - </ul> - </li> + <li><a href="faq.html">FAQ</a></li> + <li>Quickstart + <ul> + <li><a href="setup_quickstart.html">Setup</a></li> + <li><a href="run_example_quickstart.html">Run Example</a></li> + <li><a href="java_api_quickstart.html">Java API</a></li> + <li><a href="scala_api_quickstart.html">Scala API</a></li> + </ul> + </li> + + <li>Setup & Configuration + <ul> + <li><a href="local_setup.html">Local Setup</a></li> + <li><a href="building.html">Build Flink</a></li> + <li><a href="cluster_setup.html">Cluster Setup</a></li> + <li><a href="yarn_setup.html">YARN Setup</a></li> + <li><a href="config.html">Configuration</a></li> + </ul> + </li> + + <li>Programming Guides + <ul> + <li><a href="programming_guide.html">Programming Guide</a></li> + <li><a href="dataset_transformations.html">DataSet Transformations</a></li> + <li><a href="java8_programming_guide.html">Java 8 Programming Guide</a></li> + <li><a href="streaming_guide.html">Streaming Guide</a></li> + <li><a href="iterations.html">Iterations</a></li> + <li><a href="spargel_guide.html">Spargel Graph API</a></li> + <li><a href="hadoop_compatibility.html">Hadoop Compatibility</a></li> + </ul> + </li> + + <li>Examples + <ul> + <li><a href="examples.html">Bundled Examples</a></li> + <li><a href="example_connectors.html">Connecting to other systems</a></li> + </ul> + </li> + + <li>Execution + <ul> + <li><a href="local_execution.html">Local/Debugging</a></li> + <li><a href="cluster_execution.html">Cluster</a></li> + <li><a href="cli.html">Command-Line Interface</a></li> + <li><a href="web_client.html">Web Interface</a></li> + </ul> + </li> + + <li>Internals + <ul> + <li><a href="internal_overview.html">Overview</a></li> + </ul> + </li> </ul> + </div> <div class="col-md-9"> <h1>Quickstart: Java API</h1> + + <ul id="markdown-toc"> + <li><a href="#requirements">Requirements</a></li> + <li><a href="#create-project">Create Project</a></li> + <li><a href="#inspect-project">Inspect Project</a></li> + <li><a href="#build-project">Build Project</a></li> + <li><a href="#next-steps">Next Steps</a></li> +</ul> - <p>Start working on your Flink Java program in a few simple steps.</p> +<p>Start working on your Flink Java program in a few simple steps.</p> -<h1 id="requirements">Requirements</h1> +<h2 id="requirements">Requirements</h2> <p>The only requirements are working <strong>Maven 3.0.4</strong> (or higher) and <strong>Java 6.x</strong> (or higher) installations.</p> -<h1 id="create-project">Create Project</h1> +<h2 id="create-project">Create Project</h2> <p>Use one of the following commands to <strong>create a project</strong>:</p> @@ -122,7 +152,6 @@ <li class="active"><a href="#quickstart-script" data-toggle="tab">Run the <strong>quickstart script</strong></a></li> <li><a href="#maven-archetype" data-toggle="tab">Use <strong>Maven archetypes</strong></a></li> </ul> - <div class="tab-content"> <div class="tab-pane active" id="quickstart-script"> @@ -134,48 +163,52 @@ <div class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>mvn archetype:generate <span class="se">\</span> -DarchetypeGroupId<span class="o">=</span>org.apache.flink <span class="se">\</span> -DarchetypeArtifactId<span class="o">=</span>flink-quickstart-java <span class="se">\</span> - -DarchetypeVersion<span class="o">=</span>0.6.1-incubating</code></pre></div> + -DarchetypeVersion<span class="o">=</span>0.7.0-incubating</code></pre></div> This allows you to <strong>name your newly created project</strong>. It will interactively ask you for the groupId, artifactId, and package name. </div> </div> -<h1 id="inspect-project">Inspect Project</h1> +<h2 id="inspect-project">Inspect Project</h2> -<p>There will be a new directory in your working directory. If you've used the <em>curl</em> approach, the directory is called <code>quickstart</code>. Otherwise, it has the name of your artifactId.</p> +<p>There will be a new directory in your working directory. If youâve used the <em>curl</em> approach, the directory is called <code>quickstart</code>. Otherwise, it has the name of your artifactId.</p> <p>The sample project is a <strong>Maven project</strong>, which contains two classes. <em>Job</em> is a basic skeleton program and <em>WordCountJob</em> a working example. Please note that the <em>main</em> method of both classes allow you to start Flink in a development/testing mode.</p> <p>We recommend to <strong>import this project into your IDE</strong> to develop and test it. If you use Eclipse, the <a href="http://www.eclipse.org/m2e/">m2e plugin</a> allows to <a href="http://books.sonatype.com/m2eclipse-book/reference/creating-sect-importing-projects.html#fig-creating-import">import Maven projects</a>. Some Eclipse bundles include that plugin by default, other require you to install it manually. The IntelliJ IDE also supports Maven projects out of the box.</p> -<p>A note to Mac OS X users: The default JVM heapsize for Java is too small for Flink. You have to manually increase it. Choose "Run Configurations" -> Arguments and write into the "VM Arguments" box: "-Xmx800m" in Eclipse.</p> +<p>A note to Mac OS X users: The default JVM heapsize for Java is too small for Flink. You have to manually increase it. Choose âRun Configurationsâ -> Arguments and write into the âVM Argumentsâ box: â-Xmx800mâ in Eclipse.</p> -<h1 id="build-project">Build Project</h1> +<h2 id="build-project">Build Project</h2> -<p>If you want to <strong>build your project</strong>, go to your project directory and issue the <code>mvn clean package</code> command. You will <strong>find a jar</strong> that runs on every Flink cluster in <code>target/flink-project-0.1-SNAPSHOT.jar</code>.</p> +<p>If you want to <strong>build your project</strong>, go to your project directory and issue the<code>mvn clean package</code> command. You will <strong>find a jar</strong> that runs on every Flink cluster in <strong>target/your-artifact-id-1.0-SNAPSHOT.jar</strong>. There is also a fat-jar, <strong>target/your-artifact-id-1.0-SNAPSHOT-flink-fat-jar.jar</strong>. This +also contains all dependencies that get added to the maven project.</p> -<h1 id="next-steps">Next Steps</h1> +<h2 id="next-steps">Next Steps</h2> <p>Write your application!</p> -<p>The quickstart project contains a WordCount implementation, the "Hello World" of Big Data processing systems. The goal of WordCount is to determine the frequencies of words in a text, e.g., how often do the terms "the" or "house" occurs in all Wikipedia texts.</p> +<p>The quickstart project contains a WordCount implementation, the âHello Worldâ of Big Data processing systems. The goal of WordCount is to determine the frequencies of words in a text, e.g., how often do the terms âtheâ or âhouseâ occurs in all Wikipedia texts.</p> <p><strong>Sample Input</strong>:</p> -<div class="highlight"><pre><code class="language-bash" data-lang="bash">big data is big -</code></pre></div> + +<div class="highlight"><pre><code class="language-bash">big data is big</code></pre></div> + <p><strong>Sample Output</strong>:</p> -<div class="highlight"><pre><code class="language-bash" data-lang="bash">big 2 + +<div class="highlight"><pre><code class="language-bash">big 2 data 1 -is 1 -</code></pre></div> +is 1</code></pre></div> + <p>The following code shows the WordCount implementation from the Quickstart which processes some text lines with two operators (FlatMap and Reduce), and writes the prints the resulting words and counts to std-out.</p> -<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">WordCount</span> <span class="o">{</span> +<div class="highlight"><pre><code class="language-java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">WordCount</span> <span class="o">{</span> + <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> - + <span class="c1">// set up the execution environment</span> <span class="kd">final</span> <span class="n">ExecutionEnvironment</span> <span class="n">env</span> <span class="o">=</span> <span class="n">ExecutionEnvironment</span><span class="o">.</span><span class="na">getExecutionEnvironment</span><span class="o">();</span> - + <span class="c1">// get input data</span> <span class="n">DataSet</span><span class="o"><</span><span class="n">String</span><span class="o">></span> <span class="n">text</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="na">fromElements</span><span class="o">(</span> <span class="s">"To be, or not to be,--that is the question:--"</span><span class="o">,</span> @@ -183,7 +216,7 @@ is 1 <span class="s">"The slings and arrows of outrageous fortune"</span><span class="o">,</span> <span class="s">"Or to take arms against a sea of troubles,"</span> <span class="o">);</span> - + <span class="n">DataSet</span><span class="o"><</span><span class="n">Tuple2</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Integer</span><span class="o">>></span> <span class="n">counts</span> <span class="o">=</span> <span class="c1">// split up the lines in pairs (2-tuples) containing: (word,1)</span> <span class="n">text</span><span class="o">.</span><span class="na">flatMap</span><span class="o">(</span><span class="k">new</span> <span class="nf">LineSplitter</span><span class="o">())</span> @@ -193,20 +226,21 @@ is 1 <span class="c1">// emit result</span> <span class="n">counts</span><span class="o">.</span><span class="na">print</span><span class="o">();</span> - + <span class="c1">// execute program</span> <span class="n">env</span><span class="o">.</span><span class="na">execute</span><span class="o">(</span><span class="s">"WordCount Example"</span><span class="o">);</span> <span class="o">}</span> -<span class="o">}</span> -</code></pre></div> +<span class="o">}</span></code></pre></div> + <p>The operations are defined by specialized classes, here the LineSplitter class.</p> -<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">LineSplitter</span> <span class="kd">extends</span> <span class="n">FlatMapFunction</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Tuple2</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Integer</span><span class="o">>></span> <span class="o">{</span> + +<div class="highlight"><pre><code class="language-java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">LineSplitter</span> <span class="kd">extends</span> <span class="n">FlatMapFunction</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Tuple2</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Integer</span><span class="o">>></span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">flatMap</span><span class="o">(</span><span class="n">String</span> <span class="n">value</span><span class="o">,</span> <span class="n">Collector</span><span class="o"><</span><span class="n">Tuple2</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Integer</span><span class="o">>></span> <span class="n">out</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// normalize and split the line into words</span> <span class="n">String</span><span class="o">[]</span> <span class="n">tokens</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="na">toLowerCase</span><span class="o">().</span><span class="na">split</span><span class="o">(</span><span class="s">"\\W+"</span><span class="o">);</span> - + <span class="c1">// emit the pairs</span> <span class="k">for</span> <span class="o">(</span><span class="n">String</span> <span class="n">token</span> <span class="o">:</span> <span class="n">tokens</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">token</span><span class="o">.</span><span class="na">length</span><span class="o">()</span> <span class="o">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span> @@ -214,13 +248,15 @@ is 1 <span class="o">}</span> <span class="o">}</span> <span class="o">}</span> -<span class="o">}</span> -</code></pre></div> -<p><a href=https://github.com/apache/incubator-flink/blob/master//flink-examples/flink-java-examples/src/main/java/org/apache/flink/example/java/wordcount/WordCount.java>Check GitHub</a> for the full example code.</p> +<span class="o">}</span></code></pre></div> + +<p><a href="https://github.com/apache/incubator-flink/blob/master//flink-examples/flink-java-examples/src/main/java/org/apache/flink/examples/java/wordcount/WordCount.java">Check GitHub</a> for the full example code.</p> -<p>For a complete overview over our Java API, have a look at the <a href="java_api_guide.html">API Documentation</a> and <a href="java_api_examples.html">further example programs</a>. If you have any trouble, ask on our <a href="http://mail-archives.apache.org/mod_mbox/incubator-flink-dev/">Mailing List</a>. We are happy to provide help.</p> +<p>For a complete overview over our API, have a look at the <a href="programming_guide.html">Programming Guide</a> and <a href="examples.html">further example programs</a>. If you have any trouble, ask on our <a href="http://mail-archives.apache.org/mod_mbox/incubator-flink-dev/">Mailing List</a>. We are happy to provide help.</p> + + <!-- Disqus Area --> <div style="padding-top:30px" id="disqus_thread"></div> <script type="text/javascript"> @@ -235,14 +271,12 @@ is 1 })(); </script> <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> - <a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a> - </div> </div> <div class="footer"> - <p><hr class="divider"></p> + <hr class="divider" /> <p><small>Apache Flink is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC. Incubation is @@ -253,9 +287,10 @@ incubation status is not necessarily a r stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.</small></p> -<p><a href="http://incubator.apache.org/"><img src="/img/apache-incubator-logo.png" alt="Incubator Logo"></a></p> +<p><a href="http://incubator.apache.org/"><img src="/img/apache-incubator-logo.png" alt="Incubator Logo" /></a></p> -<p class="text-center"><a href="/privacy-policy.html">Privacy Policy<a></p> +<p class="text-center"><a href="privacy-policy.html">Privacy Policy<a> +</a></a></p> </div> </div> Modified: flink/site/docs/0.6-incubating/local_execution.html URL: http://svn.apache.org/viewvc/flink/site/docs/0.6-incubating/local_execution.html?rev=1657551&r1=1657550&r2=1657551&view=diff ============================================================================== --- flink/site/docs/0.6-incubating/local_execution.html (original) +++ flink/site/docs/0.6-incubating/local_execution.html Thu Feb 5 12:21:38 2015 @@ -5,140 +5,165 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Apache Flink (incubating): Local Execution</title> - <link rel="stylesheet" href="/css/bootstrap.css"> - <link rel="stylesheet" href="/css/bootstrap-lumen-custom.css"> - <link rel="stylesheet" href="/css/syntax.css"> - <link rel="/css/custom.css"> - <link rel="css/codetabs.css"> - <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> + <link rel="shortcut icon" href="favicon.ico" type="image/x-icon"> + <link rel="icon" href="favicon.ico" type="image/x-icon"> + <link rel="stylesheet" href="css/bootstrap.css"> + <link rel="stylesheet" href="css/bootstrap-lumen-custom.css"> + <link rel="stylesheet" href="css/syntax.css"> + <link rel="stylesheet" href="css/custom.css"> + <link href="css/main/main.css" rel="stylesheet"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> - <script src="/js/bootstrap.min.js"></script> + <script src="js/bootstrap.min.js"></script> <script src="js/codetabs.js"></script> </head> <body> <nav class="navbar navbar-default navbar-fixed-top" role="navigation"> <div class="container"> - <div class="navbar-header"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> - <span class="sr-only">Toggle navigation</span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="http://flink.incubator.apache.org">Apache Flink</a> - </div> - - <div class="collapse navbar-collapse" id="navbar-collapse-1"> - <ul class="nav navbar-nav"> + <div class="row"> + <div class="col-md-1 af-mobile-nav-bar"> + <a href="index.html" title="Home"> + <img class="hidden-xs hidden-sm img-responsive" + src="img/logo.png" alt="Apache Flink Logo"> + </a> + <div class="row visible-xs"> + <div class="col-xs-3"> + <a href="index.html" title="Home"> + <img class="hidden-x hidden-sm img-responsive" + src="img/logo.png" alt="Apache Flink Logo"> + </a> + </div> + <div class="col-xs-5"></div> + <div class="col-xs-4"> + <div class="af-mobile-btn"> + <span class="glyphicon glyphicon-plus"></span> + </div> + </div> + </div> + </div> + <!-- Navigation --> + <div class="col-md-11"> + <div class="collapse navbar-collapse" id="navbar-collapse-1"> + <ul class="nav navbar-nav"> + + <li> + <a href="index.html" class="">Documentation</a> + </li> + + <li> + <a href="api/java/index.html">Javadoc</a> + </li> + + <li> + <a href="api/scala/index.html#org.apache.flink.api.scala.package">Scaladoc</a> + </li> - <li> - <a href="index.html" class="">Documentation</a> - </li> - - <li> - <a href="api/java/index.html">Javadoc</a> - </li> - </ul> + </ul> + </div> + </div> </div> </div> </nav> - <div style="padding-top:70px" class="container"> + + <div style="padding-top:120px" class="container"> <div class="row"> <div class="col-md-3"> <ul> - <li>Quickstart - <ul> - <li><a href="setup_quickstart.html">Install</a></li> - <li><a href="run_example_quickstart.html">Run Example</a></li> - <li><a href="java_api_quickstart.html">Java API</a></li> - <li><a href="scala_api_quickstart.html">Scala API</a></li> - <li><a href="faq.html">FAQ</a></li> - </ul> - </li> - - <li>Setup & Configuration - <ul> - <li><a href="building.html">Build Instructions</a></li> - <li><a href="local_setup.html">Local Setup</a></li> - <li><a href="cluster_setup.html">Cluster Setup</a></li> - <li><a href="yarn_setup.html">YARN Setup</a></li> - <li><a href="config.html">Configuration</a></li> - </ul> - </li> - - <li>Programming Guides - <ul> - <li><a href="java_api_guide.html">Java API</a></li> - <li><a href="java_api_transformations.html">Java API Transformations</a></li> - <li><a href="scala_api_guide.html">Scala API</a></li> - <li><a href="iterations.html">Iterations</a></li> - <li><a href="spargel_guide.html">Spargel Graph API</a></li> - </ul> - </li> - - <li>Examples - <ul> - <li><a href="java_api_examples.html">Java API</a></li> - <li><a href="scala_api_examples.html">Scala API</a></li> - <li><a href="example_connectors.html">Connecting to other systems</a></li> - </ul> - </li> - - <li>Execution - <ul> - <li><a href="local_execution.html">Local/Debugging</a></li> - <li><a href="cluster_execution.html">Cluster</a></li> - <li><a href="cli.html">Command-Line Interface</a></li> - <li><a href="web_client.html">Web Interface</a></li> - </ul> - </li> - - <li>Internals - <ul> - <li><a href="internal_overview.html">Overview</a></li> - <li><a href="internal_general_arch.html">General Architecture</a></li> - <li><a href="internal_add_operator.html">How-to: Adding a new Operator</a></li> - </ul> - </li> + <li><a href="faq.html">FAQ</a></li> + <li>Quickstart + <ul> + <li><a href="setup_quickstart.html">Setup</a></li> + <li><a href="run_example_quickstart.html">Run Example</a></li> + <li><a href="java_api_quickstart.html">Java API</a></li> + <li><a href="scala_api_quickstart.html">Scala API</a></li> + </ul> + </li> + + <li>Setup & Configuration + <ul> + <li><a href="local_setup.html">Local Setup</a></li> + <li><a href="building.html">Build Flink</a></li> + <li><a href="cluster_setup.html">Cluster Setup</a></li> + <li><a href="yarn_setup.html">YARN Setup</a></li> + <li><a href="config.html">Configuration</a></li> + </ul> + </li> + + <li>Programming Guides + <ul> + <li><a href="programming_guide.html">Programming Guide</a></li> + <li><a href="dataset_transformations.html">DataSet Transformations</a></li> + <li><a href="java8_programming_guide.html">Java 8 Programming Guide</a></li> + <li><a href="streaming_guide.html">Streaming Guide</a></li> + <li><a href="iterations.html">Iterations</a></li> + <li><a href="spargel_guide.html">Spargel Graph API</a></li> + <li><a href="hadoop_compatibility.html">Hadoop Compatibility</a></li> + </ul> + </li> + + <li>Examples + <ul> + <li><a href="examples.html">Bundled Examples</a></li> + <li><a href="example_connectors.html">Connecting to other systems</a></li> + </ul> + </li> + + <li>Execution + <ul> + <li><a href="local_execution.html">Local/Debugging</a></li> + <li><a href="cluster_execution.html">Cluster</a></li> + <li><a href="cli.html">Command-Line Interface</a></li> + <li><a href="web_client.html">Web Interface</a></li> + </ul> + </li> + + <li>Internals + <ul> + <li><a href="internal_overview.html">Overview</a></li> + </ul> + </li> </ul> + </div> <div class="col-md-9"> <h1>Local Execution</h1> - - <h1 id="local-execution/debugging">Local Execution/Debugging</h1> + + <h2 id="local-execution">Local Execution</h2> <p>Flink can run on a single machine, even in a single Java Virtual Machine. This allows users to test and debug Flink programs locally. This section gives an overview of the local execution mechanisms.</p> -<p><strong>NOTE:</strong> Please also refer to the <a href="java_api_guide.html#debugging">debugging section</a> in the Java API documentation for a guide to testing and local debugging utilities in the Java API.</p> +<p>The local environments and executors allow you to run Flink programs in a local Java Virtual Machine, or with within any JVM as part of existing programs. Most examples can be launched locally by simply hitting the âRunâ button of your IDE.</p> -<p>The local environments and executors allow you to run Flink programs in local Java Virtual Machine, or with within any JVM as part of existing programs. Most examples can be launched locally by simply hitting the "Run" button of your IDE.</p> +<p>There are two different kinds of local execution supported in Flink. The <code>LocalExecutionEnvironment</code> is starting the full Flink runtime, including a JobManager and a TaskManager. These include memory management and all the internal algorithms that are executed in the cluster mode.</p> -<p>If you are running Flink programs locally, you can also debug your program like any other Java program. You can either use <code>System.out.println()</code> to write out some internal variables or you can use the debugger. It is possible to set breakpoints within <code>map()</code>, <code>reduce()</code> and all the other methods.</p> +<p>The <code>CollectionEnvironment</code> is executing the Flink program on Java collections. This mode will not start the full Flink runtime, so the execution is very low-overhead and lightweight. For example a <code>DataSet.map()</code>-transformation will be executed by applying the <code>map()</code> function to all elements in a Java list.</p> -<p>The <code>JobExecutionResult</code> object, which is returned after the execution finished, contains the program runtime and the accumulator results.</p> +<h2 id="debugging">Debugging</h2> -<p><em>Note:</em> The local execution environments do not start any web frontend to monitor the execution.</p> +<p>If you are running Flink programs locally, you can also debug your program like any other Java program. You can either use <code>System.out.println()</code> to write out some internal variables or you can use the debugger. It is possible to set breakpoints within <code>map()</code>, <code>reduce()</code> and all the other methods. +Please also refer to the <a href="programming_guide.html#debugging">debugging section</a> in the Java API documentation for a guide to testing and local debugging utilities in the Java API.</p> -<h1 id="maven-dependency">Maven Dependency</h1> +<h2 id="maven-dependency">Maven Dependency</h2> <p>If you are developing your program in a Maven project, you have to add the <code>flink-clients</code> module using this dependency:</p> -<div class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt"><dependency></span> + +<div class="highlight"><pre><code class="language-xml"><span class="nt"><dependency></span> <span class="nt"><groupId></span>org.apache.flink<span class="nt"></groupId></span> <span class="nt"><artifactId></span>flink-clients<span class="nt"></artifactId></span> - <span class="nt"><version></span>0.6.1-incubating<span class="nt"></version></span> -<span class="nt"></dependency></span> -</code></pre></div> -<h1 id="local-environment">Local Environment</h1> + <span class="nt"><version></span>0.7.0-incubating<span class="nt"></version></span> +<span class="nt"></dependency></span></code></pre></div> + +<h2 id="local-environment">Local Environment</h2> <p>The <code>LocalEnvironment</code> is a handle to local execution for Flink programs. Use it to run a program within a local JVM - standalone or embedded in other programs.</p> <p>The local environment is instantiated via the method <code>ExecutionEnvironment.createLocalEnvironment()</code>. By default, it will use as many local threads for execution as your machine has CPU cores (hardware contexts). You can alternatively specify the desired parallelism. The local environment can be configured to log to the console using <code>enableLogging()</code>/<code>disableLogging()</code>.</p> <p>In most cases, calling <code>ExecutionEnvironment.getExecutionEnvironment()</code> is the even better way to go. That method returns a <code>LocalEnvironment</code> when the program is started locally (outside the command line interface), and it returns a pre-configured environment for cluster execution, when the program is invoked by the <a href="cli.html">command line interface</a>.</p> -<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + +<div class="highlight"><pre><code class="language-java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> <span class="n">ExecutionEnvironment</span> <span class="n">env</span> <span class="o">=</span> <span class="n">ExecutionEnvironment</span><span class="o">.</span><span class="na">createLocalEnvironment</span><span class="o">();</span> <span class="n">DataSet</span><span class="o"><</span><span class="n">String</span><span class="o">></span> <span class="n">data</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="na">readTextFile</span><span class="o">(</span><span class="s">"file:///path/to/file"</span><span class="o">);</span> @@ -151,50 +176,48 @@ <span class="o">})</span> <span class="o">.</span><span class="na">writeAsText</span><span class="o">(</span><span class="s">"file:///path/to/result"</span><span class="o">);</span> - <span class="n">env</span><span class="o">.</span><span class="na">execute</span><span class="o">();</span> -<span class="o">}</span> -</code></pre></div> -<h1 id="local-executor">Local Executor</h1> + <span class="n">JobExecutionResult</span> <span class="n">res</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="na">execute</span><span class="o">();</span> +<span class="o">}</span></code></pre></div> -<p>The <em>LocalExecutor</em> is similar to the local environment, but it takes a <em>Plan</em> object, which describes the program as a single executable unit. The <em>LocalExecutor</em> is typically used with the Scala API. </p> +<p>The <code>JobExecutionResult</code> object, which is returned after the execution finished, contains the program runtime and the accumulator results.</p> -<p>The following code shows how you would use the <code>LocalExecutor</code> with the Wordcount example for Scala Programs:</p> -<div class="highlight"><pre><code class="language-scala" data-lang="scala"><span class="n">public</span> <span class="n">static</span> <span class="n">void</span> <span class="n">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="n">throws</span> <span class="nc">Exception</span> <span class="o">{</span> - <span class="k">val</span> <span class="n">input</span> <span class="k">=</span> <span class="nc">TextFile</span><span class="o">(</span><span class="s">"hdfs://path/to/file"</span><span class="o">)</span> +<p><em>Note:</em> The local execution environments do not start any web frontend to monitor the execution.</p> - <span class="k">val</span> <span class="n">words</span> <span class="k">=</span> <span class="n">input</span> <span class="n">flatMap</span> <span class="o">{</span> <span class="k">_</span><span class="o">.</span><span class="n">toLowerCase</span><span class="o">().</span><span class="n">split</span><span class="o">(</span><span class="s">"""\W+"""</span><span class="o">)</span> <span class="n">filter</span> <span class="o">{</span> <span class="k">_</span> <span class="o">!=</span> <span class="s">""</span> <span class="o">}</span> <span class="o">}</span> - <span class="k">val</span> <span class="n">counts</span> <span class="k">=</span> <span class="n">words</span> <span class="n">groupBy</span> <span class="o">{</span> <span class="n">x</span> <span class="k">=></span> <span class="n">x</span> <span class="o">}</span> <span class="n">count</span><span class="o">()</span> +<h2 id="collection-environment">Collection Environment</h2> - <span class="k">val</span> <span class="n">output</span> <span class="k">=</span> <span class="n">counts</span><span class="o">.</span><span class="n">write</span><span class="o">(</span><span class="n">wordsOutput</span><span class="o">,</span> <span class="nc">CsvOutputFormat</span><span class="o">())</span> +<p>The execution on Java Collections using the <code>CollectionEnvironment</code> is a low-overhead approach for executing Flink programs. Typical use-cases for this mode are automated tests, debugging and code re-use.</p> - <span class="k">val</span> <span class="n">plan</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">ScalaPlan</span><span class="o">(</span><span class="nc">Seq</span><span class="o">(</span><span class="n">output</span><span class="o">),</span> <span class="s">"Word Count"</span><span class="o">)</span> - <span class="nc">LocalExecutor</span><span class="o">.</span><span class="n">executePlan</span><span class="o">(</span><span class="n">p</span><span class="o">);</span> -<span class="o">}</span> -</code></pre></div> -<h1 id="localdistributedexecutor">LocalDistributedExecutor</h1> +<p>Users can use algorithms implemented for batch processing also for cases that are more interactive. A slightly changed variant of a Flink program could be used in a Java Application Server for processing incoming requests.</p> -<p>Flink also offers a <code>LocalDistributedExecutor</code> which starts multiple TaskManagers within one JVM. The standard <code>LocalExecutor</code> starts one JobManager and one TaskManager in one JVM. -With the <code>LocalDistributedExecutor</code> you can define the number of TaskManagers to start. This is useful for debugging network related code and more of a developer tool than a user tool.</p> -<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> - <span class="n">ExecutionEnvironment</span> <span class="n">env</span> <span class="o">=</span> <span class="n">ExecutionEnvironment</span><span class="o">.</span><span class="na">getExecutionEnvironment</span><span class="o">();</span> +<p><strong>Skeleton for Collection-based execution</strong></p> - <span class="n">DataSet</span><span class="o"><</span><span class="n">String</span><span class="o">></span> <span class="n">data</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="na">readTextFile</span><span class="o">(</span><span class="s">"hdfs://path/to/file"</span><span class="o">);</span> +<div class="highlight"><pre><code class="language-java"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="c1">// initialize a new Collection-based execution environment</span> + <span class="kd">final</span> <span class="n">ExecutionEnvironment</span> <span class="n">env</span> <span class="o">=</span> <span class="k">new</span> <span class="nf">CollectionEnvironment</span><span class="o">();</span> + + <span class="n">DataSet</span><span class="o"><</span><span class="n">User</span><span class="o">></span> <span class="n">users</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="na">fromCollection</span><span class="o">(</span> <span class="cm">/* get elements from a Java Collection */</span><span class="o">);</span> - <span class="n">data</span> - <span class="o">.</span><span class="na">filter</span><span class="o">(</span><span class="k">new</span> <span class="n">FilterFunction</span><span class="o"><</span><span class="n">String</span><span class="o">>()</span> <span class="o">{</span> - <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">filter</span><span class="o">(</span><span class="n">String</span> <span class="n">value</span><span class="o">)</span> <span class="o">{</span> - <span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="na">startsWith</span><span class="o">(</span><span class="s">"http://"</span><span class="o">);</span> - <span class="o">}</span> - <span class="o">})</span> - <span class="o">.</span><span class="na">writeAsText</span><span class="o">(</span><span class="s">"hdfs://path/to/result"</span><span class="o">);</span> + <span class="cm">/* Data Set transformations ... */</span> + + <span class="c1">// retrieve the resulting Tuple2 elements into a ArrayList.</span> + <span class="n">Collection</span><span class="o"><...></span> <span class="n">result</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o"><...>();</span> + <span class="n">resultDataSet</span><span class="o">.</span><span class="na">output</span><span class="o">(</span><span class="k">new</span> <span class="n">LocalCollectionOutputFormat</span><span class="o"><...>(</span><span class="n">result</span><span class="o">));</span> + + <span class="c1">// kick off execution.</span> + <span class="n">env</span><span class="o">.</span><span class="na">execute</span><span class="o">();</span> + + <span class="c1">// Do some work with the resulting ArrayList (=Collection).</span> + <span class="k">for</span><span class="o">(...</span> <span class="n">t</span> <span class="o">:</span> <span class="n">result</span><span class="o">)</span> <span class="o">{</span> + <span class="n">System</span><span class="o">.</span><span class="na">err</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Result = "</span><span class="o">+</span><span class="n">t</span><span class="o">);</span> + <span class="o">}</span> +<span class="o">}</span></code></pre></div> + +<p>The <code>flink-java-examples</code> module contains a full example, called <code>CollectionExecutionExample</code>.</p> - <span class="n">Plan</span> <span class="n">p</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="na">createProgramPlan</span><span class="o">();</span> - <span class="n">LocalDistributedExecutor</span> <span class="n">lde</span> <span class="o">=</span> <span class="k">new</span> <span class="nf">LocalDistributedExecutor</span><span class="o">();</span> - <span class="n">lde</span><span class="o">.</span><span class="na">startNephele</span><span class="o">(</span><span class="mi">2</span><span class="o">);</span> <span class="c1">// start two TaskManagers</span> - <span class="n">lde</span><span class="o">.</span><span class="na">run</span><span class="o">(</span><span class="n">p</span><span class="o">);</span> -<span class="o">}</span> -</code></pre></div> +<p>Please note that the execution of the collection-based Flink programs is only possible on small data, which fits into the JVM heap. The execution on collections is not multi-threaded, only one thread is used.</p> + + <!-- Disqus Area --> <div style="padding-top:30px" id="disqus_thread"></div> <script type="text/javascript"> @@ -209,14 +232,12 @@ With the <code>LocalDistributedExecutor< })(); </script> <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> - <a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a> - </div> </div> <div class="footer"> - <p><hr class="divider"></p> + <hr class="divider" /> <p><small>Apache Flink is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC. Incubation is @@ -227,9 +248,10 @@ incubation status is not necessarily a r stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.</small></p> -<p><a href="http://incubator.apache.org/"><img src="/img/apache-incubator-logo.png" alt="Incubator Logo"></a></p> +<p><a href="http://incubator.apache.org/"><img src="/img/apache-incubator-logo.png" alt="Incubator Logo" /></a></p> -<p class="text-center"><a href="/privacy-policy.html">Privacy Policy<a></p> +<p class="text-center"><a href="privacy-policy.html">Privacy Policy<a> +</a></a></p> </div> </div>
