Issue Details (XML | Word | Printable)

Key: HADOOP-1563
Type: New Feature New Feature
Status: Closed Closed
Resolution: Duplicate
Priority: Major Major
Assignee: Chris Douglas
Reporter: Owen O'Malley
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Hadoop Common

Create FileSystem implementation to read HDFS data via http

Created: 03/Jul/07 11:00 PM   Updated: 17/Aug/07 05:43 PM
Return to search
Component/s: fs
Affects Version/s: 0.14.0
Fix Version/s: None

Time Tracking:
Not Specified

File Attachments:
  Size
Text File Licensed for inclusion in ASF works httpfs.patch 2007-07-06 06:54 PM Doug Cutting 20 kB
Text File Licensed for inclusion in ASF works httpfs2.patch 2007-07-09 09:55 PM Doug Cutting 20 kB
Issue Links:
Dependants
 

Resolution Date: 16/Aug/07 11:34 PM


 Description  « Hide
There should be a FileSystem implementation that can read from a Namenode's http interface. This would have a couple of useful abilities:
1. Copy using distcp between different versions of HDFS.
2. Use map/reduce inputs from a different version of HDFS.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Doug Cutting added a comment - 06/Jul/07 06:54 PM
Attaching a FileSystem for HTTP-browsable directories.

This assumes that:

  • the URL space is hierarchical and slash-delimited;
  • URLs of directories always end in a slash;
  • GET of non-slash-terminated directory URL redirects to the slash-terminated URL;
  • the content of a directory URL contains the URLs of its children;
  • child URLs can be extracted from parent content with a regular expression.

This seems to work for directory listings produced by Apache, Tomcat, Jetty, and Subversion. If we make HDFS browsable over HTTP in the above manner, then this will work for HDFS too.

I've also added default definitions for a bunch of abstract FileSystem methods, and removed definitions in implementations that matched these default definitions, simplifying most FileSystem implementations.


Owen O'Malley added a comment - 06/Jul/07 08:57 PM
Please factor out the directory content parsing into a separate method so that it can be replaced in subclasses.

Doug Cutting added a comment - 06/Jul/07 09:20 PM
> factor out the directory content parsing into a separate method so that it can be replaced in subclasses.

Sure, that'd be easy, if we need to subclass. Do we really? Are there required features that cannot be supported by delivering HTML? Will those features be guaranteed not to change from version-to-version, potentially compromising bi-directional compatibility?


Doug Cutting added a comment - 06/Jul/07 10:38 PM
I think we should implement a servlet that:
1. Considers everything after the HttpServletRequest#getContextPath() as a path.
2. If it names an HDFS file, set attributes as HTTP headers and, if the request is HEAD return an empty page, if GET, return the content, otherwise return an error.
3. If it's a HEAD or GET of a non-slash-terminated directory, redirect to the slash-terminated directory.
4. If it's a HEAD or GET of a slash-terminated directory name, set attributes and, if GET, return HTML containing links to that directory's files;
5. Otherwise return an error.

Then we should try to use this as a source for MapReduce and distcp and see how it fares. The HTTP client may need to be replaced, file status may need to be cached, etc. But this simple approach will get us up and going, and avoid investing too much time designing a schema, parsing XML, etc. when that may not be required.

Thoughts?


Doug Cutting added a comment - 07/Jul/07 09:02 PM
A couple of thoughts:

1. If, for performance, we find we must cache FileStatus in most FileSystem#listPaths implementations, then that means the FileSystem API is inappropriate. In this case, we should replace FileSystem#listPaths() and #getFileStatus() with a single new method:

public abstract Map<Path,FileStatus> listStatus(Path path) throws IOException;

2. If, in HttpFileSystem, we find that (e.g., in order to efficiently support #listStatus) an HTML-based implementation is insufficient for HDFS, then we should not implement other directory formats by subclassing. Rather HttpFileSystem should use plugins for various formats. That fits the existing FileSystem extension mechanism better, which dispatches on protocol only.

The plugin interface might look like:

public interface HttpFileServer {
/** Set connection properties prior to connect, typically authentication headers. */
void prepareConnection(HttpURLConnection connection);
/** Parse directory content. */
Map<Path,FileStatus> parseDirectoryContent(byte[] content);
}

HttpFileSystem would pick an HttpFileServer implementation based hostname, content type or something. Content-type would be elegant, but probably insufficient, since, e.g., S3 returns a content-type of application/xml. Hostname would require reconfiguration for each site. Perhaps we can use the "Server" header. That would work for S3, and we could set it for HDFS.


Tom White added a comment - 08/Jul/07 08:47 PM

Then we should try to use this as a source for MapReduce and distcp and see how it fares. The HTTP client may need to be replaced, file status may need to be cached, etc. But this simple approach will get us up and going, and avoid investing too much time designing a schema, parsing XML, etc. when that may not be required.

+1

A couple of points regarding the patch:

In HttpFileSystem#initialize the name variable is set to itself, so it's always null.

By removing getDefaultBlockSize() in S3FileSystem the property "fs.s3.block.size" is removed (but it's still in hadoop-default.xml). This looks like a change that was made earlier in the checksumming work, so is probably fine in the context of this patch.

Finally, some unit tests would be good. Otherwise, it looks good.


Doug Cutting added a comment - 09/Jul/07 07:48 PM
Should HTML scraping prove inadequate, WebDav might be useful for this. Its PROPFIND method permits directory enumeration.

http://www.webdav.org/specs/rfc2518.html#METHOD_PROPFIND


Doug Cutting added a comment - 09/Jul/07 09:55 PM
This fixes the 'name = name' issue Tom pointed out, and permits file lengths longer than 2^31. I agree that this needs unit tests before it can be committed. I'd also like to first implement a servlet for HDFS to test that performance is acceptable.

I don't see an easy way to handle S3 with this, exposing it as a hierarchical space of slash-delimited directories, except perhaps to write a servlet that proxies directory listings and redirects for file content.


Tom White added a comment - 10/Jul/07 08:35 AM

I don't see an easy way to handle S3 with this, exposing it as a hierarchical space of slash-delimited directories, except perhaps to write a servlet that proxies directory listings and redirects for file content.

The proxy idea sounds good - the servlet pseudo code would be something like:

 
if path is not slash-terminated
  if HEAD S3 path is successful
    redirect to S3 resource at path
  else
    redirect to path/
else
  GET S3 bucket with prefix = path, delimiter = /
  if bucket is empty
    return 404
  else
    return bucket contents as XHTML

(Of course, the work to do this would go in a new Jira issue.)


Doug Cutting added a comment - 11/Jul/07 06:47 PM
I talked with Owen about this, and what he wants is more like a 'tar' format for the FileSystem API, something that preserves standard properties, without being specific to the FileSystem implementation. The URI for this should be something like hftp://host:port/a/b/c, since, while HTTP will be used as the transport, this will not be a FileSystem for arbitrary HTTP urls. Finally, we agreed that the FileSystem API should be altered, so that listStatus() is the primary method, replacing both listPaths() and getStatus(). Whether or not my HttpFileSystem (included above) is in fact ever used, that patch also has some cleanups to the FileSystem API that should be committed.

Doug Cutting added a comment - 16/Jul/07 10:25 PM
I moved the FileSystem API cleanups from the patch here to HADOOP-1620, updating them to the current trunk.

Chris Douglas added a comment - 16/Aug/07 11:34 PM