• Spark如何写入HBase/Redis/MySQL/Kafka


    一些概念

    一个partition 对应一个task,一个task 必定存在于一个Executor,一个Executor 对应一个JVM.

    • Partition 是一个可迭代数据集合
    • Task 本质是作用于Partition的线程

    问题

    Task 里如何使用Kafka Producer 将数据发送到Kafka呢。 其他譬如HBase/Redis/MySQL 也是如此。

    解决方案

    直观的解决方案自然是能够在Executor(JVM)里有个Prodcuer Pool(或者共享单个Producer实例),但是我们的代码都是
    先在Driver端执行,然后将一些函数序列化到Executor端执行,这里就有序列化问题,正常如Pool,Connection都是无法序列化的。

    一个简单的解决办法是定义个Object 类,

    譬如

    object SimpleHBaseClient {
      private val DEFAULT_ZOOKEEPER_QUORUM = "127.0.0.1:2181"
    
      private lazy val (table, conn) = createConnection
    
      def bulk(items:Iterator) = {
          items.foreach(conn.put(_))
          conn.flush....
      } 
     ......
    }

    然后保证这个类在map,foreachRDD等函数下使用,譬如:

    dstream.foreachRDD{ rdd =>
        rdd.foreachPartition{iter=>
            SimpleHBaseClient.bulk(iter)  
        }
    }

    为什么要保证放到foreachRDD/map 等这些函数里呢?
    Spark的机制是先将用户的程序作为一个单机运行(运行者是Driver),Driver通过序列化机制,将对应算子规定的函数发送到Executor进行执行。这里,foreachRDD/map 等函数都是会发送到Executor执行的,Driver端并不会执行。里面引用的object 类 会作为一个stub 被序列化过去,object内部属性的初始化其实是在Executor端完成的,所以可以避过序列化的问题。

    Pool也是类似的做法。然而我们并不建议使用pool,因为Spark 本身已经是分布式的,举个例子可能有100个executor,如果每个executor再搞10个connection
    的pool,则会有100*10 个链接,Kafka也受不了。一个Executor 维持一个connection就好。

    关于Executor挂掉丢数据的问题,其实就看你什么时候flush,这是一个性能的权衡。

  • 相关阅读:
    android studio 修改应用程序图标
    [AppDelegate window]: unrecognized selector sent to instance 0x600002b178e0
    Error compiling file: /private/var/folders/tm/rj18p_ls10lb_fsqfc7h4trm0000gn/T/jetty-0.0.0.0-8081-WebRoot-_-any-/jsp/org/apache/jsp/login_jsp.java
    mac下eclipse突然打不开了,直接停在启动页上不动
    iOS下收不到通知,或者只收到一个通知
    名词:箭头函数
    名词:硬编码
    keil5开发工具
    Android系统源码学习步骤 ,linux学习方向
    小白学习Spark系列一:Spark简介
  • 原文地址:https://www.cnblogs.com/itboys/p/8051910.html
Copyright © 2020-2023  润新知