干掉几百行大SQL。1、PreludeHadoop是目前大数据领域最主流的技术体系,包括多种技术。包括HDFS(分布式文件系统)、YARN(分布式资源调度系统)、MapReduce(分布式计算系统)等。有的朋友可能听说过Hadoop,但是不太清楚它是什么。本文将用通俗易懂的语言为您讲解。如果你公司的所有数据都存储在MySQL中,那么就把它们都放在一台数据库服务器上。假设这台服务器的磁盘空间是2T。让我们看看下面的图片。现在问题来了,你一直往这个服务器的MySQL里放数据,结果数据量越来越大,超过了2T的大小,怎么办?你说,我可以架设多个MySQL数据库服务器,分库分表!将一部分数据放在每个服务器上是不够的。如图!好的,没问题,那我们建3个数据库服务器,3个MySQL实例,每个服务器能放2T的数据。现在我问大家一个问题,所谓的大数据是干什么的?下面说说大数据最基本的一个使用场景。假设你有一个电商网站,现在你需要存储和分析用户在电商网站页面和应用上的所有点击、购买、浏览的行为日志。现在你把这些数据全部放在三台MySQL服务器上,数据量巨大,但勉强能放下。一天早上,你的老板来了。你要看一个报表,比如每天要看网站的X指标、Y指标、Z指标等等,二十个、三十个数据指标。行了,大哥,你现在试试写个SQL,把点击、购买、浏览的日志里的二十个、三十个指标分析出来?我跟你打赌,你一定会写出几百行甚至几千行的超级复杂的大SQL。你觉得这个SQL在分库分表后能跑在三台MySQL服务器上吗?如果你觉得可以,那你一定不明白分库分表后MySQL有多坑,大SQL跨库join几百行,各种复杂的计算根本不现实。所以大数据的存储和计算根本不是MySQL来完成的。因此,Hadoop、Spark等大数据技术体系应运而生。本质上,Hadoop、Spark等大数据技术实际上是一系列的分布式系统。例如Hadoop中的HDFS是大数据技术体系的核心基石,负责数据的分布式存储。这是什么意思?别担心,继续阅读。HDFS的全称是HadoopDistributedFileSystem,即Hadoop的分布式文件系统。它由很多机器组成,每台机器运行一个DataNode进程,负责管理部分数据。然后在一台机器上运行着一个NameNode进程。NameNode大致可以看做是这样一个负责管理整个HDFS集群的进程,它存储了HDFS集群的所有元数据。然后就是很多台机器,每台机器存储一部分数据!那么,HDFS现在可以很好地存储和管理大量数据。这时候你肯定会有疑问:MySQL服务器不就是这样的吗?如果你这么想,那你就大错特错了。这件事没有你想的那么简单。HDFS天生就是一种分布式技术,所以你可以上传大量的数据,存储数据,管理数据,自然可以使用HDFS来做。如果硬要基于MySQL进行分库分表,会痛苦很多倍,因为MySQL并不是设计成分布式系统架构的,在分布式数据存储上缺少很多数据保护机制。好吧,你现在用HDFS分布式存储数据,那你不想分布式计算这些数据吗?对于分布式计算:很多公司使用Hive来写几百行的大SQL(底层是基于MapReduce的)。也有很多公司慢慢用Spark来写几百行的大SQL(底层是SparkCore引擎)。简而言之,就是写一个大的SQL,会分成很多计算任务,放到每台机器上。每个计算任务负责计算一小部分数据。这就是所谓的分布式计算。这绝对比分库分表的MySQL跑几百行大SQL靠谱。至于上面提到的分布式存储和分布式计算,老规矩也给大家一张图,大家跟着图仔细回顾一下整个过程。2、HDFS的NameNode架构原理完成。前奏说完,我们就进入正题。其实本文主要讨论的是HDFS集群中NameNode的核心架构原理。NameNode有一个非常核心的功能:管理整个HDFS集群的元数据,比如文件目录树、权限设置、副本数设置等等。下面就用最典型的文件目录树维护来举个例子。让我们看看下面的图片。现在有一个客户端系统要上传一个1TB的大文件到HDFS集群。这个时候他会先跟NameNode通信,说:大哥,我要新建一个文件,他的名字是“/usr/hive/warehouse/access_20180101.log”,大小是1TB,你觉得会不会工作?然后NameNode会在自己内存的文件目录树中的指定目录下新建一个文件对象,名称为“access_20180101.log”。这个文件目录树不就是HDFS很核心的一个元数据,维护HDFS的分布式文件系统,有哪些目录和文件吧?但是有个问题,这个文件目录树是在NameNode的内存中的!这就是作弊,你把重要的元数据都放在内存里,万一NameNode不小心挂了怎么办?不是所有的元数据都丢失了吗?但是如果每次都频繁修改磁盘文件中的元数据,那性能肯定是极低的!毕竟这是大量的随机磁盘读写!没关系,我们来看看HDFS的优雅解决方案。内存中每次修改完成后,写入一个editslog,将元数据修改的操作日志写入磁盘文件。不修改磁盘文件的内容,而是顺序追加磁盘文件的内容。这个性能要高得多。每次NameNode重启,把editslog中的操作日志读到内存中回放,metadata能恢复吗?跟着上面的文字,跟着下面的图片看整个过程。但是问题又来了,如果editslog越来越大,每次重启岂不是很慢?因为需要读取大量编辑日志回放来还原元数据!于是HDFS说,我可以这样,我引入一个新的磁盘文件叫fsimage,然后引入一个JournalNodes集群和一个StandbyNameNode(备用节点)。ActiveNameNode(主节点)每次修改元数据,都会产生一个editslog,除了写入本地磁盘文件外,还会写入JournalNodes集群。然后StandbyNameNode可以从JournalNodes集群中拉取editslog,应用到自己内存中的文件目录树中,与ActiveNameNode保持一致。然后每隔一段时间,StandbyNameNode将自己内存中的文件目录树的副本写入磁盘上的fsimage。这不是日志,而是一套完整的元数据。这个操作就是所谓的checkpoint检查点操作。然后将这个fsimage上传到ActiveNameNode,然后清除ActiveNameNode旧的editslog文件。这里可能有100万行的修改日志!然后ActiveNameNode继续接收修改元数据的请求,然后写入编辑日志。写了一会儿,这里的修改日志可能只有几十行!如果此时,ActiveNameNode重启了,宾果!没关系,只要将StandbyNameNode传过来的fsimage直接读入内存即可,这个fsimage直接就是metadata,不需要额外的操作,纯读取非常高效!然后把新的editslog中的少量几十行的修改日志重放到内存中就ok了!这个过程开始得更快!因为不需要重放大量百万行的编辑日志来恢复元数据!如下所示。另外,看一下上图,现在我们有两个NameNode。一种是主节点对外提供接收请求的服务,另一种是纯粹接收并同步主节点和执行定期检查点的备节点的编辑日志。你发现了吗!两人记忆中的元数据,几乎一模一样!那么,如果ActiveNameNode挂掉了,是否可以立即切换到StandbyNameNode对外提供服务呢?这不就是所谓的NameNode主备高可用故障切换机制吗!接下来,我们再想一想,HDFS客户端在NameNode内存中的文件目录树中新增了一个文件。但是这时候,人们又想把数据上传到多台DataNode机器上。这是一个1TB的大文件!如何传承?很简单,把一个1TB的大文件拆分成N块,每块128MB。1TB=1024GB=1048576MB,一个block是128MB,那么对应8192个block。这些块将分布在不同的机器上进行管理。比如一个集群总共有100台机器,那么每台机器放80个左右的block就可以了。但是问题又来了,如果这时候一台机器宕机,那80个块不就丢了吗?也就是说,上传一个1TB的大文件,会丢失一小部分数据。没关系!已经考虑过HDFS!它会默认为每个块制作3份副本,副本完全相同,并且分布在不同的机器上。如果一台机器出现故障,则在其他机器上还有同一个块的另外两个副本!看看下面的图片。每个block在不同的机器上有3份,任何机器下来都可以!您也可以从其他机器获取该块。现在,如果你上传一个1TB的大文件到HDFS,你就可以高枕无忧了!OK,以上就是大白话加上一系列的手绘图,先说说大家能看懂的Hadoop基本架构原理,然后再说说世界上最好的分布式存储HDFS。系统承载了一些高并发请求和高性能文件上传的核心机制和原理。
