J'essaie d'utiliser Spark Cassandra Connector in Spark 1.1.0.
J'ai réussi à créer le fichier jar à partir de la branche principale sur GitHub et j'ai fait fonctionner les démos incluses. Cependant, lorsque j'essaie de charger les fichiers jar dans le spark-Shell
Je ne peux importer aucune des classes du com.datastax.spark.connector
paquet.
J'ai essayé d'utiliser le --jars
option sur spark-Shell
et en ajoutant le répertoire avec le fichier jar au CLASSPATH de Java. Aucune de ces options ne fonctionne. En fait, lorsque j'utilise le --jars
option, la sortie de journalisation montre que le pot Datastax est en cours de chargement, mais je ne peux toujours rien importer de com.datastax
.
J'ai pu charger le Tuplejump Calliope Cassandra connecteur dans le spark-Shell
en utilisant --jars
, donc je sais que ça marche. C'est juste le connecteur Datastax qui échoue pour moi.
J? ai compris. Voici ce que j'ai fait:
$ git clone https://github.com/datastax/spark-cassandra-connector.git
$ cd spark-cassandra-connector
$ sbt/sbt Assembly
$ $SPARK_HOME/bin/spark-Shell --jars ~/spark-cassandra-connector/spark-cassandra-connector/target/scala-2.10/connector-Assembly-1.2.0-SNAPSHOT.jar
Dans scala Prompt,
scala> sc.stop
scala> import com.datastax.spark.connector._
scala> import org.Apache.spark.SparkContext
scala> import org.Apache.spark.SparkContext._
scala> import org.Apache.spark.SparkConf
scala> val conf = new SparkConf(true).set("spark.cassandra.connection.Host", "my cassandra Host")
scala> val sc = new SparkContext("spark://spark Host:7077", "test", conf)
Pour des instructions détaillées, consultez le site Web du projet https://github.com/datastax/spark-cassandra-connector/blob/master/doc/13_spark_Shell.md
Ou n'hésitez pas à utiliser Spark-Packages pour charger la bibliothèque (toutes les versions ne sont pas publiées) http://spark-packages.org/package/datastax/spark-cassandra-connector
> $SPARK_HOME/bin/spark-Shell --packages com.datastax.spark:spark-cassandra-connector_2.10:1.4.0-M3-s_2.10
Vous voudrez démarrer la classe avec le jeu de –driver-class-path pour inclure toutes vos bibliothèques de connecteurs
Je vais citer un article de blog de l'illustre Amy Tobey
Le moyen le plus simple que j'ai trouvé est de définir le chemin de classe avec puis de redémarrer le contexte dans le REPL avec les classes nécessaires importées pour rendre sc.cassandraTable () visible. Les méthodes nouvellement chargées ne s'afficheront pas dans la tabulation. Je ne sais pas pourquoi.
/opt/spark/bin/spark-Shell --driver-class-path $(echo /path/to/connector/*.jar |sed 's/ /:/g')
Il imprimera un tas d'informations de journal, puis présentera scala> Invite.
scala> sc.stop
Maintenant que le contexte est arrêté, il est temps d'importer le connecteur.
scala> import com.datastax.spark.connector._
scala> val conf = new SparkConf()
scala> conf.set("cassandra.connection.Host", "node1.pc.datastax.com")
scala> val sc = new SparkContext("local[2]", "Cassandra Connector Test", conf)
scala> val table = sc.cassandraTable("keyspace", "table")
scala> table.count
Il y a un léger problème avec le chargeur de classe DSE et les conventions de dénomination des packages précédents qui vous empêcheront de trouver les nouvelles bibliothèques de connecteurs d'allumage. Vous devriez pouvoir contourner ce problème en supprimant la ligne spécifiant le chargeur de classe DSE dans les scripts démarrant spark-Shell.
Si vous voulez éviter d'arrêter/démarrer le contexte dans le Shell, vous pouvez également l'ajouter dans vos propriétés spark dans:
{spark_install} /conf/spark-defaults.conf
spark.cassandra.connection.Host=192.168.10.10
Pour accéder à Cassandra à partir du spark-Shell, j'ai construit un assembly à partir du cassandra-spark-driver avec toutes les dépendances (un "uberjar"). Le fournir au spark-Shell en utilisant l'option --jars comme ceci:
spark-Shell --jars spark-cassandra-Assembly-1.0.0-SNAPSHOT-jar-with-dependencies.jar
J'étais confronté au même problème décrit ici et cette méthode est à la fois simple et pratique (au lieu de charger la longue liste de dépendances)
J'ai créé un Gist avec le fichier POM que vous pouvez télécharger . En utilisant le pom pour créer l'uberjar, vous devez faire:
mvn package
Si vous utilisez sbt, consultez le plugin sbt-Assembly.
Code complet Spark-Cassandra-Connector en Java avec Window-7,8,10 Utile.
import com.datastax.driver.core.Session;
import com.datastax.spark.connector.cql.CassandraConnector;
import com.google.common.base.Optional;
import org.Apache.spark.SparkConf;
import org.Apache.spark.api.Java.JavaPairRDD;
import org.Apache.spark.api.Java.JavaRDD;
import org.Apache.spark.api.Java.JavaSparkContext;
import org.Apache.spark.api.Java.function.FlatMapFunction;
import org.Apache.spark.api.Java.function.Function;
import org.Apache.spark.api.Java.function.Function2;
import org.Apache.spark.api.Java.function.PairFlatMapFunction;
import scala.Tuple2;
import spark_conn.Spark_connection;
import Java.io.Serializable;
import Java.math.BigDecimal;
import Java.text.MessageFormat;
import Java.util.*;
import static com.datastax.spark.connector.CassandraJavaUtil.*;
public class App implements Serializable
{
private transient SparkConf conf;
private App(SparkConf conf) {
this.conf = conf;
}
private void run() {
JavaSparkContext sc = new JavaSparkContext(conf);
generateData(sc);
compute(sc);
showResults(sc);
sc.stop();
}
private void generateData(JavaSparkContext sc) {
CassandraConnector connector = CassandraConnector.apply(sc.getConf());
// Prepare the schema
try{
Session session=connector.openSession();
session.execute("DROP KEYSPACE IF EXISTS Java_api");
session.execute("CREATE KEYSPACE Java_api WITH
replication = {'class': 'SimpleStrategy', 'replication_factor': 1}");
session.execute("CREATE TABLE Java_api.products
(id INT PRIMARY KEY, name TEXT, parents LIST<INT>)");
session.execute("CREATE TABLE Java_api.sales
(id UUID PRIMARY KEY, product INT, price DECIMAL)");
session.execute("CREATE TABLE Java_api.summaries
(product INT PRIMARY KEY, summary DECIMAL)");
}catch(Exception e){System.out.println(e);}
// Prepare the products hierarchy
List<Product> products = Arrays.asList(
new Product(0, "All products", Collections.<Integer>emptyList()),
new Product(1, "Product A", Arrays.asList(0)),
new Product(4, "Product A1", Arrays.asList(0, 1)),
new Product(5, "Product A2", Arrays.asList(0, 1)),
new Product(2, "Product B", Arrays.asList(0)),
new Product(6, "Product B1", Arrays.asList(0, 2)),
new Product(7, "Product B2", Arrays.asList(0, 2)),
new Product(3, "Product C", Arrays.asList(0)),
new Product(8, "Product C1", Arrays.asList(0, 3)),
new Product(9, "Product C2", Arrays.asList(0, 3))
);
JavaRDD<Product> productsRDD = sc.parallelize(products);
javaFunctions(productsRDD, Product.class).
saveToCassandra("Java_api", "products");
JavaRDD<Sale> salesRDD = productsRDD.filter
(new Function<Product, Boolean>() {
@Override
public Boolean call(Product product) throws Exception {
return product.getParents().size() == 2;
}
}).flatMap(new FlatMapFunction<Product, Sale>() {
@Override
public Iterable<Sale> call(Product product) throws Exception {
Random random = new Random();
List<Sale> sales = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) {
sales.add(new Sale(UUID.randomUUID(),
product.getId(), BigDecimal.valueOf(random.nextDouble())));
}
return sales;
}
});
javaFunctions(salesRDD, Sale.class).saveToCassandra
("Java_api", "sales");
}
private void compute(JavaSparkContext sc) {
JavaPairRDD<Integer, Product> productsRDD = javaFunctions(sc)
.cassandraTable("Java_api", "products", Product.class)
.keyBy(new Function<Product, Integer>() {
@Override
public Integer call(Product product) throws Exception {
return product.getId();
}
});
JavaPairRDD<Integer, Sale> salesRDD = javaFunctions(sc)
.cassandraTable("Java_api", "sales", Sale.class)
.keyBy(new Function<Sale, Integer>() {
@Override
public Integer call(Sale sale) throws Exception {
return sale.getProduct();
}
});
JavaPairRDD<Integer, Tuple2<Sale, Product>> joinedRDD = salesRDD.join(productsRDD);
JavaPairRDD<Integer, BigDecimal> allSalesRDD = joinedRDD.flatMapToPair(new PairFlatMapFunction<Tuple2<Integer, Tuple2<Sale, Product>>, Integer, BigDecimal>() {
@Override
public Iterable<Tuple2<Integer, BigDecimal>> call(Tuple2<Integer, Tuple2<Sale, Product>> input) throws Exception {
Tuple2<Sale, Product> saleWithProduct = input._2();
List<Tuple2<Integer, BigDecimal>> allSales = new ArrayList<>(saleWithProduct._2().getParents().size() + 1);
allSales.add(new Tuple2<>(saleWithProduct._1().getProduct(), saleWithProduct._1().getPrice()));
for (Integer parentProduct : saleWithProduct._2().getParents()) {
allSales.add(new Tuple2<>(parentProduct, saleWithProduct._1().getPrice()));
}
return allSales;
}
});
JavaRDD<Summary> summariesRDD = allSalesRDD.reduceByKey(new Function2<BigDecimal, BigDecimal, BigDecimal>() {
@Override
public BigDecimal call(BigDecimal v1, BigDecimal v2) throws Exception {
return v1.add(v2);
}
}).map(new Function<Tuple2<Integer, BigDecimal>, Summary>() {
@Override
public Summary call(Tuple2<Integer, BigDecimal> input) throws Exception {
return new Summary(input._1(), input._2());
}
});
javaFunctions(summariesRDD, Summary.class).saveToCassandra("Java_api", "summaries");
}
private void showResults(JavaSparkContext sc) {
JavaPairRDD<Integer, Summary> summariesRdd = javaFunctions(sc)
.cassandraTable("Java_api", "summaries", Summary.class)
.keyBy(new Function<Summary, Integer>() {
@Override
public Integer call(Summary summary) throws Exception {
return summary.getProduct();
}
});
JavaPairRDD<Integer, Product> productsRdd = javaFunctions(sc)
.cassandraTable("Java_api", "products", Product.class)
.keyBy(new Function<Product, Integer>() {
@Override
public Integer call(Product product) throws Exception {
return product.getId();
}
});
List<Tuple2<Product, Optional<Summary>>> results = productsRdd.leftOuterJoin(summariesRdd).values().toArray();
for (Tuple2<Product, Optional<Summary>> result : results) {
System.out.println(result);
}
}
public static void main(String[] args) {
// if (args.length != 2) {
// System.err.println("Syntax: com.datastax.spark.demo.App <Spark Master URL> <Cassandra contact point>");
// System.exit(1);
// }
// SparkConf conf = new SparkConf(true)
// .set("spark.cassandra.connection.Host", "127.0.1.1")
// .set("spark.cassandra.auth.username", "cassandra")
// .set("spark.cassandra.auth.password", "cassandra");
//SparkContext sc = new SparkContext("spark://127.0.1.1:9045", "test", conf);
//return ;
/* try{
SparkConf conf = new SparkConf(true);
conf.setAppName("Spark-Cassandra Integration");
conf.setMaster("yarn-cluster");
conf.set("spark.cassandra.connection.Host", "192.168.1.200");
conf.set("spark.cassandra.connection.rpc.port", "9042");
conf.set("spark.cassandra.connection.timeout_ms", "40000");
conf.set("spark.cassandra.read.timeout_ms", "200000");
System.out.println("Hi.......Main Method1111...");
conf.set("spark.cassandra.auth.username","cassandra");
conf.set("spark.cassandra.auth.password","cassandra");
System.out.println("Connected Successful...!\n");
App app = new App(conf);
app.run();
}catch(Exception e){System.out.println(e);}*/
SparkConf conf = new SparkConf();
conf.setAppName("Java API demo");
// conf.setMaster(args[0]);
// conf.set("spark.cassandra.connection.Host", args[1]);
conf.setMaster("spark://192.168.1.117:7077");
conf.set("spark.cassandra.connection.Host", "192.168.1.200");
conf.set("spark.cassandra.connection.port", "9042");
conf.set("spark.ui.port","4040");
conf.set("spark.cassandra.auth.username","cassandra");
conf.set("spark.cassandra.auth.password","cassandra");
App app = new App(conf);
app.run();
}
public static class Product implements Serializable {
private Integer id;
private String name;
private List<Integer> parents;
public Product() { }
public Product(Integer id, String name, List<Integer> parents) {
this.id = id;
this.name = name;
this.parents = parents;
}
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<Integer> getParents() { return parents; }
public void setParents(List<Integer> parents) { this.parents = parents; }
@Override
public String toString() {
return MessageFormat.format("Product'{'id={0}, name=''{1}'', parents={2}'}'", id, name, parents);
}
}
public static class Sale implements Serializable {
private UUID id;
private Integer product;
private BigDecimal price;
public Sale() { }
public Sale(UUID id, Integer product, BigDecimal price) {
this.id = id;
this.product = product;
this.price = price;
}
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public Integer getProduct() { return product; }
public void setProduct(Integer product) { this.product = product; }
public BigDecimal getPrice() { return price; }
public void setPrice(BigDecimal price) { this.price = price; }
@Override
public String toString() {
return MessageFormat.format("Sale'{'id={0}, product={1}, price={2}'}'", id, product, price);
}
}
public static class Summary implements Serializable {
private Integer product;
private BigDecimal summary;
public Summary() { }
public Summary(Integer product, BigDecimal summary) {
this.product = product;
this.summary = summary;
}
public Integer getProduct() { return product; }
public void setProduct(Integer product) { this.product = product; }
public BigDecimal getSummary() { return summary; }
public void setSummary(BigDecimal summary) { this.summary = summary; }
@Override
public String toString() {
return MessageFormat.format("Summary'{'product={0}, summary={1}'}'", product, summary);
}
}
}
Les étapes suivantes décrivent comment configurer un serveur avec à la fois un Spark Node et un Cassandra Node.
Configuration de Spark Open Source
Cela suppose que vous disposez déjà de la configuration Cassandra.
Étape 1: Téléchargez et configurez Spark
Go to http://spark.Apache.org/downloads.html.
a) Pour simplifier les choses, nous utiliserons l'un des packages prédéfinis Spark. Choisissez Spark version 2.0.0 et préconstruit pour Hadoop 2.7 puis Direct). Téléchargement. Ceci téléchargera une archive avec les binaires construits pour Spark.
b) Extrayez-le dans un répertoire de votre choix. Je mettrai le mien dans ~/apps/spark-1.2
c) Test Spark fonctionne en ouvrant le Shell
Étape 2: Vérifiez que Spark Works
a) cd dans le répertoire Spark Exécutez "./bin/spark-Shell". Cela ouvrira le programme interactif Spark Shell)
b) Si tout a fonctionné, il devrait afficher cette invite: "scala>"
Exécutez un calcul simple:
sc.parallelize (1 à 50) .sum ( +) qui devrait produire 1250.
c) Félicitations Spark fonctionne! Quittez le shell Spark avec la commande "exit")
Le Spark Cassandra connecteur
Pour connecter Spark à un Cassandra cluster, le connecteur Cassandra Connector devra être ajouté au Spark. DataStax fournit son propre connecteur Cassandra sur GitHub et nous l’utiliserons.
Clonez le Spark Cassandra Référentiel de connecteurs:
cd dans "spark-cassandra-connector" Créez le connecteur Spark Cassandra en exécutant la commande
./sbt/sbt Dscala-2.11 = véritable assemblage
Cela devrait produire des fichiers jar compilés dans le répertoire nommé "target". Il y aura deux fichiers jar, un pour Scala et un pour Java. Le jar qui nous intéresse est: "spark-cassandra-connector-Assembly-1.1.1-SNAPSHOT.jar" le un pour Scala. Déplacez le fichier jar dans un répertoire facile à trouver: j'ai mis le mien dans ~/apps/spark-1.2/jars
Pour charger le connecteur dans le Spark Shell:
démarrez le shell avec cette commande:
../bin/spark-Shell –jars ~/apps/spark-1.2/jars/spark-cassandra-connector-Assembly-1.1.1-SNAPSHOT.jar
Connectez le Spark Context au cluster Cassandra et arrêtez le contexte par défaut:
sc.stop
Importez les fichiers jar nécessaires:
import com.datastax.spark.connector._, org.Apache.spark.SparkContext, org.Apache.spark.SparkContext._, org.Apache.spark.SparkConf
Créez un nouveau SparkConf avec les détails de connexion Cassandra:
val conf = new SparkConf (true) .set ("spark.cassandra.connection.Host", "localhost")
Créez un nouveau Spark Contexte:
val sc = nouveau SparkContext (conf)
Vous avez maintenant un nouveau SparkContext qui est connecté à votre cluster Cassandra.