在HDFS上面最不明确的事情之一就是数据的冗余。它完全是自动进行的,因为无法得知其中详细的信息,我们需要做的就是相信它。HBase完全相信 HDFS存储数据的安全性和完整性,并将数据文件交给 HDFS存储。正是因为 HDFS的数据冗余方式对于 HBase来说是完全透明的,产生了一个问题:HBase的效率会受到多大的影响?说的简单一点,当 HBase需要存取数据时,如何保证有一份冗余的数据块离自己最近? 当我们对 HBase做一次 MapReduce的扫描操作时,这个问题尤其显现出来。所有的RegionServer都在从 HDFS上面读取数据,理想的状况当然是每个RegionServer要读取的数据都离自己很近。这个问题就牵扯到HBase的数据文件是如何在HDFS上面存储的。 让我们首先抛开 HBase,假设要处理的数据就是HDFS上面的数据块,看看Hadoop是如何工作的。MapReduce总是有一个建议,那就是在每个 TaskTracker上面Map/Reduce程序要处理的数据在本地就有一份冗余。这样程序只需要与本地数据交互,减少了网络流量并提高了效率。为了做到这一点, HDFS会把大文件分割成很多小文件来存储,我们称之为数据块(Block)。每个数据块的大小比操作系统数据块的大小要大得多,默认是64M,但通常我们选择 128M,或者某个更大的值(这取决与你的文件大小,最好你的单个文件大小总是大于一个数据块)。在MapReduce中,每个数据块会被分配给一个 Task,这个 Task就负责处理这个数据块中的数据。所以数据块越大,产生的Task就越少,需要 mapper的数量就越少。Hadoop自己知道每个数据块存储的位置,这样在任务分配的时候就可以直接在存储数据块的机器上启动 Task,或者选择一个最近机器启动Task。真是因为每个数据块有多份冗余,使得 Hadoop有更大的选择空间。只要找到一份冗余符合条件就行了,不是吗?这样 Hadoop就可以保证在MapReduce期间 Task总是操作本地数据。 让我们回到 HBase,现在你已经理解了 Hadoop是如何保证在MapReduce的过程中每个 Task都尽量处理本地数据。如果你看过 HBase的存储架构你就会知道HBase只是简单的将 HFile和 WAL log存储在HDFS上面。通过简单的调用 HDFS的API来创建文件:FileSystem.create(Path path)。接下来你会关心两件事情的效率:1)随机的访问 2)通过MapReduce扫描全表。我们当然希望当每个RegionServer读取数据时存储数据的数据块就在本地。它能做到吗? 第一种情况,你有两个集群,一个集群装 Hadoop,另一个集群装 HBas...