问题描述:在同一台机器上,复制了多台虚拟机,启动后有机器不能ping通网关,也不能ping通其他机器。
原因:复制虚拟机后,启动虚拟机,选择了 I move it。虚拟机网卡的MAC地址没有改变,导致冲突。
解决办法:打开虚拟机设置,选择网络适配器,在高级选项中找到MAC地址项,点击“生成”按钮,重新生成新的MAC地址。
码农 + 测试
问题描述:在同一台机器上,复制了多台虚拟机,启动后有机器不能ping通网关,也不能ping通其他机器。
原因:复制虚拟机后,启动虚拟机,选择了 I move it。虚拟机网卡的MAC地址没有改变,导致冲突。
解决办法:打开虚拟机设置,选择网络适配器,在高级选项中找到MAC地址项,点击“生成”按钮,重新生成新的MAC地址。
sudo功能的配置文件一般在这里:/etc/sudoers,可以使用visudo编辑,好处是如果规则写的不符合要求能提示你,坏处是调出的是nano编辑器。而且/etc/sudoers的配置文件的注释里也说明了,不建议直接修改/etc/sudoers,而是通过在/etc/sudoers.d/文件夹中新增文件来完成配置。
Please consider adding local content in /etc/sudoers.d/ instead of directly modifying this file.
新增的文件就用vi编辑就可以了,比如说要为mantou增加sudo权限,就增加一个文件,文件名无所谓,内容是:
mantou ALL=(ALL) ALL
保存,退出vi
然后需要把这个文件权限设置为400:chmod 400 mantou
再用mantou用户登录后就可以使用sudo权限了。
wildml - Artificial Intelligence, Deep Learning, and NLP
(1)适合初学者的Tensorflow教程和代码示例 该教程不光提供了一些经典的数据集,更是从实现最简单的“Hello World”开始,到机器学习的经典算法,再到神经网络的常用模型,一步步带你从入门到精通,是初学者学习Tensorflow的最佳教程。
(2)从Tensorflow基础知识到有趣的项目应用 同样是适合新手的教程,从安装到项目实战,教你搭建一个属于自己的神经网络。
(3)使用Jupyter Notebook用Python语言编写的TensorFlow教程 本教程是基于Jupyter Notebook开发环境的Tensorflow教程,Jupyter Notebook是一款非常好用的交互式开发工具,不仅支持40多种编程语言,还可以实时运行代码、共享文档、数据可视化、支持markdown等,适用于机器学习、统计建模数据处理、特征提取等多个领域。
(4)构建您的第一款TensorFlow Android应用程序本教程可帮助您从零开始将张量流模型引入到Android应用程序。
MEGALODON: ML/DL Resources At One Place
How-To-Ask-Questions-The-Smart-Way
在讨论优化算法时,有一点要说明:我基本已经不用 sigmoid 激活函数了, tanh 函数在
所有场合都优于 sigmoid 函数。
但有一个例外:在二分类的问题中,对于输出层,因为𝑦的值是 0 或 1,所以想让𝑦 ^的数值介于 0 和 1 之间,而不是在-1 和+1 之间。所以需要使用 sigmoid 激活函数。
结果表明,如果在隐藏层上使用函数效果总是优于 sigmoid 函数。因为函数值域在-1 和+1的激活函数,其均值是更接近零均值的。在训练一个算法模型时,如果使用 tanh 函数代替sigmoid 函数中心化数据,使得数据的平均值更接近 0 而不是 0.5.
这会使下一层学习简单一点。
sigmoid 函数和 tanh 函数两者共同的缺点是,在𝑧特别大或者特别小的情况下,导数的
梯度或者函数的斜率会变得特别小,最后就会接近于 0,导致降低梯度下降的速度。
这有一些选择激活函数的经验法则:
如果输出是 0、 1 值(二分类问题),则输出层选择 sigmoid 函数,然后其它的所有单元都选择 Relu 函数。
这是很多激活函数的默认选择,如果在隐藏层上不确定使用哪个激活函数,那么通常会使用 Relu 激活函数。有时,也会使用 tanh 激活函数,但 Relu 的一个优点是:当𝑧是负值的时候,导数等于 0。
总而言之,不能在隐藏层用线性激活函数,可以用 ReLU 或者 tanh 或者 leaky ReLU 或者其他的非线性激活函数,唯一可以用线性激活函数的通常就是输出层;
对于一个神经网络,如果你把权重或者参数都初始化为 0,那么梯度
下降将不会起作用。
这个问题的解决方法就是随机初始化参数。 你应该这么做 : 把 𝑊[1] 设 为 np.random.randn(2,2)(生成高斯分布),通常再乘上一个小的数,比如 0.01,这样把它初始化为很小的随机数。然后𝑏没有这个对称的问题(叫做 symmetry breaking problem),所以可以把 𝑏 初始化为 0。
为什么是 0.01,而不是 100 或者 1000。我们通常
倾向于初始化为很小的随机数。因为如果你用 tanh 或者 sigmoid 激活函数,或者说只在输出层有一个 Sigmoid,如果(数值)波动太大,这种情况
下你很可能停在 tanh/sigmoid 函数的平坦的地方,这些地方梯度很小也就意味着梯度下降会很慢,因此学习也就很慢。
在机器学习中,我们通常将样本分成训练集,验证集和测试集三部分,数据集规模相对较小,适用传统的划分比例,数据集规模较大的,验证集和测试集要小于数据总量的 20%或 10%。
最后一点,就算没有测试集也不要紧,测试集的目的是对最终所选定的神经网络系统做
出无偏估计,如果不需要无偏估计,也可以不设置测试集。所以如果只有验证集,没有测试
集,我们要做的就是,在训练集上训练,尝试不同的模型框架,在验证集上评估这些模型,
然后迭代并选出适用的模型。因为验证集中已经涵盖测试集数据,其不再提供无偏性能评估。
理解偏差和方差的两个关键数据是训练集误差( Train set error)和验证集误差( Dev set error)
假定训练集误差是 1%,为了方便论证,假定验证集误差是 11%,可以看出训练集设置得非常好,而验证集设置相对较差, 我们可能过度拟合了训练集,在某种程度上,验证集并没有充分利用交叉验证集的作用, 像这种情况, 我们称之为“高方差”。
通过查看训练集误差和验证集误差,我们便可以诊断算法是否具有高方差。也就是说衡量训练集和验证集误差就可以得出不同结论。
假设训练集误差是 15%,我们把训练集误差写在首行,验证集误差是 16%,假设该案例中人的错误率几乎为 0%,人们浏览这些图片,分辨出是不是猫。算法并没有在训练集中得到很好训练,如果训练数据的拟合度不高,就是数据欠拟合,就可以说这种算法偏差比较高。
相反,它对于验证集产生的结果却是合理的,验证集中的错误率只比训练集的多了 1%,所以这种算法偏差高,因为它甚至不能拟合训练集,这与上一张幻灯片最左边的图片相似。再举一个例子,训练集误差是 15%,偏差相当高,但是,验证集的评估结果更糟糕,错误率达到 30%,在这种情况下,我会认为这种算法偏差高,因为它在训练集上结果不理想,而且方差也很高,这是方差偏差都很糟糕的情况。再看最后一个例子,训练集误差是 0.5%,验证集误差是 1%,用户看到这样的结果会很开心,猫咪分类器只有 1%的错误率,偏差和方差都很低。
这些分析都是基于假设预测的,假设人眼辨别的错误率接近 0%,一般来说,最优误差也被称为贝叶斯误差,所以,最优误差接近 0%,如果最优误差或贝叶斯误差非常高,比如 15%。我们再看看这个分类器(训练误差 15%,验证误差 16%), 15%的错误率对训练集来说也是非常合理的,偏差不高,方差也非常低。
初始模型训练完成后,我首先要知道算法的偏差高不高,如果偏差较高,试着评估训练集或训练数据的性能。如果偏差的确很高,甚至无法拟合训练集,那么你要做的就是选择一个新的网络,比如含有更多隐藏层或者隐藏单元的网络,或者花费更多时间来训练网络,或者尝试更先进的优化算法.
如果网络足够大,通常可以很好的拟合训练集,只要你能扩大网络规模,如果图片很模糊,算法可能无法拟合该图片,但如果有人可以分辨出图片,如果你觉得基本误差不是很高,那么训练一个更大的网络, 你就应该可以……至少可以很好地拟合训练集, 至少可以拟合或者过拟合训练集。一旦偏差降低到可以接受的数值,检查一下方差有没有问题,为了评估方差,我们要查看验证集性能,我们能从一个性能理想的训练集推断出验证集的性能是否也理想,如果方差高,最好的解决办法就是采用更多数据,如果你能做到,会有一定的帮助,但有时候,我们无法获得更多数据,我们也可以尝试通过正则化来减少过拟合.
有两点需要大家注意:
第一点,高偏差和高方差是两种不同的情况,我们后续要尝试的方法也可能完全不同,我通常会用训练验证集来诊断算法是否存在偏差或方差问题,然后根据结果选择尝试部分方
法。举个例子,如果算法存在高偏差问题,准备更多训练数据其实也没什么用处,至少这不是更有效的方法,所以大家要清楚存在的问题是偏差还是方差,还是两者都有问题,明确这一点有助于我们选择出最有效的方法。
第二点,在机器学习的初期阶段,关于所谓的偏差方差权衡的讨论屡见不鲜,原因是我们能尝试的方法有很多。可以增加偏差,减少方差,也可以减少偏差,增加方差,但是在深度学习的早期阶段,我们没有太多工具可以做到只减少偏差或方差却不影响到另一方。但在当前的深度学习和大数据时代,只要持续训练一个更大的网络,只要准备了更多数据,那么也并非只有这两种情况,我们假定是这样,那么,只要正则适度,通常构建一个更大的网络便可以,在不影响方差的同时减少偏差,而采用更多数据通常可以在不过多影响偏差的同时减少方差。这两步实际要做的工作是:训练网络,选择网络或者准备更多数据,现在我们有工具可以做到在减少偏差或方差的同时,不对另一方产生过多不良影响。我觉得这就是深度
学习对监督式学习大有裨益的一个重要原因,也是我们不用太过关注如何平衡偏差和方差的一个重要原因,但有时我们有很多选择,减少偏差或方差而不增加另一方。最终,我们会得到一个非常规范化的网络。
深度学习可能存在过拟合问题——高方差, 有两个解决方法, 一个是正则化, 另一个是准备更多的数据,这是非常可靠的方法,但你可能无法时时刻刻准备足够多的训练数据或者获取更多数据的成本很高,但正则化通常有助于避免过拟合或减少你的网络误差。
如果用的是𝐿1正则化, 𝑤最终会是稀疏的,也就是说𝑤向量中有很多 0,有人说这样有利于压缩模型,因为集合中参数均为 0,存储模型所占用的内存更少。实际上,虽然𝐿1正则化使模型变得稀疏,却没有降低太多存储内存,所以我认为这并不是𝐿1正则化的目的,至少不是为了压缩模型,人们在训练网络时,越来越倾向于使用𝐿2正则化。
dropout 正则化:Dropout 可以随机删除网络中的神经单元,他为什么可以通过正则化发挥如此大的作用呢?
直观上理解:不要依赖于任何一个特征,因为该单元的输入可能随时被清除,因此该单元通过这种方式传播下去,并为单元的四个输入增加一点权重,通过传播所有权重, dropout将产生收缩权重的平方范数的效果,和之前讲的𝐿2正则化类似;实施 dropout 的结果实它会压缩权重,并完成一些预防过拟合的外层正则化; 𝐿2对不同权重的衰减是不同的,它取决于激活函数倍增的大小。
总结一下, dropout 的功能类似于𝐿2正则化,与𝐿2正则化不同的是应用方式不同会带来一点点小变化,甚至更适用于不同的输入范围。
dropout 一大缺点就是代价函数𝐽不再被明确定义,每次迭代,都会随机移除一些节点,
如果再三检查梯度下降的性能,实际上是很难进行复查的。定义明确的代价函数𝐽每次迭代
后都会下降,因为我们所优化的代价函数 J 实际上并没有明确定义,或者说在某种程度上很
难计算,所以我们失去了调试工具来绘制这样的图片。我通常会关闭 dropout 函数,将 keepprob 的值设为 1,运行代码,确保𝐽函数单调递减。然后打开 dropout 函数,希望在 dropout
过程中,代码并未引入 bug。
其他正则化方法:
- 数据扩增
2.early stopping
我认为机器学习过程包括几个步骤,其中一步是选择一个算法来优化代价函数𝐽,我们有很多种工具来解决这个问题,如梯度下降,后面我会介绍其它算法,例如 Momentum,RMSprop 和 Adam 等等,但是优化代价函数𝐽之后,我也不想发生过拟合,也有一些工具可以解决该问题,比如正则化,扩增数据等等。
在机器学习中,超级参数激增,选出可行的算法也变得越来越复杂。我发现,如果我们用一组工具优化代价函数𝐽,机器学习就会变得更简单,在重点优化代价函数𝐽时,你只需要留意𝑤和𝑏, 𝐽(𝑤, 𝑏)的值越小越好,你只需要想办法减小这个值,其它的不用关注。然后,预防过拟合还有其他任务,换句话说就是减少方差,这一步我们用另外一套工具来实现,这个原理有时被称为“正交化”。思路就是在一个时间做一个任务, 后面课上我会具体介绍正交化,如果你还不了解这个概念,不用担心。
但对我来说 early stopping 的主要缺点就是你不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数𝐽,因为现在你不再尝试降低代价函数𝐽,所以代价函数𝐽的值可能不够小,同时你又希望不出现过拟合,你没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果是我要考虑的东西变得更复杂。
如果不用 early stopping,另一种方法就是𝐿2正则化,训练神经网络的时间就可能很长。我发现,这导致超级参数搜索空间更容易分解,也更容易搜索,但是缺点在于,你必须尝试很多正则化参数𝜆的值,这也导致搜索大量𝜆值的计算代价太高。
Early stopping 的优点是,只运行一次梯度下降,你可以找出𝑤的较小值,中间值和较大值,而无需尝试𝐿2正则化超级参数𝜆的很多值。
训练神经网络,其中一个加速训练的方法就是归一化输入。假设一个训练集有两个特征,输入特征为 2 维,归一化需要两个步骤:
1.零均值
2.归一化方差;
我们希望无论是训练集和测试集都是通过相同的𝜇和𝜎2定义的数据转换
在深度神经网络中,激活函数将以指数级递减,虽然我只是讨论了激活函数以与𝐿相关的指数级数增长或下降,它也适用于与层数𝐿相关的导数或梯度函数,也是呈指数级增长或呈指数递减。
𝑧 = 𝑤1𝑥1 + 𝑤2𝑥2 + ⋯ + 𝑤𝑛𝑥𝑛, 𝑏 = 0,暂时忽略𝑏,为了预防𝑧值过大或过小,你可以看到𝑛越大,你希望𝑤𝑖越小,因为𝑧是𝑤[𝑖]𝑥[𝑖]的和,如果你把很多此类项相加,希望每项值更小,最合理的方法就是设置𝑤[𝑖] = 1/𝑛, 𝑛表示神经元的输入特征数量,实际上,你要做的就是设置
某层权重矩阵𝑤[𝑙] = 𝑛𝑝. 𝑟𝑎𝑛𝑑𝑜𝑚. 𝑟𝑎𝑛𝑑𝑛(shape) ∗ np. sqrt( 1
𝑛[𝑙−1] ), 𝑛[𝑙−1]就是我喂给第𝑙层神经单元的数量(即第𝑙 − 1层神经元数量)。
结果,如果你是用的是 Relu 激活函数,而不是1/𝑛,方差设置为2/𝑛,效果会更好。你常常发现,初始化时,尤其是使用 Relu 激活函数时, 𝑔𝑙 = 𝑅𝑒𝑙𝑢(𝑧),它取决于你对随机变量的熟悉程度,这是高斯随机变量,然后乘以它的平方根,也就是引用这个方差2/n。这里,我用的是𝑛[𝑙−1],因为本例中,逻辑回归的特征是不变的。但一般情况下𝑙层上的每个神经元都有𝑛[𝑙−1]个输入。如果激活函数的输入特征被零均值和标准方差化,方差是 1, 𝑧也会调整到相似范围,这就没解决问题(梯度消失和爆炸问题)。但它确实降低了梯度消失和爆炸问题,因为它给权重矩阵𝑤设置了合理值,你也知道,它不能比 1 大很多,也不能比 1 小很多,所
以梯度没有爆炸或消失过快。
在深度学习研究早期,人们总是担心优化算法会困在极差的局部最优, 不过随着深度学习理论不断发展,我们对局部最优的理解也发生了改变。我们从深度学习历史中学到的一课就是,我们对低维度空间的大部分直觉,比如你可以画出上面的图,并不能应用到高维度空间中。适用于其它算法,因为如果你有 2 万个参数,那么𝐽函数有 2 万个维度向量,你更可能遇到鞍点,而不是局部最优点。
如果局部最优不是问题,那么问题是什么?结果是平稳段会减缓学习,平稳段是一块区域,其中导数长时间接近于 0,如果你在此处,梯度会从曲面从从上向下下降,因为梯度等于或接近 0,曲面很平坦,你得花上很长时间慢慢抵达平稳段的这个点。
所以此次视频的要点是,首先,你不太可能困在极差的局部最优中,条件是你在训练较大的神经网络,存在大量参数, 并且成本函数𝐽被定义在较高的维度空间。
第二点,平稳段是一个问题,这样使得学习十分缓慢,这也是像 Momentum 或是
RMSprop, Adam 这样的算法,能够加速学习算法的地方。在这些情况下,更成熟的优化算法,如 Adam 算法,能够加快速度,让你尽早往下走出平稳段。
0-1损失是指,预测值和目标值不相等为1,否则为0:
感知机就是用的这种损失函数。但是由于相等这个条件太过严格,因此我们可以放宽条件,即满足 |Y−f(X)|<T 时认为相等。
绝对值损失函数为:
L(Y,f(X)=|Y−f(X)|
logistic regression可以将实数域的输入映射为0到1的概率输出
最小二乘法是线性回归的一种方法,它将回归的问题转化为了凸优化的问题。最小二乘法的基本原则是:最优拟合曲线应该使得所有点到回归直线的距离和最小。通常用欧几里得距离进行距离的度量。平方损失的损失函数为:
指数损失是0-1损失函数的一种代理函数。运用指数损失的典型分类器是AdaBoost算法。
指数损失函数的标准形式:
Hinge损失函数和SVM是息息相关的。在线性支持向量机中,最优化问题可以等价于
这个式子和如下的式子非常像:
其中l(wxi+byi)就是hinge损失函数,后面相当于L2正则项。
Hinge函数的标准形式:
y是预测值,在-1到+1之间,t为目标值(-1或+1)。其含义为,y的值在-1和+1之间就可以了,并不鼓励|y|>1,即并不鼓励分类器过度自信,让某个正确分类的样本的距离分割线超过1并不会有任何奖励,从而使分类器可以更专注于整体的分类误差。
PB 为 Protocol Buffer 的缩写
AliasMapProtocolPB 接口 与 AliasMapProtocolServerSideTranslatorPB 类
AliasMapProtocolPB 接口注释:Protocol between the Namenode and the Datanode to read the AliasMap. used for Provided storage.
AliasMapProtocolServerSideTranslatorPB类实现自 AliasMapProtocolPB 接口。
AliasMapProtocolServerSideTranslatorPB类注释:AliasMapProtocolServerSideTranslatorPB is responsible for translating RPC calls and forwarding them to the internal InMemoryAliasMap.
ClientDatanodeProtocolServerSideTranslatorPB 类 ClientDatanodeProtocolPB 接口
ClientDatanodeProtocolServerSideTranslatorPB 类实现自 ClientDatanodeProtocolPB 接口
ClientNamenodeProtocolServerSideTranslatorPB 类 ClientNamenodeProtocolPB 接口 接口与实现类
DatanodeLifelineProtocolServerSideTranslatorPB 类DatanodeLifelineProtocolPB 接口 接口与实现类
DatanodeLifelineProtocolClientsideTranslatorPB 类
DatanodeProtocolPB 接口 DatanodeProtocolServerSideTranslatorPB 类 接口与实现类
InterDataNodeProtocolPB 接口 InterDatanodeProtocolServerSideTranslatorPB 类 接口与实现类
JournalProtocolPB 接口 JournalProtocolServerSideTranslatorPB 类 接口与实现类
NamenodeProtocolPB 接口 NamenodeProtocolServerSideTranslatorPB 类 接口与实现类
BlackListBasedTrustedChannelResolver
BlackListBasedTrustedChannelResolver 类继承自 TrustedChannelResolver 类
类注释:Class used to indicate whether a channel is trusted or not. The default implementation is to return false indicating that the channel is not trusted.
The class can be overridden to provide custom logic to determine whether a channel is trusted or not. The custom class can be specified via configuration.
Receiver
Receiver 实现 DataTransferProtocol接口,该接口用于——Transfer data to/from datanode using a streaming protocol (between clients and datanodes).
WhiteListBasedTrustedChannelResolver
WhiteListBasedTrustedChannelResolver 继承自 TrustedChannelResolver 类
BlockListAsLongs 类
BlockListAsLonngs 类继承自 java.lang.Iterable 接口
CacheDirective
CacheDirective 类继承自 org.apache.hadoop.util.InstrusiveCollection 类
类注释:Namenode class that tracks state related to a cached path.
FSLimitException
FSLimitException类继承自 org.apache.hadoop.hdfs.protocol.QuotaExceededException
类注释:Abstract class for deriving exceptions related to filesystem constraints.
LayoutFlags
类注释:LayoutFlags represent features which the FSImage and edit logs can either support or not, independently of layout version.
LayoutVersion
类注释:This class tracks changes in the layout version of HDFS.
Layout version is changed for following reasons:
a. The layout of how namenode or datanode stores information on disk changes.
b. A new operation code is added to the editlog.
c. Modification such as format of a record, content of a record in editlog or fsimage.
RecoveryInProgressException
RecoveryInProgressException 类继承自 IOException
类注释:Exception indicating that a replica is already being recovery.
RollingUpgradeException
RollingUpgradeException 类继承自 IOException
类注释:Exception related to rolling upgrade.
SnapshotException
SnapshotException 类继承自 IOException
类注释:Snapshot related exception
SnapshotInfo
类注释:SnapshotInfo maintains information for a snapshot.
UnregisteredNodeException
UnregisteredNodeException 类继承自 IOException
类注释:This exception is thrown when a node that has not previously registered is trying to access the name node.
org.apahce.hadoop.hdfs.net 包
DFSNetWorkTopology 类
DFSNetWorkTopology 继承自 NetWorkTopology类
类注释:The HDFS specific network topology class. The main purpose of doing this subclassing is to add storage-type-aware chooseRandom method. All the remaining parts should be the same.
DFSTopologyNodeImpl 类
DFSTopologyNodeImpl 继承自 InnerNodeImpl 类
类注释:The HDFS specific representation of a network topology inner node. The difference is thsi class includes the information about the storage type info of this subtree. This info will be used when selecting subtrees in block placement.
DomainPeerServer 类
DomainPeerServer 类继承自 PeerServer 接口
PeerServer 接口
TcpPeerServer 类
TcpPeerServer 类继承自 PeerServer 接口
org.apache.hadoop.hdfs 包内共包含10个类
1.DeprecatedUTF8 类
DeprecatedUTF8 类继承自 org.apache.hadoop.io.UTF8 类
源码中注释信息: A simple wrapper around org.apache.hadoop.io.UTF8. This class should be used only when it is absolutely necessary to use org.apache.hadoop.io.UTF8. The only difference is that using this class does not require @SuppressWarning annotation to avoid javac warning. Instead the deprecation is implied in the class name.
This should be treated as package private class to HDFS.
2.DFSConfigKeys 类
类继承关系如下图
源码中的注释信息:This class contains constants for configuration keys and default values used in hdfs.
该类只包含了hdfs中使用所有配置信息,并没有包含任何方法。这是值得学习的地方。另外该类继承的父类也是包含配置信息的类,在这种只有配置信息的地方使用继承也是值得学习的地方。
3.DFSUtil 类
类继承关系图如下图
该类方法众多,不过主要的方法集中在处理URI地址上了。
ConfigureNNAddress 是一个内部静态类,用于存储一个 NameNode 的配置信息。
ServiceComparator 是一个内部静态类,继承自 Comparator,该类主要用于对 DataNodeInfo[] 进行排序,decommissioned 节点将被移到列表的末尾。 ENTERING_MAINTENANCE 节点将被移到 live 节点后。
ServiceAndStaleComparator 是一个内部静态类,继承自 ServiceComparator. Stale 节点将被移到正常节点后
4.HAUtil 类
该类用于对处于HA(高可用 High Availability,HA) 方案模式下的NameNode的操作,包括获取 NameNodeID、获取配置信息、获取主 NameNode地址等
从上图中,我们可以看出 NameNode 的高可用架构主要分为下面几个部分:
Active NameNode 和 Standby NameNode:两台 NameNode 形成互备,一台处于 Active 状态,为主 NameNode,另外一台处于 Standby 状态,为备 NameNode,只有主 NameNode 才能对外提供读写服务。
主备切换控制器 ZKFailoverController:ZKFailoverController 作为独立的进程运行,对 NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换,当然 NameNode 目前也支持不依赖于 Zookeeper 的手动主备切换。
Zookeeper 集群:为主备切换控制器提供主备选举支持。
共享存储系统:共享存储系统是实现 NameNode 的高可用最为关键的部分,共享存储系统保存了 NameNode 在运行过程中所产生的 HDFS 的元数据。主 NameNode 和
NameNode 通过共享存储系统实现元数据同步。在进行主备切换的时候,新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务。
DataNode 节点:除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备 NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。
5.HdfsConfiguration 类
HdfsConfiguration 类继承自 Configuration 类, 主要方法 addDeprecatedKeys
6.HdfsDtFetcher 类
HdfsDtFetcher 类继承自 DtFetecher 接口
类注释:DtFetcher is an interface which permits the abstraction and separation of delegation token fetch implementation across different packages and compilation units. Resolution of fetcher impl will be done at runtime.
主要方法 addDelegationTokens
7.HDFSPolicyProvider 类
HDFSPolicyPorvider 类继承自 PolicyProvider 类
PolicyProvider 类用于提供Hadoop系统的安全定义。
主要方法 getServices
8.NameNodeProxies 类
类注释:Create Proxy objects to communicate with a remote NN. All remote access to an NN should be funneled through this class. Most of the time you’ll want to use NamenodeProxies.createProxy, which will create wither an HA- or non-HA-enabled client proxy as appropriate.
9.SWebHdfsDtFetcher 类
SWebHdfsDtFetcher 类继承自 HdfsFetcher 类
类注释:DtFetcher for SWebHdfsFileSystem using the base class HdfsDtFetcher impl.
主要方法 getServiceName
10.WebHdfsDtFetcher 类
WebHdfsDtFetcher 类继承自 HdfsFetcher 类
类注释:DtFetcher for WebHdfsFileSystem using the base class HdfsDtFetcher impl.