HDFS小文件治理總結(jié),你學(xué)會(huì)了嗎?
隨著大數(shù)據(jù)時(shí)代的到來,數(shù)據(jù)量不斷增長(zhǎng),HDFS也成為了數(shù)據(jù)存儲(chǔ)和處理的重要組成部分。然而,由于HDFS的設(shè)計(jì)原理和文件存儲(chǔ)方式,HDFS系統(tǒng)中存在大量的小文件,這些小文件會(huì)導(dǎo)致HDFS的性能下降,增加管理和維護(hù)的難度,嚴(yán)重影響數(shù)據(jù)處理效率和數(shù)據(jù)質(zhì)量。因此,HDFS小文件的治理變得越來越重要。
一、HDFS小文件的問題影響
HDFS小文件通常指文件大小小于HDFS塊(Block)大?。J(rèn)為128MB)的文件。在HDFS系統(tǒng)中,小文件會(huì)帶來以下問題:
1.占用過多的存儲(chǔ)空間:由于HDFS文件系統(tǒng)的特點(diǎn),每個(gè)文件都會(huì)占用一個(gè)獨(dú)立的Block,因此大量的小文件會(huì)導(dǎo)致內(nèi)存空間的浪費(fèi),增加HDFS系統(tǒng)的內(nèi)存開銷;
2.影響數(shù)據(jù)處理效率:HDFS是為大量的數(shù)據(jù)處理而設(shè)計(jì)的,而小文件會(huì)導(dǎo)致數(shù)據(jù)處理效率下降,增加數(shù)據(jù)處理時(shí)間和開銷;
3.增加管理和維護(hù)難度:當(dāng)HDFS系統(tǒng)中存在大量的小文件時(shí),管理和維護(hù)變得更加困難,需要耗費(fèi)更多的精力和時(shí)間來維護(hù)系統(tǒng)。
二、HDFS小文件的治理方法
針對(duì)HDFS小文件的問題,有以下幾種治理方法:
1.合并小文件:將多個(gè)小文件合并為一個(gè)大文件,減少文件數(shù)量。這種方法需要注意文件的內(nèi)容和格式,以免合并后的文件無法使用或者存在數(shù)據(jù)丟失等問題;
2.壓縮文件:將多個(gè)小文件壓縮為一個(gè)壓縮包,減少存儲(chǔ)空間。這種方法可以使用Hadoop自帶的壓縮工具,如gzip、bzip2等;
3.刪除無用文件:刪除不再需要的小文件,釋放存儲(chǔ)空間;
4.設(shè)置文件過期時(shí)間:對(duì)于不再需要的文件,可以設(shè)置其過期時(shí)間,自動(dòng)刪除過期文件;
5.使用SequenceFile:使用Hadoop自帶的SequenceFile格式存儲(chǔ)小文件,將多個(gè)小文件合并到一個(gè)SequenceFile中,以減少文件數(shù)量,提高處理效率。
3、HDFS小文件治理的實(shí)踐案例
以下是一些HDFS小文件治理的實(shí)踐案例:
1.合并小文件:對(duì)于日志文件等大量的小文件,可以使用Hadoop自帶的合并工具將多個(gè)小文件合并為一個(gè)大文件。下面是通過hive的重寫方式合并小文件,核心參數(shù)如下;
set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set hive.merge.mapfiles = true;
set hive.merge.mapredfiles = true;
set hive.merge.smallfiles.avgsize=256000000;
set hive.merge.size.per.task=12800000;
set mapred.max.split.size=256000000;
set mapred.min.split.size=64000000;
set mapred.min.split.size.per.node=64000000;
set mapred.min.split.size.per.rack=64000000;
2.壓縮文件:對(duì)于大量的小文件,可以使用壓縮工具將多個(gè)小文件壓縮為一個(gè)壓縮包,以減少存儲(chǔ)空間。例如,使用gzip或bzip2壓縮工具壓縮文件,在HDFS上存儲(chǔ)壓縮文件,以減少存儲(chǔ)空間和文件數(shù)量;
3.刪除無用文件:對(duì)于不再需要的小文件,可以使用Hadoop自帶的命令hadoop fs -rm命令刪除文件,或者使用定時(shí)任務(wù)腳本定期刪除過期文件;
4.設(shè)置文件過期時(shí)間:使用hadoop fs -touchz命令設(shè)置文件的過期時(shí)間,當(dāng)文件過期后,自動(dòng)刪除文件。例如,使用hadoop fs -touchz命令設(shè)置文件的過期時(shí)間為30天,當(dāng)文件超過30天未被訪問時(shí),自動(dòng)刪除文件;
5.使用SequenceFile:對(duì)于大量的小文件,可以使用SequenceFile格式存儲(chǔ)文件,將多個(gè)小文件合并成一個(gè)SequenceFile文件。例如,使用Hadoop自帶的SequenceFile.Writer類將多個(gè)小文件寫入SequenceFile文件中,以減少存儲(chǔ)空間和文件數(shù)量。
4、HDFS小文件監(jiān)控
HDFS的fsimage是HDFS文件系統(tǒng)的一個(gè)重要組成部分,記錄了HDFS文件系統(tǒng)的元數(shù)據(jù)信息,包括文件、目錄、權(quán)限、塊等信息。通過監(jiān)控HDFS的fsimage,可以了解HDFS文件系統(tǒng)的整體情況,包括文件數(shù)量、文件大小、文件類型等信息,進(jìn)而實(shí)現(xiàn)對(duì)HDFS小文件的監(jiān)控和治理。
具體來說,可以通過以下步驟對(duì)HDFS小文件進(jìn)行監(jiān)控:
1.獲取HDFS的fsimage:使用Hadoop自帶的命令hdfs oiv -p XML -i fsimage命令獲取HDFS的fsimage文件。該命令會(huì)將HDFS的fsimage文件以XML格式輸出,包括HDFS中所有文件和目錄的元數(shù)據(jù)信息;
2.解析fsimage文件:使用Python等腳本語言解析獲取到的fsimage文件,提取其中的文件、目錄、塊等信息??梢允褂肞ython的ElementTree模塊等工具對(duì)XML文件進(jìn)行解析,提取需要的信息;
3.統(tǒng)計(jì)文件數(shù)量和文件大?。焊鶕?jù)解析后的文件信息,統(tǒng)計(jì)HDFS中小文件的數(shù)量和大小。通??梢愿鶕?jù)文件大小和文件數(shù)量的閾值來定義小文件,例如文件大小小于128MB或文件數(shù)量小于1000個(gè)等;
4.可視化展示:使用可視化工具,如Grafana、Kibana等將統(tǒng)計(jì)結(jié)果進(jìn)行可視化展示,以便于對(duì)HDFS小文件的監(jiān)控和管理。
5、HDFS小文件監(jiān)控案例
下面是解析HDFS的fsimage文件,導(dǎo)入hive表進(jìn)行分析得到最終結(jié)果表導(dǎo)入clickhouse通過grafana進(jìn)行數(shù)據(jù)展示;
解析fsimage文件為txt文件:
hdfs oiv -i fsimage_0000000192578352133 -o /data2/data/fsimage/$day/fsimage.txt -p Delimited -t /data2/data/fsimage/$day/tmp
fsimage文件重要的字段釋義:
INODE_ID:文件或目錄的唯一標(biāo)識(shí)符;
NAME:文件或目錄的名稱;
PARENT_ID:父目錄的INODE_ID;
MODIFICATION_TIME:最后修改時(shí)間;
ACCESS_TIME:最后訪問時(shí)間;
BLOCK_IDS:文件的數(shù)據(jù)塊ID列表;
BLOCK_SIZE:數(shù)據(jù)塊大小;
NUM_BLOCKS:數(shù)據(jù)塊數(shù)量;
PERMISSIONS:文件或目錄的權(quán)限信息;
USER_NAME:文件或目錄所屬用戶;
GROUP_NAME:文件或目錄所屬用戶組;
SYMLINK:如果是符號(hào)鏈接,則包含符號(hào)鏈接的目標(biāo)路徑;
UNDER_CONSTRUCTION:如果文件正在寫入中,則為true;
UNDER_RECOVERY:如果文件正在恢復(fù)中,則為true;
FILE_LENGTH:文件長(zhǎng)度;
NS_QUOTA:命名空間配額;
DS_QUOTA:磁盤配額;
STORAGE_POLICY:存儲(chǔ)策略。
下面是基于解析后的文件映射到hive表最終處理后的數(shù)據(jù)表和最終數(shù)據(jù)樣例:
CREATE TABLE `tmp_fsimage_info_log_clean`(
`path` string,
`replication` int,
`db` string,
`table_name` string,
`parttition_nm1` string,
`parttition_nm2` string,
`parttition_nm3` string,
`file_name` string,
`modificationtime` string,
`accesstime` string,
`preferredblocksize_mb` decimal(20,5),
`blockscount` int,
`filesize_mb` decimal(20,5),
`filesize_gb` decimal(20,5),
`username` string,
`groupname` string)
PARTITIONED BY (
`stat_day` string COMMENT '分區(qū)時(shí)間:yyyy-mm-dd')
ROW FORMAT SERDE
'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
STORED AS INPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
同步hive數(shù)據(jù)到CK的工具使用的是seatunnel,下面貼一份相關(guān)的配置文件:
env {
spark.app.name = "hive_to_clickhouse"
spark.executor.instances = 10
spark.executor.cores = 4
spark.executor.memory = "12g"
}
source {
file {
path = "hdfs://ds01:8020/user/hive/warehouse/paas_test.db/db_table_file_all/stat_day="${day}""
result_table_name = "db_table_file_all"
format = "orc"
}
}
transform {
sql {
sql = "SELECT '"${dayStr}"' as stat_day, _col0 as db, _col1 as table_name,_col2 as sum_filesize,_col3 as count_filesize,_col4 as count_filesize_less_10,_col5 as count_filesize_less_50,_col6 as count_filesize_less_150,_col7 as count_filesize_less_250,_col8 as count_filesize_less_300,_col9 as count_filesize_less_10_diff,_col10 as count_filesize_less_50_diff,_col11 as count_filesize_less_150_diff,_col12 as count_filesize_less_250_diff,_col13 as count_filesize_less_300_diff,_col14 as table_storage_increase,_col15 as count_filesize_diff,_col16 as latest_accesstime from db_table_file_all"
}
}
sink {
clickhouse {
host = "ds03:8123"
clickhouse.socket_timeout = 50000
database = "fsimage_info"
table = "db_table_file_all"
fields = ["db","table_name","sum_filesize","count_filesize","count_filesize_less_10","count_filesize_less_50","count_filesize_less_150","count_filesize_less_250","count_filesize_less_300","count_filesize_less_10_diff","count_filesize_less_50_diff","count_filesize_less_150_diff","count_filesize_less_250_diff","count_filesize_less_300_diff","table_storage_increase","count_filesize_diff","latest_accesstime","stat_day"]
username = ""
password = ""
}
}
最終展示在grafana中效果:
本文轉(zhuǎn)載自微信公眾號(hào)「滌生大數(shù)據(jù)」,作者「滌生-強(qiáng)哥」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系「滌生大數(shù)據(jù)」公眾號(hào)。