• 让Kafka在scala里面跑起来


    Kafka集群对消息的保存是根据Topic进行归类的,由消息生产者(Producer)和消息消费者(Consumer)组成,另外,每一个Server称为一个Broker(经纪人)。对于Kafka集群而言,Producer和Consumer都依赖于ZooKeeper来保证数据的一致性。

      在每条消息输送到Kafka集群后,消息都会有一个Type,这个Type被称为一个Topic,不同的Topic的消息是分开存储的。每个Topic可以被分割为多个Partition,在每条消息中,它在文件中的位置称为Offset,用于标记唯一一条消息。在Kafka中,消息被消费后,消息仍然会被保留一定时间后在删除,比如在配置信息中,文件信息保留7天,那么7天后,不管Kafka中的消息是否被消费,都会被删除;以此来释放磁盘空间,减少磁盘的IO消耗。

      在Kafka中,一个Topic的多个分区,被分布在Kafka集群的多个Server上,每个Server负责分区中消息的读写操作。另外,Kafka还可以配置分区需要备份的个数,以便提高可用行。由于用到ZK来协调,每个分区都有一个Server为Leader状态,服务对外响应(如读写操作),若该Leader宕机,会由其他的Follower来选举出新的Leader来保证集群的高可用性。

    一个Topic中的消息数据按照多个分区组织,分区是kafka消息队列组织的最小单位,一个分区可以看作是一个FIFO( First Input First Output)的队列。

    kafka分区是提高kafka性能的关键所在,当你发现你的集群性能不高时,常用手段就是增加Topic的分区,分区里面的消息是按照从新到老的顺序进行组织,消费者从队列头订阅消息,生产者从队列尾添加消息。

    编译报错:WARN Selector: Error in I/O with localhost/127.0.0.1

    java.io.EOFException

    错误:https://issues.apache.org/jira/browse/KAFKA-3205

    环境准备:

    1. Java JDK (jdk1.8.0_112 64-bit)

    安装完成后添加系统变量:

    JAVA_HOME= C:Program FilesJavajdk1.8.0_112

    并在系统变量Path后添加 ;%JAVA_HOME%in;

    2. Apache ZooKeeper

    ① 解压进入目录E:ookeeperzookeeper-3.4.11conf

    ② 将“zoo_sample.cfg”重命名为“zoo.cfg”

    ③ 打开“zoo.cfg”找到并编辑dataDir=E:ookeeperzookeeper-3.4.11data

    ④ 添加系统变量:ZOOKEEPER_HOME= E:ookeeperzookeeper-3.4.11,并在系统变量Path后添加;%ZOOKEEPER_HOME%in;

    ⑤ 查看zoo.cfg文件clientPort默认值是否为2181

    ⑥ cmd中输入zkServer ,如下图则表示ZooKeeper启动成功(窗口不要关闭)

    3. Apache Kafka(请选择Binary downloads)

    ① 压进入目录E:kafka_2.12-1.0.0config

    ② 打开server.properties并编辑log.dirs=E:kafka_2.12-1.0.0kafka-logs

    ③ 确认zookeeper.connect=localhost:2181

    ④ 进入目录E:kafka_2.12-1.0.0并Shift+右键,选择“打开命令窗口”,输入:

    .inwindowskafka-server-start.bat .configserver.properties

    如果是第二次启动,则需要进入目录删除文件夹kafka_2.12-1.0.0kafka-logs后重新运行命令。

    代码测试(scala maven项目):

    1. pom.xml

    <dependency>

        <groupId>org.apache.spark</groupId>

        <artifactId>spark-core_2.10</artifactId>

        <version>1.5.1</version>

    </dependency>

    <dependency>

        <groupId>org.apache.kafka</groupId>

        <artifactId>kafka-clients</artifactId>

        <version>0.9.0.1</version>

    </dependency>

    说明:kafka-clients不要使用0.8.2.1版本,因为它的poll函数直接返回了null

    另外在0.9.0版本之后,consumer api不再区分high-level和low-level了。

    2. producer.scala

    import java.io.{File, FileInputStream}

    import java.util.Properties

    import org.apache.kafka.clients.producer.{KafkaProducer, ProducerConfig, ProducerRecord}

    import org.apache.spark.rdd.RDD

    import org.apache.spark.{SparkConf, SparkContext}

    object producer {

      def main(args: Array[String]): Unit = {

        val sparkConf = new SparkConf()

        sparkConf.setAppName("kafka").setMaster("local[4]").set("SPARK_EXECUTOR_CORES","1")

        val sc = new SparkContext(sparkConf)

        val topic: RDD[String] = sc.textFile(s"F:/123456.txt")

        val kafkaProducerCfg = "E:\kafka_2.12-1.0.0\config\producer.properties"

        val kafkaprop = new Properties()

        kafkaprop.load(new FileInputStream(new File(kafkaProducerCfg)))

        topic.repartition(1).foreachPartition((partisions: Iterator[String]) => {

          val producer: KafkaProducer[String, String] = new KafkaProducer[String, String](kafkaprop)

          var pr = new ProducerRecord[String, String]("my-topic","my-key", "hi laosiji ")

          producer.send(pr)

          pr = new ProducerRecord[String, String]("finally","kafka", "可用了 ")

          producer.send(pr)

        partisions.foreach((line: String) => {

          try {

            val pr = new ProducerRecord[String, String]("my-topic","my-key", line)

            producer.send(pr)

          } catch {

            case ex: Exception => println(ex.getMessage, ex)

          }

        }) 

          producer.close()

        })

      }

    }

    3. consumer.scala

    import java.io.{File, FileInputStream}

    import java.util.Properties

    import scala.collection.JavaConverters._

    import org.apache.kafka.clients.consumer.{ConsumerRecords, KafkaConsumer}

    object consumer {

      def main(args: Array[String]): Unit = {

        val kafkaProducerCfg = "E:\kafka_2.12-1.0.0\config\consumer.properties"

        val is = new FileInputStream(new File(kafkaProducerCfg))

        val kafkaprop = new Properties()

        // kafkaprop.load(is)

        is.close()

        kafkaprop.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")

        kafkaprop.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")

       // kafkaprop.put("partition.assignment.strategy", "range")

        kafkaprop.put("group.id", "test")

        kafkaprop.put("enable.auto.commit", "true")

        kafkaprop.put("auto.commit.interval.ms", "1000")

        kafkaprop.put("session.timeout.ms", "6000")

        kafkaprop.put("bootstrap.servers","localhost:9092")

        try{

          val consumer: KafkaConsumer[String,String] = new KafkaConsumer[String,String](kafkaprop)

          consumer.subscribe(java.util.Arrays.asList("my-topic","finally"))

          while (true) {

            val records = consumer.poll(1000)

            var it = records.records("my-topic").iterator()

            while (it.hasNext){

              println(it.next())

            }

            it = records.records("finally").iterator()

            while (it.hasNext){

              println(it.next())

            }

          }

          consumer.close()

        } catch {

          case e => e.printStackTrace()

        }

      }

    }

    4. 先启动consumer,再启动producer,可以在控制台看到运行结果。

    控制台测试:

    1. 进入目录E:kafka_2.12-1.0.0创建Topic 

    .inwindowskafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 –topic HelloKafka 

     查看Topic:

    .inwindowskafka-topics.bat --list --zookeeper localhost:2181

    2. 进入目录E:kafka_2.12-1.0.0打开cmd创建生产者:

    .inwindowskafka-console-producer.bat --broker-list localhost:9092 --topic HelloKafka

    3. 进入目录E:kafka_2.12-1.0.0打开cmd创建消费者:

    .inwindowskafka-console-consumer.bat --bootstrap-server localhost:9092 --topic HelloKafka --from-beginning

  • 相关阅读:
    [vijos P1531] 食物链
    [USACO精选] 第二章 动态规划(一)
    python 二分法查找
    python 小试牛刀之信息管理
    C语言链表实现冒泡法排序
    [笔记]libgdx在一张pixmap上按照笔刷画图
    [libgdx]项目通过RoboVm编译到ios平台并运行的环境配置
    android中sqlite distinct中使用多个字段的方法
    libgdx游戏中的中文字体工具类
    C语言实现字符串拷贝 拷贝指定长度字符串 字符串连接
  • 原文地址:https://www.cnblogs.com/envoy/p/8358737.html
Copyright © 2020-2023  润新知