zoukankan      html  css  js  c++  java
  • 当MongoDB遇见Spark

    当MongoDB遇见Spark

    96 RavenZZ 关注

    2017.03.23 00:02* 字数 428 阅读 9260评论 10喜欢 9

    适宜读者人群

    • 正在使用Mongodb的开发者

    传统Spark生态系统 和 MongoDB在Spark生态的角色

    传统Spark生态系统

    Spark生态系统

    Spark生态系统

    那么Mongodb作为一个database, 可以担任什么样的角色呢? 就是数据存储这部分, 也就是图中的黑色圈圈HDFS的部分, 如下图

    用MongoDB替换HDFS后的Spark生态系统

    Spark+Mongodb生态系统

    Spark+Mongodb生态系统

    为什么要用MongoDB替换HDFS

    1. 存储方式上, HDFS以文件为单位,每个文件64MB~128MB不等, 而MongoDB作为文档数据库则表现得更加细颗粒化
    2. MongoDB支持HDFS所没有的索引的概念, 所以在读取上更加快
    3. MongoDB支持的增删改功能比HDFS更加易于修改写入后的数据
    4. HDFS的响应级别为分钟, 而MongoDB通常是毫秒级别
    5. 如果现有数据库已经是MongoDB的话, 那就不用再转存一份到HDFS上了
    6. 可以利用MongoDB强大的Aggregate做数据的筛选或预处理

    MongoDB Spark Connector介绍

    1. 支持读取和写入,即可以将计算后的结果写入MongoDB
    2. 将查询拆分为n个子任务, 如Connector会将一次match,拆分为多个子任务交给spark来处理, 减少数据的全量读取

    MongoDB Spark 示例代码

    计算用类型Type=1的message字符数并按userid进行分组

    开发Maven dependency配置

    这里用的是mongo-spark-connector_2.11 的2.0.0版本和spark的spark-core_2.11的2.0.2版本

        <dependency>
            <groupId>org.mongodb.spark</groupId>
            <artifactId>mongo-spark-connector_2.11</artifactId>
            <version>2.0.0</version>
        </dependency>
    
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>2.0.2</version>
        </dependency>
    

    示例代码

        import com.mongodb.spark._
        import org.apache.spark.{SparkConf, SparkContext}
        import org.bson._
    
    
        val conf = new SparkConf()
          .setMaster("local")
          .setAppName("Mingdao-Score")
          //同时还支持mongo驱动的readPreference配置, 可以只从secondary读取数据
          .set("spark.mongodb.input.uri", "mongodb://xxx.xxx.xxx.xxx:27017,xxx.xxx.xxx:27017,xxx.xxx.xxx:27017/inputDB.collectionName")
          .set("spark.mongodb.output.uri", "mongodb://xxx.xxx.xxx.xxx:27017,xxx.xxx.xxx:27017,xxx.xxx.xxx:27017/outputDB.collectionName")
    
        val sc = new SparkContext(conf)
        // 创建rdd
        val originRDD = MongoSpark.load(sc)
    
        // 构造查询
        val dateQuery = new BsonDocument()
          .append("$gte", new BsonDateTime(start.getTime))
          .append("$lt", new BsonDateTime(end.getTime))
        val matchQuery = new Document("$match", BsonDocument.parse("{\"type\":\"1\"}"))
    
        // 构造Projection
        val projection1 = new BsonDocument("$project", BsonDocument.parse("{\"userid\":\"$userid\",\"message\":\"$message\"}")
    
        val aggregatedRDD = originRDD.withPipeline(Seq(matchQuery, projection1))
    
        //比如计算用户的消息字符数
        val rdd1 = aggregatedRDD.keyBy(x=>{
          Map(
            "userid" -> x.get("userid")
          )
        })
    
        val rdd2 = rdd1.groupByKey.map(t=>{
          (t._1, t._2.map(x => {
            x.getString("message").length
          }).sum)
        })
        
        rdd2.collect().foreach(x=>{
            println(x)
        })
    
        //保持统计结果至MongoDB outputurl 所指定的数据库
        MongoSpark.save(rdd2)
    

    总结

    MongoDB Connector 的文档只有基础的示例代码, 具体详情需要看GitHub中的example和部分源码

    参考链接

    小礼物走一走,来简书关注我

    赞赏支持

  • 相关阅读:
    (十)条件判断
    (九)字符处理命令
    (八)awk命令
    (六)环境变量配置文件
    (七)grep命令行提取符号
    Ⅶ 类模板与STL编程 ②
    Ⅵ 虚函数与多态性
    Ⅴ 运算符重载
    Ⅳ 继承与派生②
    Ⅳ 继承与派生①
  • 原文地址:https://www.cnblogs.com/grj001/p/12225002.html
Copyright © 2011-2022 走看看