闲谈寻址-DNS的多级缓存系统

来源:互联网 发布:西剑流 知乎 编辑:程序博客网 时间:2024/05/20 01:47

提到DNS,基本上没有不知道的,这个DNS协议非常非常之复杂,令人望而却步。我敢说DNS的复杂程度堪比HTTP,但是为什么却没有HTTP受关注度更高?世界从来不以复杂分高下,DNS虽然使用范围胜过HTTP,然而却不如HTTP浮于人们视野之内,DNS除了在目之所及的劫持与反劫持之外,未免帮了忙却又被人遗忘,实不幸也!

  Why?

  DNS实则仅仅是做网络通信第一步而已,并不参与通信本身,DNS所做的,仅仅在于,将人类可读的且认可的一个字符串名字翻译成一个计算机可读可处理的数字而已,随后的通信过程全由这个计算机可认的数字地址代理,便没有人类可读的字符串之什么事了。虽DNS不参与通信本身,然没有它的参与,后续的通信便不可行,它重要吗?

  有人说,既然DNS如此这般鸡肋,为什么不能一开始就用IP地址通信呢?不是不可能,是人们不接受,人们不可能用10001101101110000111这种来表示www.abcde.com.uk,是吗?

  有人又说,既然不能用二进制表示一个域名,那么用点分十进制总可以吧,事实证明也不可行,因为即便你用,http://192.158.133.145,也会让人觉得不知其所以然,只是比二进制表示短了一点而已。这就类似一个前端程序员看到汇编和机器码之后无法区分一样,反正都不知所云,也就没有必要区别了。

  此处正其言,域名是给普通人看的,点分十进制IP地址是给网管和程序员进行IP地址规划时看的,32位IP地址是给计算机看的;同样的,机器码是给CPU内部的逻辑电路看的,汇编是给接触机器的编程者看的,高级语言是给接触业务的编程者看的,没有优劣,只有视场景不同而观之。


IP地址是当前TCP/IP网络通信的根本,意思是说要想通信你必要有一个IP地址,这个IP从何而来?

  如果你一开始就有这个IP地址,那么你便可以直接与之通信,然而大多数情况下,你并不知晓这个IP地址,你所知晓的只是一个叫做域名人类可记忆的名字,比如www.baidu.com这类。虽然这个名字我并不觉得设计的多么优秀,但至少比点分十进制要更可读。我能从www.baidu.com这个域名中看得出最终我要访问的是百度公司的一个IP地址,但是我还是很难理解什么是www和什么是com,要想理解这些需要做很多的功课,但至少就我识别出baidu这个关键词来讲,什么是www,什么是com,都是无所谓的,如果我给出一个IP地址183.61.92.33,你能从字面上看得出它是Intel的吗?


DNS协议是干什么的

很简单,DNS负责把一个aaa.bbb.ccc.ddd.eee….这种域名解析成一个IP地址,关键是怎么个解析方式。这就涉及到了DNS的整体结构

DNS的结构

本质上,DNS系统是一个典型的寻址结构,就像内存寻址一样,给出一个域名,它可以定位到该域名所对应的其它内容,即一个IP地址,然而这一切是这么做到的呢?

  DNS目前采用的是BIND,依然来自伯克利,跟古老的socket师出同门,由此也看得出伯克利在计算机网络领域的重要性,后面用DNS指代实际的BIND。简单点说,DNS的特点有两点:
1. 多级缓存查询
2. 分布式分级管理
我们先看下它的整体结构:

这里写图片描述

是不是很像CDN的架构?我们把DNS分布式存储服务器看作CDN源站,把DNS查询的缓存服务器看作是就近的CDN边缘站点,简直就是相同的架构。理解了这一点,非常有益于在整体上把我DNS的精髓,即它对查询效率的要求非常高,同时它的应用又非常普遍,这就要求查询既要是分布式的,又要是快速的。

  早期的hosts文件的弊端在于查询是集中的,你必须从同一台服务器上去下载最新的hosts文件,当全世界的每一个角落都有这样的需求时,集中式的查询方式就显得力不从心了,同时如果把hosts文件管理职责下放到其它机构,又会面临信息同步的问题,如何让查询变得分布,同时管理上又不用面临信息同步问题,这就需要好好设计设计。

DNS的授权模型

苏联和美国哪个好,1991年的时候终于见分晓,一个是邦联制,一个是联邦制,之所以联邦制优于邦联制,其核心就在于它的授权模型,当然,DNS也是得益于此。

  既然在同一个地方存储所有的域名/IP地址的对应信息不合适,那就把域名试着分下类,然后把每一类的管理职责下放给单独的机构来管理,同时在这些机构之间建立关联,这样当有查询请求到达时,顺着这些关联就能得到最终的答案。循着这个思路,域名就被设计成了点分字符串的分层结构,从右到左,每越过一个点就抵达离树根更远的层级:

这里写图片描述

以下的篇幅中,我始终用这个shugoulu.jiadingqu.shanghaishi.cn.域名作为例子来描述细节,它并不存在,但它能说明问题。我假设世界上每一条街道都有一个域名(不远的将来可能真的这样),那么由于街道在地球上的编址属于规则编址,因此这是一个典型的树型结构,你在地图上找到它或者希望到达那个地方,就跟计算机内存寻址一样简单,直接按照地址一级一级找就是了:
- 先到中国,然后问中国人上海在哪里,人们会告诉你上海的位置以及到达上海的方式;
- 于是你到了上海,你问上海人嘉定区在哪里,人们告诉了你答案;
- 接着你到了嘉定区,你问一个嘉定人墅沟路在哪里,他告诉了你应该怎么走;
- 于是你终于到达了目的地.
这是一个典型的问路模式,你不能指望你在美国的时候一个美国人告诉你全部信息,首先他可能并不知道,其次你也不一定记得住,再次万一以前的路由信息是陈旧的,还得重来,因此逐跳逼近目标才是合理的方案。

  当你去过了墅沟路一次后,这条路线可能就会记在你的脑海中了,当你再去墅沟路的时候,你就不用问来问去了,如果有私人飞机,直接飞过去也是可以的。然而过了几年,你也许忘记了墅沟路,但是你还记得上海,当你再去墅沟路时,你便可以先直飞上海,然后再去问上海人嘉定区的位置,这样至少你不用先跑到北京了。

  很棒!DNS就是这样运作的!


DNS的查询过程

以下就是DNS解析的一个过程图解

这里写图片描述

请注意那些叫做查询服务器的节点,它们试图在本机保存整个分布式的管理结构的信息,这就是所谓的多级缓存!也就是说,它们并不一定非要保存域名和IP地址的直接对应信息,如果没有找到这个对应,它们会努力帮你找到离目标最近的管理服务器,比如虽然它没有shugoulu.jiadingqu.shanghaishi.cn.,但是它有shanghaishi.cn.,这也算是一种命中,至少查询不会从根部开始了。

  这意味着什么?

  这种设计无形中大幅降低了根管理服务器的流量压力,只有在查询服务器把各级缓存全都遗忘的时候,才会从根部开始一次查询,而这次新的查询结束后,查询服务器又会把它记住,直到岁月导致的遗忘。

  如果同一个查询服务器收到了一个同样的DNS解析请求,它将按照下面的流程行事:

这里写图片描述

再看上面这个结构,由于是分布式的授权管理结构,如果哪个域名的IP地址变化了,不像集中式的hosts文件那般牵一发而动全身了,直接把更改过的信息上报给你的授权方即可,到此为止这次的变更通知就结束了,你的授权方不必把你的域名IP地址的变更信息再通知更上面的授权方,这就是授权模型的好处,它正是这句中世纪古话“我的领主的领主不是我的领主,我的附庸的附庸不是我的附庸”的完美体现!

  扯句闲话,是不是让中国人设计DNS,就不会这样设计呢?我想肯定设计成变更逐级透传到根服务器呢?毕竟我们也有一句古话“普天之下,莫非王土;率土之滨,莫非王臣”

术语和细节

我觉得这篇讲DNS的闲扯已经够“不专业”了,这是为了可以秒懂。事实上有很多计算机网络领域的设计思想,都是来源于甚至千百年来早已有之的实践,就像我常常说的那样,就算现在再牛逼的精确制导的导弹,其核心与原始野人玩的弹弓没有本质的区别,更不用说什么手枪,大炮了,其核心就两样,给它一个动力,给它一个方向,仅此而已吧,然而在践行这个动力来源以及方向定位的时候,却有了千奇百怪般的持续进化,从树枝弹力,风向瞄准,到臂力拉弓,人眼瞄准,然后再到机械驱动,再到火药驱动,燃料驱动核弹头,最终把一台计算机装在弹头上,根据现状实时计算并改变弹头的方向,我想如此先进的核弹技术无外乎也就是跟让一个野人坐在一只巨大的箭头上把握风帆根据目标调整方向没有什么大不同,这些设想古人早已有之,只是限于生产力尚未发达,只能在神话故事中显灵了。

  回到正题,计算机网络是一门实践科学,但凡实践就涉及到具体操作,操作就必然有规章,规章则要统一言辞,这就导致了很多的术语,只要你操作,这些术语你就要记住,只要你运维,你排错,这些术语不光要记住,还要与其它术语关联,这就给人一种印象,计算机网络技术是复杂的,甚至超级复杂的。你要搭建一个DNS服务器,不知道什么是A记录怎么行,不知道什么是CNAME怎么行,到底什么是权威回答,什么是非权威回答?…我只能说,操作多了自然就记住了,没有捷径,然而也没有必要去死记硬背,死记硬背的东西终于还是要遗忘的。我为什么觉得外语是简单的然而很多人学不会,一样的道理,你不说不读不写,怎能学会,没有捷径。

  还是以上图为例,我大致说一下必要的一些概念,全在图中,如有遗漏以及疑问,请发邮件告知或探讨(marywangran@126.com):

这里写图片描述

本文中,我一直试图避开真正的DNS,唯一真实的就是.cn这个顶级域,和它并列的.com顶级域我就没有提及,但这没关系,翻开《DNS与BIND(第五版)》,花半个小时读一下前两章,你就什么都懂了,对,相信我,真的就只用半小时就能看完前两章,该书写的特别通俗!本文不会去说那些书上或者RFC上有的东西,所以说本文只是我个人对DNS系统的一点感受,我觉得时不时的进行一些看似与具体技术无关的臆想,对理解整个系统是非常有帮助的。

  另外,想进一步了解DNS的,学会dig就够了,并且dig非常好玩,虽然dig是domain information groper的简称,跟铲子铁锹没有任何关系,但你用过之后,会有一种感觉,这工具真的是一把铁锹,能把你想挖的东西都挖出来摆在你面前,这难道是英文版的说文解字之实例吗?

  最后说说Linux系统上常年运行的nscd。

  这个叫做nscd的玩意儿就是个缓存管理系统,它可以把你最近查过的域名映射到IP的结果保存在一个文件中,这是一个系统的机制,就连gethostbyname调用都跟它有关,nscd非常重要。

  然而nscd也可能蒙蔽了很多细节,所以如果你想彻底学习DNS,最好是把它停掉,一切都自己动手去dig,这样才能理解究竟。

原创粉丝点击