You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-dev@hadoop.apache.org by "George Porter (JIRA)" <ji...@apache.org> on 2008/12/07 20:35:44 UTC

[jira] Created: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

DFS read performance suboptimal when client co-located on nodes with data
-------------------------------------------------------------------------

                 Key: HADOOP-4801
                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
             Project: Hadoop Core
          Issue Type: Improvement
          Components: dfs
    Affects Versions: 0.19.0
            Reporter: George Porter


One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.

After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.

Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.

I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Raghu Angadi (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656699#action_12656699 ] 

Raghu Angadi commented on HADOOP-4801:
--------------------------------------

Security is of course important and there could be some more ways other than just reading over a TCP socket (shared memory and mem mapped file, for e.g). In the worst case this could be configuration option where only less security sensitive clusters might use.

Since Security in Hadoop is in very early stages, I don't think work in this jira should be too attached to it, yet. There should be an option to disable this feature in a cluster, of course.


> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Allen Wittenauer (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12654539#action_12654539 ] 

Allen Wittenauer commented on HADOOP-4801:
------------------------------------------

I think there are some security issues here.  Let me explain:

In order for the task to read the block directly, they'll need to have read permission at the fs level for that block.  This means that the HDFS will need to write the block either with global read, the same group as all users, or a compatible group as all users.  So, we now have at the Unix level drives full of blocks that are world readable.

A task gets run on those machines.  How do you prevent the task from reading from a block it shouldn't be able to read from?  The 'real' HDFS permissions are at the API level.  Since the API can now be bypassed...

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Bryan Duxbury (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656254#action_12656254 ] 

Bryan Duxbury commented on HADOOP-4801:
---------------------------------------

This sounds super promising. I'll try to take a look at the patch this weekend.

As far as security concerns above, I think that the answer is that you make the blocks themselves world readable, but you make the metadata about which blocks belong to which files something that the namenode keeps behind authorization. So, true, you could scan all the blocks and read data you're not supposed to be able to, but depending on the amount of data and number of nodes in this system, this is probably both impractical and unlikely to give you very much useful unauthorized data.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "George Porter (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

George Porter updated HADOOP-4801:
----------------------------------

    Attachment: HADOOP-4801.3.patch

Version 3 of this patch fixes a NPE exception.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch, HADOOP-4801.2.patch, HADOOP-4801.3.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Allen Wittenauer (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656753#action_12656753 ] 

Allen Wittenauer commented on HADOOP-4801:
------------------------------------------

Right. You'd basically end up building a separate key for pretty much every file, if not every block....

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Doug Cutting (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656751#action_12656751 ] 

Doug Cutting commented on HADOOP-4801:
--------------------------------------

> That doesn't help you with file permissions.

Wouldn't it if the namenode only gives the decryption key to folks with read permission?  You might need to encrypt & timestamp the block's key when it's passed to the client, so that only a datanode can use it...

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "George Porter (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

George Porter updated HADOOP-4801:
----------------------------------

    Attachment: HADOOP-4801.1.patch

This patch contains a proof-of-concept implementation of "HDFS Direct-I/O", which is a mechanism for HDFS clients to directly access datablocks residing on the local host.  It does this by bypassing the standard HDFS datablock streaming protocol to the local DataNode, and instead locates and opens the raw datablocks directly.

The changes are mostly contained to DFSClient.java.  BlockReader is now an interface, and there are two implementing classes: RemoteBlockReader and DirectBlockReader.  RemoteBlockReader is the baseline, working exactly as before.  DirectBlockReader instances are created in blockSeekTo(long).  A check is made to see if the requested offset resides in a local block on the same machine as the DFSClient.  If so, then the DirectBlockReader opens that file and passes through any I/O operations directly to the Java filesystem layer.

I performed two main sets of performance testing: a streaming test and a random read test.  Both tests were performed on a single machine running the Hadoop trunk code in the pseudodistributed mode (with 1 datanode, 1 namenode, and dfs.replication set to 1 and the default block size).

In the streaming test, I opened a 1GB file and read it from start to finish into memory.
  Baseline: 8.730 seconds with std. dev of 0.052
  DirectIO: 5.266 seconds with std. dev of 0.116

In the random test, I opened a 1GB or 4GB file, then performed a set of random reads, by picking a random offset in the file, seeking to that offset, and reading 1KB of data.

For the 1 GB file
  Baseline with 1024 reads: 861 reads/second
  DirectIO with 1024 reads: 5988 reads/second

  Baseline with 4096 reads: 1065 reads/second
  DirectIO with 4096 reads: 9287 reads/second

For the 4 GB file
  Baseline with 65,535 reads: 535 reads/second
  DirectIO with 65,535 reads: 17,852 reads/second

It's hard to tell how much these results are affected by various disk caches, etc., and so I wanted to put this patch out there to get your experiences with it.  Obviously local block read performance will only improve application performance to the extent that you read from locally resident disk blocks.

Your feedback appreciated!  Thanks.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Allen Wittenauer (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656704#action_12656704 ] 

Allen Wittenauer commented on HADOOP-4801:
------------------------------------------

Do these reads still show up in the audit logs?

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Raghu Angadi (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656694#action_12656694 ] 

Raghu Angadi commented on HADOOP-4801:
--------------------------------------


It is good start for a proof-of-concept. Currently it does not take care of CRCs.. I think it should to be in par with normal read. In a real implementation, Client would talk to DataNode about the block location (preferably over locahost interface).

Regd random reads, I don't think reading directly alone explains the results. There is something odd. What can explain performance increase as the size of the file increases (if anything, it should only reduce).



> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Allen Wittenauer (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656704#action_12656704 ] 

aw edited comment on HADOOP-4801 at 12/15/08 11:24 AM:
---------------------------------------------------------------------

Do these reads still show up in the audit logs?

Also:

> In terms of security, wouldn't the ideal approach be to encrypt each 
> datablock with its own key? 

That doesn't help you with file permissions.

      was (Author: aw):
    Do these reads still show up in the audit logs?
  
> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Issue Comment Edited: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "he yongqiang (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12654682#action_12654682 ] 

he yongqiang edited comment on HADOOP-4801 at 12/8/08 7:31 PM:
---------------------------------------------------------------

We also see the same problem. Hope this could be fixed.
for read, maybe we could just tell the DFSClient where the data lies and let DFSClient fetch the data itself, instead of sending the data directly to DFSClient.

      was (Author: he yongqiang):
    We also see the same problem. Hope this could be fixed.
for read, maybe we could just tell the DFSClient where the data lies and let DFSClient fetch the data itself, insteading of sending the data directly to DFSClient.
  
> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Doug Cutting (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656747#action_12656747 ] 

Doug Cutting commented on HADOOP-4801:
--------------------------------------

> In terms of security, wouldn't the ideal approach be to encrypt each datablock with its own key?

That's an interesting idea.  We'd want to encrypt it in the client, checksumming the encrypted data, so that the datanode would never see the cleartext.  Then only metadata communication need be encrypted by the communications layer, since the data would already be encrypted, providing a performance boost over an encrypted pipe.


> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "George Porter (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656701#action_12656701 ] 

George Porter commented on HADOOP-4801:
---------------------------------------

Thanks for the comments.  I'm working on a macro benchmark with a much larger dataset now.  I think that some of the performance gains as the number of reads increases is due to reads hitting an already warm cache (that would explain why more reads == higher performance, even on larger sized files).  I definitely agree that adding additional datapaths is not desirable.  However, if local reads dominate and are the common case, then we may want to look into optimizing that common case.  Like I said, I'm not really attached to this approach (its mostly a hack) but wanted to at least get a sense of what gains might be possible as a point of reference, especially if we up the number of disks per core to the double digits (e.g., 16 disks per core).

In terms of security, wouldn't the ideal approach be to encrypt each datablock with its own key?  The namenode would keep that key as part of the HDFS metadata, and when an appropriately authorized client issues a getBlockLocations(), those keys are sent back to the client?  Then the DataNodes don't have to worry about security at all (that is enforced in the namenode, a logically centralized place).

What's nice about that too is that if the DataNodes were to be compromised, hacked, or just decommissioned, you wouldn't have to worry about leftover data floating around out there.  This would especially be true in virtual datacenter or datacenter on demand environments where machines are spun up due to peak loads, then released when no longer needed.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Raghu Angadi (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12654604#action_12654604 ] 

Raghu Angadi commented on HADOOP-4801:
--------------------------------------


This is something HDFS should eventually do. I would keep the focus of this jira mainly to making DFSClient access the block data directly. 

Other things like reading larger than 64KB chunks from OS are orthogonal issues and I suspect extra user to kernel context switches would make extremely small impact on CPU (if any, at least on Linux/Intel).

Since Hadoop security is based on mostly trusted components acting responsibly, we could make DFSClient to be polite and get  permission from DataNode before accessing data directly. Such a protocol would be necessary any way since DataNode might want to know how many active readers are present for a block for non-security reasons.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "George Porter (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

George Porter updated HADOOP-4801:
----------------------------------

    Attachment: HADOOP-4801.2.patch

This updated patch (HADOOP-4801.2.patch) includes the BlockReader interface.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch, HADOOP-4801.2.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Jonathan Gray (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12657260#action_12657260 ] 

Jonathan Gray commented on HADOOP-4801:
---------------------------------------

I'm having similar issue as stack.  Turns out that blocks are actually located within subdir# directories inside of 'current' directory and patch is looking just in the root 'current' directory not within subdirs.

What are these exactly?  Is there a way to turn them off so all blocks are located in root directory?

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch, HADOOP-4801.2.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "stack (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656875#action_12656875 ] 

stack commented on HADOOP-4801:
-------------------------------

Tried installing patch to see what for an improvement I'd see at application-level.  Had to infer BlockRead interface since not in the patch but I've messed up something in that no block is local in my 3 node hdfs cluster with replication of 3 nor in a one node cluster with replication 1.  Lets try and figure it George over in #hbase.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Doug Cutting (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656689#action_12656689 ] 

Doug Cutting commented on HADOOP-4801:
--------------------------------------

> make the blocks themselves world readable, but you make the metadata about which blocks belong to which files something that the namenode keeps behind authorization

That's insufficient.  It may work in some cases, but it cannot be considered secure.

The micro benchmark is impressive, but it would be good to also find a macro benchmark that benefits significantly from this.  For mapreduce jobs whose output size is proportional to input size, the cost of output would still dominate, no?


> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "Owen O'Malley (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656687#action_12656687 ] 

Owen O'Malley commented on HADOOP-4801:
---------------------------------------

I think this patch is going the wrong way. Giving up the security and sanity of a single data path is a *really* high cost. I think it is much more important to get the pread performance up than add a second, security-destroying datapath.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>         Attachments: HADOOP-4801.1.patch
>
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (HADOOP-4801) DFS read performance suboptimal when client co-located on nodes with data

Posted by "he yongqiang (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/HADOOP-4801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12654682#action_12654682 ] 

he yongqiang commented on HADOOP-4801:
--------------------------------------

We also see the same problem. Hope this could be fixed.
for read, maybe we could just tell the DFSClient where the data lies and let DFSClient fetch the data itself, insteading of sending the data directly to DFSClient.

> DFS read performance suboptimal when client co-located on nodes with data
> -------------------------------------------------------------------------
>
>                 Key: HADOOP-4801
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4801
>             Project: Hadoop Core
>          Issue Type: Improvement
>          Components: dfs
>    Affects Versions: 0.19.0
>            Reporter: George Porter
>
> One of the major strategies Hadoop uses to get scalable data processing is to move the code to the data.  However, putting the DFS client on the same physical node as the data blocks it acts on doesn't improve read performance as much as expected.
> After looking at Hadoop and O/S traces (via HADOOP-4049), I think the problem is due to the HDFS streaming protocol causing many more read I/O operations (iops) than necessary.  Consider the case of a DFSClient fetching a 64 MB disk block from the DataNode process (running in a separate JVM) running on the same machine.  The DataNode will satisfy the single disk block request by sending data back to the HDFS client in 64-KB chunks.  In BlockSender.java, this is done in the sendChunk() method, relying on Java's transferTo() method.  Depending on the host O/S and JVM implementation, transferTo() is implemented as either a sendfilev() syscall or a pair of mmap() and write().  In either case, each chunk is read from the disk by issuing a separate I/O operation for each chunk.  The result is that the single request for a 64-MB block ends up hitting the disk as over a thousand smaller requests for 64-KB each.
> Since the DFSClient runs in a different JVM and process than the DataNode, shuttling data from the disk to the DFSClient also results in context switches each time network packets get sent (in this case, the 64-kb chunk turns into a large number of 1500 byte packet send operations).  Thus we see a large number of context switches for each block send operation.
> I'd like to get some feedback on the best way to address this, but I think providing a mechanism for a DFSClient to directly open data blocks that happen to be on the same machine.  It could do this by examining the set of LocatedBlocks returned by the NameNode, marking those that should be resident on the local host.  Since the DataNode and DFSClient (probably) share the same hadoop configuration, the DFSClient should be able to find the files holding the block data, and it could directly open them and send data back to the client.  This would avoid the context switches imposed by the network layer, and would allow for much larger read buffers than 64KB, which should reduce the number of iops imposed by each read block operation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.