This is an automated email from the ASF dual-hosted git repository. git-site-role pushed a commit to branch asf-staging in repository https://gitbox.apache.org/repos/asf/accumulo-website.git
The following commit(s) were added to refs/heads/asf-staging by this push: new 4935fed Automatic Site Publish by Buildbot 4935fed is described below commit 4935fed7a581dd65bb6c4e68b53b6ae94f4c524a Author: buildbot <us...@infra.apache.org> AuthorDate: Wed Feb 26 22:25:18 2020 +0000 Automatic Site Publish by Buildbot --- .../blog/2020/02/26/accumulo-spark-connector.html | 433 +++++++++++++ output/css/accumulo.css | 2 + output/css/accumulo.css.map | 4 +- output/feed.xml | 305 ++++++++- output/images/blog/202002_masc/architecture.png | Bin 0 -> 86251 bytes output/images/blog/202002_masc/architecture.svg | 713 +++++++++++++++++++++ output/images/blog/202002_masc/runtime.png | Bin 0 -> 37732 bytes .../blog/202002_masc/sparkml_vs_mleap_accumulo.png | Bin 0 -> 20964 bytes output/index.html | 14 +- output/news/index.html | 13 +- output/search_data.json | 8 + 11 files changed, 1450 insertions(+), 42 deletions(-) diff --git a/output/blog/2020/02/26/accumulo-spark-connector.html b/output/blog/2020/02/26/accumulo-spark-connector.html new file mode 100644 index 0000000..6131c21 --- /dev/null +++ b/output/blog/2020/02/26/accumulo-spark-connector.html @@ -0,0 +1,433 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<meta charset="utf-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/paper/bootstrap.min.css" rel="stylesheet" integrity="sha384-awusxf8AUojygHf2+joICySzB780jVvQaVCAt1clU3QsyAitLGul28Qxb2r1e5g+" crossorigin="anonymous"> +<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs/jq-2.2.3/dt-1.10.12/datatables.min.css"> +<link href="/css/accumulo.css" rel="stylesheet" type="text/css"> + +<title>Microsoft MASC, an Apache Spark connector for Apache Accumulo</title> + +<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script> +<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> +<script type="text/javascript" src="https://cdn.datatables.net/v/bs/jq-2.2.3/dt-1.10.12/datatables.min.js"></script> +<script> + // show location of canonical site if not currently on the canonical site + $(function() { + var host = window.location.host; + if (typeof host !== 'undefined' && host !== 'accumulo.apache.org') { + $('#non-canonical').show(); + } + }); + + $(function() { + // decorate section headers with anchors + return $("h2, h3, h4, h5, h6").each(function(i, el) { + var $el, icon, id; + $el = $(el); + id = $el.attr('id'); + icon = '<i class="fa fa-link"></i>'; + if (id) { + return $el.append($("<a />").addClass("header-link").attr("href", "#" + id).html(icon)); + } + }); + }); + + // fix sidebar width in documentation + $(function() { + var $affixElement = $('div[data-spy="affix"]'); + $affixElement.width($affixElement.parent().width()); + }); +</script> + +</head> +<body style="padding-top: 100px"> + + <nav class="navbar navbar-default navbar-fixed-top"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-items"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a href="/"><img id="nav-logo" alt="Apache Accumulo" class="img-responsive" src="/images/accumulo-logo.png" width="200" + /></a> + </div> + <div class="collapse navbar-collapse" id="navbar-items"> + <ul class="nav navbar-nav"> + <li class="nav-link"><a href="/downloads">Download</a></li> + <li class="nav-link"><a href="/tour">Tour</a></li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Releases<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/release/accumulo-2.0.0/">2.0.0 (Latest)</a></li> + <li><a href="/release/accumulo-1.9.3/">1.9.3</a></li> + <li><a href="/release/">Archive</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Documentation<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/docs/2.x">User Manual (2.x)</a></li> + <li><a href="/docs/2.x/apidocs">Javadocs (2.0)</a></li> + <li><a href="/quickstart-1.x">Quickstart (1.x)</a></li> + <li><a href="/accumulo2-maven-plugin">Accumulo Maven Plugin</a></li> + <li><a href="/1.9/accumulo_user_manual.html">User Manual (1.9)</a></li> + <li><a href="/1.9/apidocs">Javadocs (1.9)</a></li> + <li><a href="/external-docs">External Docs</a></li> + <li><a href="/docs-archive/">Archive</a></li> + </ul> + </li> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#">Community<span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="/contact-us">Contact Us</a></li> + <li><a href="/how-to-contribute">How To Contribute</a></li> + <li><a href="/people">People</a></li> + <li><a href="/related-projects">Related Projects</a></li> + </ul> + </li> + <li class="nav-link"><a href="/search">Search</a></li> + </ul> + <ul class="nav navbar-nav navbar-right"> + <li class="dropdown"> + <a class="dropdown-toggle" data-toggle="dropdown" href="#"><img alt="Apache Software Foundation" src="https://www.apache.org/foundation/press/kit/feather.svg" width="15"/><span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a href="https://www.apache.org">Apache Homepage <i class="fa fa-external-link"></i></a></li> + <li><a href="https://www.apache.org/licenses/">License <i class="fa fa-external-link"></i></a></li> + <li><a href="https://www.apache.org/foundation/sponsorship">Sponsorship <i class="fa fa-external-link"></i></a></li> + <li><a href="https://www.apache.org/security">Security <i class="fa fa-external-link"></i></a></li> + <li><a href="https://www.apache.org/foundation/thanks">Thanks <i class="fa fa-external-link"></i></a></li> + <li><a href="https://www.apache.org/foundation/policies/conduct">Code of Conduct <i class="fa fa-external-link"></i></a></li> + <li><a href="https://www.apache.org/events/current-event.html">Current Event <i class="fa fa-external-link"></i></a></li> + </ul> + </li> + </ul> + </div> + </div> +</nav> + + + <div class="container"> + <div class="row"> + <div class="col-md-12"> + + <div id="non-canonical" style="display: none; background-color: #F0E68C; padding-left: 1em;"> + Visit the official site at: <a href="https://accumulo.apache.org">https://accumulo.apache.org</a> + </div> + <div id="content"> + + <h1 class="title">Microsoft MASC, an Apache Spark connector for Apache Accumulo</h1> + + <p> +<b>Author: </b> Markus Cozowicz, Scott Graham<br> +<b>Date: </b> 26 Feb 2020<br> + +</p> + +<h1 id="overview">Overview</h1> +<p><a href="https://github.com/microsoft/masc">MASC</a> provides an Apache Spark native connector for Apache Accumulo to integrate the rich Spark machine learning eco-system with the scalable and secure data storage capabilities of Accumulo.</p> + +<h2 id="major-features">Major Features</h2> +<ul> + <li>Simplified Spark DataFrame read/write to Accumulo using DataSource v2 API</li> + <li>Speedup of 2-5x over existing approaches for pulling key-value data into DataFrame format</li> + <li>Scala and Python support without overhead for moving between languages</li> + <li>Process streaming data from Accumulo without loading it all into Spark memory</li> + <li>Push down filtering with a flexible expression language (<a href="http://juel.sourceforge.net/">JUEL</a>): user can define logical operators and comparisons to reduce the amount of data returned from Accumulo</li> + <li>Column pruning based on selected fields transparently reduces the amount of data returned from Accumulo</li> + <li>Server side inference: ML model inference can run on the Accumulo nodes using MLeap to increase the scalability of AI solutions as well as keeping data in Accumulo</li> +</ul> + +<h2 id="use-cases">Use-cases</h2> +<p>MASC is advantageous in many use-cases, below we list a few.</p> + +<p><strong>Scenario 1</strong>: A data analyst needs to execute model inference on large amount of data in Accumulo.<br /> +<strong>Benefit</strong>: Instead of transferring all the data to a large Spark cluster to score using a Spark model, the connector exports and runs the model on the Accumulo cluster. This reduces the need for a large Spark cluster as well as the amount of data transferred between systems, and can improve inference speeds (>2x speedups observed).</p> + +<p><strong>Scenario 2</strong>: A data scientist needs to train a Spark model on a large amount of data in Accumulo.<br /> +<strong>Benefit</strong>: Instead of pulling all the data into a large Spark cluster and restructuring the format to use Spark ML Lib tools, the connector streams data into Spark as a DataFrame reducing time to train and Spark cluster size / memory requirements.</p> + +<p><strong>Scenario 3</strong>: A data analyst needs to perform ad hoc analysis on large amounts of data stored in Accumulo.<br /> +<strong>Benefit</strong>: Instead of pulling all the data into a large Spark cluster, the connector prunes rows and columns using pushdown filtering with a flexible expression language.</p> + +<h1 id="architecture">Architecture</h1> +<p>The Accumulo-Spark connector is composed of two components:</p> + +<ul> + <li>Accumulo server-side iterator performs + <ul> + <li>column pruning</li> + <li>row-based filtering</li> + <li><a href="https://github.com/combust/mleap">MLeap</a> ML model inference and</li> + <li>row assembly using <a href="https://avro.apache.org/">Apache AVRO</a></li> + </ul> + </li> + <li>Spark DataSource V2 + <ul> + <li>determines the number of Spark tasks based on available Accumulo table splits</li> + <li>translates Spark filter conditions into a <a href="http://juel.sourceforge.net/">JUEL</a> expression</li> + <li>configures the Accumulo iterator</li> + <li>deserializes the AVRO payload</li> + </ul> + </li> +</ul> + +<p><img src="/images/blog/202002_masc/architecture.svg" alt="Architecture" title="MASC Architecture Diagram" /></p> + +<h1 id="usage">Usage</h1> +<p>More detailed documentation on installation and use is available in the +<a href="https://github.com/microsoft/masc/blob/master/connector/README.md">Connector documentation</a></p> + +<h2 id="dependencies">Dependencies</h2> +<ul> + <li>Java 8</li> + <li>Spark 2.4.3+</li> + <li>Accumulo 2.0.0+</li> +</ul> + +<p>JARs available on Maven Central Repository:</p> +<ul> + <li> + <p><a href="https://search.maven.org/search?q=g:%22com.microsoft.masc%22%20AND%20a:%22microsoft-accumulo-spark-datasource%22"><img src="https://img.shields.io/maven-central/v/com.microsoft.masc/microsoft-accumulo-spark-datasource.svg?label=Maven%20Central" alt="Maven Central" /> Spark DataSource</a></p> + </li> + <li> + <p><a href="https://search.maven.org/search?q=g:%22com.microsoft.masc%22%20AND%20a:%22microsoft-accumulo-spark-iterator%22"><img src="https://img.shields.io/maven-central/v/com.microsoft.masc/microsoft-accumulo-spark-iterator.svg?label=Maven%20Central" alt="Maven Central" /> Accumulo Iterator</a> - Backend for Spark DataSource</p> + </li> +</ul> + +<h2 id="example-use">Example use</h2> +<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">configparser</span> <span class="kn">import</span> <span class="n">ConfigParser</span> +<span class="kn">from</span> <span class="nn">pyspark.sql</span> <span class="kn">import</span> <span class="n">types</span> <span class="k">as</span> <span class="n">T</span> + +<span class="k">def</span> <span class="nf">get_properties</span><span class="p">(</span><span class="n">properties_file</span><span class="p">):</span> + <span class="s">"""Read Accumulo client properties file"""</span> + <span class="n">config</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="p">()</span> + <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">properties_file</span><span class="p">)</span> <span class="k">as</span> <span class="n">stream</span><span class="p">:</span> + <span class="n">config</span><span class="o">.</span><span class="n">read_string</span><span class="p">(</span><span class="s">"[top]</span><span class="se">\n</span><span class="s">"</span> <span class="o">+</span> <span class="n">stream</span><span class="o">.</span><span class="n">read</span><span class="p">())</span> + <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">config</span><span class="p">[</span><span class="s">'top'</span><span class="p">])</span> + +<span class="n">properties</span> <span class="o">=</span> <span class="n">get_properties</span><span class="p">(</span><span class="s">'/opt/muchos/install/accumulo-2.0.0/conf/accumulo-client.properties'</span><span class="p">)</span> +<span class="n">properties</span><span class="p">[</span><span class="s">'table'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'demo_table'</span> <span class="c1"># Define Accumulo table where data will be written +</span><span class="n">properties</span><span class="p">[</span><span class="s">'rowkey'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'id'</span> <span class="c1"># Identify column to use as the key for Accumulo rows +</span> +<span class="c1"># define the schema +</span><span class="n">schema</span> <span class="o">=</span> <span class="n">T</span><span class="o">.</span><span class="n">StructType</span><span class="p">([</span> + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"sentiment"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">IntegerType</span><span class="p">(),</span> <span class="bp">True</span><span class="p">),</span> + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"date"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">(),</span> <span class="bp">True</span><span class="p">),</span> + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"query_string"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">(),</span> <span class="bp">True</span><span class="p">),</span> + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"user"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">(),</span> <span class="bp">True</span><span class="p">),</span> + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"text"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">(),</span> <span class="bp">True</span><span class="p">)</span> +<span class="p">])</span> + +<span class="c1"># Read from Accumulo +</span><span class="n">df</span> <span class="o">=</span> <span class="p">(</span><span class="n">spark</span> + <span class="o">.</span><span class="n">read</span> + <span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="s">"com.microsoft.accumulo"</span><span class="p">)</span> + <span class="o">.</span><span class="n">options</span><span class="p">(</span><span class="o">**</span><span class="n">options</span><span class="p">)</span> <span class="c1"># define Accumulo properties +</span> <span class="o">.</span><span class="n">schema</span><span class="p">(</span><span class="n">schema</span><span class="p">))</span> <span class="c1"># define schema for data retrieval +</span> +<span class="c1"># Write to Accumulo +</span><span class="n">properties</span><span class="p">[</span><span class="s">'table'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'output_table'</span> + +<span class="p">(</span><span class="n">df</span> + <span class="o">.</span><span class="n">write</span> + <span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="s">"com.microsoft.accumulo"</span><span class="p">)</span> + <span class="o">.</span><span class="n">options</span><span class="p">(</span><span class="o">**</span><span class="n">options</span><span class="p">)</span> + <span class="o">.</span><span class="n">save</span><span class="p">())</span> +</code></pre></div></div> + +<p>See the <a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnector.ipynb">demo notebook</a> for more examples.</p> + +<h1 id="computational-performance-of-ai-scenario">Computational Performance of AI Scenario</h1> +<h2 id="setup">Setup</h2> +<p>The benchmark setup used a 1,000-node Accumulo 2.0.0 Cluster (16,000 cores) running and a 256-node Spark 2.4.3 cluster (4,096 cores). All nodes used <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sizes-general">Azure D16s_v3</a> (16 cores) virtual machines. <a href="https://github.com/apache/fluo-muchos">Fluo-muchos</a> was used to handle Accumulo and Spark cluster deployments and configuration.</p> + +<p>In all experiments we use the same base dataset which is a collection of Twitter user tweets with labeled sentiment value. This dataset is known as the Sentiment140 dataset (<a href="http://www-nlp.stanford.edu/courses/cs224n/2009/fp/3.pdf">Go, Bhayani, & Huang, 2009</a>). The training data consist of 1.6M samples of tweets, where each tweet has columns indicating the sentiment label, user, timestamp, query term, and text. The text is limited to 140 characters and the overall unco [...] + +<table> + <thead> + <tr> + <th>sentiment</th> + <th>id</th> + <th>date</th> + <th>query_string</th> + <th>user</th> + <th>text</th> + </tr> + </thead> + <tbody> + <tr> + <td>0</td> + <td>1467810369</td> + <td>Mon Apr 06 22:19:…</td> + <td>NO_QUERY</td> + <td><em>TheSpecialOne</em></td> + <td>@switchfoot http:…</td> + </tr> + <tr> + <td>0</td> + <td>1467810672</td> + <td>Mon Apr 06 22:19:…</td> + <td>NO_QUERY</td> + <td>scotthamilton</td> + <td>is upset that he …</td> + </tr> + <tr> + <td>0</td> + <td>1467810917</td> + <td>Mon Apr 06 22:19:…</td> + <td>NO_QUERY</td> + <td>mattycus</td> + <td>@Kenichan I dived…</td> + </tr> + </tbody> +</table> + +<p>To evaluate different table sizes and the impact of splitting the following procedure was used to generate the Accumulo tables:</p> + +<ul> + <li>Prefix id with split keys (e.g. 0000, 0001, …, 1024)</li> + <li>Create Accumulo table and configure splits</li> + <li>Upload prefixed data to Accumulo using Spark and the MASC writer</li> + <li>Duplicate data using custom Accumulo server-side iterator</li> + <li>Validate data partitioning</li> +</ul> + +<p>A common machine learning scenario was evaluated using a sentiment model trained using <a href="https://spark.apache.org/docs/latest/ml-guide.html">SparkML</a>. +To train the classification model, we generated feature vectors from the text of tweets (text column). We used a feature engineering pipeline (a.k.a. featurizer) that breaks the text into tokens, splitting on whitespaces and discarding any capitalization and non-alphabetical characters. The pipeline consisted of</p> + +<ul> + <li>Regex Tokenizer</li> + <li>Hashing Transformer</li> + <li>Logistic Regression</li> +</ul> + +<p>See the <a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnectorBenchmark.ipynb">benchmark notebook (Scala)</a> for more details.</p> + +<h2 id="results">Results</h2> +<p>The first set of experiments evaluated data transfer efficiency and ML model inference performance. The chart below shows</p> + +<ul> + <li>Accumulo table split size (1GB, 8GB, 32GB, 64GB)</li> + <li>Total table size (1TB, 10TB, 100TB, 1PB)</li> + <li>Operations + <ul> + <li>Count: plain count of the data</li> + <li>Inference: Accumulo server-side inference using MLeap</li> + <li>Transfer: Filtering results for 30% data transfer</li> + </ul> + </li> + <li>Time is reported in minutes</li> +</ul> + +<p>Remarks</p> +<ul> + <li>Time is log-scale</li> + <li>Inference was run with and without data transfer to isolate server-side performance.</li> + <li>The smaller each Accumulo table split is, the more splits we have and thus higher parallelization.</li> +</ul> + +<p><img src="/images/blog/202002_masc/runtime.png" alt="Runtime" title="Runtime Performance" class="blog-img-center" /></p> + +<p>The second set of experiments highlights the computational performance improvement of using the server-side inference approach compared to running inference on the Spark cluster.</p> + +<p><img src="/images/blog/202002_masc/sparkml_vs_mleap_accumulo.png" alt="Mleap" title="Spark ML vs MLeap Performance" class="blog-img-center" /></p> + +<h1 id="learnings">Learnings</h1> +<ul> + <li>Accumulo MLeap Server-side inference vs Spark ML results in a 2x improvement</li> + <li>Multi-threading in Spark jobs can be used to fully utilize Accumulo servers + <ul> + <li>Useful if less Spark cluster has less cores than Accumulo</li> + <li>e.g. 8 threads * 2,048 Spark executor = 16,384 Accumulo threads</li> + </ul> + </li> + <li>Unbalanced Accumulo table splits can introduce performance bottlenecks</li> +</ul> + +<h1 id="useful-links">Useful links</h1> +<ul> + <li><a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnector.ipynb">Complete Jupyter demo notebook (PySpark)</a> for usage of the Accumulo-Spark connector</li> + <li><a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnectorBenchmark.ipynb">Complete Jupyter benchmark notebook (Scala)</a> for usage of the Accumulo-Spark connector</li> + <li>GitHub Repository <a href="https://github.com/microsoft/masc">Microsoft’s contributions for Spark with Apache Accumulo</a></li> + <li><a href="https://github.com/combust/mleap">MLeap</a> - Scala/Java stand-alone model inference for SparkML-based models</li> + <li><a href="https://spark.apache.org/docs/latest/ml-guide.html">SparkML</a> - Spark machine learning library</li> + <li>MASC Maven artifacts + <ul> + <li><a href="https://mvnrepository.com/artifact/com.microsoft.masc/microsoft-accumulo-spark-iterator">Accumulo Iterator - Backend for Spark DataSource</a></li> + <li><a href="https://mvnrepository.com/artifact/com.microsoft.masc/microsoft-accumulo-spark-datasource">Spark DataSource</a></li> + </ul> + </li> +</ul> + +<h1 id="license">License</h1> +<p>This work is publicly available under the Apache License 2.0 on GitHub under <a href="https://github.com/microsoft/masc">Microsoft’s contributions for Apache Spark with Apache Accumulo</a>.</p> + +<h1 id="contributions">Contributions</h1> +<p>Feedback, questions, and contributions are welcome!</p> + +<p>Thanks to contributions from members on the Azure Global Customer Engineering and Azure Government teams.</p> + +<ul> + <li><a href="https://github.com/AnupamMicrosoft">Anupam Sharma</a></li> + <li><a href="https://github.com/arvindshmicrosoft">Arvind Shyamsundar</a></li> + <li><a href="https://github.com/billierinaldi">Billie Rinaldi</a></li> + <li><a href="https://github.com/chenhuims">Chenhui Hu</a></li> + <li><a href="https://github.com/loomlike">Jun-Ki Min</a></li> + <li><a href="https://github.com/phrocker">Marc Parisi</a></li> + <li><a href="https://github.com/eisber">Markus Cozowicz</a></li> + <li>Pavandeep Kalra</li> + <li><a href="https://github.com/roalexan">Robert Alexander</a></li> + <li><a href="https://github.com/gramhagen">Scott Graham</a></li> + <li><a href="https://github.com/wutaomsft">Tao Wu</a></li> +</ul> + +<p>Special thanks to <a href="https://github.com/ancasarb">Anca Sarb</a> for promptly assisting with <a href="https://github.com/combust/mleap/issues/633">MLeap performance issues</a>.</p> + + +<p><strong>View all posts in the <a href="/news">news archive</a></strong></p> + + </div> + + +<footer> + + <p><a href="https://www.apache.org/foundation/contributing"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support the ASF" id="asf-logo" height="100" /></a></p> + + <p>Copyright © 2011-2020 <a href="https://www.apache.org">The Apache Software Foundation</a>. +Licensed under the <a href="https://www.apache.org/licenses/">Apache License, Version 2.0</a>.</p> + + <p>Apache®, the names of Apache projects and their logos, and the multicolor feather +logo are registered trademarks or trademarks of The Apache Software Foundation +in the United States and/or other countries.</p> + +</footer> + + + </div> + </div> + </div> +</body> +</html> diff --git a/output/css/accumulo.css b/output/css/accumulo.css index 67751ee..0197723 100644 --- a/output/css/accumulo.css +++ b/output/css/accumulo.css @@ -284,4 +284,6 @@ a.prop { display: block; content: " "; margin-top: -90px; height: 90px; visibili .navbar-collapse.collapse.in { display: block !important; } .collapsing { overflow: hidden !important; } } +.blog-img-center { max-width: 95%; margin-top: 10px; margin-bottom: 10px; margin-left: auto; margin-right: auto; display: block; } + /*# sourceMappingURL=accumulo.css.map */ \ No newline at end of file diff --git a/output/css/accumulo.css.map b/output/css/accumulo.css.map index 0a8c603..32bd782 100644 --- a/output/css/accumulo.css.map +++ b/output/css/accumulo.css.map @@ -6,9 +6,9 @@ "_sass/_syntax-highlighting.scss" ], "sourcesContent": [ - "@import \"syntax-highlighting\";\n\ntable {\n margin: 10px 0px 30px 0px;\n padding: 10px 5px 10px 5px;\n}\n\nth, td {\n padding: 10px 40px 10px 5px;\n border-bottom: 1px solid #ddd;\n}\n\nh1 {\n font-size: 34px;\n}\n\nh2 {\n font-size: 28px;\n}\n\nh3 {\n font-size: 22px;\n}\n\nh4 {\n font-size: 18px;\n}\n\nh5 {\n font-size: 16px;\n}\n\nh6 {\n font-size: 15px;\n}\n\nbody { \n font-size: 14px;\n}\n\npre code {\n font-size: 14px;\n}\n\ncode {\n background-color: #f5f5f5;\n c [...] + "@import \"syntax-highlighting\";\n\ntable {\n margin: 10px 0px 30px 0px;\n padding: 10px 5px 10px 5px;\n}\n\nth, td {\n padding: 10px 40px 10px 5px;\n border-bottom: 1px solid #ddd;\n}\n\nh1 {\n font-size: 34px;\n}\n\nh2 {\n font-size: 28px;\n}\n\nh3 {\n font-size: 22px;\n}\n\nh4 {\n font-size: 18px;\n}\n\nh5 {\n font-size: 16px;\n}\n\nh6 {\n font-size: 15px;\n}\n\nbody { \n font-size: 14px;\n}\n\npre code {\n font-size: 14px;\n}\n\ncode {\n background-color: #f5f5f5;\n c [...] ".highlight .hll { background-color: #d6d6d6 }\n.highlight { background: #f5f5f5; color: #4d4d4c }\n.highlight .c { color: #8e908c } /* Comment */\n.highlight .err { color: #c82829 } /* Error */\n.highlight .k { color: #8959a8 } /* Keyword */\n.highlight .l { color: #f5871f } /* Literal */\n.highlight .n { color: #4d4d4c } /* Name */\n.highlight .o { color: #3e999f } /* Operator */\n.highlight .p { color: #4d4d4c } /* Punctuation */\n.highlight .cm { color: #8e908c } /* Comment.Multil [...] ], "names": [], - "mappings": "ACAA,AAAA,UAAU,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,OAAQ,GAAE;;AAC9C,AAAA,UAAU,CAAE,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,OAAQ,GAAE;;AACpD,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,aAAa;AAC9C,AAAA,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,WAAW;AAC9C,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,aAAa;AAC9C,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,aAAa;AAC9C,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,UAAU;AAC3C,AAAA,UAAU,CA [...] + "mappings": "ACAA,AAAA,UAAU,CAAC,IAAI,CAAC,EAAE,gBAAgB,EAAE,OAAQ,GAAE;;AAC9C,AAAA,UAAU,CAAE,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,OAAQ,GAAE;;AACpD,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,aAAa;AAC9C,AAAA,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,WAAW;AAC9C,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,aAAa;AAC9C,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,aAAa;AAC9C,AAAA,UAAU,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAQ,GAAE;;AAAA,UAAU;AAC3C,AAAA,UAAU,CA [...] } \ No newline at end of file diff --git a/output/feed.xml b/output/feed.xml index 4c61e58..0784d48 100644 --- a/output/feed.xml +++ b/output/feed.xml @@ -6,12 +6,283 @@ </description> <link>https://accumulo.apache.org/</link> <atom:link href="https://accumulo.apache.org/feed.xml" rel="self" type="application/rss+xml"/> - <pubDate>Tue, 18 Feb 2020 17:14:36 +0000</pubDate> - <lastBuildDate>Tue, 18 Feb 2020 17:14:36 +0000</lastBuildDate> + <pubDate>Wed, 26 Feb 2020 22:25:12 +0000</pubDate> + <lastBuildDate>Wed, 26 Feb 2020 22:25:12 +0000</lastBuildDate> <generator>Jekyll v4.0.0</generator> <item> + <title>Microsoft MASC, an Apache Spark connector for Apache Accumulo</title> + <description><h1 id="overview">Overview</h1> +<p><a href="https://github.com/microsoft/masc">MASC</a> provides an Apache Spark native connector for Apache Accumulo to integrate the rich Spark machine learning eco-system with the scalable and secure data storage capabilities of Accumulo.</p> + +<h2 id="major-features">Major Features</h2> +<ul> + <li>Simplified Spark DataFrame read/write to Accumulo using DataSource v2 API</li> + <li>Speedup of 2-5x over existing approaches for pulling key-value data into DataFrame format</li> + <li>Scala and Python support without overhead for moving between languages</li> + <li>Process streaming data from Accumulo without loading it all into Spark memory</li> + <li>Push down filtering with a flexible expression language (<a href="http://juel.sourceforge.net/">JUEL</a>): user can define logical operators and comparisons to reduce the amount of data returned from Accumulo</li> + <li>Column pruning based on selected fields transparently reduces the amount of data returned from Accumulo</li> + <li>Server side inference: ML model inference can run on the Accumulo nodes using MLeap to increase the scalability of AI solutions as well as keeping data in Accumulo</li> +</ul> + +<h2 id="use-cases">Use-cases</h2> +<p>MASC is advantageous in many use-cases, below we list a few.</p> + +<p><strong>Scenario 1</strong>: A data analyst needs to execute model inference on large amount of data in Accumulo.<br /> +<strong>Benefit</strong>: Instead of transferring all the data to a large Spark cluster to score using a Spark model, the connector exports and runs the model on the Accumulo cluster. This reduces the need for a large Spark cluster as well as the amount of data transferred between systems, and can improve inference speeds (&gt;2x speedups observed).</p> + +<p><strong>Scenario 2</strong>: A data scientist needs to train a Spark model on a large amount of data in Accumulo.<br /> +<strong>Benefit</strong>: Instead of pulling all the data into a large Spark cluster and restructuring the format to use Spark ML Lib tools, the connector streams data into Spark as a DataFrame reducing time to train and Spark cluster size / memory requirements.</p> + +<p><strong>Scenario 3</strong>: A data analyst needs to perform ad hoc analysis on large amounts of data stored in Accumulo.<br /> +<strong>Benefit</strong>: Instead of pulling all the data into a large Spark cluster, the connector prunes rows and columns using pushdown filtering with a flexible expression language.</p> + +<h1 id="architecture">Architecture</h1> +<p>The Accumulo-Spark connector is composed of two components:</p> + +<ul> + <li>Accumulo server-side iterator performs + <ul> + <li>column pruning</li> + <li>row-based filtering</li> + <li><a href="https://github.com/combust/mleap">MLeap</a> ML model inference and</li> + <li>row assembly using <a href="https://avro.apache.org/">Apache AVRO</a></li> + </ul> + </li> + <li>Spark DataSource V2 + <ul> + <li>determines the number of Spark tasks based on available Accumulo table splits</li> + <li>translates Spark filter conditions into a <a href="http://juel.sourceforge.net/">JUEL</a> expression</li> + <li>configures the Accumulo iterator</li> + <li>deserializes the AVRO payload</li> + </ul> + </li> +</ul> + +<p><img src="/images/blog/202002_masc/architecture.svg" alt="Architecture" title="MASC Architecture Diagram" /></p> + +<h1 id="usage">Usage</h1> +<p>More detailed documentation on installation and use is available in the +<a href="https://github.com/microsoft/masc/blob/master/connector/README.md">Connector documentation</a></p> + +<h2 id="dependencies">Dependencies</h2> +<ul> + <li>Java 8</li> + <li>Spark 2.4.3+</li> + <li>Accumulo 2.0.0+</li> +</ul> + +<p>JARs available on Maven Central Repository:</p> +<ul> + <li> + <p><a href="https://search.maven.org/search?q=g:%22com.microsoft.masc%22%20AND%20a:%22microsoft-accumulo-spark-datasource%22"><img src="https://img.shields.io/maven-central/v/com.microsoft.masc/microsoft-accumulo-spark-datasource.svg?label=Maven%20Central" alt="Maven Central" /> Spark DataSource</a></p> + </li> + <li> + <p><a href="https://search.maven.org/search?q=g:%22com.microsoft.masc%22%20AND%20a:%22microsoft-accumulo-spark-iterator%22"><img src="https://img.shields.io/maven-central/v/com.microsoft.masc/microsoft-accumulo-spark-iterator.svg?label=Maven%20Central" alt="Maven Central" /> Accumulo Iterator</a> - Backend for Spark DataSource</p> + </li> +</ul> + +<h2 id="example-use">Example use</h2> +<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">configparser</span> <span class="kn">import</span> <span class="n">ConfigParser</span> +<span class="kn">from</span> <span class="nn">pyspark.sql</span> <span class="kn">import</span> <span class="n">types</span> <span class="k">as</span> <span class="n">T</span> + +<span class="k">def</span> <span class="nf">get_properties</span><span class="p">(</span><span class="n">properties_file</span><span class="p">):</span> + <span class="s">"""Read Accumulo client properties file"""</span> + <span class="n">config</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="p">()</span> + <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">properties_file</span><span class="p">)</span> <span class="k">as</span> <span class="n">stream</span><span class="p">:</span> + <span class="n">config</span><span class="o">.</span><span class="n">read_string</span><span class="p">(</span><span class="s">"[top]</span><span class="se">\n</span><span class="s">"</span> <span class="o">+</span> <span class="n">stream</span><span class="o"> [...] + <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">config</span><span class="p">[</span><span class="s">'top'</span><span class="p">])</span> + +<span class="n">properties</span> <span class="o">=</span> <span class="n">get_properties</span><span class="p">(</span><span class="s">'/opt/muchos/install/accumulo-2.0.0/conf/accumulo-client.properties'</span><span class="p">)</span> +<span class="n">properties</span><span class="p">[</span><span class="s">'table'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'demo_table'</span> <span class="c1"># Define Accumulo table where data will be written +</span><span class="n">properties</span><span class="p">[</span><span class="s">'rowkey'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'id'</span> <span class="c1"># Identify column to use as the key for Accumulo rows +</span> +<span class="c1"># define the schema +</span><span class="n">schema</span> <span class="o">=</span> <span class="n">T</span><span class="o">.</span><span class="n">StructType</span><span class="p">([</span> + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"sentiment"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">IntegerType</span><span class="p">(), [...] + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"date"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">(),</s [...] + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"query_string"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">( [...] + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"user"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">(),</s [...] + <span class="n">T</span><span class="o">.</span><span class="n">StructField</span><span class="p">(</span><span class="s">"text"</span><span class="p">,</span> <span class="n">T</span><span class="o">.</span><span class="n">StringType</span><span class="p">(),</s [...] +<span class="p">])</span> + +<span class="c1"># Read from Accumulo +</span><span class="n">df</span> <span class="o">=</span> <span class="p">(</span><span class="n">spark</span> + <span class="o">.</span><span class="n">read</span> + <span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="s">"com.microsoft.accumulo"</span><span class="p">)</span> + <span class="o">.</span><span class="n">options</span><span class="p">(</span><span class="o">**</span><span class="n">options</span><span class="p">)</span> <span class="c1"># define Accumulo properties +</span> <span class="o">.</span><span class="n">schema</span><span class="p">(</span><span class="n">schema</span><span class="p">))</span> <span class="c1"># define schema for data retrieval +</span> +<span class="c1"># Write to Accumulo +</span><span class="n">properties</span><span class="p">[</span><span class="s">'table'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'output_table'</span> + +<span class="p">(</span><span class="n">df</span> + <span class="o">.</span><span class="n">write</span> + <span class="o">.</span><span class="nb">format</span><span class="p">(</span><span class="s">"com.microsoft.accumulo"</span><span class="p">)</span> + <span class="o">.</span><span class="n">options</span><span class="p">(</span><span class="o">**</span><span class="n">options</span><span class="p">)</span> + <span class="o">.</span><span class="n">save</span><span class="p">())</span> +</code></pre></div></div> + +<p>See the <a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnector.ipynb">demo notebook</a> for more examples.</p> + +<h1 id="computational-performance-of-ai-scenario">Computational Performance of AI Scenario</h1> +<h2 id="setup">Setup</h2> +<p>The benchmark setup used a 1,000-node Accumulo 2.0.0 Cluster (16,000 cores) running and a 256-node Spark 2.4.3 cluster (4,096 cores). All nodes used <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sizes-general">Azure D16s_v3</a> (16 cores) virtual machines. <a href="https://github.com/apache/fluo-muchos">Fluo-muchos</a> was used to handle Accumulo and Spark cluster deployments and configuration.</p> + +<p>In all experiments we use the same base dataset which is a collection of Twitter user tweets with labeled sentiment value. This dataset is known as the Sentiment140 dataset (<a href="http://www-nlp.stanford.edu/courses/cs224n/2009/fp/3.pdf">Go, Bhayani, &amp; Huang, 2009</a>). The training data consist of 1.6M samples of tweets, where each tweet has columns indicating the sentiment label, user, timestamp, query term, and text. The text is limited to 140 [...] + +<table> + <thead> + <tr> + <th>sentiment</th> + <th>id</th> + <th>date</th> + <th>query_string</th> + <th>user</th> + <th>text</th> + </tr> + </thead> + <tbody> + <tr> + <td>0</td> + <td>1467810369</td> + <td>Mon Apr 06 22:19:…</td> + <td>NO_QUERY</td> + <td><em>TheSpecialOne</em></td> + <td>@switchfoot http:…</td> + </tr> + <tr> + <td>0</td> + <td>1467810672</td> + <td>Mon Apr 06 22:19:…</td> + <td>NO_QUERY</td> + <td>scotthamilton</td> + <td>is upset that he …</td> + </tr> + <tr> + <td>0</td> + <td>1467810917</td> + <td>Mon Apr 06 22:19:…</td> + <td>NO_QUERY</td> + <td>mattycus</td> + <td>@Kenichan I dived…</td> + </tr> + </tbody> +</table> + +<p>To evaluate different table sizes and the impact of splitting the following procedure was used to generate the Accumulo tables:</p> + +<ul> + <li>Prefix id with split keys (e.g. 0000, 0001, …, 1024)</li> + <li>Create Accumulo table and configure splits</li> + <li>Upload prefixed data to Accumulo using Spark and the MASC writer</li> + <li>Duplicate data using custom Accumulo server-side iterator</li> + <li>Validate data partitioning</li> +</ul> + +<p>A common machine learning scenario was evaluated using a sentiment model trained using <a href="https://spark.apache.org/docs/latest/ml-guide.html">SparkML</a>. +To train the classification model, we generated feature vectors from the text of tweets (text column). We used a feature engineering pipeline (a.k.a. featurizer) that breaks the text into tokens, splitting on whitespaces and discarding any capitalization and non-alphabetical characters. The pipeline consisted of</p> + +<ul> + <li>Regex Tokenizer</li> + <li>Hashing Transformer</li> + <li>Logistic Regression</li> +</ul> + +<p>See the <a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnectorBenchmark.ipynb">benchmark notebook (Scala)</a> for more details.</p> + +<h2 id="results">Results</h2> +<p>The first set of experiments evaluated data transfer efficiency and ML model inference performance. The chart below shows</p> + +<ul> + <li>Accumulo table split size (1GB, 8GB, 32GB, 64GB)</li> + <li>Total table size (1TB, 10TB, 100TB, 1PB)</li> + <li>Operations + <ul> + <li>Count: plain count of the data</li> + <li>Inference: Accumulo server-side inference using MLeap</li> + <li>Transfer: Filtering results for 30% data transfer</li> + </ul> + </li> + <li>Time is reported in minutes</li> +</ul> + +<p>Remarks</p> +<ul> + <li>Time is log-scale</li> + <li>Inference was run with and without data transfer to isolate server-side performance.</li> + <li>The smaller each Accumulo table split is, the more splits we have and thus higher parallelization.</li> +</ul> + +<p><img src="/images/blog/202002_masc/runtime.png" alt="Runtime" title="Runtime Performance" class="blog-img-center" /></p> + +<p>The second set of experiments highlights the computational performance improvement of using the server-side inference approach compared to running inference on the Spark cluster.</p> + +<p><img src="/images/blog/202002_masc/sparkml_vs_mleap_accumulo.png" alt="Mleap" title="Spark ML vs MLeap Performance" class="blog-img-center" /></p> + +<h1 id="learnings">Learnings</h1> +<ul> + <li>Accumulo MLeap Server-side inference vs Spark ML results in a 2x improvement</li> + <li>Multi-threading in Spark jobs can be used to fully utilize Accumulo servers + <ul> + <li>Useful if less Spark cluster has less cores than Accumulo</li> + <li>e.g. 8 threads * 2,048 Spark executor = 16,384 Accumulo threads</li> + </ul> + </li> + <li>Unbalanced Accumulo table splits can introduce performance bottlenecks</li> +</ul> + +<h1 id="useful-links">Useful links</h1> +<ul> + <li><a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnector.ipynb">Complete Jupyter demo notebook (PySpark)</a> for usage of the Accumulo-Spark connector</li> + <li><a href="https://github.com/microsoft/masc/blob/master/connector/examples/AccumuloSparkConnectorBenchmark.ipynb">Complete Jupyter benchmark notebook (Scala)</a> for usage of the Accumulo-Spark connector</li> + <li>GitHub Repository <a href="https://github.com/microsoft/masc">Microsoft’s contributions for Spark with Apache Accumulo</a></li> + <li><a href="https://github.com/combust/mleap">MLeap</a> - Scala/Java stand-alone model inference for SparkML-based models</li> + <li><a href="https://spark.apache.org/docs/latest/ml-guide.html">SparkML</a> - Spark machine learning library</li> + <li>MASC Maven artifacts + <ul> + <li><a href="https://mvnrepository.com/artifact/com.microsoft.masc/microsoft-accumulo-spark-iterator">Accumulo Iterator - Backend for Spark DataSource</a></li> + <li><a href="https://mvnrepository.com/artifact/com.microsoft.masc/microsoft-accumulo-spark-datasource">Spark DataSource</a></li> + </ul> + </li> +</ul> + +<h1 id="license">License</h1> +<p>This work is publicly available under the Apache License 2.0 on GitHub under <a href="https://github.com/microsoft/masc">Microsoft’s contributions for Apache Spark with Apache Accumulo</a>.</p> + +<h1 id="contributions">Contributions</h1> +<p>Feedback, questions, and contributions are welcome!</p> + +<p>Thanks to contributions from members on the Azure Global Customer Engineering and Azure Government teams.</p> + +<ul> + <li><a href="https://github.com/AnupamMicrosoft">Anupam Sharma</a></li> + <li><a href="https://github.com/arvindshmicrosoft">Arvind Shyamsundar</a></li> + <li><a href="https://github.com/billierinaldi">Billie Rinaldi</a></li> + <li><a href="https://github.com/chenhuims">Chenhui Hu</a></li> + <li><a href="https://github.com/loomlike">Jun-Ki Min</a></li> + <li><a href="https://github.com/phrocker">Marc Parisi</a></li> + <li><a href="https://github.com/eisber">Markus Cozowicz</a></li> + <li>Pavandeep Kalra</li> + <li><a href="https://github.com/roalexan">Robert Alexander</a></li> + <li><a href="https://github.com/gramhagen">Scott Graham</a></li> + <li><a href="https://github.com/wutaomsft">Tao Wu</a></li> +</ul> + +<p>Special thanks to <a href="https://github.com/ancasarb">Anca Sarb</a> for promptly assisting with <a href="https://github.com/combust/mleap/issues/633">MLeap performance issues</a>.</p> +</description> + <pubDate>Wed, 26 Feb 2020 00:00:00 +0000</pubDate> + <link>https://accumulo.apache.org/blog/2020/02/26/accumulo-spark-connector.html</link> + <guid isPermaLink="true">https://accumulo.apache.org/blog/2020/02/26/accumulo-spark-connector.html</guid> + + + <category>blog</category> + + </item> + + <item> <title>Accumulo Clients in Other Programming Languages</title> <description><p>Apache Accumulo has an <a href="https://github.com/apache/accumulo-proxy">Accumulo Proxy</a> that allows communication with Accumulo using clients written in languages other than Java. This blog post shows how to run the Accumulo Proxy process using <a href="https://github.com/apache/fluo-uno">Uno</a> @@ -1317,35 +1588,5 @@ address thrift CVE. Issue <a href="https://github.com/apache/accumulo/is </item> - <item> - <title>NoSQL Day 2019</title> - <description><p>On May 21st in Washington, DC, there will be a one-day community event for Apache Accumulo, -HBase, and Phoenix called <a href="https://dataworkssummit.com/nosql-day-2019/">NoSQL Day</a>. We hope that these three Apache communities can come together to share -stories from the field and learn from one another. This event is being offered by the -DataWorks Summit organization, prior to their DataWorks Summit event May 20th through 23rd.</p> - -<p>At this time, we are looking for speakers, attendees, and sponsors for the event. For -speakers, we hope to see a wide breadth of subjects and focus, anything from performance, -scaling, real-life applications, dev-ops, or best-practices. All speakers are welcome! -Abstracts can be submitted <a href="https://dataworkssummit.com/abstracts/">here</a>.</p> - -<p>For attendees, we want to get the best and brightest from each of the respective communities -because the organizers believe we have much to learn from from each other. We’ve tried to -keep costs down to make this approachable for all.</p> - -<p>Finally, sponsors are the major enabler to provide events like these at low-costs -to attendees. If you are interested in a corporate sponsorship, please feel free to contact -<a href="mailto:els...@apache.org">Josh Elser</a> for more information.</p> - -</description> - <pubDate>Thu, 28 Feb 2019 00:00:00 +0000</pubDate> - <link>https://accumulo.apache.org/blog/2019/02/28/nosql-day.html</link> - <guid isPermaLink="true">https://accumulo.apache.org/blog/2019/02/28/nosql-day.html</guid> - - - <category>blog</category> - - </item> - </channel> </rss> diff --git a/output/images/blog/202002_masc/architecture.png b/output/images/blog/202002_masc/architecture.png new file mode 100644 index 0000000..89718e2 Binary files /dev/null and b/output/images/blog/202002_masc/architecture.png differ diff --git a/output/images/blog/202002_masc/architecture.svg b/output/images/blog/202002_masc/architecture.svg new file mode 100644 index 0000000..80c347f --- /dev/null +++ b/output/images/blog/202002_masc/architecture.svg @@ -0,0 +1,713 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Generated by Microsoft Visio, SVG Export architecture.svg Page-1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" + xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.69012in" height="8.85433in" + viewBox="0 0 409.689 637.512" xml:space="preserve" color-interpolation-filters="sRGB" class="st12"> + <v:documentProperties v:langID="1033" v:viewMarkup="false"/> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:#4672c4;stroke-width:0.75} + .st2 {fill:none;stroke:none;stroke-width:0.25} + .st3 {fill:#ffffff;stroke:#70ad47;stroke-width:0.75} + .st4 {fill:#70ad47;font-family:Calibri;font-size:1.00001em} + .st5 {fill:#ffffff;stroke:#ed7d31;stroke-width:0.75} + .st6 {fill:#ed7d31;font-family:Calibri;font-size:1.00001em} + .st7 {fill:#4672c4;font-family:Calibri;font-size:1.00001em} + .st8 {font-size:1em} + .st9 {marker-end:url(#mrkr4-35);stroke:#4672c4;stroke-linecap:round;stroke-linejoin:round;stroke-width:1} + .st10 {fill:#4672c4;fill-opacity:1;stroke:#4672c4;stroke-opacity:1;stroke-width:0.28409090909091} + .st11 {fill:none;stroke:#b5c6e7;stroke-dasharray:5.25,3.75;stroke-width:0.75} + .st12 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <defs id="Markers"> + <g id="lend4"> + <path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"/> + </g> + <marker id="mrkr4-35" class="st10" v:arrowType="4" v:arrowSize="2" v:setback="7.04" refX="-7.04" orient="auto" + markerUnits="strokeWidth" overflow="visible"> + <use xlink:href="#lend4" transform="scale(-3.52,-3.52) "/> + </marker> + </defs> + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Page-1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <v:layer v:name="Connector" v:index="0"/> + <g id="shape1004-1" v:mID="1004" v:groupContext="shape" transform="translate(0.75,-106.441)"> + <title>Sheet.1004</title> + <rect x="0" y="129.543" width="130.394" height="507.968" class="st1"/> + </g> + <g id="shape1000-3" v:mID="1000" v:groupContext="shape" transform="translate(278.545,-106.441)"> + <title>Sheet.1000</title> + <rect x="0" y="129.543" width="130.394" height="507.968" class="st1"/> + </g> + <g id="shape1-5" v:mID="1" v:groupContext="shape" transform="translate(327.129,-584.822)"> + <title>Sheet.1</title> + <rect v:rectContext="foreign" x="0" y="616.927" width="38.7" height="20.5851" class="st2"/> + <image x="0" y="616.927" width="38.7" height="20.5851" preserveAspectRatio="none" xlink:href="data:image/png;base64, + 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 + Dy5zyZJv/hArAAAAAElFTkSuQmCC"/> + <rect v:rectContext="foreign" x="0" y="616.927" width="38.7" height="20.5851" class="st2"/> + </g> + <g id="shape1001-9" v:mID="1001" v:groupContext="shape" transform="translate(289.786,-381.889)"> + <title>Sheet.1001</title> + <desc>Spark ML Pipeline</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="615.392" width="113.39" height="44.2404"/> + <rect x="0" y="593.271" width="113.386" height="44.2404" class="st3"/> + <text x="13.22" y="618.99" class="st4" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Spark ML Pipeline</text> </g> + <g id="shape1002-12" v:mID="1002" v:groupContext="shape" transform="translate(9.25393,-458.504)"> + <title>Sheet.1002</title> + <desc>AvroIterator</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/> + <v:textRect cx="56.6929" cy="589.059" width="113.39" height="96.9051"/> + <rect x="0" y="540.607" width="113.386" height="96.9051" class="st5"/> + <text x="26.52" y="555.41" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>AvroIterator</text> </g> + <g id="shape1003-15" v:mID="1003" v:groupContext="shape" transform="translate(46.1043,-458.504)"> + <title>Sheet.1003</title> + <desc>Pushdown Filter</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="38.2677" cy="615.392" width="76.54" height="44.2404"/> + <rect x="0" y="593.271" width="76.5354" height="44.2404" class="st1"/> + <text x="12.76" y="611.79" class="st7" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Pushdown<v:newlineChar/><tspan + x="25.67" dy="1.2em" class="st8">Filter</tspan></text> </g> + <g id="shape2-19" v:mID="2" v:groupContext="shape" transform="translate(9.02896,-576.316)"> + <title>Sheet.2</title> + <rect v:rectContext="foreign" x="0" y="608.42" width="113.836" height="29.0914" class="st2"/> + <image x="0" y="608.42" width="113.836" height="29.0914" preserveAspectRatio="none" xlink:href="data:image/png;base64, + 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"/> + <rect v:rectContext="foreign" x="0" y="608.42" width="113.836" height="29.0914" class="st2"/> + </g> + <g id="shape1007-23" v:mID="1007" v:groupContext="shape" transform="translate(289.786,-511.169)"> + <title>Sheet.1007</title> + <desc>Accumulo DataSourceV2</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="615.392" width="113.39" height="44.2404"/> + <rect x="0" y="593.271" width="113.386" height="44.2404" class="st5"/> + <text x="32.51" y="611.79" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Accumulo <tspan + x="22.11" dy="1.2em" class="st8">DataSourceV2</tspan></text> </g> + <g id="shape1008-27" v:mID="1008" v:groupContext="shape" transform="translate(289.786,-446.529)"> + <title>Sheet.1008</title> + <desc>Spark Dataframe</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="615.392" width="113.39" height="44.2404"/> + <rect x="0" y="593.271" width="113.386" height="44.2404" class="st3"/> + <text x="15.71" y="618.99" class="st4" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Spark Dataframe</text> </g> + <g id="shape1010-30" v:mID="1010" v:groupContext="shape" v:layerMember="0" transform="translate(122.64,-526.202)"> + <title>Dynamic connector.1010</title> + <path d="M0 630.43 L160.11 630.43" class="st9"/> + </g> + <g id="shape1011-36" v:mID="1011" v:groupContext="shape" v:layerMember="0" transform="translate(339.393,-511.169)"> + <title>Dynamic connector.1011</title> + <path d="M7.09 637.51 L7.09 650.87" class="st9"/> + </g> + <g id="shape1012-41" v:mID="1012" v:groupContext="shape" v:layerMember="0" transform="translate(339.393,-446.529)"> + <title>Dynamic connector.1012</title> + <path d="M7.09 637.51 L7.09 650.87" class="st9"/> + </g> + <g id="shape1014-46" v:mID="1014" v:groupContext="shape" transform="translate(289.786,-317.249)"> + <title>Sheet.1014</title> + <desc>MLeap Bundle</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="615.392" width="113.39" height="44.2404"/> + <rect x="0" y="593.271" width="113.386" height="44.2404" class="st3"/> + <text x="21.59" y="618.99" class="st4" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>MLeap Bundle</text> </g> + <g id="shape1020-49" v:mID="1020" v:groupContext="shape" transform="translate(289.786,-235.706)"> + <title>Sheet.1020</title> + <desc>Accumulo DataSourceV2</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="615.392" width="113.39" height="44.2404"/> + <rect x="0" y="593.271" width="113.386" height="44.2404" class="st5"/> + <text x="32.51" y="611.79" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Accumulo <tspan + x="22.11" dy="1.2em" class="st8">DataSourceV2</tspan></text> </g> + <g id="shape1021-53" v:mID="1021" v:groupContext="shape" transform="translate(9.25393,-115.512)"> + <title>Sheet.1021</title> + <desc>AvroIterator</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197" v:verticalAlign="0"/> + <v:textRect cx="56.6929" cy="555.295" width="113.39" height="164.434"/> + <rect x="0" y="473.077" width="113.386" height="164.434" class="st5"/> + <text x="26.52" y="487.88" class="st6" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>AvroIterator</text> </g> + <g id="shape1022-56" v:mID="1022" v:groupContext="shape" transform="translate(46.1043,-203.386)"> + <title>Sheet.1022</title> + <desc>Pushdown Filter</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="38.2677" cy="615.392" width="76.54" height="44.2404"/> + <rect x="0" y="593.271" width="76.5354" height="44.2404" class="st1"/> + <text x="12.76" y="611.79" class="st7" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Pushdown<v:newlineChar/><tspan + x="25.67" dy="1.2em" class="st8">Filter</tspan></text> </g> + <g id="shape1023-60" v:mID="1023" v:groupContext="shape" transform="translate(46.1043,-159.145)"> + <title>Sheet.1023</title> + <desc>MLeap Execution</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="38.2677" cy="615.392" width="76.54" height="44.2404"/> + <rect x="0" y="593.271" width="76.5354" height="44.2404" class="st1"/> + <text x="21.6" y="611.79" class="st7" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>MLeap<v:newlineChar/><tspan + x="14.36" dy="1.2em" class="st8">Execution</tspan></text> </g> + <g id="shape1024-64" v:mID="1024" v:groupContext="shape" transform="translate(46.1043,-115.512)"> + <title>Sheet.1024</title> + <desc>Pushdown Score Filter</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="38.2677" cy="615.392" width="76.54" height="44.2404"/> + <rect x="0" y="593.271" width="76.5354" height="44.2404" class="st1"/> + <text x="12.76" y="611.79" class="st7" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Pushdown<v:newlineChar/><tspan + x="10.78" dy="1.2em" class="st8">Score Filter</tspan></text> </g> + <g id="shape1025-68" v:mID="1025" v:groupContext="shape" v:layerMember="0" transform="translate(339.393,-381.889)"> + <title>Dynamic connector.1025</title> + <path d="M7.09 637.51 L7.09 650.87" class="st9"/> + </g> + <g id="shape1026-73" v:mID="1026" v:groupContext="shape" v:layerMember="0" transform="translate(339.393,-317.249)"> + <title>Dynamic connector.1026</title> + <path d="M7.09 637.51 L7.09 667.77" class="st9"/> + </g> + <g id="shape1027-78" v:mID="1027" v:groupContext="shape" v:layerMember="0" transform="translate(122.64,-250.739)"> + <title>Dynamic connector.1027</title> + <path d="M0 630.43 L160.11 630.43" class="st9"/> + </g> + <g id="shape1028-83" v:mID="1028" v:groupContext="shape" transform="translate(287.049,-115.512)"> + <title>Sheet.1028</title> + <desc>Spark Dataframe</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="615.392" width="113.39" height="44.2404"/> + <rect x="0" y="593.271" width="113.386" height="44.2404" class="st3"/> + <text x="15.71" y="618.99" class="st4" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Spark Dataframe</text> </g> + <g id="shape1030-86" v:mID="1030" v:groupContext="shape" v:layerMember="0" transform="translate(338.024,-235.706)"> + <title>Dynamic connector.1030</title> + <path d="M7.09 637.51 L7.09 706.43" class="st9"/> + </g> + <g id="shape1032-91" v:mID="1032" v:groupContext="shape" transform="translate(167.222,-540.551)"> + <title>Sheet.1032</title> + <desc>Training</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="43.2913" cy="627.512" width="86.59" height="20"/> + <rect x="0" y="617.512" width="86.5827" height="20" class="st2"/> + <text x="23.52" y="631.11" class="st7" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Training</text> </g> + <g id="shape1031-94" v:mID="1031" v:groupContext="shape" transform="translate(2.16732,-302.598)"> + <title>Sheet.1031</title> + <path d="M0 637.51 L403.94 637.51 L403.94 371.62 L0 371.62 L0 637.51 Z" class="st11"/> + </g> + <g id="shape1033-96" v:mID="1033" v:groupContext="shape" transform="translate(165.159,-265.748)"> + <title>Sheet.1033</title> + <desc>Inference</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="43.2913" cy="627.512" width="86.59" height="20"/> + <rect x="0" y="617.512" width="86.5827" height="20" class="st2"/> + <text x="20.06" y="631.11" class="st7" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Inference</text> </g> + <g id="shape1034-99" v:mID="1034" v:groupContext="shape" transform="translate(2.16732,-111.26)"> + <title>Sheet.1034</title> + <path d="M0 637.51 L403.94 637.51 L403.94 456.09 L0 456.09 L0 637.51 Z" class="st11"/> + </g> + </g> +</svg> diff --git a/output/images/blog/202002_masc/runtime.png b/output/images/blog/202002_masc/runtime.png new file mode 100644 index 0000000..06c0e6f Binary files /dev/null and b/output/images/blog/202002_masc/runtime.png differ diff --git a/output/images/blog/202002_masc/sparkml_vs_mleap_accumulo.png b/output/images/blog/202002_masc/sparkml_vs_mleap_accumulo.png new file mode 100644 index 0000000..2a2dafb Binary files /dev/null and b/output/images/blog/202002_masc/sparkml_vs_mleap_accumulo.png differ diff --git a/output/index.html b/output/index.html index f9491ee..1f2f10e 100644 --- a/output/index.html +++ b/output/index.html @@ -179,6 +179,13 @@ <div class="row latest-news-item"> <div class="col-sm-12" style="margin-bottom: 5px"> + <span style="font-size: 12px; margin-right: 5px;">Feb 2020</span> + <a href="/blog/2020/02/26/accumulo-spark-connector.html">Microsoft MASC, an Apache Spark connector for Apache Accumulo</a> + </div> + </div> + + <div class="row latest-news-item"> + <div class="col-sm-12" style="margin-bottom: 5px"> <span style="font-size: 12px; margin-right: 5px;">Dec 2019</span> <a href="/blog/2019/12/16/accumulo-proxy.html">Accumulo Clients in Other Programming Languages</a> </div> @@ -205,13 +212,6 @@ </div> </div> - <div class="row latest-news-item"> - <div class="col-sm-12" style="margin-bottom: 5px"> - <span style="font-size: 12px; margin-right: 5px;">Sep 2019</span> - <a href="/blog/2019/09/10/accumulo-S3-notes.html">Using S3 as a data store for Accumulo</a> - </div> - </div> - <div id="news-archive-link"> <p>View all posts in the <a href="/news">news archive</a></p> </div> diff --git a/output/news/index.html b/output/news/index.html index 3e23ea9..785d167 100644 --- a/output/news/index.html +++ b/output/news/index.html @@ -143,11 +143,22 @@ <div> -<h3>2019</h3> +<h3>2020</h3> <div class="row" style="margin-top: 15px"> + <div class="col-md-1">Feb 26</div> + <div class="col-md-10"><a href="/blog/2020/02/26/accumulo-spark-connector.html">Microsoft MASC, an Apache Spark connector for Apache Accumulo</a></div> + </div> + + + + + <hr /> + <h3>2019</h3> + + <div class="row" style="margin-top: 15px"> <div class="col-md-1">Dec 16</div> <div class="col-md-10"><a href="/blog/2019/12/16/accumulo-proxy.html">Accumulo Clients in Other Programming Languages</a></div> </div> diff --git a/output/search_data.json b/output/search_data.json index bbdd783..f5f743b 100644 --- a/output/search_data.json +++ b/output/search_data.json @@ -302,6 +302,14 @@ }, + "blog-2020-02-26-accumulo-spark-connector-html": { + "title": "Microsoft MASC, an Apache Spark connector for Apache Accumulo", + "content" : "OverviewMASC provides an Apache Spark native connector for Apache Accumulo to integrate the rich Spark machine learning eco-system with the scalable and secure data storage capabilities of Accumulo.Major Features Simplified Spark DataFrame read/write to Accumulo using DataSource v2 API Speedup of 2-5x over existing approaches for pulling key-value data into DataFrame format Scala and Python support without overhead for moving between languages Process streaming da [...] + "url": " /blog/2020/02/26/accumulo-spark-connector.html", + "categories": "blog" + } + , + "blog-2019-12-16-accumulo-proxy-html": { "title": "Accumulo Clients in Other Programming Languages", "content" : "Apache Accumulo has an Accumulo Proxy that allows communication with Accumulo using clients writtenin languages other than Java. This blog post shows how to run the Accumulo Proxy process using Unoand communicate with Accumulo using a Python client.First, clone the Accumulo Proxy repository.git clone https://github.com/apache/accumulo-proxyAssuming you have Uno set up on your machine, configure uno.conf to start the Accumulo Proxyby setting the configuration below:exp [...]