首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 39)——构造函数重载

构造函数作为一种特殊方法,也可以重载。 Swift中构造函数可以多个,他们参数列表和返回值可以不同,这些构造函数构成重载。 示例代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Rectangle{ varwidth:Double varheight:Double init(width:Double,height:Double){ self.width=width self.height=height } init(Wwidth:Double,Hheight:Double){ self.width=width self.height=height } init(length:Double){ self.width=length self.height=length } init(){ self.width= 640.0 self.height= 940.0 } } varrectc1=Rectangle(width: 320.0 ,height: 480.0 ) print( "长方形:\(rectc1.width)x\(rectc1.height)" ) varrectc2=Rectangle(W: 320.0 ,H: 480.0 ) print( "长方形:\(rectc2.width)x\(rectc2.height)" ) varrectc3=Rectangle(length: 500.0 ) print( "长方形3:\(rectc3.width)x\(rectc3.height)" ) varrectc4=Rectangle() print( "长方形4:\(rectc4.width)x\(rectc4.height)" ) 构造函数代理 为了减少多个构造函数间的代码重复,在定义构造函数时,可以通过调用其他构造函数来完成实例的部分构造过程,这个过程称为构造函数代理。构造函数代理在结构体和类中使用方式是不同,先介绍结构体中构造函数代理。 将上一节的示例修改如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 structRectangle{ varwidth:Double varheight:Double init(width:Double,height:Double){ self.width=width self.height=height } init(Wwidth:Double,Hheight:Double){ self.width=width self.height=height } init(length:Double){ //调用了self.init语句 self.init(W:length,H:length) } init(){ //调用了self.init语句 self.init(width: 640.0 ,height: 940.0 ) } } varrectc1=Rectangle(width: 320.0 ,height: 480.0 ) print( "长方形:\(rectc1.width)x\(rectc1.height)" ) varrectc2=Rectangle(W: 320.0 ,H: 480.0 ) print( "长方形:\(rectc2.width)x\(rectc2.height)" ) varrectc3=Rectangle(length: 500.0 ) print( "长方形3:\(rectc3.width)x\(rectc3.height)" ) varrectc4=Rectangle() print( "长方形4:\(rectc4.width)x\(rectc4.height)" ) 将Rectangle声明为结构体类型,其中也有4个构造函数重载。 这种在同一个类型中通过self.init语句进行调用当前类型其它构造函数,其它构造函数被称为构造函数代理。 类构造函数横向代理 由于类有继承关系,类构造函数代理比较复杂,分为横向代理和向上代理。 横向代理类似于结构体类型构造函数代理,发生在同一类内部,这种构造函数称为便利构造函数(convenience initializers)。 向上代理发生在继承情况下,在子类构造过程中要先调用父类构造函数,初始化父类的存储属性,这种构造函数称为指定构造函数(designated initializers)。 将上面的示例修改如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Rectangle{ varwidth:Double varheight:Double init(width:Double,height:Double){ self.width=width self.height=height } init(Wwidth:Double,Hheight:Double){ self.width=width self.height=height } convenienceinit(length:Double){ self.init(W:length,H:length) } convenienceinit(){ self.init(width: 640.0 ,height: 940.0 ) } } varrectc1=Rectangle(width: 320.0 ,height: 480.0 ) print( "长方形:\(rectc1.width)x\(rectc1.height)" ) varrectc2=Rectangle(W: 320.0 ,H: 480.0 ) print( "长方形:\(rectc2.width)x\(rectc2.height)" ) varrectc3=Rectangle(length: 500.0 ) print( "长方形3:\(rectc3.width)x\(rectc3.height)" ) varrectc4=Rectangle() print( "长方形4:\(rectc4.width)x\(rectc4.height)" ) 将Rectangle声明为类,其中也有4个构造函数重载。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1747009,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop HDFS概念学习系列之HDFS Master/Slave架构(十)

相比于基于P2P模型的分布式文件系统架构,HDFS采用的是基于Master/Slave主从架构的分布式文件系统,一个HDFS集群包含一个单独的Master节点和多个Slave节点服务器,这里的一个单独的Master节点的含义是HDFS系统中只存在一个逻辑上的Master组件。一个逻辑的Master节点可以包括两台物理主机,即两台Master服务器、多台Slave服务器。一台Master服务器组成单NameNode集群,两台Master服务器组成双NameNode集群,并且同时被多个客户端访问.所有的这此机器通常都是普通的Linux机器,运行着用户级别(user-level)的服务进程。HDFS架构设计图如下: 上图展示了HDFS的NameNode、 DataNode以及客户端之间的存取访问关系,单一节点的NameNode大大简化了系统架构。NameNode负责保存和管理所有的HDFS元数据,因而用户数据就不需要通过NameNode,也就是说文件数据的读写是直接在DataNode上进行的。HDFS存储的文件都被分割成固定大小的Block,在创建Block的时候,NameNode服务器会给每个Block分配一个唯一不变的Block标识。DataNode服务器把Block以Linux文件的形式保存在本地硬盘上,并且根据指定的Block标识和字节范围来读写块数据。出于可靠性的考虑,每个块都会复制到多个DataNode服务器上。在默认情况下,HDFS使用三个冗余备份,当然用户可以为不同的文件命名空间设定不同的复制因子数。NameNode管理所有的文件系统元数据。这些元数据包括名称空间、访问控制信息、文件和Block的映射信息,以及当前Block的位置信息。NameNode还管理着系统范围内的活动,比如,Block租用管理、孤立Block的I回收,以及Block 在 DataNode服务器之间的迁移。NameNode使信息周期性地和每个DataNode服务器通信,发送指令到各个DataNode服务器并接收DataNode中Block的状态信息。 HDFS客户端代码以库的形式被链接到客户程序中。在客户端代码中需要实现HDFS文件系统的API 接口函数,应用程序与NameNode和DataNode服务器通信,以及对数据进行读写操作。客户端和NameNode的通信只获取元数据,所有的数据操作都是由客户端直接和DataNode服务器进行交互的。HDFS不提供POSIX标准的API功能,因此,HDFS API调用不需要深入到Linux vnode级别。无论是客户端还是DataNode服务器都不需要缓存文件数据。客户端缓存数据几乎没有什么用处,因为大部分程序要么以流的方式读取一个巨大的文件,要么工作集太大根本无法被缓存。因此,无须考虑与缓存相关的问题,同时也简化了客户端及整个系统的设计和实现。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5081550.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 51)——扩展构造函数

扩展类型的时候,也可以添加新的构造函数。值类型与引用类型扩展有所区别。值类型包括了除类以外的其他类型,主要是枚举类型和结构体类型。 值类型扩展构造函数 扩展结构体类型中定义构造函数的示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 structRectangle{ varwidth:Double varheight:Double init(width:Double,height:Double){ self.width=width self.height=height } } extensionRectangle{ //定义了Rectangle的扩展类型 init(length:Double){ self.init(width:length,height:length) } } varrect=Rectangle(width: 320.0 ,height: 480.0 ) //调用两个参数的构造函数,这个构造函数是原始类型提供,Rectangle类型已经是扩展类型 print( "长方形:\(rect.width)x\(rect.height)" ) varsquare=Rectangle(length: 500.0 ) //调用一个参数的构造函数,这个构造函数是扩展类型提供的 print( "正方形:\(square.width)x\(square.height)" ) self.init是调用了原始类型的两个参数的构造函数。 引用类型扩展构造函数 扩展类中定义构造函数的示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Person{ varname:String varage:Int funcdescription()->String{ return "\(name)年龄是:\(age)" } init(name:String,age:Int){ self.name=name self.age=age } } extensionPerson{ //定义Person类的扩展类型 convenienceinit(name:String){ //便利构造函数 self.init(name:name,age: 8 ) } } letp1=Person(name: "Mary" ) //调用两个参数的构造函数,这个构造函数是原始类型提供,这时候的Person类型已经是扩展类型。 print( "Person1:\(p1.description())" ) letp2=Person(name: "Tony" ,age: 28 ) //调用一个参数的构造函数创建Person实例,这个构造函数是扩展类型提供的。 print( "Person2:\(p2.description())" ) 代码self.init(name :name, age : 8)调用指定构造函数代理部分构造任务。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1748298,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 23)——尾随闭包

闭包表达式可以作为函数的参数传递,如果闭包表达式很长,就会影响程序的可读性。尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。 下面我们来看一个示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 funccalculate(opr:String,funN:(Int,Int)->Int){ //最后一个参数funN是(Int,Int)->Int函数类型,funN可以接收闭包表达式 switch (opr){ case "+" : print( "10+5=\(funN(10,5))" ) default : print( "10-5=\(funN(10,5))" ) } } calculate( "+" ,funN:{(a:Int,b:Int)->Intin return a+b}) //调用 calculate( "+" ){(a:Int,b:Int)->Intin return a+b} //调用,这种形式就是尾随闭包 calculate( "+" ){$ 0 +$ 1 } //调用,这种形式就是尾随闭包 需要注意的是,闭包必须是参数列表的最后一个参数,如果calculate函数采用如下形式定义: func calculate(funN:(Int,Int)->Int,opr:String) { ... } 由于闭包表达式不是最后一个参数,那么调用calculate函数就不能使用尾随闭包写法的。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746417,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android开发学习:向模拟器的sdcard中添加文件

向模拟器的sdcard中添加文件有两种方法: 1.在eclipse的DDMS视图中操作 启动eclipse---打开DDMS视图---选择File Explorer,出现下面的窗口 选中sdcard文件夹---点击,选择你需要添加的文件就可以了 2.运用adb命令操作 先将要添加的文件放到platform-tools(我的platform-tools路径 D:\Android\android-sdk-windows\platform-tools)文件夹下,之后在命令行窗口进入 D:\Android\android-sdk-windows\platform-tools,输入adb命令添加文件,如下图所示: 这时,文件music.mp3就被添加到sdcard/Android目录下面 之后可以在模拟器中打开dev tools,运行Media Scanner,在音乐中播放添加的音乐 还可以在命令行运行adb shell来查看sdcard中的文件,如下图所示: 向模拟器的sdcard中添加文件常见的错误: 1.Failed to push items null 解决的方法:首先重启eclipse,如果重启之后再出现这个问题,那就要修改超时数,依次展开eclipse---windwos---Preferences---Android---DDMS---ADB connection time out (ms),将参数改得大一些,如下图所示: 2.Failed to push selection: Invalid argument 原因:android不支持中文名称的文件 3.Failed to push XXXXX.txt(添加的文件) on emulator- : Read-only file system 解决的方法:在启动模拟器的时候带着的参数中,模拟器镜像路径需是绝对路径:-sdcard E:\android\android-sdk-windows\tools\sdcard.img注意这个绝对路径里面不能带空格(如Program Files)注意:(卷标、标签)必须是sdcard。如mksdcard -l sdcard128Me:\haogood.image(而不能是mksdcard -l haogood128Me:\haogood.image) 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/673776

优秀的个人博客,低调大师

Spark SQL概念学习系列之如何使用 Spark SQL(六)

al sqlContext = new org.apache.spark.sql.SQLContext(sc) // 在这里引入 sqlContext 下所有的方法就可以直接用 sql 方法进行查询 import sqlContext._ case class Person(name: String, age: Int) // 下面的 people 是含有 case 类型数据的 RDD,会默认由 Scala 的 implicit 机制将 RDD 转换为 SchemaRDD, SchemaRDD 是 SparkSQL 中的核心 RDD val people = sc.textFile("examples/src/main/resources/people.txt").map(_. split(",")).map(p => Person(p(0), p(1).trim.toInt)) // 在内存的元数据中注册表信息,这样一个 Spark SQL 表就创建完成了 people.registerAsTable("people") // sql 语句就会触发上面分析的 Spark SQL 的执行过程,读者可以参考上面的图示 val teenagers = sql("SELECT name FROM people WHERE age >= 13 AND age <= 19") // 最后生成 teenagers 也是一个 RDD teenagers.map(t =>"Name: " + t(0)).collect().foreach(println) 通过之前的介绍,读者对支撑结构化数据分析任务的 Spark SQL 的原理与使用有了一定的了解。在生产环境中,有一类数据分析任务对响应延迟要求高,需要实时处理流数据,在 BDAS 中, Spark Streaming 用于支撑大规模流式处理分析任务。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5725106.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop HDFS概念学习系列之HDFS源代码结构(十四)

了解了HDFS体系结构中的名字节点、数据节点和客户端以后,我们来分析HDFS实现的源代码结构。HDFS源代码都在org.apache.hadoop.hdfs包下,其结构如图6-3所示。 HDFS的源代码分布在I6个目录下,它们可以分为如下四类1.基础包 包括工具和安全包。其中,hdfs.util包含了一些HDFS实现需要的辅助数据结构:hdfs.security.token.hlock和hdfs.security.token.delegation结合Hadaop的安全框架,提供了安全访问HDFS的机制。该安全特性最先是由Yahoo开发的,集成了企业广泛应用的Kerberos标准,使得用户可以在一个集群管理各类商业敏感数据。 2.HDFS实体实现包 这是代码分析的重点,包含7个包: hdfs.server.common包含了一些名字节点和数据节点共享的功能,如系统升级、存储空间信息等。hdfs.protocol包提供了HDFS各个实体间通过IPC交互的接口。hdfs.server.datanode和hdfs分别包含了名字节点、数据节点和客户端的实现。上述代码是HDFS代码分析的重点。hdfs.server.namennde.metrics包和hdfs.server.datanode.metrics包实现了名字节点和数据节点上度量数据的收集功能。度量数据包括名字节点进程和数据节点进程上事件的计数,例如数据节点上就可以收集到写入字节数、被复制的块的数量等信息。 3.应用包 包括hdfs.tools包和hdfs.server.balancer包,这两个包提供查询HDFS状态信息工具dfsadmin、文件系统检查工具fsck和HDFS均衡器balancer(通过start-balancer. sh启动)的实现。 4. WebHDFS相关包 包括hdfs.web.resources包,hdfs.server.namenode.web.resourees包,hdfs.server.datanode.web.resources包和hdfs.web包共4个包。 WebHDFS是HDFS 1.0中引入的新功能,它提供了一个完整的、通过HTTP访问HDFS的机制。对比只读的hftp文件系统,WebHDFS提供了HTTP上读写HDFS的能力,并在此基础上实现了访问 HDFS的C客户端和用户空间文件系统〔FUSE)。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5089745.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop概念学习系列之Hadoop的文件系统(十六)

Hadoop整合了众多文件系统,它首先提供了一个高层的文件系统抽象类org.apache.hadoop.fs.FileSystem,这个抽象类展示了一个分布式文件系统,并有几个具体实现。 如下表所示。 Hadovp提供了许多文件系统的接口,用户可使用URI方案选取合适的文件系统来实现交互。比如,可以使用文件系统命令行接口来进行Hadoop文件系统的操作。如果想列出本地文件系统的目录,那么执行以下shell命令即可: hadoop fs -lsfile:/// (1)接口 Hadoop是使用Java编写的,而Hadoop中不同文件系统之间的交互是由Java API进行调解的。事实上,前面使用的文件系统的shell就是一个Java应用,它使用Java文件系统类来提供文件系统操作。即使其他文件系统比如FTP, S3都有自己的访问工具,这些接口在HDFS中还是被广泛使用,主要用来进行Hadoop文件系统之间的协作。 (2)Thrift 上面提到可以通过Java API与Hadoop的文件系统进行交互,而对于其他非Java应用访问Hadaop文件系统则比较麻烦。Thriftfs分类单元中的Thrift API可通过将Hadaop文件系统展示为一个Apache Thrift服务来填补这个不足,让任何有Thrift绑定的语言都能轻松地与Hadoop文件系统进行交互。Thrift是由Facebook公司开发的一种可伸缩的跨语言服务的发展软件框架。Thrift解决了各系统间大数据量的传输通信,以及系统之间因语言环境不同而需要跨平台的问题。在多种不同的语言之间通信时,Thrift可以作为二进制的高性能的通信中间件,它支持数据(对象)序列化和多种类型 的RPC服务。 下面来看如何使用Thrift API。要使用Thrift API,首先要运行提供Thrill服务的Java服务器,并以代理的方式访问Hadoop文件系统。Thrill API包含很多其他语言生成的stub,包括C++、Perl、PHP、 Python等。Thrift支持不同的版本,因此可以从同一个客户代码中访问不同版本的Hadoop文件系统,但要运行针对不同版本的代理。 (3)C语言库 Hadoop提供了映射Java文件系统接口的C语言库—libhdfs。libhdfs可以编写为一个访问HDFS的C语言库,实际上,它可以访问任意的Haduap文件系统,它也可以使用JNI(Java Native Interface)来调用Java文件系统的客户端。 这里的C语言的接口和Java的使用非常相似,只是稍滞后于Java,目前还不支持一些新特性。相关资料可参见libhdfs/docs/api目录中关丁Hadoop分布的C API文档。 (4) FUSE FUSE(Filesystem in Userspace)允许将文件系统整合为一个Unix文件系统并在用户空间中执行。通过使用Hadoop Fuse-DFS的contirb模块来支持任意的Hadoop文件系统作为一个标准的文件系统挂载,便可以使用Unix的工具(像1s, cat)和文件系统进行交互,还可以通过任意一种编程语言使用POSIX库来访问文件系统。 Fuse-DFS是用C语言实现的,可使用libhdfs作为与HDFS的接口,关于如何编译和运行Fuse-DFS,可以参见src/contrib../fuse-dfs中的相关文档。 (5) WebDAV WebDAV是一系列支持编辑和更新文件的HTTP的扩展,在大部分操作系统中,WeDAV共享都可以作为文件系统进行挂载,因此,可通过WebDAV来对外提供HDFS或其他Nadoop文件系统,可以将HDFS作为一个标淮的文件系统进行访问。 (6)其他HDFS接口 HDFS接口还提供了以下其他两种特定的接口。 HTTP。 HDFS定义了一个只读接口,用来在HTTP上检索目录列表和数据。NameNode的嵌入式Web服务器运行在50070端口上,以XML格式提供服务,文件数据由DataNode通过它们的Web服务器50075端日向NameNode提供。这个协议并不拘泥于某个HDFS版本,所以用户可以自己编写使用HTTP从运行不同版本的Hadoop的NDFS中读取数据。HftpFileSystem就是其中的一种实现,它是一个通过HTTP和HDFS交流的Hadoop文件系统,是HTTPS的变体。 FTP。Hadoop接口中还有一个HDFS的FTP接口,它允许使用FTP协议和HDFS交互,即使用FTP客户端和HDFS进行交互。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5089369.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop概念学习系列之重温Hadoop基本知识(十一)

Hadoop是一个由Apache基金会开发的分布式编程框架,允许在集群服务器上使用简单的编程模型(MapReduce)对大数据集进行分布式处理。 Hadoop框架的核心的是HDFS、MapReduce和Yarn。 其中HDFS提供海量数据的存储, MapReduce提供数据计算, Yarn是集群资源管理和调度平台。 掌握了这三部分,也就掌握了Hadoop最核心的东西。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5080008.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop MapReduce概念学习系列之新旧 MapReduce API 比较(四)

从 0.20.0 版本开始,Hadoop 同时提供了新旧两套 MapReduce API。新 API 在旧 API 基础上进行了封装,使得其在扩展性和易用性方面更好。新旧版 MapReduce API 的主要区 别如下。 (1)存放位置 旧版 API 放在 org.apache.hadoop.mapred 包中,而新版 API 则放在 org.apache.hadoop. mapreduce 包及其子包中。 (2)接口变为抽象类 接口通常作为一种严格的“协议约束”。它只有方法声明而没有方法实现,且要求所有实 现类(不包括抽象类)必须实现接口中的每一个方法。接口的最大优点是允许一个类实现多 个接口,进而实现类似 C++ 中的“多重继承”。抽象类则是一种较宽松的“约束协议”,它可 为某些方法提供默认实现。而继承类则可选择是否重新实现这些方法。正是因为这一点,抽 象类在类衍化方面更有优势,也就是说,抽象类具有良好的向后兼容性,当需要为抽象类添 加新的方法时,只要新添加的方法提供了默认实现,用户之前的代码就不必修改了。 考虑到抽象类在API衍化方面的优势,新API在InputFormat、OutputFormat、Mapper、Reducer和Partitioner由接口变成抽象类。 (3)上下文封装 新版 API 将变量和函数封装成各种上下文(Context)类,使得 API 具有更好的易用性 和扩展性。首先,函数参数列表经封装后变短,使得函数更容易使用 ;其次,当需要修改 或添加某些变量或函数时,只需修改封装后的上下文类即可,用户代码无须修改,这样保 证了向后兼容性,具有良好的扩展性。 上图展示了新版API中树形的Context 类继承关系。这些Context 各自封装了一种实体的基本信息及对应的操作(setter和getter 函数),如JobContext、TaskAttemptContext 分 别封装了Job和Task的基本信息,TaskInputOutputContext 封装了Task的各种输入输出操作,MapContext 和ReduceContext分别封装了Mapper和Reducer对外的公共接口。 除了以上三点不同之外,新旧API 在很多其他细节方面也存在小的差别。由于新版和旧版API 在类层次结构、编程接口名称及对应的参数列表等方面存在较大差别,所以两种 API 不能兼容。但考虑到应用程序的向后兼容性,短时间内不会将旧API从MapReduce 中去掉。即使在完全采用新 API 的0.21.0/0.22.X 版本系列中,也仅仅将旧 API 标注为过期(deprecated),用户仍然可以使用。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5058689.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Spark Tachyon概念学习系列之Spark Tachyon是什么?(一)

Tachyon是一个分布式内存文件系统,可以理解为内存中的HDFS。 为了提供更高的性能,将数据存储剥离Java Heap。 用户可以基于Tachyon实现RDD或者文件的跨应用共享,并提供高容错机制,保证数据的可靠性。 1、Tachyon介绍 1.1Tachyon简介 随着实时计算的需求日益增多,分布式内存计算也持续升温,怎样将海量数据近乎实时地处理,或者说怎样把离线批处理的速度再提升到一个新的高度是当前研究的重点。近年来,内存的吞吐量成指数倍增长,而磁盘的吞吐量增长缓慢,那么将原有计算框架中文件落地磁盘替换为文件落地内存,也是提高效率的优化点。 目前已经使用基于内存计算的分布式计算框架有:Spark、Impala及SAP的HANA等。但是其中不乏一些还是有文件落地磁盘的操作,如果能让这些落地磁盘的操作全部落地到一个共享的内存中,那么这些基于内存的计算框架的效率会更高。 Tachyon是AmpLab的李浩源所开发的一个分布式内存文件系统,可以在集群里以访问内存的速度来访问存在Tachyon里的文件。Tachyon是架构在最底层的分布式文件存储和上层的各种计算框架之间的一种中间件,其主要职责是将那些不需要落地到DFS里的文件落地到分布式内存文件系统中来达到共享内存,从而提高效率。同时可以减少内存冗余、GC时间等,Tachyon的在大数据中层次关系如下图所示: Tachyon允许文件以内存的速度在集群框架中进行可靠的共享,就像Spark和MapReduce那样。通过利用信息继承、内存侵入,Tachyon获得了高性能。Tachyon工作集文件缓存在内存中,并且让不同的Jobs/Queries以及框架都能以内存的速度来访问缓存文件。因此,Tachyon可以减少那些需要经常使用数据集通过访问磁盘来获得的次数。 1.2Tachyon系统架构 1.2.1系统架构 Tachyon在Spark平台的部署:总的来说,Tachyon有三个主要的部件:Master,Client,与Worker。在每个Spark Worker节点上,都部署了一个Tachyon Worker,Spark Worker通过Tachyon Client访问Tachyon进行数据读写。所有的Tachyon Worker都被Tachyon Master所管理,Tachyon Master通过Tachyon Worker定时发出的心跳来判断Worker是否已经崩溃以及每个Worker剩余的内存空间量。 1.2.2Tachyon Master结构 Tachyon Master的结构其主要功能如下:首先,Tachyon Master是个主管理器,处理从各个Client发出的请求,这一系列的工作由Service Handler来完成。这些请求包括:获取Worker的信息,读取File的Block信息,创建File等等;其次,Tachyon Master是个Name Node,存放着所有文件的信息,每个文件的信息都被封装成一个Inode,每个Inode都记录着属于这个文件的所有Block信息。在Tachyon中,Block是文件系统存储的最小单位,假设每个Block是256MB,如果有一个文件的大小是1GB,那么这个文件会被切为4个Block。每个Block可能存在多个副本,被存储在多个Tachyon Worker中,因此Master里面也必须记录每个Block被存储的Worker地址;第三,Tachyon Master同时管理着所有的Worker,Worker会定时向Master发送心跳通知本次活跃状态以及剩余存储空间。Master是通过Master Worker Info去记录每个Worker的上次心跳时间,已使用的内存空间,以及总存储空间等信息。 1.2.3Tachyon Worker结构 Tachyon Worker主要负责存储管理:首先,Tachyon Worker的Service Handler处理来自Client发来的请求,这些请求包括:读取某个Block的信息,缓存某个Block,锁住某个Block,向本地内存存储要求空间等等。第二,Tachyon Worker的主要部件是Worker Storage,其作用是管理Local Data(本地的内存文件系统)以及Under File System(Tachyon以下的磁盘文件系统,比如HDFS)。第三,Tachyon Worker还有个Data Server以便处理其他的Client对其发起的数据读写请求。当由请求达到时,Tachyon会先在本地的内存存储找数据,如果没有找到则会尝试去其他的Tachyon Worker的内存存储中进行查找。如果数据完全不在Tachyon里,则需要通过Under File System的接口去磁盘文件系统(HDFS)中读取。 1.2.4Tachyon Client结构 Tachyon Client主要功能是向用户抽象一个文件系统接口以屏蔽掉底层实现细节。首先,Tachyon Client会通过Master Client部件跟Tachyon Master交互,比如可以向Tachyon Master查询某个文件的某个Block在哪里。Tachyon Client也会通过Worker Client部件跟Tachyon Worker交互, 比如向某个Tachyon Worker请求存储空间。在Tachyon Client实现中最主要的是Tachyon File这个部件。在Tachyon File下实现了Block Out Stream,其主要用于写本地内存文件;实现了Block In Stream主要负责读内存文件。在Block In Stream内包含了两个不同的实现:Local Block In Stream主要是用来读本地的内存文件,而Remote Block In Stream主要是读非本地的内存文件。请注意,非本地可以是在其它的Tachyon Worker的内存文件里,也可以是在Under File System的文件里。 1.2.5场景说明 现在我们通过一个简单的场景把各个部件都串起来:假设一个Spark作业发起了一个读请求,它首先会通过Tachyon Client去Tachyon Master查询所需要的Block所在的位置。如果所在的Block不在本地的Tachyon Worker里,此Client则会通过Remote Block In Stream向别的Tachyon Worker发出读请求,同时在Block读入的过程中,Client也会通过Block Out Stream把Block写入到本地的内存存储里,这样就可以保证下次同样的请求可以由本机完成。 1.3HDFS与Tachyon HDFS(Hadoop Distributed File System)是一个分布式文件系统。HDFS具有高容错性(fault-tolerant)特点,并且设计用来部署在低廉的硬件上。而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了POSIX的要求,这样可以实现以流的形式访问(streaming access)文件系统中的数据。 HDFS采用Master/Slave架构。HDFS集群是由一个Namenode和一定数目的Datanode组成的。Namenode是一台中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。集群中的Datanode一般是一个节点一个,负责管理它所在节点上的存储。HDFS暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组Datanode上。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录,它也负责确定数据块到具体Datanode节点的映射。Datanode负责处理文件系统客户端的读写请求,在Namenode的统一调度下对数据块进行创建、删除和复制。 HDFS架构示意图如下图所示。 Namenode和Datanode被设计成可以在普通的商用机器上运行,这些机器一般运行着GNU/Linux操作系统。HDFS采用Java语言开发,因此任何支持Java的机器都可以部署Namenode或Datanode。由于采用了可移植性极强的Java语言,使得HDFS可以部署到多种类型的机器上。一个典型的部署场景是一台机器上只运行一个Namenode实例,而集群中的其他机器则分别运行一个Datanode实例。这种架构并不排斥在一台机器上运行多个Datanode,只不过这样的情况比较少见。 集群中单一Namenode的结构大大简化了系统的架构。Namenode是所有HDFS元数据的仲裁者和管理者,这样用户数据永远不会流过Namenode。 对比HDFS和Tachyon,首先从两者的存储结构来看,HDFS设计为用来存储海量文件的分布式系统,Tachyon设计为用来缓存常用数据的分布式内存文件系统。从这点来看,Tachyon可以认为是操作系统层面上的Cache,HDFS可以认为是磁盘。 在可靠性方面,HDFS采用副本技术来保证出现系统宕机等意外情况时文件访问的一致性以及可靠性;而Tachyon是依赖于底层文件系统的可靠性来实现自身文件的可靠性的。由于相对于磁盘资源来说,内存是非常宝贵的,所以Tachyon通过在其underfs(一般使用HDFS)上写入CheckPoint日志信息来实现对文件系统的可恢复性。 从文件的读取以及写入方式来看,Tachyon可以更好地利用本地模式来读取文件信息,当文件读取客户端和文件所在的Worker位于一台机器上时,客户端会直接绕过Worker直接读取对应的物理文件,减少了本机的数据交互。而HDFS在遇到这样的情况时,会通过本地Socket进行数据交换,这也会有一定的系统资源开销。在写入文件时,HDFS只能写入磁盘,而Tachyon却提供了5种数据写入模式用以满足不同需求。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5723929.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Spark SQL概念学习系列之Spark SQL 架构分析(四)

Spark SQL 与传统 DBMS 的查询优化器 + 执行器的架构较为类似,只不过其执行器是在分布式环境中实现,并采用的 Spark 作为执行引擎。 Spark SQL 的查询优化是Catalyst,其基于 Scala 语言开发,可以灵活利用 Scala 原生的语言特性很方便进行功能扩展,奠定了 Spark SQL 的发展空间。 Catalyst 将 SQL 语言翻译成最终的执行计划,并在这个过程中进行查询优化。这里和传统不太一样的地方就在于, SQL 经过查询优化器最终转换为可执行的查询计划是一个查询树,传统 DB 就可以执行这个查询计划了。而 Spark SQL 最后执行还是会在 Spark 内将这棵执行计划树转换为 Spark 的有向无环图DAG 再执行。 1.Catalyst 架构及执行流程分析 下图1所示是Catalyst 的整体架构。 图 1 Spark SQL 查询引擎 Catalyst 的架构 从图1 中可以看到整个 Catalyst 是 Spark SQL 的调度核心,遵循传统数据库的查询解析步骤,对 SQL 进行解析,转换为逻辑查询计划、 物理查询计划,最终转换为 Spark 的 DAG 后再执行。图 2为 Catalyst 的执行流程。 SqlParser 将 SQL 语句转换为逻辑查询计划, Analyzer 对逻辑查询计划进行属性和关系关联检验,之后 Optimizer 通过逻辑查询优化将逻辑查询计划转换为优化的逻辑查询计划, QueryPlanner 将优化的逻辑查询计划转换为物理查询计划, prepareForExecution 调整数据分布,最后将物理查询计划转换为执行计划进入Spark 执行任务。 图2 Catalyst 的执行流程 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5725065.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 41)——类的继承

Swift中的继承只能发生在类上,不能发生在枚举和结构体上。一个类可以继承另一个类的方法、属性、下标等特征,当一个类继承其他类时,继承类叫子类,被继承类叫父类(或超类)。子类继承父类后,可以重写父类的方法、属性、下标等特征。 为了了解继承性,看这样一个场景:一位面向对象的程序员小赵,在编程过程中需要描述和处理个人信息,于是他定义了类Person,如下所示: 1 2 3 4 5 6 7 8 9 10 11 12 class Person{ varname:String varage:Int funcdescription()->String{ return "\(name)年龄是:\(age)" } init(){ name= "" age= 1 } } 一周以后,小赵又遇到了新的需求,需要描述和处理学生信息,于是他又定义了一个新的类Student,如下所示: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Student{ varname:String varage:Int varschool:String funcdescription()->String{ return "\(name)年龄是:\(age)" } init(){ school= "" name= "" age= 8 } } 很多人会认为小赵的做法能够理解并相信这是可行的,但是问题在于Student和Person两个类的结构太接近了,后者只比前者多了一个属性school,却要重复定义其他所有的内容,实在让人“不甘心”。Swift提供了解决类似问题的机制,那就是类的继承,代码如下所示: 1 2 3 4 5 6 7 8 class Student:Person{ varschool:String overrideinit(){ school= "" super .init() age= 8 } } Student类继承了Person类中的所有特征,“:”之后的Person类是父类。Swift中的类可以没有父类,例如Person类,定义的时候后面没有“:”,这种没有父类的就是基类。 此外override init()是子类重写父类构造函数。 一般情况下,一个子类只能继承一个父类,这称为单继承,但有的情况下一个子类可以有多个不同的父类,这称为多重继承。在Swift中,类的继承只能是单继承。多重继承可以通过遵从多个协议实现。也就是说,在Swift中,一个类只能继承一个父类,但是可以遵循多个协议。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1747494,如需转载请自行联系原作者

优秀的个人博客,低调大师

Spark SQL概念学习系列之Spark SQL 优化策略(五)

查询优化是传统数据库中最为重要的一环,这项技术在传统数据库中已经很成熟。除了查询优化,Spark SQL 在存储上也进行了优化,从以下几点查看 Spark SQL 的一些优化策略。(1)内存列式存储与内存缓存表 Spark SQL 可以通过 cacheTable 将数据存储转换为列式存储,同时将数据加载到内存进行缓存。 cacheTable 相当于在分布式集群的内存物化视图,将数据进行缓存,这样迭代的或者交互式的查询不用再从 HDFS 读数据,直接从内存读取数据大大减少了 I/O 开销。列式存储的优势在于 Spark SQL 只需要读出用户需要的列,而不需要像行存储那样需要每次将所有列读出,从而大大减少内存缓存数据 量,更高效地利用内存数据缓存,同时减少网络传输和 I/O 开销。数据按照列式存储,由于是数据类型相同的数据连续存储,能够利用序列化和压缩减少内存空间的占用。 (2)列存储压缩 为了减少内存和硬盘空间占用, Spark SQL 采用了一些压缩策略对内存列存储数据 进 行 压 缩。 Spark SQL 的 压 缩 方 式 要 比 Shark 丰 富 很 多, 例 如 它 支 持 PassThrough,RunLengthEncoding, DictionaryEncoding, BooleanBitSet, IntDelta, LongDelta 等多种压缩方式。这样能够大幅度减少内存空间占用和网络传输开销和 I/O 开销。(3)逻辑查询优化 Spark SQL 在逻辑查询优化(如图 1 所示)上支持列剪枝、谓词下压、属性合并等逻辑查询优化方法。列剪枝为了减少读取不必要的属性列,减少数据传输和计算开销,在查询优化器进行转换的过程中会进行列剪枝的优化。 图 1 逻辑查询优化 下面介绍一个逻辑优化例子: SELECT Class FROM (SELECT ID,Name,Class FROM STUDENT ) S WHERE S.ID=1 Catalyst 将原有查询通过谓词下压,将选择操作 ID=1 优先执行,这样过滤大部分数据,通过属性合并将最后的投影只做一次最终保留 Class 属性列。 (4) Join 优化 Spark SQL 深度借鉴传统数据库查询优化技术的精髓,同时也在分布式环境下进行特定的优化策略调整和创新。 Spark SQL 对 Join 进行了优化支持多种连接算法,现 在的连接算法已经比 Shark 丰富,而且很多原来 Shark 的元素也逐步迁移过来。例如:BroadcastHashJoin、 BroadcastNestedLoopJoin、 HashJoin、 LeftSemiJoin,等等。 下面介绍一个其中的 BroadcastHashJoin 算法思想。BroadcastHashJoin 将小表转化为广播变量进行广播,这样避免 Shuff le 开销,最后在分区内做 Hash 连接。这里用的就是 Hive 中 Map Side Join 的思想。同时用了 DBMS中的 Hash 连接算法做连接。 随着 Spark SQL 的发展,未来会有更多的查询优化策略加入进来。同时后续 SparkSQL 会 支 持 像 Shark Server 一 样 的 服 务 端、 JDBC 接 口, 兼 容 更 多 的 持 久 化 层 例 如NoSQL,传统的 DBMS 等。一个强有力的结构化大数据查询引擎正在崛起。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5725097.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Spark SQL概念学习系列之SQL on Spark的简介(三)

AMPLab 将大数据分析负载分为三大类型:批量数据处理、交互式查询、实时流处理。而其中很重要的一环便是交互式查询。 大数据分析栈中需要满足用户 ad-hoc、reporting、 iterative 等类型的查询需求,也需要提供 SQL 接口来兼容原有数据库用户的使用习惯,同时也需要 SQL 能够进行关系模式的重组。完成这些重要的 SQL 任务的便是Spark SQL 和 Shark这两个开源分布式大数据查询引擎,它们可以理解为轻量级 HiveSQL 在 Spark 上的实现,业界将该类技术统称为 SQL on Hadoop。 在 Spark 峰 会 2014 上, Databricks 宣 布 不 再 支 持 Shark 的 开 发, 全 力 以 赴 开 发Shark 的下一代技术 Spark SQL,同时 Hive 社区也启动了 Hive on Spark 项目, 将 Spark作为 Hive(除 MapReduce 和 Tez 之外的)新执行引擎。根据伯克利的 Big Data Benchmark测试对比数据,Shark 的 In Memory 性能 可 以 达 到 Hive 的 100 倍, 即 使 是On Disk 也能达到 10 倍的性能提升,是 Hive 强有力的替代解决方案。而作为Shark 的进化版本的 Spark SQL,在 AMPLab 最新的测试中的性能已经超过 Shark。图 1 展示了 Spark SQL和 Hive on Spark 是新的发展方向。 图 1 Spark SQL 和 Hive on Spark 是新的发展方向 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5725020.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册