首页 文章 精选 留言 我的

精选列表

搜索[谷歌I/O],共10009篇文章
优秀的个人博客,低调大师

Hadoop TDG 2 – I/O

Data Integrity HDFS transparently checksums all data written to it and by default verifies checksums when reading data. A separate checksum is created for every io.bytes.per.checksum bytes of data. The default is 512 bytes, and since a CRC-32 checksum is 4 bytes long, the storage overhead is less than 1%. 关于数据一致性, Hadoop通过CRC-32的校验和来保证 Compression Compression and Input Splits 关注一下这个问题, 并不是每一种压缩都支持splits, 比如gzip就不支持, 知道gzip的原理就知道, 他通过指针指向前面已经出现过的数据, 所以单独给你一块, 你无法解压. Serialization Serialization is the process of turning structured objects into a byte stream for transmission over a network or for writing to persistent storage. Deserialization is the reverse process of turning a byte stream back into a series of structured objects. 序列化问题倒是比较重要的, 因为分布式计算, node之间的数据传输都需要序列化和反序列化的过程. Hadoop uses its own serialization format,Writables, which is certainly compact and fast,butnot so easy to extend or use from languages other than Java. The Writable Interface The Writable interface defines two methods: one for writing its state to a DataOutput binary stream, and one for reading its state from a DataInput binary stream: package org.apache.hadoop.io; import java.io.DataOutput; import java.io.DataInput; import java.io.IOException; public interface Writable { void write(DataOutput out) throws IOException; void readFields(DataInput in) throws IOException; } 这个抽象接口, 到很容易理解, 序列化和反序列化就是, 把类型数据输出成二进制流, 再从二进制流将类型数据恢复出来. 可见Hadoop提供了很全的类型封装, Java primitive Writable implementation Serialized size (bytes) boolean BooleanWritable 1 byte ByteWritable 1 int IntWritable 4 VIntWritable 1–5 float FloatWritable 4 long LongWritable 8 VLongWritable 1–9 double DoubleWritable 8 String Text byte[] BytesWritable NullWritable 0, used as a placeholder, a key or a value can be declared as a NullWritable when you don’t need to use that position ObjectWritable General-purpose wrapper, useful when a field can be of more than one type. 问题是浪费空间, writes the classname of the wrapped type every time it is serialized GenericWritable 用于优化ObjectWritable, 当可能的类型比较少, 我们又可以预先知道, 定义static array of types, 这样序列化的时候只需要记下array index, 而不用记录class name Arrays ArrayWritable TwoDArrayWritable two-dimensional arrays Map MapWritable java.util.Map<Writable, Writable> SortedMap SortedMapWritable java.util.SortedMap<WritableComparable, Writable> 细心点会发现, 里面没有对set和list经行封装, 所以怎么表示这两种结构? Conspicuous by their absence are Writable collection implementations forsetsandlists. Asetcan be emulated by using aMapWritable(or a SortedMapWritable for a sorted set),with NullWritable values. Forlistsof a single type of Writable,ArrayWritableis adequate, but to storedifferent types of Writable in a single list, you can useGenericWritabletowrap the elementsin anArrayWritable. Alternatively, you could write a general ListWritable using the ideas from MapWritable. WritableComparable and Comparators WritableComparable, 顾名思义, 就是在序列化的基础上, 还能支持sort, 这个很有用, 由于hadoop需要对key进行排序, 所以所有的key都必须是WritableComparable类型. 所以对于Writable, 需要多实现一个compareTo function. 但当Hadoop经行shuffle sort时, 需要sort大量的中间结果, 所以为了sort, 需要把byte stream反序列化成类型, 然后sort结束再序列化成byte stream. 这样当数据量很大时, 效率会比较低, 所以可以定义Comparators来进行优化. This interface permits implementors to compare records read from a stream without deserializing them into objects, thereby avoiding any overhead of object creation. 这样就避免了反序列化和序列化的overhead, 但是有个问题是, 并不是所有的类型都可以同bytes steaming进行sort的, 所以不是所有的WritableComparable都可以用compactors进行优化. package org.apache.hadoop.io; import java.util.Comparator; public interface RawComparator<T> extends Comparator<T> { public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2); } Serialization Frameworks Although most MapReduce programs use Writable key and value types, this isn’t mandated by the MapReduce API. In fact, any types can be used; the only requirement is that there be a mechanism that translates to and from a binary representation of each type. 上面说了, Writable是不错, 不过有个问题就是无法用于Java以外的语言, 所以需要有其它的serialization framework Avro (http://avro.apache.org/docs/current/index.html) Apache Avro# is a language-neutral data serialization system. The project was created byDoug Cutting(the creator of Hadoop) to address the major downside of Hadoop Writables: lack of language portability. Having a data format that can be processed by many languages (currently C, C++, Java, Python, and Ruby) makes it easier to share datasets with a wider audience than one tied to a single language. It is also more futureproof, allowing data to potentially outlive the language used to read and write it. Avro就用于解决上面的语言扩展性问题... 与Avro类似的二进制序列化framework, 还有Thrift和Protocol buffer, 提供通讯数据序列化的功能和RPC服务. 区别, 或者说Avro的特点在底下这个比较blog里面说的比较清楚 Apache Avro 与 Thrift 比较 http://www.tbdata.org/archives/1307 Thrift是一个面向编程的系统, 完全依赖于IDL->Binding Language的代码生成。 Schema也“隐藏”在生成的代码中了,完全静态。为了让系统识别处理一个新的数据源,必须走编辑IDL,代码生成,编译载入的流程。 可见, Thrift是种传统的序列化的方案, 比如把java类进行序列化, 那么类对象的schema本身就包含在类定义里面, 所以在序列化的时候, 需要把Java的类定义代码转化为IDL格式, 并保存为schema文件. IDL, 接口定义语言, 可以看成一种伪码, 可以简单的和其他各种编程语言进行互相转换 然后把类对象中包含的数据进行序列化, 结果如下, 每个Field data前面都是需要带Tag的,这个Tag用于标识这个域的类型和顺序ID(IDL中定义,用于Versioning)。在同一批数据里面,这些Tag的信息是完全相同的,当数据条数大的时候这显然就浪费了。 然后当反序列化的时候, 我们首先要有个code generation的过程, 把IDL文件翻译成目标语言代码的过程, 然后再去读数据, 并用生成的类代码产生相应的类对象, 完成反序列化的过程. 而Avro在支持Thrift的这种方法的同时, 还提出另外一种更为灵活的方案... Avro-specific方式(Thrift的方式相似),依赖代码生成产生特定的类,并内嵌JSON Schema. Avro-generic方式支持Schema的动态加载,用通用的结构(map)代表数据对象,不需要编译加载直接就可以处理新的数据源。 首先Avro也是可以支持Thrift那样的静态序列化的方式的, Avro-specific方式 Avro-generic方式和Thrift最大的不同是, 它的schema以Json格式存储, 这样便于将schema也放在data file中(开头位置), 如下图. 在反序列化的时候, 我们不需要先得到IDL, 再产生code, 然后在读数据. 而是可以直接从data file中读出schema, 并根据schema动态加载后面的数据. Avro规定一个标准的序列化的格式,即无论是文件存储还是网络传输,数据的Schema(in JSON)都出现在数据的前面。数据本身并不包含任何Metadata(Tag).在文件储存的时候,schema出现在文件头中。在网络传输的时候Schema出现在初始的握手阶段.这样的好处一是使数据self describe,提高了数据的透明度和可操作性,二是减少了数据本身的信息量提高存储效率,可谓一举二得了 总结, Avro除了具备, 跨多语言, 支持RPC, 二进制格式...还有如下特色, Avro provides functionality similar to systems such asThrift,Protocol Buffers, etc. Avro differs from these systems in the following fundamental aspects. Dynamic typing: Avro does not require that code be generated. Data is always accompanied by a schema that permits full processing of that data without code generation, static datatypes, etc. This facilitates construction of generic data-processing systems and languages. Untagged data: Since the schema is present when data is read, considerably less type information need be encoded with data, resulting in smaller serialization size. No manually-assigned field IDs: When a schema changes, both the old and new schema are always present when processing data, so differences may be resolved symbolically, using field names. File-Based Data Structures SequenceFile是一种<key,value>的二进制的文件格式, 因为如果将<key,value>以文件格式存放的话, 必然会导致时空效率问题. 所以Hadoop在存放map的中间结果时都是使用SequenceFile来存放<key,value>的, SequenceFile还有另外一个用处就是, 将多个小文件组合成单个文件. 但它的问题是, 首先只支持Java, 其他语言开发Hadoop就无法使用 Avro就可以解决这个问题, 跨语言的, 而且结构更为紧凑, 而且附带schema数据可以自解释, 而且可以存放除<key,value>以外的其他类型 MapFile is a sorted SequenceFile with an index to permit lookups by key. MapFile can be thought of as a persistent form of java.util.Map (although it doesn’t implement this interface), which is able to grow beyond the size of a Map that is kept in memory. 浅析Hadoop文件格式 http://www.infoq.com/cn/articles/hadoop-file-format 1 SequenceFile SequenceFile是Hadoop API 提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中。这种二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。Hive 中的SequenceFile 继承自Hadoop API 的SequenceFile,不过它的key为空,使用value 存放实际的值, 这样是为了避免MR 在运行map 阶段的排序过程。如果你用Java API 编写SequenceFile,并让Hive 读取的话,请确保使用value字段存放数据,否则你需要自定义读取这种SequenceFile 的InputFormat class 和OutputFormat class。 图1:Sequencefile 文件结构 3 Avro Avro是一种用于支持数据密集型的二进制文件格式。它的文件格式更为紧凑,若要读取大量数据时,Avro能够提供更好的序列化和反序列化性能。并且Avro数据文件天生是带Schema定义的,所以它不需要开发者在API 级别实现自己的Writable对象。最近多个Hadoop 子项目都支持Avro 数据格式,如Pig 、Hive、Flume、Sqoop和Hcatalog。 图3:Avro MR 文件格式 4. 文本格式 除上面提到的3种二进制格式之外,文本格式的数据也是Hadoop中经常碰到的。如TextFile 、XML和JSON。 文本格式除了会占用更多磁盘资源外,对它的解析开销一般会比二进制格式高几十倍以上,尤其是XML 和JSON,它们的解析开销比Textfile 还要大,因此强烈不建议在生产系统中使用这些格式进行储存。 如果需要输出这些格式,请在客户端做相应的转换操作。 文本格式经常会用于日志收集,数据库导入,Hive默认配置也是使用文本格式,而且常常容易忘了压缩,所以请确保使用了正确的格式。另外文本格式的一个缺点是它不具备类型和模式,比如销售金额、利润这类数值数据或者日期时间类型的数据,如果使用文本格式保存,由于它们本身的字符串类型的长短不一,或者含有负数,导致MR没有办法排序,所以往往需要将它们预处理成含有模式的二进制格式,这又导致了不必要的预处理步骤的开销和储存资源的浪费。 本文章摘自博客园,原文发布日期:2012-09-06

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

Java I/O面试题

Java IO是面试中常问到的问题. 参考图 输入输出流关系图 什么是IO流? 它是一种数据的流从源头流到目的地。比如文件拷贝,输入流和输出流都包括了。输入流从文件中读取数据存储到进程(process)中,输出流从进程中读取数据然后写入到目标文件。 字节流和字符流的区别。 字节流在JDK1.0中就被引进了,用于操作包含ASCII字符的文件。JAVA也支持其他的字符如Unicode,为了读取包含Unicode字符的文件,JAVA语言设计者在JDK1.1中引入了字符流。ASCII作为Unicode的子集,对于英语字符的文件,可以可以使用字节流也可以使用字符流。 Java中流类的超类主要由那些? java.io.InputStream java.io.OutputStream java.io.Reader java.io.Writer FileInputStream和FileOutputStream是什么? 这是在拷贝文件操作的时候,经常用到的两个类。在处理小文件的时候,它们性能表现还不错,在大文件的时候,最好使用BufferedInputStream (或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter) 案例: public class InputAndOutputBuffering { public static void main(String args[]) throws IOException { FileInputStream fistream = new FileInputStream("pqr.txt"); BufferedInputStream bistream = new BufferedInputStream(fistream); FileOutputStream fostream = new FileOutputStream("xyz.txt"); BufferedOutputStream bostream = new BufferedOutputStream(fostream); int temp; while( ( temp = bistream.read() ) != -1 ) { bostream.write(temp); System.out.print((char) temp); } bostream.close(); fostream.close(); bistream.close(); fistream.close(); } } 字节流和字符流,你更喜欢使用拿一个? 个人来说,更喜欢使用字符流,因为他们更新一些。许多在字符流中存在的特性,字节流中不存在。比如使用BufferedReader而不是BufferedInputStreams或DataInputStream,使用newLine()方法来读取下一行,但是在字节流中我们需要做额外的操作。 System.out.println()是什么?println是PrintStream的一个方法。out是一个静态PrintStream类型的成员变量,System是一个java.lang包中的类,用于和底层的操作系统进行交互。 什么是Filter流? Filter Stream是一种IO流主要作用是用来对存在的流增加一些额外的功能,像给目标文件增加源文件中不存在的行数,或者增加拷贝的性能。 有哪些可用的Filter流? 在java.io包中主要由4个可用的filter Stream。两个字节filter stream,两个字符filter stream. 分别是FilterInputStream, FilterOutputStream, FilterReader and FilterWriter.这些类是抽象类,不能被实例化的。 有些Filter流的子类。 LineNumberInputStream 给目标文件增加行号 DataInputStream 有些特殊的方法如readInt(), readDouble()和readLine() 等可以读取一个 int, double和一个string一次性的, BufferedInputStream 增加性能 PushbackInputStream 推送要求的字节到系统中 SequenceInputStream的作用? 在拷贝多个文件到一个目标文件的时候是非常有用的。可用使用很少的代码实现 案例: public class TwoFiles { public static void main(String args[]) throws IOException { FileInputStream fistream1 = new FileInputStream("/Users/aihe/Desktop/Songshu/code/java8source/src/main/resources/A.txt"); // first source file FileInputStream fistream2 = new FileInputStream("/Users/aihe/Desktop/Songshu/code/java8source/src/main/resources/B.txt"); //second source file SequenceInputStream sistream = new SequenceInputStream(fistream1, fistream2); FileOutputStream fostream = new FileOutputStream("C.txt"); // destination file int temp; while( ( temp = sistream.read() ) != -1) { System.out.print( (char) temp ); // to print at DOS prompt fostream.write(temp); // to write to file } fostream.close(); sistream.close(); fistream1.close(); fistream2.close(); } } 说说PrintStream和PrintWriter 他们两个的功能相同,但是属于不同的分类。字节流和字符流。他们都有println()方法。 在文件拷贝的时候,那一种流可用提升更多的性能? 在字节流的时候,使用BufferedInputStream和BufferedOutputStream。 在字符流的时候,使用BufferedReader 和 BufferedWriter 说说管道流(Piped Stream) 有四种管道流, PipedInputStream, PipedOutputStream, PipedReader 和 PipedWriter.在多个线程或进程中传递数据的时候管道流非常有用。 说说File类 它不属于 IO流,也不是用于文件操作的,它主要用于知道一个文件的属性,读写权限,大小等信息。 说说RandomAccessFile? 它在java.io包中是一个特殊的类,既不是输入流也不是输出流,它两者都可以做到。他是Object的直接子类。通常来说,一个流只有一个功能,要么读,要么写。但是RandomAccessFile既可以读文件,也可以写文件。 DataInputStream 和 DataOutStream有的方法,在RandomAccessFile中都存在。 最后 这篇文章是我从国外翻译的,看完之后觉得对Java IO理解的更多了一些,翻译过来分享给大家。 附录 IO Java Interview Questions

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册