| 1 | ◢ <[wiki:III140118/Lab8 實作八]> | <[wiki:III140118 回課程大綱]> ▲ | <[wiki:III140118/Lab10 實作十]> ◣ |
| 2 | |
| 3 | = 實作九 Lab9 = |
| 4 | |
| 5 | {{{ |
| 6 | #!html |
| 7 | <p style="text-align: center;"><big style="font-weight: bold;"><big>Hadoop FileSystem API 原始碼觀察<br>Learn from Apache Hadoop FsShell.java Source Code</big></big></p> |
| 8 | }}} |
| 9 | |
| 10 | [[PageOutline]] |
| 11 | |
| 12 | {{{ |
| 13 | #!text |
| 14 | 請先連線至 nodeN.3du.me , N 為您的報名編號 |
| 15 | }}} |
| 16 | |
| 17 | == 替 Hadoop 上補丁的方法 == |
| 18 | |
| 19 | * 在前面的範例中,我們使用 Bash 除錯技巧,得知當我們執行 hadoop fs 時,等同呼叫 !FsShell 類別 |
| 20 | * 那 !FsShell 類別在 Apache Hadoop 中,放在哪裡呢? 我們可以透過 find 指令查出來。 |
| 21 | {{{ |
| 22 | lab@node1:~$ find ~/hadoop/src -name "FsShell.java" |
| 23 | /home/user/hadoop/src/core/org/apache/hadoop/fs/FsShell.java |
| 24 | }}} |
| 25 | * 現在,我們知道 !FsShell.java 原始碼的位置,我們想要對它做小幅的修正。 |
| 26 | * 下一個範例我們使用了一個 update jar 檔的技巧,直接修改 hadoop-core-$VERSION.jar 壓縮檔中某幾個類別(CLASS)的內容,來達成我們觀察 Hadoop 行為模式的目的 |
| 27 | * 執行的方式很簡單,請剪貼以下指令: |
| 28 | {{{ |
| 29 | lab@node1:~$ cd ~/hadoop_labs |
| 30 | lab@node1:~/hadoop_labs$ lab003/FsShell |
| 31 | }}} |
| 32 | |
| 33 | * 但是背後的意義是什麼呢?首先,讓我們用 diff 觀察一下原始碼做了什麼修改 |
| 34 | {{{ |
| 35 | lab@node1:~$ cd ~/hadoop_labs/lab003/ |
| 36 | lab@node1:~/hadoop_labs/lab003$ diff -Naur ~/hadoop/src/core/org/apache/hadoop/fs/FsShell.java src/FsShell.java |
| 37 | }}} |
| 38 | {{{ |
| 39 | #!diff |
| 40 | --- /home/user/hadoop/src/core/org/apache/hadoop/fs/FsShell.java 2012-10-03 13:17:16.000000000 +0800 |
| 41 | +++ src/FsShell.java 2013-10-19 11:25:16.419320587 +0800 |
| 42 | @@ -571,6 +571,9 @@ |
| 43 | Path srcPath = new Path(srcf); |
| 44 | FileSystem srcFs = srcPath.getFileSystem(this.getConf()); |
| 45 | FileStatus[] srcs = srcFs.globStatus(srcPath); |
| 46 | + // Add by Jazz |
| 47 | + System.out.println("srcFs = " + srcFs.getClass().toString()); |
| 48 | + System.out.println("Uri = " + srcFs.getUri().toString()); |
| 49 | if (srcs==null || srcs.length==0) { |
| 50 | throw new FileNotFoundException("Cannot access " + srcf + |
| 51 | ": No such file or directory."); |
| 52 | @@ -1786,8 +1789,12 @@ |
| 53 | exitCode = FsShellPermissions.changePermissions(fs, cmd, argv, i, this); |
| 54 | } else if ("-ls".equals(cmd)) { |
| 55 | if (i < argv.length) { |
| 56 | + // Add by Jazz |
| 57 | + System.out.println("doall("+cmd+","+argv+","+i+")"); |
| 58 | exitCode = doall(cmd, argv, i); |
| 59 | } else { |
| 60 | + // Add by Jazz |
| 61 | + System.out.println("ls("+Path.CUR_DIR+",false), Path.CUR_DIR = " + Path.CUR_DIR); |
| 62 | exitCode = ls(Path.CUR_DIR, false); |
| 63 | } |
| 64 | } else if ("-lsr".equals(cmd)) { |
| 65 | }}} |
| 66 | * 至於 ant 的 build.xml 中,有一個比較特殊的語法,在第 42 行使用了 update="true" 這個選項,其意義就是呼叫 jar 的 update (-u) 功能 |
| 67 | {{{ |
| 68 | #!java |
| 69 | 41 <target name="jar" depends="compile,doc" description="Package the classes into a .jar file"> |
| 70 | 42 <jar update="true" destfile="${jarname}" basedir="${bindir}" /> |
| 71 | 43 </target> |
| 72 | }}} |
| 73 | {{{ |
| 74 | lab@node1:~/hadoop_labs/lab003$ jar |
| 75 | 用法:jar {ctxui}[vfm0Me] [jar 檔案] [清單檔案] [進入點] [-C 目錄] 檔案 ... |
| 76 | 選項: |
| 77 | -c 建立新的歸檔 |
| 78 | -t 列出歸檔的目錄 |
| 79 | -x 從歸檔中擷取已命名的 (或所有) 檔案 |
| 80 | -u 更新現有歸檔 |
| 81 | -v 在標準輸出中產生詳細輸出 |
| 82 | -f 指定歸檔檔案名稱 |
| 83 | -m 包含指定清單檔案中的清單資訊 |
| 84 | -e 為獨立應用程式指定應用程式進入點 |
| 85 | 已隨附於可執行 jar 檔案中 |
| 86 | -0 僅儲存;不使用 ZIP 壓縮方式 |
| 87 | -M 不為項目建立清單檔案 |
| 88 | -i 為指定的 jar 檔案產生索引資訊 |
| 89 | -C 變更至指定目錄並包含後面所列的檔案 |
| 90 | }}} |
| 91 | |
| 92 | * lab003/FsShell 所做的動作: |
| 93 | 1. 安裝 ant |
| 94 | 2. 編譯 src/FsShell.java 並使用 jar -u 將產生的 .class 更新到 hadoop-core-$VERSION.jar |
| 95 | 3. 顯示 hadoop-core-$VERSION.jar 與原始備份 hadoop-core-$VERSION.jar.org 的差異(請觀察日期) |
| 96 | 4. 採用 HADOOP_CONF_DIR 環境變數切換成單機模式,請留意畫面中出現的 srcFS 內容 |
| 97 | 5. 切換回全分散式模式,請留意畫面中出現的 srcFS 內容 |
| 98 | |
| 99 | == 實作習題 == |
| 100 | |
| 101 | <問題 1> 執行 lab003/FsShell,在單機模式時,srcFs 物件是哪一個 Java 類別 |
| 102 | {{{ |
| 103 | #!text |
| 104 | (A) org.apache.hadoop.fs.LocalFileSystem |
| 105 | (B) org.apache.hadoop.hdfs.DistributedFileSystem |
| 106 | (C) org.apache.hadoop.fs.shell.Count |
| 107 | (D) org.apache.hadoop.fs.shell.CommandFormat |
| 108 | }}} |
| 109 | |
| 110 | <問題 2> 執行 lab003/FsShell,在全分散模式時,srcFs 物件是哪一個 Java 類別 |
| 111 | {{{ |
| 112 | #!text |
| 113 | (A) org.apache.hadoop.fs.LocalFileSystem |
| 114 | (B) org.apache.hadoop.hdfs.DistributedFileSystem |
| 115 | (C) org.apache.hadoop.fs.shell.Count |
| 116 | (D) org.apache.hadoop.fs.shell.CommandFormat |
| 117 | }}} |
| 118 | |
| 119 | <問題 3> 從實作中,我們可以觀察到切換不同的設定時,!FileSystem 父物件參照(Reference)指向子類別實作,會視 Configuration 而有所不同。請參考提示,並根據 ${HOME}/hadoop/src/core/org/apache/hadoop/fs 目錄的內容,試猜測 Hadoop 1.0.4 支援哪幾種檔案系統: (複選) |
| 120 | |
| 121 | <提示> http://answers.oreilly.com/topic/456-get-to-know-hadoop-filesystems/ |
| 122 | {{{ |
| 123 | #!text |
| 124 | (A) HDFS (hdfs://namenode:port) |
| 125 | (B) Amazon S3 (s3:// , s3n://) |
| 126 | (C) KFS |
| 127 | (D) Local File System (file:///) |
| 128 | (F) FTP (ftp://user:passwd@ftp-server:port) |
| 129 | (G) RAMFS (ramfs://) |
| 130 | (H) HAR (Hadoop Archive Filesystem, har://underlyingfsscheme-host:port/archivepath or har:///archivepath ) |
| 131 | }}} |