blob: ff5a76ea7ec451cf33f54bb3af505c077d349e7b [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 -->
<meta name="description" content="A new open source Apache Hadoop ecosystem project, Apache Kudu completes Hadoop's storage layer to enable fast analytics on fast data" />
<meta name="author" content="Cloudera" />
<title>Apache Kudu - Testing Apache Kudu Applications on the JVM</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
crossorigin="anonymous">
<!-- Custom styles for this template -->
<link href="/css/kudu.css" rel="stylesheet"/>
<link href="/css/asciidoc.css" rel="stylesheet"/>
<link rel="shortcut icon" href="/img/logo-favicon.ico" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css" />
<link rel="alternate" type="application/atom+xml"
title="RSS Feed for Apache Kudu blog"
href="/feed.xml" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[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>
<div class="kudu-site container-fluid">
<!-- Static navbar -->
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<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="logo" href="/"><img
src="//d3dr9sfxru4sde.cloudfront.net/i/k/apachekudu_logo_0716_80px.png"
srcset="//d3dr9sfxru4sde.cloudfront.net/i/k/apachekudu_logo_0716_80px.png 1x, //d3dr9sfxru4sde.cloudfront.net/i/k/apachekudu_logo_0716_160px.png 2x"
alt="Apache Kudu"/></a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li >
<a href="/">Home</a>
</li>
<li >
<a href="/overview.html">Overview</a>
</li>
<li >
<a href="/docs/">Documentation</a>
</li>
<li >
<a href="/releases/">Releases</a>
</li>
<li class="active">
<a href="/blog/">Blog</a>
</li>
<!-- NOTE: this dropdown menu does not appear on Mobile, so don't add anything here
that doesn't also appear elsewhere on the site. -->
<li class="dropdown">
<a href="/community.html" role="button" aria-haspopup="true" aria-expanded="false">Community <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="dropdown-header">GET IN TOUCH</li>
<li><a class="icon email" href="/community.html">Mailing Lists</a></li>
<li><a class="icon slack" href="https://getkudu-slack.herokuapp.com/">Slack Channel</a></li>
<li role="separator" class="divider"></li>
<li><a href="/community.html#meetups-user-groups-and-conference-presentations">Events and Meetups</a></li>
<li><a href="/committers.html">Project Committers</a></li>
<!--<li><a href="/roadmap.html">Roadmap</a></li>-->
<li><a href="/community.html#contributions">How to Contribute</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">DEVELOPER RESOURCES</li>
<li><a class="icon github" href="https://github.com/apache/incubator-kudu">GitHub</a></li>
<li><a class="icon gerrit" href="http://gerrit.cloudera.org:8080/#/q/status:open+project:kudu">Gerrit Code Review</a></li>
<li><a class="icon jira" href="https://issues.apache.org/jira/browse/KUDU">JIRA Issue Tracker</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">SOCIAL MEDIA</li>
<li><a class="icon twitter" href="https://twitter.com/ApacheKudu">Twitter</a></li>
<li><a href="https://www.reddit.com/r/kudu/">Reddit</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">APACHE SOFTWARE FOUNDATION</li>
<li><a href="https://www.apache.org/security/" target="_blank">Security</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html" target="_blank">Sponsorship</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a></li>
<li><a href="https://www.apache.org/licenses/" target="_blank">License</a></li>
</ul>
</li>
<li >
<a href="/faq.html">FAQ</a>
</li>
</ul><!-- /.nav -->
</div><!-- /#navbar -->
</div><!-- /.container-fluid -->
</nav>
<div class="row header">
<div class="col-lg-12">
<h2><a href="/blog">Apache Kudu Blog</a></h2>
</div>
</div>
<div class="row-fluid">
<div class="col-lg-9">
<article>
<header>
<h1 class="entry-title">Testing Apache Kudu Applications on the JVM</h1>
<p class="meta">Posted 19 Mar 2019 by Grant Henke & Mike Percy</p>
</header>
<div class="entry-content">
<p>Note: This is a cross-post from the Cloudera Engineering Blog
<a href="https://blog.cloudera.com/blog/2019/03/testing-apache-kudu-applications-on-the-jvm/">Testing Apache Kudu Applications on the JVM</a></p>
<p>Although the Kudu server is written in C++ for performance and efficiency, developers can write
client applications in C++, Java, or Python. To make it easier for Java developers to create
reliable client applications, we’ve added new utilities in Kudu 1.9.0 that allow you to write tests
using a Kudu cluster without needing to build Kudu yourself, without any knowledge of C++,
and without any complicated coordination around starting and stopping Kudu clusters for each test.
This post describes how the new testing utilities work and how you can use them in your application
tests.</p>
<!--more-->
<h2 id="user-guide">User Guide</h2>
<p>Note: It is possible this blog post could become outdated – for the latest documentation on using
the JVM testing utilities see the
<a href="https://kudu.apache.org/docs/developing.html#_jvm_based_integration_testing">Kudu documentation</a>.</p>
<h3 id="requirements">Requirements</h3>
<p>In order to use the new testing utilities, the following requirements must be met:</p>
<ul>
<li>OS
<ul>
<li>macOS El Capitan (10.11) or later</li>
<li>CentOS 6.6+, Ubuntu 14.04+, or another recent distribution of Linux
<a href="https://kudu.apache.org/docs/installation.html#_prerequisites_and_requirements">supported by Kudu</a></li>
</ul>
</li>
<li>JVM
<ul>
<li>Java 8+</li>
<li>Note: Java 7+ is deprecated, but still supported</li>
</ul>
</li>
<li>Build Tool
<ul>
<li>Maven 3.1 or later, required to support the
<a href="https://github.com/trustin/os-maven-plugin">os-maven-plugin</a></li>
<li>Gradle 2.1 or later, to support the
<a href="https://github.com/google/osdetector-gradle-plugin">osdetector-gradle-plugin</a></li>
<li>Any other build tool that can download the correct jar from Maven</li>
</ul>
</li>
</ul>
<h3 id="build-configuration">Build Configuration</h3>
<p>In order to use the Kudu testing utilities, add two dependencies to your classpath:</p>
<ul>
<li>The <code class="language-plaintext highlighter-rouge">kudu-test-utils</code> dependency</li>
<li>The <code class="language-plaintext highlighter-rouge">kudu-binary</code> dependency</li>
</ul>
<p>The <code class="language-plaintext highlighter-rouge">kudu-test-utils</code> dependency has useful utilities for testing applications that use Kudu.
Primarily, it provides the
<a href="https://github.com/apache/kudu/blob/master/java/kudu-test-utils/src/main/java/org/apache/kudu/test/KuduTestHarness.java">KuduTestHarness class</a>
to manage the lifecycle of a Kudu cluster for each test. The <code class="language-plaintext highlighter-rouge">KuduTestHarness</code> is a
<a href="https://junit.org/junit4/javadoc/4.12/org/junit/rules/TestRule.html">JUnit TestRule</a>
that not only starts and stops a Kudu cluster for each test, but also has methods to manage the
cluster and get pre-configured <code class="language-plaintext highlighter-rouge">KuduClient</code> instances for use while testing.</p>
<p>The <code class="language-plaintext highlighter-rouge">kudu-binary</code> dependency contains the native Kudu (server and command-line tool) binaries for
the specified operating system. In order to download the right artifact for the running operating
system it is easiest to use a plugin, such as the
<a href="https://github.com/trustin/os-maven-plugin">os-maven-plugin</a> or
<a href="https://github.com/google/osdetector-gradle-plugin">osdetector-gradle-plugin</a>, to detect the
current runtime environment. The <code class="language-plaintext highlighter-rouge">KuduTestHarness</code> will automatically find and use the <code class="language-plaintext highlighter-rouge">kudu-binary</code>
jar on the classpath.</p>
<p>WARNING: The <code class="language-plaintext highlighter-rouge">kudu-binary</code> module should only be used to run Kudu for integration testing purposes.
It should never be used to run an actual Kudu service, in production or development, because the
<code class="language-plaintext highlighter-rouge">kudu-binary</code> module includes native security-related dependencies that have been copied from the
build system and will not be patched when the operating system on the runtime host is patched.</p>
<h4 id="maven-configuration">Maven Configuration</h4>
<p>If you are using Maven to build your project, add the following entries to your project’s
<code class="language-plaintext highlighter-rouge">pom.xml</code> file:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;build&gt;</span>
<span class="nt">&lt;extensions&gt;</span>
<span class="c">&lt;!-- Used to find the right kudu-binary artifact with the Maven
property ${os.detected.classifier} --&gt;</span>
<span class="nt">&lt;extension&gt;</span>
<span class="nt">&lt;groupId&gt;</span>kr.motd.maven<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>os-maven-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>1.6.2<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/extension&gt;</span>
<span class="nt">&lt;/extensions&gt;</span>
<span class="nt">&lt;/build&gt;</span>
<span class="nt">&lt;dependencies&gt;</span>
<span class="nt">&lt;dependency&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.kudu<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>kudu-test-utils<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>1.9.0<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
<span class="nt">&lt;dependency&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.kudu<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>kudu-binary<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>1.9.0<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;classifier&gt;</span>${os.detected.classifier}<span class="nt">&lt;/classifier&gt;</span>
<span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
<span class="nt">&lt;/dependencies&gt;</span></code></pre></figure>
<h4 id="gradle-configuration">Gradle Configuration</h4>
<p>If you are using Gradle to build your project, add the following entries to your project’s
<code class="language-plaintext highlighter-rouge">build.gradle</code> file:</p>
<figure class="highlight"><pre><code class="language-groovy" data-lang="groovy"><span class="n">plugins</span> <span class="o">{</span>
<span class="c1">// Used to find the right kudu-binary artifact with the Gradle</span>
<span class="c1">// property ${osdetector.classifier}</span>
<span class="n">id</span> <span class="s2">"com.google.osdetector"</span> <span class="n">version</span> <span class="s2">"1.6.2"</span>
<span class="o">}</span>
<span class="n">dependencies</span> <span class="o">{</span>
<span class="n">testCompile</span> <span class="s2">"org.apache.kudu:kudu-test-utils:1.9.0"</span>
<span class="n">testCompile</span> <span class="s2">"org.apache.kudu:kudu-binary:1.9.0:${osdetector.classifier}"</span>
<span class="o">}</span></code></pre></figure>
<h2 id="test-setup">Test Setup</h2>
<p>Once your project is configured correctly, you can start writing tests using the <code class="language-plaintext highlighter-rouge">kudu-test-utils</code>
and <code class="language-plaintext highlighter-rouge">kudu-binary</code> artifacts. One line of code will ensure that each test automatically starts and
stops a real Kudu cluster and that cluster logging is output through <code class="language-plaintext highlighter-rouge">slf4j</code>:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Rule</span> <span class="kd">public</span> <span class="nc">KuduTestHarness</span> <span class="n">harness</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">KuduTestHarness</span><span class="o">();</span></code></pre></figure>
<p>The <a href="https://github.com/apache/kudu/blob/master/java/kudu-test-utils/src/main/java/org/apache/kudu/test/KuduTestHarness.java">KuduTestHarness</a>
has methods to get pre-configured clients, start and stop servers, and more. Below is an example
test to showcase some of the capabilities:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kn">import</span> <span class="nn">org.apache.kudu.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.kudu.client.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.apache.kudu.test.KuduTestHarness</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.junit.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Arrays</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Collections</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyKuduTest</span> <span class="o">{</span>
<span class="nd">@Rule</span>
<span class="kd">public</span> <span class="nc">KuduTestHarness</span> <span class="n">harness</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">KuduTestHarness</span><span class="o">();</span>
<span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">test</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
<span class="c1">// Get a KuduClient configured to talk to the running mini cluster.</span>
<span class="nc">KuduClient</span> <span class="n">client</span> <span class="o">=</span> <span class="n">harness</span><span class="o">.</span><span class="na">getClient</span><span class="o">();</span>
<span class="c1">// Some of the other most common KuduTestHarness methods include:</span>
<span class="nc">AsyncKuduClient</span> <span class="n">asyncClient</span> <span class="o">=</span> <span class="n">harness</span><span class="o">.</span><span class="na">getAsyncClient</span><span class="o">();</span>
<span class="nc">String</span> <span class="n">masterAddresses</span><span class="o">=</span> <span class="n">harness</span><span class="o">.</span><span class="na">getMasterAddressesAsString</span><span class="o">();</span>
<span class="nc">List</span><span class="o">&lt;</span><span class="nc">HostAndPort</span><span class="o">&gt;</span> <span class="n">masterServers</span> <span class="o">=</span> <span class="n">harness</span><span class="o">.</span><span class="na">getMasterServers</span><span class="o">();</span>
<span class="nc">List</span><span class="o">&lt;</span><span class="nc">HostAndPort</span><span class="o">&gt;</span> <span class="n">tabletServers</span> <span class="o">=</span> <span class="n">harness</span><span class="o">.</span><span class="na">getTabletServers</span><span class="o">();</span>
<span class="n">harness</span><span class="o">.</span><span class="na">killLeaderMasterServer</span><span class="o">();</span>
<span class="n">harness</span><span class="o">.</span><span class="na">killAllMasterServers</span><span class="o">();</span>
<span class="n">harness</span><span class="o">.</span><span class="na">startAllMasterServers</span><span class="o">();</span>
<span class="n">harness</span><span class="o">.</span><span class="na">killAllTabletServers</span><span class="o">();</span>
<span class="n">harness</span><span class="o">.</span><span class="na">startAllTabletServers</span><span class="o">();</span>
<span class="c1">// Create a new Kudu table.</span>
<span class="nc">String</span> <span class="n">tableName</span> <span class="o">=</span> <span class="s">"myTable"</span><span class="o">;</span>
<span class="nc">Schema</span> <span class="n">schema</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Schema</span><span class="o">(</span><span class="nc">Arrays</span><span class="o">.</span><span class="na">asList</span><span class="o">(</span>
<span class="k">new</span> <span class="nc">ColumnSchema</span><span class="o">.</span><span class="na">ColumnSchemaBuilder</span><span class="o">(</span><span class="s">"key"</span><span class="o">,</span> <span class="nc">Type</span><span class="o">.</span><span class="na">INT32</span><span class="o">).</span><span class="na">key</span><span class="o">(</span><span class="kc">true</span><span class="o">).</span><span class="na">build</span><span class="o">(),</span>
<span class="k">new</span> <span class="nc">ColumnSchema</span><span class="o">.</span><span class="na">ColumnSchemaBuilder</span><span class="o">(</span><span class="s">"value"</span><span class="o">,</span> <span class="nc">Type</span><span class="o">.</span><span class="na">STRING</span><span class="o">).</span><span class="na">key</span><span class="o">(</span><span class="kc">true</span><span class="o">).</span><span class="na">build</span><span class="o">()</span>
<span class="o">));</span>
<span class="nc">CreateTableOptions</span> <span class="n">opts</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">CreateTableOptions</span><span class="o">()</span>
<span class="o">.</span><span class="na">setRangePartitionColumns</span><span class="o">(</span><span class="nc">Collections</span><span class="o">.</span><span class="na">singletonList</span><span class="o">(</span><span class="s">"key"</span><span class="o">));</span>
<span class="n">client</span><span class="o">.</span><span class="na">createTable</span><span class="o">(</span><span class="n">tableName</span><span class="o">,</span> <span class="n">schema</span><span class="o">,</span> <span class="n">opts</span><span class="o">);</span>
<span class="nc">KuduTable</span> <span class="n">table</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">openTable</span><span class="o">(</span><span class="n">tableName</span><span class="o">);</span>
<span class="c1">// Write a few rows to the table</span>
<span class="nc">KuduSession</span> <span class="n">session</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSession</span><span class="o">();</span>
<span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="nc">Insert</span> <span class="n">insert</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="na">newInsert</span><span class="o">();</span>
<span class="nc">PartialRow</span> <span class="n">row</span> <span class="o">=</span> <span class="n">insert</span><span class="o">.</span><span class="na">getRow</span><span class="o">();</span>
<span class="n">row</span><span class="o">.</span><span class="na">addInt</span><span class="o">(</span><span class="s">"key"</span><span class="o">,</span> <span class="n">i</span><span class="o">);</span>
<span class="n">row</span><span class="o">.</span><span class="na">addString</span><span class="o">(</span><span class="s">"value"</span><span class="o">,</span> <span class="nc">String</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">i</span><span class="o">));</span>
<span class="n">session</span><span class="o">.</span><span class="na">apply</span><span class="o">(</span><span class="n">insert</span><span class="o">);</span>
<span class="o">}</span>
<span class="n">session</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
<span class="c1">// ... Continue the test. Read and validate the rows, alter the table, etc.</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>For a complete example of a project using the <code class="language-plaintext highlighter-rouge">KuduTestHarness</code>, see the
<a href="https://github.com/apache/kudu/tree/master/examples/java/java-example">java-example</a> project in
the Kudu source code repository. The Kudu project itself uses the <code class="language-plaintext highlighter-rouge">KuduTestHarness</code> for all of its
own integration tests. For more complex examples, you can explore the various
<a href="https://github.com/apache/kudu/tree/master/java/kudu-client/src/test/java/org/apache/kudu/client">Kudu integration</a>
tests in the Kudu source code repository.</p>
<h2 id="feedback">Feedback</h2>
<p>Kudu 1.9.0 is the first release to have these testing utilities available. Although these utilities
simplify testing of Kudu applications, there is always room for improvement.
Please report any issues, ideas, or feedback to the Kudu user mailing list, Jira, or Slack channel
and we will try to incorporate your feedback quickly. See the
<a href="https://kudu.apache.org/community.html">Kudu community page</a> for details.</p>
<h2 id="thank-you">Thank You</h2>
<p>We would like to give a special thank you to everyone who helped contribute to the <code class="language-plaintext highlighter-rouge">kudu-test-utils</code>
and <code class="language-plaintext highlighter-rouge">kudu-binary</code> artifacts. We would especially like to thank
<a href="https://www.linkedin.com/in/brian-mcdevitt-1136a08/">Brian McDevitt</a> at <a href="https://www.phdata.io/">phData</a>
and
<a href="https://twitter.com/timrobertson100">Tim Robertson</a> at <a href="https://www.gbif.org/">GBIF</a> who helped us
tremendously.</p>
</div>
</article>
</div>
<div class="col-lg-3 recent-posts">
<h3>Recent posts</h3>
<ul>
<li> <a href="/2020/07/30/building-near-real-time-big-data-lake.html">Building Near Real-time Big Data Lake</a> </li>
<li> <a href="/2020/05/18/apache-kudu-1-12-0-release.html">Apache Kudu 1.12.0 released</a> </li>
<li> <a href="/2019/11/20/apache-kudu-1-11-1-release.html">Apache Kudu 1.11.1 released</a> </li>
<li> <a href="/2019/11/20/apache-kudu-1-10-1-release.html">Apache Kudu 1.10.1 released</a> </li>
<li> <a href="/2019/07/09/apache-kudu-1-10-0-release.html">Apache Kudu 1.10.0 Released</a> </li>
<li> <a href="/2019/04/30/location-awareness.html">Location Awareness in Kudu</a> </li>
<li> <a href="/2019/04/22/fine-grained-authorization-with-apache-kudu-and-impala.html">Fine-Grained Authorization with Apache Kudu and Impala</a> </li>
<li> <a href="/2019/03/19/testing-apache-kudu-applications-on-the-jvm.html">Testing Apache Kudu Applications on the JVM</a> </li>
<li> <a href="/2019/03/15/apache-kudu-1-9-0-release.html">Apache Kudu 1.9.0 Released</a> </li>
<li> <a href="/2019/03/05/transparent-hierarchical-storage-management-with-apache-kudu-and-impala.html">Transparent Hierarchical Storage Management with Apache Kudu and Impala</a> </li>
<li> <a href="/2018/12/11/call-for-posts.html">Call for Posts</a> </li>
<li> <a href="/2018/10/26/apache-kudu-1-8-0-released.html">Apache Kudu 1.8.0 Released</a> </li>
<li> <a href="/2018/09/26/index-skip-scan-optimization-in-kudu.html">Index Skip Scan Optimization in Kudu</a> </li>
<li> <a href="/2018/09/11/simplified-pipelines-with-kudu.html">Simplified Data Pipelines with Kudu</a> </li>
<li> <a href="/2018/08/06/getting-started-with-kudu-an-oreilly-title.html">Getting Started with Kudu - an O'Reilly Title</a> </li>
</ul>
</div>
</div>
<footer class="footer">
<div class="row">
<div class="col-md-9">
<p class="small">
Copyright &copy; 2019 The Apache Software Foundation.
</p>
<p class="small">
Apache Kudu, Kudu, Apache, the Apache feather logo, and the Apache Kudu
project logo are either registered trademarks or trademarks of The
Apache Software Foundation in the United States and other countries.
</p>
</div>
<div class="col-md-3">
<a class="pull-right" href="https://www.apache.org/events/current-event.html">
<img src="https://www.apache.org/events/current-event-234x60.png"/>
</a>
</div>
</div>
</footer>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
// Try to detect touch-screen devices. Note: Many laptops have touch screens.
$(document).ready(function() {
if ("ontouchstart" in document.documentElement) {
$(document.documentElement).addClass("touch");
} else {
$(document.documentElement).addClass("no-touch");
}
});
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
crossorigin="anonymous"></script>
<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-68448017-1', 'auto');
ga('send', 'pageview');
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/3.1.0/anchor.js"></script>
<script>
anchors.options = {
placement: 'right',
visible: 'touch',
};
anchors.add();
</script>
</body>
</html>