初学spark基本操作SparkSession、Dataset

RDD的具体描述RDD(弹性分布式数据集)是Spark提供的最重要的抽象的概念,它是一种有容错机制的特殊集合,可以分布在集群的节点上,以函数式编操作集合的方式,进行各种并行操作。可以将RDD理解为一个具有容错机制的特殊集合,它提供了一种只读、只能有已存在的RDD变换而来的共享内存,然后将所有数据都加载到内存中,方便进行多次重用。

a.他是分布式的,可以分布在多台机器上,进行计算。

 b.他是弹性的,计算过程中内存不够时它会和磁盘进行数据交换。

c.这些限制可以极大的降低自动容错开销

d.实质是一种更为通用的迭代并行计算框架,用户可以显示的控制计算的中间结果,然后将其自由运用于之后的计算。

对于spark的容错机制:数据检查点记录更新,其中父RDD和子RDD的依赖可分为 宽依赖窄依赖

窄依赖:子RDD中的每个数据块只依赖于父RDD中对应的有限个固定的数据块;例如:map变换,子RDD中的数据块只依赖于父RDD中对应的一个数据块。 窄依赖可以在某个计算节点上直接通过计算父RDD的某块数据计算得到子RDD对应的某块数据;当数据丢失时,对于窄依赖只需要重新计算丢失的那一块数据来恢复  

宽依赖:子RDD中的一个数据块可以依赖于父RDD中的所有数据块。例如:groupByKey变换,子RDD中的数据块会依赖于多有父RDD中的数据块,因为一个key可能存在于父RDD的任何一个数据块中。宽依赖则要等到父RDD所有数据都计算完成之后,并且父RDD的计算结果进行hash并传到对应节点上之后才能计算子RDD。数据丢失时,宽依赖要将祖先RDD中的所有数据块全部重新计算来恢复。

   ------------- 对于所以在长“血统”链特别是有宽依赖的时候,需要在适当的时机设置数据检查点。也是这两个特性要求对于不同依赖关系要采取不同的任务调度机制和容错恢复机制。

原文地址:https://blog.csdn.net/china_demon/article/details/52082429

(1)如何获取RDD

    a.从共享的文件系统获取,(如:HDFS)

     b.通过已存在的RDD转换

     c.将已存在scala集合(只要是Seq对象)并行化 ,通过调用SparkContext的parallelize方法实现

     d.改变现有RDD的之久性;RDD是懒散,短暂的。(RDD的固化:cache缓存至内错; save保存到分布式文件系统)

(2)操作RDD的两个动作

     a.Actions:对数据集计算后直接得到一个值或者一个结果返回给驱动程序;

     b.Transformation:根据数据集创建一个新的数据集,计算后返回一个新RDD;(从RDD生成一个新的RDD)


RDD的操作分为转化操作(transformation)和行动操作(action),RDD之所以将操作分成这两类这是和RDD惰性运算有关,当RDD执行转化操作时候,实际计算并没有被执行,只有当RDD执行行动操作时候才会促发计算任务提交,执行相应的计算操作。区别转化操作和行动操作也非常简单,转化操作就是从一个RDD产生一个新的RDD操作,而行动操作就是进行实际的计算



回归正题:

1.创建SparkSession:

//读取数据库配置

Properties properties=PropertyKit.loadProperties("config.properties");
SparkConf sparkConf=new SparkConf(true);
sparkConf.setAppName(taskName).setMaster(properties.getProperty("spark_master","local[4]"));

SparkSession spark=SparkSession.builder().config(sparkConf).getOrCreate();

2.利用spark读取jdbc

Dataset<Row> df_org = spark.read().jdbc(this.properties.getProperty(PropertyKeys.URL_JDBC_SLAVE), "org", this.properties);

3.进行简单的操作

long countNet = df_org.filter("type=2").count();//过滤在org表中属性type==2的总条数

------------------------------------

原文地址:https://blog.csdn.net/dark_zhou/article/details/78490635

Dataset<Row> dataset = spark.read().jdbc(connectionProperties.getProperty("url"),"cq_jqxx",connectionProperties).persist();
Dataset<Map> mapDataset = dataset.map(newMapFunction<Row,Map>() {
  @Override
  public Map call(Row row)throws Exception {
  HashMap hashMap =new HashMap();
  //这是一个遍历操作,row即表示为当前行数据,get(i)表示当前行的第几列
  hashMap.put(row.get(0),row.get(1));
  return hashMap;
}
  //转换为基本类型时用Encoders>STRING()等对应的基本类型
  // 当使用Encoders.javaSerialization()时当前类需要实现序列化
  },Encoders.javaSerialization(Map.class));
List<Map> maps = mapDataset.collectAsList();

Dataset<Row>相关类型的互相转换

1.java中List转为数组结构(由于经常使用到)
List<String> list = new ArrayList<>();
String[] strings = list.toArray(new String[list.size()]);
2.Dataset<Row>转为JavaRDD
JavaRDD<Row> rowJavaRDD = dataset.javaRDD();
3.JavaRDD<ROW>转为Dataset<ROW>
  Dataset<Row> dataFrame = sparkSession.createDataFrame(rowJavaRDD,Row.class);
4.利用内部类实现Row转为自己需要的Row,例如将某行进行分词变为String[]
Dataset<Row> select = dataset.select("label","message");
   JavaRDD<WordParticiple> map = select.javaRDD().map(WordParticiple::parseWordParticiple);
   Dataset<Row> wordParticiple = spark.createDataFrame(map,WordParticiple.class);

内部类对象
public static class WordParticiple{
  private String label;
  private String[] message;
public WordParticiple(String label,String[] message) {
  this.label= label;
  this.message= message;
}
public WordParticiple() {
}
public String getLabel() {
  returnlabel;
}
public void setLabel(String label) {
  this.label= label;
}
public String[] getMessage() {
  return message;
}
public void setMessage(String[] message) {
  this.message= message;
}
public static WordParticiple parseWordParticiple(Row row) throws IOException {
  String string = row.getString(1);
  String[] split = TermTokenizer.split(string);
  return new WordParticiple(row.get(0).toString(),split);
  }
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章