SparkSqlは、カスタムデータソースの実装から読み取ります

プロセスデータのソースは.sparksqlを読み取ります

1.spark現在、読書JDBC、ハイブ、テキスト、オークや他の種類のデータをサポートすることがHBaseのか、他のデータソースをサポートするためであれば、あなたがカスタマイズする必要があります

 2.読み取り処理

(1)sparksql进行session.read.text()或者session.read .format( "テキスト").OPTIONS(地図( "" - > "B"))。負荷( "")

 

 

 

 

。読む:オブジェクトの作成DataFrameReader

方法フォーマット:DataFrameReadeを割り当てられたデータ・ソース・タイプ

オプション方法:割り当てDataFrameReade追加の構成オプション

 内部はsession.read.text()メソッドを入力して、あなたはフォーマットが「テキスト」で見ることができます

Loadメソッドに(2)

 負荷があることが判明:sparkSession.baseRelationToDataFrameこの方法は、最終的にデータフレームを作成します

(3 に入るデータソースresolveRelation()メソッドを

 

 この段落は、次のとおりprovidingClassこのクラスは、無着信スキーマ2つのシェマとに分割されているインタフェースが存在する実装するクラスであります

(3)providingClassフォーマットは、着信データ・ソース・タイプであり、ソースの前にあります

 

 

 地図スパーク源は、すべてのデータを提供します

 4. ちょうど実装RelationProviderがメソッドbaserelationに戻る方法は、次のことクラスを作成結論します

DEFのCreateRelation(sqlContext:SQLContext、パラメータ:地図[文字列、文字列]):BaseRelation

 我们在实现baserelation里面的逻辑就可以了

 5.看看spark读取jdbc类

需要一个类,实现xxxScan这中类,这种类有三种,全局扫描tableScan,PrunedFilteredScan(列裁剪与谓词下推),PrunedScan ,

实现buildscan方法返回row类型rdd,结合baserelation有shcame这个变量 ,就凑成了dataframe

 6.jdbcRdd.scanTable方法,得到RDD

7.查看jdbcRDD的compute方法,是通过jdbc查询sql的方式获取数据

RDD的计算是惰性的,一系列转换操作只有在遇到动作操作是才会去计算数据,而分区作为数据计算的基本单位。在计算链中,无论一个RDD有多么复杂,其最终都会调用内部的compute函数来计算一个分区的数据。

override def compute(thePart: Partition, context: TaskContext): Iterator[InternalRow] = {
    var closed = false
    var rs: ResultSet = null
    var stmt: PreparedStatement = null
    var conn: Connection = null

    def close() {
      if (closed) return
      try {
        if (null != rs) {
          rs.close()
        }
      } catch {
        case e: Exception => logWarning("Exception closing resultset", e)
      }
      try {
        if (null != stmt) {
          stmt.close()
        }
      } catch {
        case e: Exception => logWarning("Exception closing statement", e)
      }
      try {
        if (null != conn) {
          if (!conn.isClosed && !conn.getAutoCommit) {
            try {
              conn.commit()
            } catch {
              case NonFatal(e) => logWarning("Exception committing transaction", e)
            }
          }
          conn.close()
        }
        logInfo("closed connection")
      } catch {
        case e: Exception => logWarning("Exception closing connection", e)
      }
      closed = true
    }

    context.addTaskCompletionListener{ context => close() }

    val inputMetrics = context.taskMetrics().inputMetrics
    val part = thePart.asInstanceOf[JDBCPartition]
    conn = getConnection()
    val dialect = JdbcDialects.get(url)
    import scala.collection.JavaConverters._
    dialect.beforeFetch(conn, options.asProperties.asScala.toMap)

    // H2's JDBC driver does not support the setSchema() method.  We pass a
    // fully-qualified table name in the SELECT statement.  I don't know how to
    // talk about a table in a completely portable way.

//坐上每个分区的Filter条件
    val myWhereClause = getWhereClause(part)

  //最終查询sql语句
    val sqlText = s"SELECT $columnList FROM ${options.table} $myWhereClause"
//jdbc查询
    stmt = conn.prepareStatement(sqlText,
        ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)
    stmt.setFetchSize(options.fetchSize)
    rs = stmt.executeQuery()

    val rowsIterator = JdbcUtils.resultSetToSparkInternalRows(rs, schema, inputMetrics)
//返回迭代器
    CompletionIterator[InternalRow, Iterator[InternalRow]](
      new InterruptibleIterator(context, rowsIterator), close())
  }

  

おすすめ

転載: www.cnblogs.com/hejunhong/p/12405517.html
おすすめ