簡(jiǎn)介
大數(shù)據(jù)是一個(gè)概念也是一門技術(shù)
其技術(shù)指在以hadoop為代表的平臺(tái)框架上進(jìn)行數(shù)據(jù)分析的技術(shù)。包括實(shí)時(shí)數(shù)據(jù)處理、離線數(shù)據(jù)處理、數(shù)據(jù)分析、數(shù)據(jù)挖掘和用機(jī)器學(xué)習(xí)方法進(jìn)行預(yù)測(cè)分析等技術(shù)
hadoop是一個(gè)開(kāi)源大數(shù)據(jù)框架,是一個(gè)分布式計(jì)算的解決方案。
hadoop早期兩大核心,HDFS和MapReduce
HDFS(分布式文件系統(tǒng)):存儲(chǔ)是大數(shù)據(jù)技術(shù)的基礎(chǔ)。
MapReduce(編程模型):分布式計(jì)算是大數(shù)據(jù)應(yīng)用的解決方案。
HDFS
三個(gè)主要概念:
- 數(shù)據(jù)塊:
數(shù)據(jù)塊是HDFS上的抽象數(shù)據(jù)概念,在HDFS上我們將文件切分成為一個(gè)個(gè)數(shù)據(jù)塊進(jìn)行存儲(chǔ)。在hadoop中默認(rèn)的塊大小:1.x中為64M,2.x中為128M。

NameNode:
管理文件系統(tǒng)的命名空間,存放數(shù)據(jù)元數(shù)據(jù)(描述數(shù)據(jù)的數(shù)據(jù))。維護(hù)著文件系統(tǒng)的所有文件和目錄,文件與數(shù)據(jù)塊的映射等。記錄每個(gè)文件各個(gè)數(shù)據(jù)塊的所在數(shù)據(jù)結(jié)點(diǎn)的信息。DataNode:
存儲(chǔ)并檢索數(shù)據(jù)塊,想NameNode更新所存儲(chǔ)塊的列表。
優(yōu)點(diǎn)
適合大文件的存儲(chǔ)和訪問(wèn),有副本策略來(lái)保證高可靠性。
構(gòu)建在大規(guī)模廉價(jià)的機(jī)器上,有高擴(kuò)展性。
支持流式存儲(chǔ),以此寫入多次讀取。
缺點(diǎn)
不適合多個(gè)小文件的存儲(chǔ)。
不適合并發(fā)寫入,不支持隨機(jī)修改。
不支持隨機(jī)讀等低延時(shí)的訪問(wèn)方式。
HDFS寫流程:
客戶端向NameNode發(fā)出寫數(shù)據(jù)請(qǐng)求,NameNode反饋可用的DataNode節(jié)點(diǎn)。

客戶端將數(shù)據(jù)分塊,然后根據(jù)反饋內(nèi)容找到可用的數(shù)據(jù)結(jié)點(diǎn),將分塊后的數(shù)據(jù)依次存入DataNode中,DataNode會(huì)自動(dòng)完成備份工作。
DataNode向NameNode匯報(bào)備份完成。NameNode告知客戶端寫完成。

HDFS讀流程:
客戶端向NameNode發(fā)出請(qǐng)求,NameNode通過(guò)查看自己維護(hù)的信息告知客戶端數(shù)據(jù)塊所在DataNode地址。
客戶端根據(jù)DataNode的遠(yuǎn)近程度選擇DataNode來(lái)分塊取回所需要的數(shù)據(jù)。

HDFS常見(jiàn)Shell指令
類Linux系統(tǒng)的:
ls、cat、mkdir、rm、chmod、chown
HDFS文件交互:
copyFromLocal
copyToLocal
get
put
在實(shí)際演示以上指令前,確定已有一個(gè)hadoop平臺(tái)并啟動(dòng)了相關(guān)的服務(wù):

hadoop/bin中有幾個(gè)主要的可執(zhí)行文件:

我們使用指令:hdfs dfs -ls / 查看hdfs目錄下有哪些文件。
隨后使用指令:hdfs dfs -mkdir /edwinTest 創(chuàng)建一個(gè)目錄。

使用指令:hdfs dfs -copyFromLocal /文件路徑 /edwinTest/
將一個(gè)本地的文件上傳到了hdfs文件系統(tǒng)中

可以使用
指令:hdfs dfs -cat /edwinTest/fanren.txt 將文件輸出
指令:hdfs dfs -copyToLocal /edwinTest/fanren.txt /home/edwin/ 將文件拷貝到本地
指令:hdfs dfs -chmod 777 /edwinTest/fanren.txt 修改文件權(quán)限

可以使用指令:hdfs dfs -help 隨時(shí)查看幫助

python操作HDFS
from hdfs3 import HDFileSystem
test_host = '192.168.1.200'
test_port = 9000#default port
def hdfs_exists(client):
path = '/tmp/test'
if client.exists(path):
client.rm(path)
client.makedirs(path)#級(jí)聯(lián)創(chuàng)建
def hdfs_write_read(client):
data = b"hello hadoop" * 10
file_a = '/tmp/test/file_a'
# wb:二進(jìn)制寫入
# relication = 1 :備份數(shù)量
with client.open(file_a,'wb',replication = 1) as f:
f.write(data)
with client.open(file_a,'rb') as f:
out = f.read(len(data))
assert out == data
def hdfs_readLine(client):
data = b"hello\nhadoop"
file_b = '/tmp/test/file_b'
with client.open(file_b,'wb',replication = 1) as f:
f.write(data)
with client.open(file_b,'rb') as f:
lines = f.readlines()
assert len(lines) == 2
if __name__ == '__main__':
hdfs_client = HDFileSystem(host=test_host,port=test_port)
hdfs_exists(hdfs_client)
hdfs_write_read(hdfs_client)
hdfs_readLine(hdfs_client)
print("--------------running succeed----------------")
運(yùn)行結(jié)果:

值得一提的是:
from hdfs3 import HDFileSystem
要安裝hdfs3這個(gè)包需要去官網(wǎng)查看installment文檔,推薦使用anaconda的conda指令進(jìn)行安裝,因?yàn)槠湟蕾嚨陌容^難裝。
同時(shí)端口號(hào)在配置文件core-site.xml文件中有,

這里給出一些端口的信息
hadoop集群常用端口默認(rèn)端口號(hào)
MapReduce
簡(jiǎn)介
MapReduce是一種編程模型也是一種編程方法和抽象理論
在2.X中,MapReduce由YARN進(jìn)行支持。
YARN
負(fù)責(zé)整個(gè)集群的資源管理,有三個(gè)主要的概念:
ResourceManager
分配資源
啟動(dòng)和監(jiān)控ApplicationMaster
監(jiān)控NodeManagerApplicationMaster
為MapReduce類型的程序分配資源并分配集群內(nèi)部的資源
負(fù)責(zé)數(shù)據(jù)切分
監(jiān)控任務(wù)保證容錯(cuò)NodeManager
管理單個(gè)結(jié)點(diǎn)的資源
處理ResourceManager和ApplicationMaster的命令
編程模型
輸入一個(gè)大文件,通過(guò)Split分為多個(gè)片。
每個(gè)文件交由單個(gè)機(jī)器去處理,這就是Map。
將每個(gè)機(jī)器的處理結(jié)果進(jìn)行匯總,并得到最終的結(jié)果,這就是Reduce。
形如:
from functools import reduce
li = ['aa', 'bbb', 'cccc']
li_count = map(len,li)
countList = list(li_count)
li_sum = reduce(lambda x,y:x+y,countList)
編程實(shí)現(xiàn)
- map文件:
import sys
def read_input(file):
for line in file:
yield line.split()
def main():
# file = open("1.txt")
data = read_input(sys.stdin)
for words in data:
for word in words:
print("%s%s%d" % (word,'\t',1))
if __name__ == '__main__':
main()
Reduce文件
import sys
from operator import itemgetter
from itertools import groupby
def read_mapper_output(file,seperator = '\t'):
for line in file:
yield line.rstrip().split(seperator,1)
def main():
data = read_mapper_output(sys.stdin)
for current_word, group in groupby(data,itemgetter(0)):
total_count = sum(int(count) for current_word, count in group)
print("%s%s%d" % (current_word,'\t',total_count))
if __name__ == '__main__':
main()
在運(yùn)行之前,回憶一下hdfs的操作:
本次mapReduce的文件上傳到edwinTest目錄下

運(yùn)行指令:
~/hadoop/hadoop-2.9.0/bin/hadoop jar ~/hadoop/hadoop-2.9.0/share/hadoop/tools/lib/hadoop-streaming-2.9.0.jar -D stream.non.zero.exit.is.failure=false -files "map.py,reduce.py" -input /edwinTest/1.txt -output /edwinTest/wordcountResult -mapper "map.py" -reducer "reduce.py"
指令的一些說(shuō)明:
-D stream.non.zero.exit.is.failure=false
streaming默認(rèn)的情況下,mapper和reducer的返回值不是0,被認(rèn)為異常任務(wù),將被再次執(zhí)行,默認(rèn)嘗試4次都不是0,整個(gè)job都將失敗,所以用這條指令來(lái)修正。
-input /edwinTest/1.txt -output /edwinTest/wordcountResult
輸入輸出的位置都必須是hdfs目錄下的路徑。
運(yùn)行結(jié)果:
出現(xiàn)下圖內(nèi)容說(shuō)明任務(wù)成功

在控制臺(tái)中可以看到任務(wù)結(jié)果

進(jìn)入hdfs中查看結(jié)果:
hdfs dfs -cat /edwinTest/wordcountResult/part-00000
生態(tài)圈內(nèi)的一些組件
HBase
高可靠、高性能、面向列、可伸縮、實(shí)時(shí)讀寫的分布式數(shù)據(jù)庫(kù)。
利用HDFS作為其文件系統(tǒng),支持MR程序讀取數(shù)據(jù)。
支持非結(jié)構(gòu)化、半結(jié)構(gòu)化數(shù)據(jù)。
主要名詞:
RowKey:數(shù)據(jù)唯一標(biāo)識(shí),按字典排序
Column Family:列族,多個(gè)列的組合,最多不超過(guò)3個(gè)。
TimeStamp:時(shí)間戳,支持多版本的數(shù)據(jù)同時(shí)存在。
下圖中cf為列族

spark
基于內(nèi)存計(jì)算的大數(shù)據(jù)并行計(jì)算框架。
Spark是MapReduce的替代方案,兼容HDFS,HIVE等數(shù)據(jù)源。
抽象出了分布式內(nèi)存存儲(chǔ)數(shù)據(jù)結(jié)構(gòu):彈性分布式數(shù)據(jù)集RDD。
基于事件驅(qū)動(dòng),通過(guò)線程池的復(fù)用來(lái)提高性能。