Характеристики вставки Cassandra с использованием разъема Spark-Cassandra

Я новичок в Spark и Cassandra. Я пытаюсь вставить в таблицу cassandra, используя разъем Spark-Cassandra, как показано ниже:

import java.util.UUID

import org.apache.spark.{SparkContext, SparkConf}
import org.joda.time.DateTime
import com.datastax.spark.connector._

case class TestEntity(id:UUID, category:String, name:String,value:Double, createDate:DateTime, tag:Long)

object SparkConnectorContext {
  val conf = new SparkConf(true).setMaster("local")
    .set("spark.cassandra.connection.host", "192.168.xxx.xxx")
  val sc = new SparkContext(conf)
}
object TestRepo {
  def insertList(list: List[TestEntity]) = {
    SparkConnectorContext.sc.parallelize(list).saveToCassandra("testKeySpace", "testColumnFamily")
  }
}
object TestApp extends App {
  val start = System.currentTimeMillis()
  TestRepo.insertList(Utility.generateRandomData())
  val end = System.currentTimeMillis()
  val timeDiff = end-start
  println("Difference (in millis)= "+timeDiff)
}

Когда я вставляю, используя вышеуказанный метод (список из 100 объектов), требуется 300-1100 milliseconds. Я пробовал вставить те же данные с помощью библиотеки phantom. Это займет меньше, чем 20-40 milliseconds.

Может ли кто-нибудь сказать мне, почему разъем свечи так долго вставляется? Я делаю что-то не так в своем коде или не рекомендуется использовать коннектор spark-cassandra для операций вставки?


person Yadu Krishnan    schedule 11.08.2015    source источник
comment
Сколько у вас узлов Cassandra? Ваши рабочие искры работают на узлах Cassandra? Я не вижу никаких измерений времени в вашем коде, поэтому похоже, что вы измеряете гораздо больше операций, чем просто время вставки.   -  person Jim Meyer    schedule 11.08.2015
comment
Я просто начал с кассандры и искры. Итак, я использую локальную искру. Но кассандра находится на другой машине, но в той же сети. Что касается измерения времени, я отредактировал код.   -  person Yadu Krishnan    schedule 11.08.2015
comment
@YaduKrishnan Spark распределяет операции по всей сети, тогда как фантом выполняет прямые записи, распараллеленные на JVM, посредством классической многопоточности. Это также намного быстрее при отображении данных, поскольку большая часть волшебства - это время компиляции, здесь нет боксов во время выполнения, поскольку все преобразования являются специализированными, соединитель искры на самом деле не так хорошо затрагивает биты Scala.   -  person flavian    schedule 12.08.2015
comment
@flavian: Спасибо за информацию. Я буду использовать искру для всего анализа. А как со вставкой в ​​кассандру какой способ лучше? с помощью прямого фантома или искрового разъема? Я буду получать список данных каждые несколько секунд.   -  person Yadu Krishnan    schedule 12.08.2015
comment
@YaduKrishnan Если вам ничто не мешает использовать фантом для вставки, дерзайте.   -  person flavian    schedule 12.08.2015
comment
Разъем @flavian spark cassandra также не выполняет сопоставление во время выполнения. Он также выполняет часть сопоставления во время компиляции, а часть, которая зависит от схемы базы данных, известной только во время выполнения, выполняется во время инициализации только один раз. Часть отображения никогда не появлялась, чтобы занять значительную часть рабочего времени в любом профилировании, которое мы выполняли, и очень маловероятно, что это приведет к разнице в производительности. Конечно, мы, вероятно, могли бы ускорить отображение и преобразование за счет использования экспериментальных и хрупких функций, таких как макросы, но это будет оптимизация чего-то, что займет менее 1% от общего времени.   -  person Piotr Kołaczkowski    schedule 12.08.2015
comment
@PiotrKolaczkowski Достаточно честно, я не очень хорошо знаком с внутренним устройством разъема Spark. Я думаю, что мы говорим об инструментах, созданных для совершенно разных целей, и что, как вы указываете в своем ответе, разница в тестах зависит от времени установки, я сомневаюсь, что у кого-то есть волшебная палочка для более высокой скорости ввода-вывода.   -  person flavian    schedule 13.08.2015


Ответы (2)


Похоже, вы включаете операцию распараллеливания в свой тайминг. Кроме того, поскольку ваш искровый воркер работает на другом компьютере, чем Cassandra, операция saveToCassandra будет записывать по сети.

Попробуйте настроить свою систему так, чтобы запускать рабочие искры на узлах Cassandra. Затем создайте RDD на отдельном шаге и вызовите на нем действие, подобное count (), для загрузки данных в память. Также вы можете захотеть сохранить () или кэшировать () RDD, чтобы убедиться, что он остается в памяти для теста.

Затем рассчитайте только saveToCassandra этого кешированного RDD.

Вы также можете посмотреть на метод repartitionByCassandraReplica, предлагаемый коннектором Cassandra. Это разделит данные в RDD в зависимости от того, на какой узел Cassandra необходимо выполнить запись. Таким образом вы используете локальность данных и часто избегаете операций записи и перетасовки по сети.

person Jim Meyer    schedule 11.08.2015
comment
Я пробовал использовать кэшированный rdd, и он значительно улучшает производительность обработки. Но я сомневаюсь, что если новая запись будет вставлена ​​в таблицу C *, которая кэшируется rdd с помощью искрового коннектора, будет ли кеш очищен или обновлен автоматически? Или останется прежним? - person Yadu Krishnan; 12.08.2015
comment
RDD неизменны, поэтому вы не можете их изменить. В Spark вы создаете новые RDD, а не изменяете существующие. Кэшированные RDD будут исключены, когда Spark понадобится память для других вещей. - person Jim Meyer; 12.08.2015

Есть несколько серьезных проблем с вашим "тестом":

  1. Ваш набор данных настолько мал, что вы измеряете в основном только время настройки задания. Сохранение 100 объектов должно длиться порядка миллисекунд на одном узле, а не секунд. Кроме того, сохранение 100 объектов не дает JVM возможности скомпилировать код, который вы запускаете, в оптимизированный машинный код.
  2. Вы включили инициализацию контекста искры в свое измерение. JVM лениво загружает классы, поэтому код для инициализации искры действительно вызывается после начала измерения. Это чрезвычайно дорогостоящий элемент, который обычно выполняется только один раз за все приложение искры, даже не за одно задание.
  3. Вы выполняете измерение только один раз за запуск. Это означает, что вы даже неправильно измеряете настройку Spark ctx и время настройки задания, потому что JVM должна загружать все классы в первый раз, и у Hotspot, вероятно, нет шансов сработать.

Подводя итог, вы, скорее всего, измеряете в основном время загрузки классов, которое зависит от размера и количества загруженных классов. Spark - довольно большая вещь для загрузки, и несколько сотен миллисекунд совсем не удивительны.

Чтобы правильно измерить производительность вставки:

  • использовать больший набор данных
  • исключить из измерения одноразовую настройку
  • выполните несколько запусков с использованием одного и того же искрового контекста и отбросьте несколько начальных, пока не достигнете стабильной производительности.

Кстати, если вы включаете уровень ведения журнала отладки, соединитель регистрирует время вставки для каждого раздела в журналах исполнителя.

person Piotr Kołaczkowski    schedule 12.08.2015