Перейти к основному содержимому
Перейти к основному содержимому

Интеграция Amazon Glue с ClickHouse и Spark

ClickHouse Supported

Amazon Glue — это полностью управляемый бессерверный сервис интеграции данных от Amazon Web Services (AWS). Он упрощает поиск, подготовку и преобразование данных для аналитики, машинного обучения и разработки приложений.

Установка

Чтобы интегрировать код Glue с ClickHouse, можно использовать наш официальный коннектор Spark в Glue одним из следующих способов:

  • Установить коннектор ClickHouse Glue из AWS Marketplace (рекомендуется).
  • Вручную добавить JAR-файлы коннектора Spark в задачу Glue.
  1. Подпишитесь на коннектор

    Чтобы получить доступ к коннектору в своей учетной записи, подпишитесь на ClickHouse AWS Glue Connector в AWS Marketplace.

  2. Предоставьте необходимые разрешения

    Убедитесь, что роль IAM для задачи Glue имеет необходимые разрешения, как описано в руководстве по минимальным привилегиям.

  3. Активируйте коннектор и создайте подключение

    Активировать коннектор и создать подключение можно напрямую, перейдя по этой ссылке. Она открывает страницу создания подключения Glue с уже заполненными ключевыми полями. Укажите имя подключения и нажмите create (на этом этапе данные для подключения к ClickHouse вводить не нужно).

  4. Использование в задаче Glue

    В задаче Glue откройте вкладку Job details и разверните раздел Advanced properties. В разделе Connections выберите только что созданное подключение. Коннектор автоматически добавит необходимые JAR-файлы в среду выполнения задачи.

Конфигурация подключений Glue Notebook
Примечание

JAR-файлы, используемые в коннекторе Glue, собраны для Spark 3.3, Scala 2 и Python 3. Обязательно выберите эти версии при настройке задачи Glue.

Примеры

import com.amazonaws.services.glue.GlueContext
import com.amazonaws.services.glue.util.GlueArgParser
import com.amazonaws.services.glue.util.Job
import com.clickhouseScala.Native.NativeSparkRead.spark
import org.apache.spark.sql.SparkSession

import scala.collection.JavaConverters._
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._

object ClickHouseGlueExample {
  def main(sysArgs: Array[String]) {
    val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)

    val sparkSession: SparkSession = SparkSession.builder
      .config("spark.sql.catalog.clickhouse", "com.clickhouse.spark.ClickHouseCatalog")
      .config("spark.sql.catalog.clickhouse.host", "<your-clickhouse-host>")
      .config("spark.sql.catalog.clickhouse.protocol", "https")
      .config("spark.sql.catalog.clickhouse.http_port", "<your-clickhouse-port>")
      .config("spark.sql.catalog.clickhouse.user", "default")
      .config("spark.sql.catalog.clickhouse.password", "<your-password>")
      .config("spark.sql.catalog.clickhouse.database", "default")
      // for ClickHouse cloud
      .config("spark.sql.catalog.clickhouse.option.ssl", "true")
      .config("spark.sql.catalog.clickhouse.option.ssl_mode", "NONE")
      .getOrCreate

    val glueContext = new GlueContext(sparkSession.sparkContext)
    Job.init(args("JOB_NAME"), glueContext, args.asJava)
    import sparkSession.implicits._

    val url = "s3://{path_to_cell_tower_data}/cell_towers.csv.gz"

    val schema = StructType(Seq(
      StructField("radio", StringType, nullable = false),
      StructField("mcc", IntegerType, nullable = false),
      StructField("net", IntegerType, nullable = false),
      StructField("area", IntegerType, nullable = false),
      StructField("cell", LongType, nullable = false),
      StructField("unit", IntegerType, nullable = false),
      StructField("lon", DoubleType, nullable = false),
      StructField("lat", DoubleType, nullable = false),
      StructField("range", IntegerType, nullable = false),
      StructField("samples", IntegerType, nullable = false),
      StructField("changeable", IntegerType, nullable = false),
      StructField("created", TimestampType, nullable = false),
      StructField("updated", TimestampType, nullable = false),
      StructField("averageSignal", IntegerType, nullable = false)
    ))

    val df = sparkSession.read
      .option("header", "true")
      .schema(schema)
      .csv(url)

    // Write to ClickHouse
    df.writeTo("clickhouse.default.cell_towers").append()


    // Read from ClickHouse
    val dfRead = spark.sql("select * from clickhouse.default.cell_towers")
    Job.commit()
  }
}

Подробнее см. в документации по Spark.