A, 스트리밍 불꽃
스파크 스트리밍 점화 API는 코어의 확장 실시간 데이터 스트림, 높은 처리량, 결함 허용 프로세스 스트림을 확장 할 수있다. 데이터는 다양한 소스 (예를 들면, 카프카, 수로, 운동성 또는 TCP 소켓)로부터 추출 될 수 있고, 복잡한 알고리즘에 의해 표시되는 높은 수준의 기능을 처리하기 위해 사용될 수있다 map
, 예를 들어, reduce
, join
및 window
. 마지막으로, 처리 된 데이터는, 파일 시스템, 데이터베이스 및 실시간 대시로 푸시 될 수있다.
두, SparkStreaming 달성
카프카와 사육사가 설치 사전, 사육사를 설치하지 마십시오, 당신은 카프카 서비스를 실행할 수 없습니다. 그러나 클러스터를 설치하고 CloudKarafka 사육사로 구성되었습니다.
나는 스칼라 받는다는 프로젝트, 환경 프로젝트입니다 내장하고 단일 시스템에서 실행됩니다.
1, 내 pom.xml 파일의 구성을 보면 :
<? XML 버전 = "1.0"인코딩 = "UTF-8"?> <프로젝트의 xmlns = "http://maven.apache.org/POM/4.0.0" 에 xmlns :이 xsi = "HTTP : //www.w3 .ORG / 2001 / 된 XMLSchema 인스턴스 " 는 xsi :의 schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd "> <modelVersion> 4.0.0 </ modelVersion> <의 groupId> com.sparkstream </의 groupId> <artifactId를> LyhSparkStreaming </ artifactId를> <version>은 1.0 SNAPSHOT </ 버전> <속성> <spark.version> 2.3.3 < /spark.version> <scala.version> 2.11 </scala.version> </ 속성> <의존성> <의존성> <의 groupId> org.apache.spark </의 groupId> <artifactId를> 스파크 코어 _ scala.version $ {} </ artifactId를> <버전> $ {spark.version} </ 버전> <제외> <배제> <의 groupId> 평민 - beanutils </의 groupId> <artifactId를> 평민 - beanutils 코어 </ artifactId를> </ 배제> </ 제외> < / 의존성> <! - https://mvnrepository.com/artifact/org.apache.spark/spark-streaming-kafka -> <의존성> <의 groupId> org.apache.spark </의 groupId> <artifactId를> 스파크 -streaming-kafka_2.11 </ artifactId를> <version>은 1.6.3 </ 버전> </ 의존성> <의존성> <의 groupId> org.apache.spark </의 groupId> <artifactId를> 스파크 스트리밍 _ scala.version $ {} </ artifactId를> <version>은 $ {spark.version} </ 버전> </ 의존성> <의존성 > <의 groupId> org.apache.spark </의 groupId> <artifactId를> 스파크 SQL _ scala.version $ {} </ artifactId를> <version>은 $ {spark.version} </ 버전> </ 의존성> <의존성> < 의 groupId> org.apache.spark </의 groupId> <artifactId를> 스파크 하이브 _ scala.version $ {} </ artifactId를> <버전>$ {spark.version} </ 버전> </ 의존성> <의존성> <의 groupId> org.apache.spark </의 groupId> <artifactId를> 스파크 mllib _ scala.version $ {} </ artifactId를> <version>은 $ {spark.version} </ 버전> </ 의존성> </ 의존성> < > 구축 <플러그인> <플러그인> <의 groupId> org.scala-도구 </의 groupId> <artifactId를> 받는다는 - 스칼라 - 플러그인 </ artifactId를> <버전> 2.15.2 </ 버전> <실행> <실행> <목표를 > <목표> 컴파일 </ 목표> <목표> testCompile </ 목표> </ 목표> </ 실행> </ 실행> </ 플러그인> <플러그인> <artifactId를> 받는다는 컴파일러 - 플러그인 </ artifactId를> <version>은 3.6.0 </ 버전> <구성> <소스> 1.8 </ 소스> <목표> 1.8 </ 대상> </ 구성> </ 플러그인> <플러그인> <의 groupId> org.apache.maven.plugins </의 groupId> <artifactId를> 받는다는 - 확실한 - 플러그인 </ artifactId를> <버전> 2.19 </ 버전> <구성> <스킵> 진정한 </ 스킵> </ 구성></ 스킵> 진정한 </ 플러그인> </ 플러그인> </ 빌드> </ 프로젝트>
나는 스칼라 버전 2.11.8을 사용합니다.
2, 내 생산자, text1.txt 코드는 파일의 내용을 읽은 다음 카프카의 각 행에 데이터를 전송 헌터라는 주제를 ,이 이름은이 주제는 카프카의 말에 존재하지 않는 경우, 시스템 것, 그것을 자신 할 수 있습니다 자동으로 생성. 자신에게 파일을 생성 text1.txt, 라인 데이터에 의해 라인이 될 수있다, 어떤 경로를 자체로 파일을 요청하지 않았다.
KafkaAndStreaming 패키지 가져 오기는 java.io {을, BufferedReader의 FileInputStream에, FileNotFoundException이, IOException가의 InputStreamReader} java.util.Properties 가져 오기 org.apache.kafka.clients.consumer.KafkaConsumer 가져 오기 org.apache.kafka.clients.producer를. {콜백, KafkaProducer, 프로듀서, ProducerRecord, RecordMetadata} 오브젝트 {TestKafkaProducer 유형 문자열의 = 키 에 문자열 유형 = 발의 DEF getProducerCnfig () : 속성 = { / ** * 카프카 생산 관련 구성 파일 항목에 대한 * 확인 자신의 다른 속성이있다 ** / 발 소품 다음은 속성 = 새로운 새로운 속성은 () // 카프카는 URL에 거주하는 데 사용 props.put ( "bootstrap.servers", "로컬 호스트 : 9092") // group.id 바로 쓰기 props.put ( "group.id", "프로듀서 그룹") props.put ( "replication.factor", "min.insync.replicas") //备份数量 props.put ( "min.insync.replicas을" "3") props.put ( "key.serializer", "org.apache.kafka.common.serialization.StringSerializer") props.put ( "value.serializer", "org.apache.kafka.common.serialization.StringSerializer ") 소품 } 데프 주 (인수 : 배열 [문자열]) = { //获取配置文件 발 소품 : 속성 = getProducerCnfig () //创建生产者 VAR 생산 = 새로운 KafkaProducer [문자열, 문자열 (소품) {시도 / /读取保存的文件 발 FIS :FileInputStream에 = 새로운 FileInputStream에 ( "/ 사용자 / 사냥꾼 / text1.txt") 발 ISR :InputStreamReader = 새로운 InputStreamReader (FIS, "UTF-8") 발에 BR : BufferedReader로 = 새의 BufferedReader (ISR) VAR 라인 : 문자열 = "" 라인 = br.readLine () VAR I : 지능 = 0 동안 (! 라인 = NULL) { producer.send (toMessage (line.toString, 옵션 ( i.toString), 옵션 ( "헌터")), 새로운 콜백 { onCompletion (recordMetadata 데프 재정의 : recordMetadata, E : 예외) : 단위 = { ""+ recordMetadata :에 println (들은 "" "메시지 $ 난에 보내" .topic ()) } }) I + = 1 개 라인 = br.readLine () } producer.close () br.close () } {캐치 케이스 예 :FileNotFoundException이 => {) (가까운 ) (isr.close fis.close () 키 일치 { 에 println ( "파일 예외 없음") } 의 경우 예 : IOException이 => { 에 println ( "IO 예외") } 의 경우 _ => { 에 println ( "다른 오류를 가지고") } } // dealWithData } //把我的消息包装成了ProducerRecord 개인 toMessage 데프 (값 : 문자열, 키 : 옵션 [문자열] = 없음 : 옵션 [키] 없음, 주제 =) : ProducerRecord [키, 발] = { 발 t = topic.getOrElse (옵션 ( "테스트" ) .getOrElse가)) (새, IllegalArgumentException를 슬로우 ( "항목 또는 기본 항목을 제공해야합니다") (! t.isEmpty, "주제는 비워 둘 수 없습니다")이 필요한 경우 일부 (k)를 => 새로운 ProducerRecord (t, K, 값) 의 경우 _ => 새로운 ProducerRecord (t, 값) } } }
3 주 함수 매개 변수가 매개 변수를 시작하는 데 필요한 내 소비자 끝, localhost입니다 : 9092 헌터
다음과 같이 코드입니다 :
KafkaAndStreaming 패키지 가져 오기 kafka.common.TopicAndPartition 가져 오기 kafka.message.MessageAndMetadata 가져 오기 kafka.serializer.StringDecoder 가져 오기 org.apache.spark. SparkConf {} TaskContext 가져 오기 org.apache.spark.streaming.kafka. {HasOffsetRanges, KafkaUtils, OffsetRange} {org.apache.spark.streaming 초 오기, StreamingContext}. KafkaAndPrintInSpark 객체 { // 항목 길이 매개 변수는 적어도 2 주제 즉, 단일 테스트 실행 브로커를 포함하도록 상기 입력 파라미터 세트가 결정되면,인지 : 로컬 호스트 = 브로커 : 시험 주제 = 9092 DEF 메인 (인수 : 배열 [문자열]) { IF (args.length <2) { System.err.println을 ( S "" " | 사용법 : DirectKafkaWordCount <중개사> <주제> | <중개사> 하나 이상의 카프카 브로커의 목록입니다 <주제> 카프카에서 소비하는 하나 개 이상의 주제의 목록입니다 |는 "" ".stripMargin) .을 System.exit (1) } 매개 변수 인수로 읽어 //은 어레이 브로 어레이 (중개인 주제) = 인수는 // 컨텍스트를 생성하기 위해 2 초 간격으로 일괄 브로 sparkConf 새로운 새 sparkConf = (). setMaster ( "로컬 [2]"). setAppName ( "DirectKafkaWordCount")를 발 StreamingContext 새로운 새 SSC = ( sparkConf, 초이 빠른 (5)) // 브로커와 주제와 카프카 스트림을 생성 toset) ","발 topicsSet = topics.split (. 발 kafkaParams이지도 [문자열, 문자열 (= "metadata.broker.list"-> 브로커, "bootstrap.servers"->"로컬 호스트 : 9092" // "auto.offset.reset"-> "작은", "key.deserializer "->"org.apache.kafka.common.serialization.StringDeserializer " "value.deserializer"-> "org.apache.kafka.common.serialization.StringDeserializer") 발 메시지 = KafkaUtils.createDirectStream [문자열, 문자열, StringDecoder, StringDecoder ( SSC, kafkaParams, topicsSet) 정의는 상기도 5 (5L)로부터 판독 된 오프셋을 나타내는 // 주석 부. 기본값은 시작 마지막으로 읽은 위치의 끝에서 오프셋, 최신을 읽는 것입니다 // 발 offsetList 목록 = (( "헌터", 0, 5L)) // 발 fromOffsets의 =의 setFromOffsets (offsetList) // 처리 목록, 원하는 포맷으로, 즉, 맵 [TopicAndPartition 롱] // =에 messageHandler 발 (MAM : MessageAndMetadata [문자열, 문자열) => (mam.topic, mam.message ()) // 구축 MessageAndMetadata 모두 사용 같은, 그래서 쓰기 = KafkaUtils.createDirectStream [문자열, // 발 메시지를 문자열, StringDecoder, // SSC, kafkaParams, fromOffsets,에 messageHandler) messages.foreachRDD (RDD => { // IF (rdd.count ()> 0) { rdd.foreach (기록 => { 에 println ( "_ 1 :"+ records._1) 에 println ( "_ 2 :"+ records._2) }) 브로 offsetRanges = rdd.asInstanceOf [HasOffsetRanges] .offsetRanges의 rdd.foreachPartition {ITER => 발 O : OffsetRange = offsetRanges (TaskContext.get.partitionId ()) 에 println (들 "$ {o.topic} $ {o.partition} $ {o.fromOffset} $ {o.untilOffset}") } //} } ) //开始计算 ssc.start () ssc.awaitTermination () } 데프 setFromOffsets (목록 : 목록 [(문자열, INT, 롱)]) : 맵 [TopicAndPartition, 긴] = { var에 fromOffsets : 맵 [TopicAndPartition, 긴] =지도 () 대한 (오프셋 <- 목록) { 발 TP = TopicAndPartition (offset._1을 offset._2) 파티션과 주제의 // 수 fromOffsets + = (TP -> offset._3 ) // 오프셋 위치 } fromOffsets } }
셋째, 최종 결과
1 생산국
2, 소비자