1. 程式人生 > >大資料開發過程中遇到的問題

大資料開發過程中遇到的問題

1.由於記憶體不夠引起
在linux下執行top命令檢視各程序使用記憶體情況
如果發現沒有程序耗費太大的記憶體
檢視空閒記憶體:free -m
這裡寫圖片描述
發現空閒記憶體所剩無幾:
buffers與cached佔用了將近一半的記憶體
什麼是buffer/cache?
buffer和cache是兩個在計算機技術中被用濫的名詞,放在不通語境下會有不同的意義。在Linux的記憶體管理中,這裡的buffer指Linux記憶體的:Buffer cache。這裡的cache指Linux記憶體中的:Page cache。翻譯成中文可以叫做緩衝區快取和頁面快取。在歷史上,它們一個(buffer)被用來當成對io裝置寫的快取,而另一個(cache)被用來當作對io裝置的讀快取,這裡的io裝置,主要指的是塊裝置檔案和檔案系統上的普通檔案。但是現在,它們的意義已經不一樣了。在當前的核心中,page cache顧名思義就是針對記憶體頁的快取,說白了就是,如果有記憶體是以page進行分配管理的,都可以使用page cache作為其快取來管理使用。當然,不是所有的記憶體都是以頁(page)進行管理的,也有很多是針對塊(block)進行管理的,這部分記憶體使用如果要用到cache功能,則都集中到buffer cache中來使用。(從這個角度出發,是不是buffer cache改名叫做block cache更好?)然而,也不是所有塊(block)都有固定長度,系統上塊的長度主要是根據所使用的塊裝置決定的,而頁長度在X86上無論是32位還是64位都是4k。

明白了這兩套快取系統的區別,就可以理解它們究竟都可以用來做什麼了。

什麼是page cache?
Page cache主要用來作為檔案系統上的檔案資料的快取來用,尤其是針對當程序對檔案有read/write操作的時候。如果你仔細想想的話,作為可以對映檔案到記憶體的系統呼叫:mmap是不是很自然的也應該用到page cache?在當前的系統實現裡,page cache也被作為其它檔案型別的快取裝置來用,所以事實上page cache也負責了大部分的塊裝置檔案的快取工作。

什麼是buffer cache

Buffer cache則主要是設計用來在系統對塊裝置進行讀寫的時候,對塊進行資料快取的系統來使用。這意味著某些對塊的操作會使用buffer cache進行快取,比如我們在格式化檔案系統的時候。一般情況下兩個快取系統是一起配合使用的,比如當我們對一個檔案進行寫操作的時候,page cache的內容會被改變,而buffer cache則可以用來將page標記為不同的緩衝區,並記錄是哪一個緩衝區被修改了。這樣,核心在後續執行髒資料的回寫(writeback)時,就不用將整個page寫回,而只需要寫回修改的部分即可。

如何回收cache?
Linux核心會在記憶體將要耗盡的時候,觸發記憶體回收的工作,以便釋放出記憶體給急需記憶體的程序使用。一般情況下,這個操作中主要的記憶體釋放都來自於對buffer/cache的釋放。尤其是被使用更多的cache空間。既然它主要用來做快取,只是在記憶體夠用的時候加快程序對檔案的讀寫速度,那麼在記憶體壓力較大的情況下,當然有必要清空釋放cache,作為free空間分給相關程序使用。所以一般情況下,我們認為buffer/cache空間可以被釋放,這個理解是正確的。

但是這種清快取的工作也並不是沒有成本。理解cache是幹什麼的就可以明白清快取必須保證cache中的資料跟對應檔案中的資料一致,才能對cache進行釋放。所以伴隨著cache清除的行為的,一般都是系統IO飆高。因為核心要對比cache中的資料和對應硬碟檔案上的資料是否一致,如果不一致需要寫回,之後才能回收。
cat /proc/sys/vm/drop_caches
1
方法是:

echo 1 > /proc/sys/vm/drop_caches
當然,這個檔案可以設定的值分別為1、2、3。它們所表示的含義為:

echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。
echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的物件(包括目錄項快取和inode快取)。slab分配器是核心中管理記憶體的一種機制,其中很多快取資料實現都是用的pagecache。
echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的快取物件。
我們這裡執行:echo 3,執行之後發現buffer跟cache所佔記憶體明顯小了

2.批量刪除hadoop中的任務
for i in hadoop job -list | grep -w root| awk '{print $1}' | grep job_; do hadoop job -kill $i; done
for i in yarn application -list | grep -w root| awk '{print $1}' | grep application_; do yarn application -kill $i; done

3.map,reudce鎖死問題:
(我們用的CDH平臺,解決方式是把mapreduce.job.reduce.slowstart.completedmaps中的引數由0.8改為1)參考部落格:https://www.cnblogs.com/yueweimian/p/4667888.html

"4 .java.io.IOException: Filesystem closed"
多執行緒併發呼叫org.apache.hadoop.fs.FileSystem.close()
解決方式:
禁用hdfs緩衝
conf.setBoolean(“fs.hdfs.impl.disable.cache”, true);
"5.hbase預分割槽後只有一個map"
解決方式:
預設map數量是由region數量決定的,但是好像沒有起作用,用TableMapReduceUtil.initTableMapperJob中的scan,有多少個scan就有多少個map
List scans = getScans(conf);
TableMapReduceUtil.initTableMapperJob(scans, PerformanceCounterDJob.PerformanceMapper.class,
ImmutableBytesWritable.class, LongWritable.class, job);