MapReduce 和 HDFS介绍

 

--------------------------------
原文链接:http://blog.csdn.net/amuseme_lu/article/details/5616198

Overview


* 为什么要用Mapreduce?
* 什么是Mapreduce?
* Hadoop的分布式文件系统

How MapReduce is Structured:

* 函数式程式满足了分布式计算的要求
* 大批量的数据处理系统
* 在应用逻辑层面上把很多可靠的因素考虑进来了

MapReduce Provides:

* 自动化的平行&数据分布
* 高可用性
* 状态与监控工具
* 为程序员提供了一种清晰的抽象

Programming Model:

* 来看一下什么是函数式编程
* 用可实现了下面两个方法

- map (in_key, in_value) -> (out_key, intermediate_value) list
- reduce (out_key, intermediate_value list) -> out_value list

Map:

* 从数据源中读取一条条记录来用做为Map函数的key和value对,如filename, line, etc..
* map()产生了一个或多个中间的value值,这些值是由input的输出key来提供的。

[c-sharp] view plain copy print ?
  1. map (in_key , in_value) -> (out_key, intermediate_value) list
  2. Example: Upper-case Mapper: 
  3. let map(key ,v ) = emit(k.toUpper(), v.toUpper()) 
  4. ("foo","bar")     ->     ("FOO","BAR"
  5. ("Foo","other")     ->    ("FOO","OTHER"
  6. ("key2","data")    ->    ("KEY2","DATA"
map (in_key , in_value) -> (out_key, intermediate_value) list Example: Upper-case Mapper: let map(key ,v ) = emit(k.toUpper(), v.toUpper()) ("foo","bar") -> ("FOO","BAR") ("Foo","other") -> ("FOO","OTHER") ("key2","data") -> ("KEY2","DATA")
Explode Mapper:

[c-sharp] view plain copy print ?
  1. let map(k, v) = foreachchar c in v: emit(k,v) 
  2. ("A","cats") -> ("A","c"), ("A","a"),("A","t"),("A","s"
  3. ("B","hi")    ->    ("B","h"), ("B","i"
let map(k, v) = foreach char c in v: emit(k,v) ("A","cats") -> ("A","c"), ("A","a"),("A","t"),("A","s") ("B","hi") -> ("B","h"), ("B","i")

Filter Mapper:
[c-sharp] view plain copy print ?
  1. let map(k, v) = if (isPrime(v)) then emit(k,v) 
  2. ("foo",7)     ->    ("foo",7) 
  3. ("test",10)    ->    (nothin) 
let map(k, v) = if (isPrime(v)) then emit(k,v) ("foo",7) -> ("foo",7) ("test",10) -> (nothin)
Changing Keyspaces:
[c-sharp] view plain copy print ?
  1. let map(k, v) = emit(v.length(), v) 
  2. ("hi","test")    ->    (4,"test"
  3. ("x","quux")    ->    (4,"quux"
  4. ("y","abracadabra")    ->    (10,"abracadabra"
let map(k, v) = emit(v.length(), v) ("hi","test") -> (4,"test") ("x","quux") -> (4,"quux") ("y","abracadabra") -> (10,"abracadabra")

reduce:

* 当map过程结束后,所有的中间值都会通过唯一的输出key聚合在一起,来作为reduce的输出值
* reudce()方法把这些有相同输出key的中间值组合成一个或多个最终的值(final values)
* 在实际中,一般一个Key只有一个value

[c-sharp] view plain copy print ?
  1. reduce (out_key, intermediate_value list) -> out_value list 
  2. Example: Sum Reducer 
  3. let reduce(k, vals) = 
  4.     sum = 0 
  5.     foreach int vin vals: 
  6.         sum += v 
  7.     emit(k, sum) 
  8.     
  9. ("A",[42,100,312])     ->    ("A",454) 
  10. ("B",[12,6,-2])        ->    ("B",16) 
  11. Identity Reducer: 
  12. let reduce(k, vals) = 
  13.     foreach v in vals: 
  14.         emit(k, v) 
  15.         
  16. ("A", [ 42, 100, 312])    ->    ("A",42),("A",100),("A",312) 
  17. ("B",[12,6,-2])    ->    ("B",12),("B",6),("B",-2) 
reduce (out_key, intermediate_value list) -> out_value list Example: Sum Reducer let reduce(k, vals) = sum = 0 foreach int v in vals: sum += v emit(k, sum) ("A",[42,100,312]) -> ("A",454) ("B",[12,6,-2]) -> ("B",16) Identity Reducer: let reduce(k, vals) = foreach v in vals: emit(k, v) ("A", [ 42, 100, 312]) -> ("A",42),("A",100),("A",312) ("B",[12,6,-2]) -> ("B",12),("B",6),("B",-2)

Parallelism

* map() 函数是可以并行运行的,它从不同的输入数据集中创建了不同的中间值
* reduce() 函数也是并行运行的,各个执行者都有不同的输出key
* 所有的值都是相互独立(independently)处理的,也就是说并行处理的节点之间没有数据上的关联
* Bottleneck: reduce方法要等map方法完全处理完了才能够开始运行

[c-sharp] view plain copy print ?
  1. Example: Count word occurrences 
  2. map(String input_key, String input_value): 
  3.     // input_key: document name 
  4.     // input_value: document contents 
  5.     for each word w in input_value: 
  6.         emit(w,1); 
  7.         
  8. reduce(String output_key, Iterator<int> intermediate_values): 
  9.     // output_key: a word 
  10.     // output_values: a list of counts 
  11.     int result = 0; 
  12.     for each v in intermediate_values: 
  13.         result += v; 
  14.     emit(output_key, result); 
Example: Count word occurrences map(String input_key, String input_value): // input_key: document name // input_value: document contents for each word w in input_value: emit(w,1); reduce(String output_key, Iterator<int> intermediate_values): // output_key: a word // output_values: a list of counts int result = 0; for each v in intermediate_values: result += v; emit(output_key, result);

Combing Phase:

* 在Mapper节点上运行
* "Mini-reduce",只针对map的本地输出
* 在把数据发到reducer之前减少带宽的占用量
* reducer可以被组合,如果它是交互的或有关联的,如SumReducer。(不明白??)

[c-sharp] view plain copy print ?
  1. WordCountRedux: 
  2. map(String input_key, String input_value): 
  3.   // input_key: document name 
  4.   // input_value: document contents 
  5.   for each word w in input_value: 
  6.     emit(w, 1); 
  7. reduce(String output_key, Iterator<int
  8.   intermediate_values): 
  9.   // output_key: a word 
  10.   // output_values: a list of counts 
  11.   int result = 0; 
  12.   for each v in intermediate_values: 
  13.     result += v; 
  14.   emit(output_key, result); 
WordCountRedux: map(String input_key, String input_value): // input_key: document name // input_value: document contents for each word w in input_value: emit(w, 1); reduce(String output_key, Iterator<int> intermediate_values): // output_key: a word // output_values: a list of counts int result = 0; for each v in intermediate_values: result += v; emit(output_key, result);

MapReduce Conclusions

* Maprduce在某些场合被证明是非常有用的抽象
* 很大程度上简化了大规模计算的复杂度
* 函数式编程的范例被证明可以用来处理大规模应用
* 你可以专心的解决实际问题,其它的事让library来帮你做吧

-=========================

HDFS

HDFS: Motivation

* 基于Google的GFS
* 大量的冗余数据分布式廉价的和不可靠的计算机上
* 为什么不使用现有的计算机文件系统呢?
    - 不同的数据负载量和设计的优先级
    - 不同与其它文件系统的大数据量处理能力

Assumptions

* 组件节点的高失效率
    - 廉价的商用组件随时随地都可以失效
* "适当" 数量的大(HUGE)文件
    - 数量只有几百万
    - 每一个只有100MB或更大;一般都是几GB的文件
* 文件大者是写一次,append很多次
    - 大概这些都是并行发生的
* 大量的数据流读操作
* 大量持久的吞吐量

HDFS Design Decisions

* 文件是以块的方式进行存储
    - 块的大小都比一般的文件系统大,一般为64MB
* 通用复制数据块来得到高可用性
    - 一般每一个数据块被复制成三份放在不同的数据节点上(DataNodes)
* 单个主节点(NameNode)管理对元数据的读写操作
    - 简单的集中式管理
* 没有数据caching
    - 有一点点得利于大规模数据集和流读取
* 熟悉的和可扩展的API
    - 简化问题;集成分布式应用

HDFS Architecture

Picture::


Metadata

* 单个NameNode管理所有的元数据
    - 文件名,每个文件在DataNodes上的地址
* 这些都存储在RAM中以提高访问速度
* 每一个DataNode以"block"为对象在本地文件系统对文件内容进行存储和管理

HDFS Conclusions

* HDFS支持在商用硬件平台上对大规模数据进行处理
    - 设计用于支持使用的频繁失效
    - 对于大文件的append和read进行了优化
    - 文件系统接口为不同的工作而定制,但是又对开发者而言保持相对熟悉
    - 简单的解决方案也可以工作,如单个master
* 在单个clusters上可靠的存储数TB的数据

你可能感兴趣的:(MapReduce 和 HDFS介绍)