Apache Spark, универсальная платформа для крупномасштабной обработки данных, в сочетании с Redis способна обеспечить ускоренные расчеты в реальном времени для таких задач, как анализ временных рядов, прогнозы и рекомендации на основе машинного обучения и т. д.

Spark также способен извлекать датасеты в кэш-память кластера. Это невероятно полезно, когда приложению необходимо многократно запрашивать одни и те же данные. Если вы используете датасет, создание которого достаточно затратно, и который потом используется в вашем приложении не один раз, то этот датасет обязательно нужно кэшировать. Но если вы захотите получить доступ к этому датасету сразу из нескольких приложений, то вам придется поломать голову, как это сделать. Здесь на помощь приходит коннектор Spark-Redis.

Redis — это размещаемое в памяти хранилище структур данных с открытым исходным кодом (под лицензией BSD), используемое в качестве базы данных, кэша и брокера сообщений. Оно поддерживает множество разных структур данных, таких как строки, хэши, списки, сэты и так далее.

Redis Labs недавно опубликовала в общий доступ пакет “spark-redis”. Как следует из названия, это коннектор Redis для Apache Spark, который обеспечивает доступ для чтения и записи ко всем основным структурам данных Redis в виде RDD (Resilient Distributed Datasets, в терминологии Spark), что позволяет Spark использовать Redis в качестве одного из источников данных. Этот коннектор предоставляет Spark структуры данных Redis, тем самым обеспечивая значительный прирост производительности для всех типов расчетов. Он также позволяет нам организовать совместный доступ к DataSet/DataFrame/RDD Spark из сразу нескольких разных приложений.

Но прежде чем мы сможем использовать коннектор Spark-Redis, нам сперва нужно позаботиться о наличии нескольких ключевых элементов, а именно: Apache Spark, Scala, Jedis и Redis.

Чтобы без особой необходимости не растягивать этот пост, предположим, что о всем вышеперечисленном вы уже позаботились. Поэтому давайте сразу перейдем к делу — как запустить эту мощную комбинацию. Включите указанные ниже зависимости в свой проект вместе со Spark:

spark-redis
jedis

Совместный доступ к датасету из разных приложений
Совместный доступ к датасету из разных приложений

Запись Spark-датасета из одного приложения в Redis с помощью Scala 

Следующий фрагмент кода демонстрирует, как выглядит кэширование Spark-датасета в Redis:

def main(args: Array[String]): Unit = {
val sparkSession = org.apache.spark.sql.SparkSession.builder
    .config(new SparkConf()
      .setMaster("local")
      .setAppName("myApp")
      // начальный хост Redis - может быть любым узлом в кластерном режиме
      .set("redis.host", "localhost")
      // начальный порт redis
      .set("redis.port", "6379")
      // опциональный AUTH-пароль redis
      //.set("redis.auth", "")
    ).getOrCreate;
val path = "/dev/test/test.csv"
  val base_df = sparkSession.read.option("header","true").csv(path)
  // сохраняем датасет в Redis
  base_df.write
    .format("org.apache.spark.sql.redis")
    .option("table", "temp")
    .mode(SaveMode.Overwrite)
    .save()
}

Чтение Spark-датасета из Redis с помощью Scala

Следующий фрагмент кода демонстрирует, как читать кэшированный Spark-датасет из Redis:

def main(args: Array[String]): Unit = {
  val sparkSession = org.apache.spark.sql.SparkSession.builder
    .config(new SparkConf()
      .setMaster("local")
      .setAppName("myApp")
      // начальный хост Redis — может быть любым узлом в кластерном режиме
      .set("redis.host", "localhost")
      // начальный порт redis
      .set("redis.port", "6379")
      // опциональный AUTH-пароль redis
      //.set("redis.auth", "")
    ).getOrCreate;
// считываем ранее сохраненный датасет из Redis
  val loadedDf = sparkSession.read
    .format("org.apache.spark.sql.redis")
    .option("table", "temp")
    .load()
  loadedDf.printSchema()
  loadedDf.show()  
}

Преимущества использования Redis со Spark

  • Redis может повысить производительность Spark до 50 раз для некоторых вариантов использования, таких как, например, spark-timeseries. Коннектор Spark-Redis автоматизирует их, предоставляя Spark API и структуры данных Redis.

На приведенном ниже графике, взятом с сайта redislabs.com, показан прирост производительности при использовании Redis Cache вместе со Spark.

На графике показано среднее время выполнения для разных сценариев.
На графике показано среднее время выполнения для разных сценариев.
  • Redis позволяет Spark совместно использовать датасет разными приложениями.

  • Структуры данных Redis позволяют получить доступ к отдельным элементам данных, сводя к минимуму накладные расходы на сериализацию/десериализацию и избегая необходимости передавать туда-сюда большие фрагменты данных.

  • Модули Redis, такие как Redis-ML, ускоряют библиотеки Spark ML, позволяя реализовать быстрейшую доставку моделей машинного обучения, которые изначально хранятся в Redis, могут повторно использоваться во многих приложениях и языках, легко развертываются в рабочей среде с уменьшенной в 5–10 раз задержкой выполнения.

Заключение

Redis “утоляет жажду” Spark к данным. Spark-Redis позволяет объединить RDD и основные структуры данных Redis с помощью всего одной строчки кода на Scala. Пакет Spark-Redis предоставляет прямой доступ для чтения/записи ко всем основным структурам данных с параллелизацией RDD и bpzoysq (т. е. на основе SCAN) способ получения имен ключей. Кроме того, коннектор заключает в себе значительный скрытый потенциал, поскольку он фактически поддерживает кластер (Redis) и сопоставляет партиции RDD с хэш-слотами, чтобы уменьшить перетасовку между ядрами (inter-engine shuffling).

Ссылки

Коннектор для Spark, который позволяет читать и записывать в/из кластера Redis — RedisLabs/spark-redis


Какие коннекторы используются Spark из коробки, какие коннекторы подключаются из библиотек, а какие и когда надо писать самому? Ответы на эти вопросы можно получить на открытом уроке «Использование коннекторов для Spark». Регистрация по ссылке.

Комментарии (0)