As an extension of Spark Core, Spark Streaming is used for high-throughput and fault-tolerant processing of continuous data. Currently supported external input sources include Kafka, Flume, HDFS/S3, Kinesis, Twitter, and TCP socket.


Spark Streaming abstracts continuous data into DStream (Discretized Stream), which is composed of a series of continuous RDDs (Resilient Distributed Datasets). Each RDD represents data generated over a certain time interval. Processing a DStream using functions is essentially processing these RDDs.


When Spark Streaming is used as data input for Kafka, the following stable and experimental Kafka versions are supported:
Kafka Version | spark-streaming-kafka-0.8 | spark-streaming-kafka-0.10 |
Broker Version | 0.8.2.1 or higher | 0.10.0 or higher |
Api Maturity | Deprecated | Stable |
Language Support | Scala、Java、Python | Scala、Java |
Receiver DStream | Yes | No |
Direct DStream | Yes | Yes |
SSL / TLS Support | No | Yes |
Offset Commit Api | No | Yes |
Dynamic Topic Subscription | No | Yes |
Currently, CKafka is compatible with version above 0.9. The Kafka dependency of v0.10.2.1 is used in this practice scenario.
Additionally, Spark Streaming in EMR also supports direct integration with CKafka. For more information, see Spark Streaming Integration with CKafka Service.
Instructions
Step 1. Get the CKafka instance access address
1. Log in to the CKafka console.
2. In the left navigation bar, select Instance List, then click on the instance "ID" to access the basic information page of the instance.
3. On the Access Mode module of the instance's basic information page, you can obtain the instance's access address, which is the bootstrap-server required for production and consumption.


Step 2. Create a topic
1. On the instance basic information page, select the Topic Management tab at the top.
2. On the Topic Management page, click Create to establish a Topic named 'test'. The following discussion will use this Topic as an example to illustrate how to produce and consume.


Step 3. Prepare the CVM environment
CentOS 6.8 System
package | version |
sbt | 0.13.16 |
hadoop | 2.7.3 |
spark | 2.1.0 |
protobuf | 2.5.0 |
ssh | Default CentOS Installation |
Java | 1.8 |
Step 4. Connect to CKafka
The Kafka dependency of v0.10.2.1 is used here.
1. Add dependencies to the
build.sbt file:name := "Producer Example"version := "1.0"scalaVersion := "2.11.8"libraryDependencies += "org.apache.kafka" % "kafka-clients" % "0.10.2.1"
2. Configure
producer_example.scala:import java.util.Propertiesimport org.apache.kafka.clients.producer._object ProducerExample extends App {val props = new Properties()props.put("bootstrap.servers", "172.16.16.12:9092") //Private IP and port from the instance informationprops.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")val producer = new KafkaProducer[String, String](props)val TOPIC="test" //Specify the Topic to producefor(i<- 1 to 50){val record = new ProducerRecord(TOPIC, "key", s"hello $i") //Produces a message with the key as "key" and value as "hello i"producer.send(record)}val record = new ProducerRecord(TOPIC, "key", "the end "+new java.util.Date)producer.send(record)producer.close() // Finally, disconnect}
DirectStream
1. Add dependencies to the
build.sbt file:name := "Consumer Example"version := "1.0"scalaVersion := "2.11.8"libraryDependencies += "org.apache.spark" %% "spark-core" % "2.1.0"libraryDependencies += "org.apache.spark" %% "spark-streaming" % "2.1.0"libraryDependencies += "org.apache.spark" %% "spark-streaming-kafka-0-10" % "2.1.0"
2. Configure
DirectStream_example.scala:import org.apache.kafka.clients.consumer.ConsumerRecordimport org.apache.kafka.common.serialization.StringDeserializerimport org.apache.kafka.common.TopicPartitionimport org.apache.spark.streaming.kafka010._import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistentimport org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribeimport org.apache.spark.streaming.kafka010.KafkaUtilsimport org.apache.spark.streaming.kafka010.OffsetRangeimport org.apache.spark.streaming.{Seconds, StreamingContext}import org.apache.spark.SparkConfimport org.apache.spark.SparkContextimport collection.JavaConversions._import Array._object Kafka {def main(args: Array[String]) {val kafkaParams = Map[String, Object]("bootstrap.servers" -> "172.16.16.12:9092","key.deserializer" -> classOf[StringDeserializer],"value.deserializer" -> classOf[StringDeserializer],"group.id" -> "spark_stream_test1","auto.offset.reset" -> "earliest","enable.auto.commit" -> "false")val sparkConf = new SparkConf()sparkConf.setMaster("local")sparkConf.setAppName("Kafka")val ssc = new StreamingContext(sparkConf, Seconds(5))val topics = Array("spark_test")val offsets : Map[TopicPartition, Long] = Map()for (i <- 0 until 3){val tp = new TopicPartition("spark_test", i)offsets.updated(tp , 0L)}val stream = KafkaUtils.createDirectStream[String, String](ssc,PreferConsistent,Subscribe[String, String](topics, kafkaParams))println("directStream")stream.foreachRDD{ rdd=>// Output the received messagerdd.foreach{iter =>val i = iter.valueprintln(s"${i}")}//Acquiring the offsetval offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRangesrdd.foreachPartition { iter =>val o: OffsetRange = offsetRanges(TaskContext.get.partitionId)println(s"${o.topic} ${o.partition} ${o.fromOffset} ${o.untilOffset}")}}// Start the computationssc.start()ssc.awaitTermination()}}
RDD
1. Configure
build.sbt (configuration is the same as above, click to view).2. Configuration of
RDD_example:import org.apache.kafka.clients.consumer.ConsumerRecordimport org.apache.kafka.common.serialization.StringDeserializerimport org.apache.spark.streaming.kafka010._import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistentimport org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribeimport org.apache.spark.streaming.kafka010.KafkaUtilsimport org.apache.spark.streaming.kafka010.OffsetRangeimport org.apache.spark.streaming.{Seconds, StreamingContext}import org.apache.spark.SparkConfimport org.apache.spark.SparkContextimport collection.JavaConversions._import Array._object Kafka {def main(args: Array[String]) {val kafkaParams = Map[String, Object]("bootstrap.servers" -> "172.16.16.12:9092","key.deserializer" -> classOf[StringDeserializer],"value.deserializer" -> classOf[StringDeserializer],"group.id" -> "spark_stream","auto.offset.reset" -> "earliest","enable.auto.commit" -> (false: java.lang.Boolean))val sc = new SparkContext("local", "Kafka", new SparkConf())val java_kafkaParams : java.util.Map[String, Object] = kafkaParams//Fetch messages from the partition in the specified offset range sequentially. If no messages are available, block until the wait time is exceeded or the required number of new messages is produced.val offsetRanges = Array[OffsetRange](OffsetRange("spark_test", 0, 0, 5),OffsetRange("spark_test", 1, 0, 5),OffsetRange("spark_test", 2, 0, 5))val range = KafkaUtils.createRDD[String, String](sc,java_kafkaParams,offsetRanges,PreferConsistent)range.foreach(rdd=>println(rdd.value))sc.stop()}}
Environment Configuration
Installing sbt
1. Download the sbt package from the sbt official website.
2. After decompression, create an
sbt_run.sh script with the following content in the sbt directory and add executable permissions:#!/bin/bashSBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"java $SBT_OPTS -jardirname$0/bin/sbt-launch.jar "$@"
chmod u+x ./sbt_run.sh
3. Run the following command:
./sbt-run.sh sbt-version
The display of sbt version indicates a successful installation.
Installing Protobuf
1. Download the corresponding version of protobuf.
2. Decompress and enter the directory.
./configuremake && make install
You should install gcc-g++ in advance, and the root permission may be required during installation.
3. Log in again and enter the following on the command line:
protoc --version
4. The display of Protobuf version indicates a successful installation.
Installing Hadoop
1. Visit the Hadoop official website to download the desired version.
2. Add a Hadoop user.
useradd -m hadoop -s /bin/bash
3. Grant admin permissions.
visudo
4. Add a new line below
root ALL=(ALL) ALL: hadoop ALL=(ALL) ALL. Save and exit.5. Use Hadoop for operations.
su hadoop
6. Configure SSH password-free login.
cd ~/.ssh/ # If there is no such directory, runssh localhostfirstssh-keygen -t rsa # There will be prompts. Simply press Entercat id_rsa.pub >> authorized_keys # Add authorizationchmod 600 ./authorized_keys # Modify file permission
7. Install Java.
sudo yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel
8. Configure
${JAVA_HOME}.vim /etc/profile
Add the following at the end:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el6_8.x86_64/jreexport PATH=$PATH:$JAVA_HOME
Modify the corresponding path based on the installation information.
9. Decompress Hadoop and enter the directory.
./bin/hadoop version
The display of version information indicates a successful installation.
10. Configure a pseudo-distributed single-node setup (different types of clusters can be built as per requirements).
vim /etc/profile
Add the following at the end:
export HADOOP_HOME=/usr/local/hadoopexport PATH=$HADOOP_HOME/bin:$PATH
Modify the corresponding path based on the installation information.
11. Modify the
/etc/hadoop/core-site.xml file.<configuration><property><name>hadoop.tmp.dir</name><value>file:/usr/local/hadoop/tmp</value><description>Abase for other temporary directories.</description></property><property><name>fs.defaultFS</name><value>hdfs://localhost:9000</value></property></configuration>
12. Modify the
/etc/hadoop/hdfs-site.xml file.<configuration><property><name>dfs.replication</name><value>1</value></property><property><name>dfs.namenode.name.dir</name><value>file:/usr/local/hadoop/tmp/dfs/name</value></property><property><name>dfs.datanode.data.dir</name><value>file:/usr/local/hadoop/tmp/dfs/data</value></property></configuration>
13. Modify the JAVA_HOME in
/etc/hadoop/hadoop-env.sh to the path of Java.export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el6_8.x86_64/jre
14. Perform NameNode formatting.
./bin/hdfs namenode -format
If
Exitting with status 0 is displayed, the operation is successful.15. Initiate Hadoop.
./sbin/start-dfs.sh
Upon successful startup, the following processes will be present:
NameNode, DataNode, and SecondaryNameNode.Installing Spark
Visit the Spark official website to download the desired version.
Since Hadoop has been previously installed, select
Pre-built with user-provided Apache Hadoop.Note
In this example, the
hadoop user is also used for the operations.1. Decompress and enter the directory.
2. Modify the configuration file.
cp ./conf/spark-env.sh.template ./conf/spark-env.shvim ./conf/spark-env.sh
Add the following in the first line:
export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)
Modify the path based on the Hadoop installation information.
3. Run the example.
bin/run-example SparkPi
The display of an approximate value of
π output by the program indicates a successful installation.