blob: 02504618c01f7caa7dd442a48f743653fb5f3067 [file] [log] [blame]
<!DOCTYPE html>
<!--
| Generated by Apache Maven Doxia Site Renderer 1.8 from src/site/markdown/metron-sensors/fastcapa/index.md at 2019-05-14
| Rendered using Apache Maven Fluido Skin 1.7
-->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="Date-Revision-yyyymmdd" content="20190514" />
<meta http-equiv="Content-Language" content="en" />
<title>Metron &#x2013; Fastcapa</title>
<link rel="stylesheet" href="../../css/apache-maven-fluido-1.7.min.css" />
<link rel="stylesheet" href="../../css/site.css" />
<link rel="stylesheet" href="../../css/print.css" media="print" />
<script type="text/javascript" src="../../js/apache-maven-fluido-1.7.min.js"></script>
<script type="text/javascript">
$( document ).ready( function() { $( '.carousel' ).carousel( { interval: 3500 } ) } );
</script>
</head>
<body class="topBarDisabled">
<div class="container-fluid">
<div id="banner">
<div class="pull-left"><a href="http://metron.apache.org/" id="bannerLeft"><img src="../../images/metron-logo.png" alt="Apache Metron" width="148px" height="48px"/></a></div>
<div class="pull-right"></div>
<div class="clear"><hr/></div>
</div>
<div id="breadcrumbs">
<ul class="breadcrumb">
<li class=""><a href="http://www.apache.org" class="externalLink" title="Apache">Apache</a><span class="divider">/</span></li>
<li class=""><a href="http://metron.apache.org/" class="externalLink" title="Metron">Metron</a><span class="divider">/</span></li>
<li class=""><a href="../../index.html" title="Documentation">Documentation</a><span class="divider">/</span></li>
<li class="active ">Fastcapa</li>
<li id="publishDate" class="pull-right"><span class="divider">|</span> Last Published: 2019-05-14</li>
<li id="projectVersion" class="pull-right">Version: 0.7.1</li>
</ul>
</div>
<div class="row-fluid">
<div id="leftColumn" class="span2">
<div class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">User Documentation</li>
<li><a href="../../index.html" title="Metron"><span class="icon-chevron-down"></span>Metron</a>
<ul class="nav nav-list">
<li><a href="../../CONTRIBUTING.html" title="CONTRIBUTING"><span class="none"></span>CONTRIBUTING</a></li>
<li><a href="../../Upgrading.html" title="Upgrading"><span class="none"></span>Upgrading</a></li>
<li><a href="../../metron-analytics/index.html" title="Analytics"><span class="icon-chevron-right"></span>Analytics</a></li>
<li><a href="../../metron-contrib/metron-docker/index.html" title="Docker"><span class="none"></span>Docker</a></li>
<li><a href="../../metron-contrib/metron-performance/index.html" title="Performance"><span class="none"></span>Performance</a></li>
<li><a href="../../metron-deployment/index.html" title="Deployment"><span class="icon-chevron-right"></span>Deployment</a></li>
<li><a href="../../metron-interface/index.html" title="Interface"><span class="icon-chevron-right"></span>Interface</a></li>
<li><a href="../../metron-platform/index.html" title="Platform"><span class="icon-chevron-right"></span>Platform</a></li>
<li><a href="../../metron-sensors/index.html" title="Sensors"><span class="icon-chevron-down"></span>Sensors</a>
<ul class="nav nav-list">
<li class="active"><a href="#"><span class="none"></span>Fastcapa</a></li>
<li><a href="../../metron-sensors/pycapa/index.html" title="Pycapa"><span class="none"></span>Pycapa</a></li>
</ul>
</li>
<li><a href="../../metron-stellar/stellar-3rd-party-example/index.html" title="Stellar-3rd-party-example"><span class="none"></span>Stellar-3rd-party-example</a></li>
<li><a href="../../metron-stellar/stellar-common/index.html" title="Stellar-common"><span class="icon-chevron-right"></span>Stellar-common</a></li>
<li><a href="../../metron-stellar/stellar-zeppelin/index.html" title="Stellar-zeppelin"><span class="none"></span>Stellar-zeppelin</a></li>
<li><a href="../../use-cases/index.html" title="Use-cases"><span class="icon-chevron-right"></span>Use-cases</a></li>
</ul>
</li>
</ul>
<hr />
<div id="poweredBy">
<div class="clear"></div>
<div class="clear"></div>
<div class="clear"></div>
<div class="clear"></div>
<a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="../../images/logos/maven-feather.png" /></a>
</div>
</div>
</div>
<div id="bodyColumn" class="span10" >
<!--
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.
-->
<h1>Fastcapa</h1>
<p>Fastcapa is a probe that performs fast network packet capture by leveraging Linux kernel-bypass and user space networking technology. The probe will bind to a network interface, capture network packets, and send the raw packet data to Kafka. This provides a scalable mechanism for ingesting high-volumes of network packet data into a Hadoop-y cluster.</p>
<p>Fastcapa leverages the Data Plane Development Kit (<a class="externalLink" href="http://dpdk.org/">DPDK</a>). DPDK is a set of libraries and drivers to perform fast packet processing in Linux user space.</p>
<ul>
<li><a href="#Quick_Start">Quick Start</a></li>
<li><a href="#Requirements">Requirements</a></li>
<li><a href="#Installation">Installation</a></li>
<li><a href="#Usage">Usage</a>
<ul>
<li><a href="#Parameters">Parameters</a></li>
<li><a href="#Output">Output</a></li>
<li><a href="#Kerberos">Kerberos</a></li>
</ul>
</li>
<li><a href="#How_It_Works">How It Works</a></li>
<li><a href="#Performance">Performance</a></li>
<li><a href="#FAQs">FAQs</a></li>
</ul>
<div class="section">
<h2><a name="Quick_Start"></a>Quick Start</h2>
<p>The quickest way to see Fastcapa in action is to use a Virtualbox environment on your local machine. The necessary files and instructions to do this are located at <a href="../../metron-deployment/vagrant/fastcapa-test-platform/index.html"><tt>metron-deployment/vagrant/fastcapa-vagrant</tt></a>. All you need to do is execute the following.</p>
<div>
<div>
<pre class="source">cd metron-deployment/vagrant/fastcapa-test-platform
vagrant up
</pre></div></div>
<p>This environment sets up two nodes. One node produces network packets over a network interface. The second node uses Fastcapa to capture those packets and write them to a Kafka broker running on the first node. Basic validation is performed to ensure that Fastcapa is able to land packet data in Kafka.</p></div>
<div class="section">
<h2><a name="Requirements"></a>Requirements</h2>
<p>The following system requirements must be met to run the Fastcapa probe.</p>
<ul>
<li>Linux kernel &gt;= 2.6.34</li>
<li>A <a class="externalLink" href="http://dpdk.org/doc/nics">DPDK supported ethernet device; NIC</a>.</li>
<li>Port(s) on the ethernet device that can be dedicated for exclusive use by Fastcapa</li>
</ul></div>
<div class="section">
<h2><a name="Installation"></a>Installation</h2>
<p>The process of installing Fastcapa has a fair number of steps and involves building DPDK, loading specific kernel modules, enabling huge page memory, and binding compatible network interface cards.</p>
<div class="section">
<h3><a name="Automated_Installation"></a>Automated Installation</h3>
<p>The best documentation is code that actually does this for you. An Ansible role that performs the entire installation procedure can be found at <a href="../../metron-deployment/roles/fastcapa/index.html"><tt>metron-deployment/roles/fastcapa</tt></a>. Use this to install Fastcapa or as a guide for manual installation. The automated installation assumes CentOS 7.1 and is directly tested against <a class="externalLink" href="https://atlas.hashicorp.com/bento/boxes/centos-7.1">bento/centos-7.1</a>.</p></div>
<div class="section">
<h3><a name="Manual_Installation"></a>Manual Installation</h3>
<p>The following manual installation steps assume that they are executed on CentOS 7.1. Some minor differences may result if you use a different Linux distribution.</p>
<ul>
<li><a href="#Enable_Transparent_Huge_Pages">Enable Transparent Huge Pages</a></li>
<li><a href="#Install_DPDK">Install DPDK</a></li>
<li><a href="#Install_Librdkafka">Install Librdkafka</a></li>
<li><a href="#Install_Fastcapa">Install Fastcapa</a></li>
</ul>
<div class="section">
<h4><a name="Enable_Transparent_Huge_Pages"></a>Enable Transparent Huge Pages</h4>
<p>The probe performs its own memory management by leveraging transparent huge pages. In Linux, Transparent Huge Pages (THP) can be enabled either dynamically or on boot. It is recommended that these be allocated on boot to increase the chance that a larger, physically contiguous chunk of memory can be allocated.</p>
<p>The size of THPs that are supported will vary based on your CPU. These typically include 2 MB and 1 GB THPs. For better performance, allocate 1 GB THPs if supported by your CPU.</p>
<ol style="list-style-type: decimal">
<li>
<p>Ensure that your CPU supports 1 GB THPs. A CPU flag <tt>pdpe1gb</tt> indicates whether or not the CPU supports 1 GB THPs.</p>
<div>
<div>
<pre class="source">grep --color=always pdpe1gb /proc/cpuinfo | uniq
</pre></div></div>
</li>
<li>
<p>Add the following boot parameters to the Linux kernel. Edit <tt>/etc/default/grub</tt> and add the additional kernel parameters to the line starting with <tt>GRUB_CMDLINE_LINUX</tt>.</p>
<div>
<div>
<pre class="source">GRUB_CMDLINE_LINUX=... default_hugepagesz=1G hugepagesz=1G hugepages=16
</pre></div></div>
</li>
<li>
<p>Rebuild the grub configuration then reboot. The location of the Grub configuration file will differ across Linux distributions.</p>
<div>
<div>
<pre class="source">cp /etc/grub2-efi.cfg /etc/grub2-efi.cfg.orig
/sbin/grub2-mkconfig -o /etc/grub2-efi.cfg
</pre></div></div>
</li>
<li>
<p>Once the host has been rebooted, ensure that the THPs were successfully allocated.</p>
<div>
<div>
<pre class="source">$ grep HugePage /proc/meminfo
AnonHugePages: 933888 kB
HugePages_Total: 16
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
</pre></div></div>
<p>The total number of huge pages that you have been allocated should be distributed fairly evenly across each NUMA node. In this example, a total of 16 were requested and 8 have been assigned on each of the 2 NUMA nodes.</p>
<div>
<div>
<pre class="source">$ cat /sys/devices/system/node/node*/hugepages/hugepages-1048576kB/nr_hugepages
8
8
</pre></div></div>
</li>
<li>
<p>Once the THPs have been reserved, they need to be mounted to make them available to the probe.</p>
<div>
<div>
<pre class="source">cp /etc/fstab /etc/fstab.orig
mkdir -p /mnt/huge_1GB
echo &quot;nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0&quot; &gt;&gt; /etc/fstab
mount -fav
</pre></div></div>
</li>
</ol></div>
<div class="section">
<h4><a name="Install_DPDK"></a>Install DPDK</h4>
<ol style="list-style-type: decimal">
<li>
<p>Install the required dependencies.</p>
<div>
<div>
<pre class="source">yum -y install &quot;@Development tools&quot;
yum -y install pciutils net-tools glib2 glib2-devel git
yum -y install kernel kernel-devel kernel-headers
</pre></div></div>
</li>
<li>
<p>Decide where DPDK will be installed.</p>
<div>
<div>
<pre class="source">export DPDK_HOME=/usr/local/dpdk/
</pre></div></div>
</li>
<li>
<p>Download, build and install DPDK.</p>
<div>
<div>
<pre class="source">wget http://fast.dpdk.org/rel/dpdk-16.11.1.tar.xz -O - | tar -xJ
cd dpdk-stable-16.11.1/
make config install T=x86_64-native-linuxapp-gcc DESTDIR=$DPDK_HOME
</pre></div></div>
</li>
<li>
<p>Find the PCI address of the ethernet device that you plan on using to capture network packets. In the following example I plan on binding <tt>enp9s0f0</tt> which has a PCI address of <tt>09:00.0</tt>.</p>
<div>
<div>
<pre class="source">$ lspci | grep &quot;VIC Ethernet&quot;
09:00.0 Ethernet controller: Cisco Systems Inc VIC Ethernet NIC (rev a2)
0a:00.0 Ethernet controller: Cisco Systems Inc VIC Ethernet NIC (rev a2)
</pre></div></div>
</li>
<li>
<p>Bind the device. Replace the device name and PCI address with what is appropriate for your environment.</p>
<div>
<div>
<pre class="source">ifdown enp9s0f0
modprobe uio_pci_generic
$DPDK_HOME/sbin/dpdk-devbind --bind=uio_pci_generic &quot;09:00.0&quot;
</pre></div></div>
</li>
<li>
<p>Ensure that the device was bound. It should be shown as a &#x2018;network device using DPDK-compatible driver.&#x2019;</p>
<div>
<div>
<pre class="source">$ dpdk-devbind --status
Network devices using DPDK-compatible driver
============================================
0000:09:00.0 'VIC Ethernet NIC' drv=uio_pci_generic unused=enic
Network devices using kernel driver
===================================
0000:01:00.0 'I350 Gigabit Network Connection' if=eno1 drv=igb unused=uio_pci_generic
</pre></div></div>
</li>
</ol></div>
<div class="section">
<h4><a name="Install_Librdkafka"></a>Install Librdkafka</h4>
<p>The probe has been tested with <a class="externalLink" href="https://github.com/edenhill/librdkafka/releases/tag/v0.9.4">Librdkafka 0.9.4</a>.</p>
<ol style="list-style-type: decimal">
<li>
<p>Choose an installation path. In this example, the libs will actually be installed at <tt>/usr/local/lib</tt>; note that <tt>lib</tt> is appended to the prefix.</p>
<div>
<div>
<pre class="source">export RDK_PREFIX=/usr/local
</pre></div></div>
</li>
<li>
<p>Download, build and install.</p>
<div>
<div>
<pre class="source">wget https://github.com/edenhill/librdkafka/archive/v0.9.4.tar.gz -O - | tar -xz
cd librdkafka-0.9.4/
./configure --prefix=$RDK_PREFIX
make
make install
</pre></div></div>
</li>
<li>
<p>Ensure that the installation location is on the search path for the runtime shared library loader.</p>
<div>
<div>
<pre class="source">export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RDK_PREFIX/lib
</pre></div></div>
</li>
</ol></div>
<div class="section">
<h4><a name="Install_Fastcapa"></a>Install Fastcapa</h4>
<ol style="list-style-type: decimal">
<li>
<p>Set the required environment variables.</p>
<div>
<div>
<pre class="source">export RTE_SDK=$DPDK_HOME/share/dpdk/
export RTE_TARGET=x86_64-native-linuxapp-gcc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RDK_HOME
</pre></div></div>
</li>
<li>
<p>Build Fastcapa. The resulting binary will be placed at <tt>build/app/fastcapa</tt>.</p>
<div>
<div>
<pre class="source">cd metron/metron-sensors/fastcapa
make
</pre></div></div>
</li>
</ol></div></div></div>
<div class="section">
<h2><a name="Usage"></a>Usage</h2>
<p>Follow these steps to run Fastcapa.</p>
<ol style="list-style-type: decimal">
<li>
<p>Create a configuration file that at a minimum specifies your Kafka broker. An example configuration file, <tt>conf/fastcapa.conf</tt>, is available that documents other useful parameters.</p>
<div>
<div>
<pre class="source">[kafka-global]
metadata.broker.list = kafka-broker1:9092
</pre></div></div>
</li>
<li>
<p>Bind the capture device. This is only needed if the device is not already bound. In this example, the device <tt>enp9s0f0</tt> with a PCI address of <tt>09:00:0</tt> is bound. Use values specific to your environment.</p>
<div>
<div>
<pre class="source">ifdown enp9s0f0
modprobe uio_pci_generic
$DPDK_HOME/sbin/dpdk-devbind --bind=uio_pci_generic &quot;09:00.0&quot;
</pre></div></div>
</li>
<li>
<p>Run Fastcapa.</p>
<div>
<div>
<pre class="source">fastcapa -c 0x03 --huge-dir /mnt/huge_1GB -- -p 0x01 -t pcap -c /etc/fastcapa.conf
</pre></div></div>
</li>
<li>
<p>Terminate Fastcapa with <tt>SIGINT</tt> or by entering <tt>CTRL-C</tt>. The probe will cleanly shut down all of the workers and allow the backlog of packets to drain. To terminate the process without clearing the queue, send a <tt>SIGKILL</tt> or be entering <tt>killall -9 fastcapa</tt>.</p>
</li>
</ol>
<div class="section">
<h3><a name="Parameters"></a>Parameters</h3>
<p>Fastcapa accepts three sets of parameters.</p>
<ol style="list-style-type: decimal">
<li>Command-line parameters passed directly to DPDK&#x2019;s Environmental Abstraction Layer (EAL)</li>
<li>Command-line parameters that define how Fastcapa will interact with DPDK. These parametera are separated on the command line by a double-dash (<tt>--</tt>).</li>
<li>A configuration file that define how Fastcapa interacts with Librdkafka.</li>
</ol>
<div class="section">
<h4><a name="Environmental_Abstraction_Layer_Parameters"></a>Environmental Abstraction Layer Parameters</h4>
<p>The most commonly used EAL parameter involves specifying which logical CPU cores should be used for processing. This can be specified in any of the following ways.</p>
<div>
<div>
<pre class="source"> -c COREMASK Hexadecimal bitmask of cores to run on
-l CORELIST List of cores to run on
The argument format is &lt;c1&gt;[-c2][,c3[-c4],...]
where c1, c2, etc are core indexes between 0 and 128
--lcores COREMAP Map lcore set to physical cpu set
The argument format is
'&lt;lcores[@cpus]&gt;[&lt;,lcores[@cpus]&gt;...]'
lcores and cpus list are grouped by '(' and ')'
Within the group, '-' is used for range separator,
',' is used for single number separator.
'( )' can be omitted for single element group,
'@' can be omitted if cpus and lcores have the same value
</pre></div></div>
<p>To get more information about other EAL parameters, run the following.</p>
<div>
<div>
<pre class="source">fastcapa -h
</pre></div></div>
</div>
<div class="section">
<h4><a name="Fastcapa-Core_Parameters"></a>Fastcapa-Core Parameters</h4>
<table border="0" class="table table-striped">
<thead>
<tr class="a">
<th> Name </th>
<th> Command </th>
<th> Description </th>
<th> Default </th></tr>
</thead><tbody>
<tr class="b">
<td> Port Mask </td>
<td> -p PORT_MASK </td>
<td> A bit mask identifying which ports to bind. </td>
<td> 0x01 </td></tr>
<tr class="a">
<td> Receive Burst Size </td>
<td> -b RX_BURST_SIZE </td>
<td> The max number of packets processed by a receive worker. </td>
<td> 32 </td></tr>
<tr class="b">
<td> Transmit Burst Size </td>
<td> -w TX_BURST_SIZE </td>
<td> The max number of packets processed by a transmit worker. </td>
<td> 256 </td></tr>
<tr class="a">
<td> Receive Descriptors </td>
<td> -d NB_RX_DESC </td>
<td> The number of descriptors for each receive queue (the size of the receive queue.) Limited by the ethernet device in use. </td>
<td> 1024 </td></tr>
<tr class="b">
<td> Transmission Ring Size </td>
<td> -x TX_RING_SIZE </td>
<td> The size of each transmission ring. This must be a power of 2. </td>
<td> 2048 </td></tr>
<tr class="a">
<td> Number Receive Queues </td>
<td> -q NB_RX_QUEUE </td>
<td> Number of receive queues to use for each port. Limited by the ethernet device in use. </td>
<td> 2 </td></tr>
<tr class="b">
<td> Kafka Topic </td>
<td> -t KAFKA_TOPIC </td>
<td> The name of the Kafka topic. </td>
<td> pcap </td></tr>
<tr class="a">
<td> Configuration File </td>
<td> -c KAFKA_CONF </td>
<td> Path to a file containing configuration values. </td>
<td> </td></tr>
<tr class="b">
<td> Stats </td>
<td> -s KAFKA_STATS </td>
<td> Appends performance metrics in the form of JSON strings to the specified file. </td>
<td> </td></tr>
</tbody>
</table>
<p>To get more information about the Fastcapa specific parameters, run the following. Note that this puts the <tt>-h</tt> after the double-dash <tt>--</tt>.</p>
<div>
<div>
<pre class="source">fastcapa -- -h
fastcapa [EAL options] -- [APP options]
-p PORT_MASK bitmask of ports to bind [0x01]
-b RX_BURST_SIZE burst size of receive worker [32]
-w TX_BURST_SIZE burst size of transmit worker [256]
-d NB_RX_DESC num of descriptors for receive ring [1024]
-x TX_RING_SIZE size of tx rings (must be a power of 2) [2048]
-q NB_RX_QUEUE num of receive queues for each device [1]
-t KAFKA_TOPIC name of the kafka topic [pcap]
-c KAFKA_CONF file containing configs for kafka client
-s KAFKA_STATS append kafka client stats to a file
-h print this help message
</pre></div></div>
</div>
<div class="section">
<h4><a name="Fastcapa-Kafka_Configuration_File"></a>Fastcapa-Kafka Configuration File</h4>
<p>The path to the configuration file is specified with the <tt>-c</tt> command line argument. The file can contain any global or topic-specific, producer-focused <a class="externalLink" href="https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md">configuration values accepted by Librdkafka</a>.</p>
<p>The configuration file is a <tt>.ini</tt>-like Glib configuration file. The global configuration values should be placed under a <tt>[kafka-global]</tt> header and topic-specific values should be placed under <tt>[kafka-topic]</tt>.</p>
<p>A minimally viable configuration file would only need to include the Kafka broker to connect to.</p>
<div>
<div>
<pre class="source">[kafka-global]
metadata.broker.list = kafka-broker1:9092, kafka-broker2:9092
</pre></div></div>
<p>The configuration parameters that are important for either basic functioning or performance tuning of Fastcapa include the following.</p>
<p>Global configuration values that should be located under the <tt>[kafka-global]</tt> header.</p>
<table border="0" class="table table-striped">
<thead>
<tr class="a">
<th> <i>Name</i> </th>
<th> <i>Description</i> </th>
<th> <i>Default</i> </th></tr>
</thead><tbody>
<tr class="b">
<td> metadata.broker.list </td>
<td> Initial list of brokers as a CSV list of broker host or host:port </td>
<td> </td></tr>
<tr class="a">
<td> client.id </td>
<td> Client identifier. </td>
<td> </td></tr>
<tr class="b">
<td> queue.buffering.max.messages </td>
<td> Maximum number of messages allowed on the producer queue </td>
<td> 100000 </td></tr>
<tr class="a">
<td> queue.buffering.max.ms </td>
<td> Maximum time, in milliseconds, for buffering data on the producer queue </td>
<td> 1000 </td></tr>
<tr class="b">
<td> message.copy.max.bytes </td>
<td> Maximum size for message to be copied to buffer. Messages larger than this will be passed by reference (zero-copy) at the expense of larger iovecs. </td>
<td> 65535 </td></tr>
<tr class="a">
<td> batch.num.messages </td>
<td> Maximum number of messages batched in one MessageSet </td>
<td> 10000 </td></tr>
<tr class="b">
<td> statistics.interval.ms </td>
<td> How often statistics are emitted; 0 = never </td>
<td> 0 </td></tr>
<tr class="a">
<td> compression.codec </td>
<td> Compression codec to use for compressing message sets; {none, gzip, snappy, lz4 } </td>
<td> none </td></tr>
</tbody>
</table>
<p>Topic configuration values that should be located under the <tt>[kafka-topic]</tt> header.</p>
<table border="0" class="table table-striped">
<thead>
<tr class="a">
<th> <i>Name</i> </th>
<th> <i>Description</i> </th>
<th> <i>Default</i> </th></tr>
</thead><tbody>
<tr class="b">
<td> compression.codec </td>
<td> Compression codec to use for compressing message sets; {none, gzip, snappy, lz4 } </td>
<td> none </td></tr>
<tr class="a">
<td> request.required.acks </td>
<td> How many acknowledgements the leader broker must receive from ISR brokers before responding to the request; { 0 = no ack, 1 = leader ack, -1 = all ISRs } </td>
<td> 1 </td></tr>
<tr class="b">
<td> message.timeout.ms </td>
<td> Local message timeout. This value is only enforced locally and limits the time a produced message waits for successful delivery. A time of 0 is infinite. </td>
<td> 300000 </td></tr>
<tr class="a">
<td> queue.buffering.max.kbytes </td>
<td> Maximum total message size sum allowed on the producer queue </td>
<td> </td></tr>
</tbody>
</table></div></div>
<div class="section">
<h3><a name="Output"></a>Output</h3>
<p>When running the probe some basic counters are output to stdout. Of course during normal operation these values will be much larger.</p>
<div>
<div>
<pre class="source"> ------ in ------ --- queued --- ----- out ----- ---- drops ----
[nic] 8 - - -
[rx] 8 0 8 0
[tx] 8 0 8 0
[kaf] 8 1 7 0
</pre></div></div>
<ul>
<li><tt>[nic]</tt> + <tt>in</tt>: The ethernet device is reporting that it has seen 8 packets.</li>
<li><tt>[rx]</tt> + <tt>in</tt>: The receive workers have consumed 8 packets from the device.</li>
<li><tt>[rx]</tt> + <tt>out</tt>: The receive workers have enqueued 8 packets onto the transmission rings.</li>
<li><tt>[rx]</tt> + <tt>drops</tt>: If the transmission rings become full it will prevent the receive workers from enqueuing additional packets. The excess packets are dropped. This value will never decrease.</li>
<li><tt>[tx]</tt> + <tt>in</tt>: The transmission workers have consumed 8 packets.</li>
<li><tt>[tx]</tt> + <tt>out</tt>: The transmission workers have packaged 8 packets into Kafka messages.</li>
<li><tt>[tx]</tt> + <tt>drops</tt>: If the Kafka client library accepted fewer packets than expected. This value can increase or decrease over time as additional packets are acknowledged by the Kafka client library at a later point in time.</li>
<li><tt>[kaf]</tt> + <tt>in</tt>: The Kafka client library has received 8 packets.</li>
<li><tt>[kaf]</tt> + <tt>out</tt>: A total of 7 packets has successfully reached Kafka.</li>
<li><tt>[kaf]</tt> + <tt>queued</tt>: There is 1 packet within the <tt>rdkafka</tt> queue waiting to be sent.</li>
</ul></div>
<div class="section">
<h3><a name="Kerberos"></a>Kerberos</h3>
<p>The probe can be used in a Kerberized environment. Follow these additional steps to use Fastcapa with Kerberos. The following assumptions have been made. These may need altered to fit your environment.</p>
<ul>
<li>The Kafka broker is at <tt>kafka1:6667</tt></li>
<li>Zookeeper is at <tt>zookeeper1:2181</tt></li>
<li>The Kafka security protocol is <tt>SASL_PLAINTEXT</tt></li>
<li>The keytab used is located at <tt>/etc/security/keytabs/metron.headless.keytab</tt></li>
<li>The service principal is <tt>metron@EXAMPLE.COM</tt></li>
</ul>
<ol style="list-style-type: decimal">
<li>
<p>Build Librdkafka with SASL support (<tt>--enable-sasl</tt>).</p>
<div>
<div>
<pre class="source">wget https://github.com/edenhill/librdkafka/archive/v0.9.4.tar.gz -O - | tar -xz
cd librdkafka-0.9.4/
./configure --prefix=$RDK_PREFIX --enable-sasl
make
make install
</pre></div></div>
</li>
<li>
<p>Validate Librdkafka does indeed support SASL. Run the following command and ensure that <tt>sasl</tt> is returned as a built-in feature.</p>
<div>
<div>
<pre class="source">$ examples/rdkafka_example -X builtin.features
builtin.features = gzip,snappy,ssl,sasl,regex
</pre></div></div>
<p>If it is not, ensure that you have <tt>libsasl</tt> or <tt>libsasl2</tt> installed. On CentOS, this can be installed with the following command.</p>
<div>
<div>
<pre class="source">yum install -y cyrus-sasl cyrus-sasl-devel cyrus-sasl-gssapi
</pre></div></div>
</li>
<li>
<p>Grant access to your Kafka topic. In this example, it is simply named <tt>pcap</tt>.</p>
<div>
<div>
<pre class="source">$KAFKA_HOME/bin/kafka-acls.sh --authorizer kafka.security.auth.SimpleAclAuthorizer \
--authorizer-properties zookeeper.connect=zookeeper1:2181 \
--add --allow-principal User:metron --topic pcap
</pre></div></div>
</li>
<li>
<p>Obtain a Kerberos ticket.</p>
<div>
<div>
<pre class="source">kinit -kt /etc/security/keytabs/metron.headless.keytab metron@EXAMPLE.COM
</pre></div></div>
</li>
<li>
<p>Add the following additional configuration values to your Fastcapa configuration file.</p>
<div>
<div>
<pre class="source">security.protocol = SASL_PLAINTEXT
sasl.kerberos.keytab = /etc/security/keytabs/metron.headless.keytab
sasl.kerberos.principal = metron@EXAMPLE.COM
</pre></div></div>
</li>
<li>
<p>Now run Fastcapa as you normally would. It should have no problem landing packets in your kerberized Kafka broker.</p>
</li>
</ol></div></div>
<div class="section">
<h2><a name="How_It_Works"></a>How It Works</h2>
<p>The probe leverages a poll-mode, burst-oriented mechanism to capture packets from a network interface and transmit them efficiently to a Kafka topic. Each packet is wrapped within a single Kafka message and the current timestamp, as epoch microseconds in network byte order, is attached as the message&#x2019;s key.</p>
<p>The probe leverages Receive Side Scaling (RSS), a feature provided by some ethernet devices that allows processing of received data to occur across multiple processes and logical cores. It does this by running a hash function on each packet, whose value assigns the packet to one, of possibly many, receive queues. The total number and size of these receive queues are limited by the ethernet device in use. More capable ethernet devices will offer a greater number and greater sized receive queues.</p>
<ul>
<li>Increasing the number of receive queues allows for greater parallelization of receive side processing.</li>
<li>Increasing the size of each receive queue can allow the probe to handle larger, temporary spikes of network packets that can often occur.</li>
</ul>
<p>A set of receive workers, each assigned to a unique logical core, are responsible for fetching packets from the receive queues. There can only be one receive worker for each receive queue. The receive workers continually poll the receive queues and attempt to fetch multiple packets on each request. The maximum number of packets fetched in one request is known as the &#x2018;burst size&#x2019;. If the receive worker actually receives &#x2018;burst size&#x2019; packets, then it is likely that the queue is under pressure and more packets are available. In this case the worker immediately fetches another &#x2018;burst size&#x2019; set of packets. It repeats this process up to a fixed number of times while the queue is under pressure.</p>
<p>The receive workers then enqueue the received packets into a fixed size ring buffer known as a transmit ring. There is always one transmit ring for each receive queue. A set of transmit workers then dequeue packets from the transmit rings. There can be one or more transmit workers assigned to any single transmit ring. Each transmit worker has its own unique connection to Kafka.</p>
<ul>
<li>Increasing the number of transmit workers allows for greater parallelization when writing data to Kafka.</li>
<li>Increasing the size of the transmit rings allows the probe to better handle temporary interruptions and latency when writing to Kafka.</li>
</ul>
<p>After receiving the network packets from the transmit worker, the Kafka client library internally maintains its own send queue of messages. Multiple threads are then responsible for managing this queue and creating batches of messages that are sent in bulk to a Kafka broker. No control is exercised over this additional send queue and its worker threads, which can be an impediment to performance. This is an opportunity for improvement that can be addressed as follow-on work.</p></div>
<div class="section">
<h2><a name="Performance"></a>Performance</h2>
<p>Beyond tuning the parameters previously described, the following should be carefully considered to achieve maximum performance.</p>
<div class="section">
<h3><a name="Kafka_Partitions"></a>Kafka Partitions</h3>
<p>Parallelizing access to a topic in Kafka is achieved by defining multiple partitions. The greater the number of partitions, the more parallelizable access to that topic becomes. To achieve high throughput it is important to ensure that the Kafka topic in use has a large number of partitions, evenly distributed across each of the nodes in your Kafka cluster.</p>
<p>The specific number of partitions needed will differ for each environment, but at least 128 partitions has been shown to significantly increase performance in some environments.</p></div>
<div class="section">
<h3><a name="Physical_Layout"></a>Physical Layout</h3>
<p>It is important to note the physical layout of the hardware when assigning worker cores to the probe. The worker cores should be on the same NUMA node or socket as the ethernet device itself. Assigning logical cores across NUMA boundaries can significantly impede performance.</p>
<p>The following commands can help identify logical cores that are located on the same NUMA node or socket as the ethernet device itself. These commands should be run when the device is still managed by the kernel itself; before binding the interface.</p>
<div>
<div>
<pre class="source">$ cat /sys/class/net/enp9s0f0/device/local_cpulist
0-7,16-23
</pre></div></div>
<p>The following command can be used to better understand the physical layout of the CPU in relation to NUMA nodes.</p>
<div>
<div>
<pre class="source">$ lscpu
...
NUMA node0 CPU(s): 0-7,16-23
NUMA node1 CPU(s): 8-15,24-31
</pre></div></div>
<p>In this example <tt>enp9s0f0</tt> is located on NUMA node 0 and is local to the logical cores 0-7 and 16-23. You should choose worker cores from this list.</p></div>
<div class="section">
<h3><a name="CPU_Isolation"></a>CPU Isolation</h3>
<p>Once you have chosen the logical cores to use that are local to the ethernet device, it also beneficial to isolate those cores so that the Linux kernel scheduler does not attempt to run tasks on them. This can be done using the <tt>isolcpus</tt> kernel boot parameter.</p>
<div>
<div>
<pre class="source">isolcpus=0,1,2,3,4,5,6,7
</pre></div></div>
</div>
<div class="section">
<h3><a name="Device_Limitations"></a>Device Limitations</h3>
<p>Check the output of running the probe to ensure that there are no device limitations that you are not aware of. While you may have specified 16 receive queues on the command line, your device may not support that number. This is especially true for the number of receive queues and descriptors.</p>
<p>The following example shows the output when the number of receive descriptors requested is greater than what can be supported by the device. In many cases the probe will not terminate, but will choose the maximum allowable value and continue. This behavior is specific to the underlying device driver in use.</p>
<div>
<div>
<pre class="source">PMD: rte_enic_pmd: Rq 0 Scatter rx mode enabled
PMD: rte_enic_pmd: Rq 0 Scatter rx mode not being used
PMD: rte_enic_pmd: Number of rx_descs too high, adjusting to maximum
PMD: rte_enic_pmd: Using 512 rx descriptors (sop 512, data 0)
PMD: rte_enic_pmd: Rq 1 Scatter rx mode enabled
PMD: rte_enic_pmd: Rq 1 Scatter rx mode not being used
PMD: rte_enic_pmd: Number of rx_descs too high, adjusting to maximum
PMD: rte_enic_pmd: Using 512 rx descriptors (sop 512, data 0)
PMD: rte_enic_pmd: TX Queues - effective number of descs:32
PMD: rte_enic_pmd: vNIC resources used: wq 1 rq 4 cq 3 intr 0
</pre></div></div>
</div>
<div class="section">
<h3><a name="More_Information"></a>More Information</h3>
<p>More information on this topic can be found in <a class="externalLink" href="http://dpdk.org/doc/guides/linux_gsg/nic_perf_intel_platform.html">DPDK&#x2019;s Getting Started Guide</a>.</p></div></div>
<div class="section">
<h2><a name="FAQs"></a>FAQs</h2>
<div class="section">
<h3><a name="No_free_hugepages_reported"></a>No free hugepages reported</h3>
<p>Problem: When executing <tt>fastcapa</tt> it fails with the following error message.</p>
<div>
<div>
<pre class="source">EAL: No free hugepages reported in hugepages-1048576kB
PANIC in rte_eal_init():
Cannot get hugepage information
</pre></div></div>
<p>Solution: This can occur if any process that has been allocated THPs crashes and fails to return the resources.</p>
<ul>
<li>
<p>Delete the THP files that are not in use.</p>
<div>
<div>
<pre class="source">rm -f /mnt/huge_1GB/rtemap_*
</pre></div></div>
</li>
<li>
<p>If the first option does not work, re-mount the <tt>hugetlbfs</tt> file system.</p>
<div>
<div>
<pre class="source">umount -a -t hugetlbfs
mount -a
</pre></div></div>
</li>
</ul></div>
<div class="section">
<h3><a name="No_ethernet_ports_detected"></a>No ethernet ports detected</h3>
<p>Problem: When executing <tt>fastcapa</tt> it fails with the following error message.</p>
<div>
<div>
<pre class="source">EAL: Error - exiting with code: 1
Cause: No ethernet ports detected.
</pre></div></div>
<ul>
<li>Solution 1: The <tt>uio_pci_generic</tt> kernel module has not been loaded.</li>
</ul>
<div>
<div>
<pre class="source">modprobe uio_pci_generic
</pre></div></div>
<ul>
<li>Solution 2: Ensure that the ethernet device is bound. Re-bind if necessary.</li>
</ul>
<div>
<div>
<pre class="source"> dpdk-devbind --unbind &quot;09:00.0&quot;
dpdk-devbind --bind=uio_pci_generic &quot;09:00.0&quot;
dpdk-devbind --status
</pre></div></div></div></div>
</div>
</div>
</div>
<hr/>
<footer>
<div class="container-fluid">
<div class="row-fluid">
© 2015-2016 The Apache Software Foundation. Apache Metron, Metron, Apache, the Apache feather logo,
and the Apache Metron project logo are trademarks of The Apache Software Foundation.
</div>
</div>
</footer>
</body>
</html>