龙空技术网

SMB传输为什么弱?原因不止是绝大部分的NAS的SMB都是山寨货

iN在 16356

前言:

当前同学们对“pythonsmb”大概比较看重,各位老铁们都需要了解一些“pythonsmb”的相关文章。那么小编同时在网上收集了一些关于“pythonsmb””的相关内容,希望姐妹们能喜欢,大家一起来了解一下吧!

上一篇文章给大家揭示了一个事实——SMB文件共享的性能很拉胯。

今天也就给大家讲讲为什么大多数NAS上的文件共享的性能是“拉胯他妈给拉胯开门——拉胯到家了”。

“文件共享”这件事在现在大多数计算机用户或者数码用户看来是一个再寻常不过的操作。但很多人并不自知“文件共享”的性能羸弱的问题。

我们先做一个脑补一个故事情节:

在一个闭塞的小山村里面,人们还保持着先秦时代的生活和运作方式,对外界一无所知。他们也会有一些货运的需求,在这个小山村里面有两种运输工具,一种是牛车,另一种是马车。

村里面的大聪明就会觉得马车在驰骋起来的速度要比牛车快很多。

但村里还有更聪明的人,通过观察得出来另一个结论——在走山路的时候,由于牛的力气比马大,在山路的运输中牛车比马车更有效率。

于是在村里就对到底是马车还是牛车更有运输效率一直争吵了很多年,直到这个村子里的人看到有一条铁路从村子边上通过。

村里的人就开始嘲笑,用这些东西运输还不如牛车吧?

……

其实大部分普通用户就是生活在村子里面的村民,IT是一个“知道经济”,它的价值在于你见过多少东西。如果村民们不到外面走走,哪怕是他们看到了村边的火车,也难以想象到世界上还有这玩意:

这个故事情节,大家自行对号入座。

好了,说回SMB,今天我们对SMB要有一个比较全面的认知。

SMB(Server Message Block,服务器消息块)是一个老古董了,老到了比看这篇文章的人都要古老,在1987年,微软为了让网络上的计算机相互通讯开发了SMB协议。

如果对IT的历史有所了解的话,会发现这个协议是在1983年TCP/IP协议制定之后被开发出来的。但是我们要知道,1983年internet网络并不普及。因此SMB并不是针对于TCP/IP协议开发的。

SMB的再下一层实际上是NetBIOS(Network Basic Input/Output System,网络基本输入/输出系统)。

因此,我们在看到一个网络共享的时候,我们会发现在网络共享的资源地址上有一个“主机名”。

这个主机名又别于TCP/IP网络中的主机名,也和域名系统的主机名有所差别。就是简简单单的一个字符串。实际上这个在SMB中的主机名就来自于NetBIOS。

NetBIOS的这个历史就更久远了。这是1981年IBM立项,在1983年由sytek开发实施的IBM PC Network中的功能。IBM PC Network是第一个PC局域网标准。但是IBM当时并不看好这种形式,而采用了当时更先进的令牌环网,当然了,后面的事情我们也知道,令牌环网迅速的被以太网所取代……而NetBIOS标记主机的功能却被一代代的沿袭下来。

直至现在,很多主机还是支持NetBios的功能的。

“直至现在”还在支持,这里面就牵扯到了早早年间的老技术如何适配到现在的新技术上的问题了。其实,我们在Windows PC上所使用的NetBIOS并不是原汁原味的。在Windows系统中一共出现了三种NetBIOS,最早期纯的NetBIOS是配合令牌网络存在的,还有 NetBIOS over IPX/SPX是对应IPX网络的,以及NetBIOS over TCP/IP是对应于现在的TCP/IP网络系统的。在当年计算机上网络设置并不仅仅是要设置IP地址,还得设置一个IPX ID。其实在1995年左右的时间大部分可以局域网对战的游戏都是只支持IPX网络的……当时的联众之所以能让大家在网络上玩局域网互联游戏也是因为联众本身就是一个IPX Proxy。

SMB协议的底层就是建立在对NetBIOS的支持下才能够完成服务器消息块的传递。在这个时候我们就可以看到,本身在TCP/IP协议下可以直达的一个信息通道,就非得往NetBIOS上再绕一圈。

“TCP/IP一家独大”是当初微软开发SMB的时候所没有预见到的。而微软没有预见到的事情还不止这点。SMB——服务器消息块,如果我们从字面上看“服务器消息块”怎么都难以和“文件传输”或者“文件共享”联系到一起。要知道早期的开发人员都是王八吃筷子——脑子一根筋,起的名字各种名称十分的专业务实但也必须必的土掉渣,像是FTP(File Transfer Protocol,文件传输协议)、HTTP(Hypertext Transfer Protocol,超文本传输协议)、TCP(Transmission Control Protocol,传输控制协议)、SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)……都是望文生义直接能读出来就知道是做什么用的协议。

而“服务器消息块”,我们也可以直接读出来,并理解这是“服务器以块数据包传输消息”的协议,注意这里是传送消息,并不是传送文件。基于SMB我们不仅仅可以传输文件、还能共享打印机、发送服务器控制指令、获取服务器状态信息……

微软嘛……总是喜欢一不小心把事情搞大。这种公司的文化就是如此,当初搞个游戏机不叫游戏机,而叫做客厅电脑;搞个浏览器不叫浏览器而叫Internet Desktop;

搞个MP3不叫MP3而叫数字媒体播放器……

这个公司的企业文化就是这样,总是喜欢把很多的功能集合在一起,再弄个一个大一统的名字,这是刻在骨子里的基因。

所以,SMB并不只是文件传输用的协议大家也就应该有所了解了——这是M$tyle。事情做好没做好在其次,M$得有自己的架势(Or 风格)。

但多功能、大一统就意味着样样都会也样样稀松。这类东西就得慢慢的打磨,有的实在打磨不下去了,就干脆舍弃掉,例如WindowsPhone

有的打磨的还不错,就可以一直走下去,例如Windows Server;但在生或死之间则有更多的产品是处在薛定谔猫的状态——半死不活。SMB就是一个很典型的案例。

它的根基扎在NetBIOS上,放眼的却是未来。在SMB成长的阶段中微软没有预见到文件共享、把文件在局域网上传输逐渐的成了一个使用计算机系统的常见场景。等到预见到的时候大家对SMB的依赖已经成了一个常态。在Windows Vista阶段,微软试图给SMB改个名字叫做CIFS(Common Internet File System,通用互联网文件系统),呃,呃,呃,听听这个名字,是不是很有M$tyle?

传文件就传文件,搞个毛毛的“通用互联网文件系统”这么大的概念来吓唬我们?相对于SMB微软又在CIFS里面增加了大量的能够实现“通用互联网文件系统”的功能。

好在SMB大家都已经用惯了叫惯了,CIFS在短暂出现后,又被后面的SMB2、SMB3逐渐取代。虽然被逐渐打磨升级,但SMB本身的底层设计并没有改变。

在SMB的逻辑中当一台服务器响应了SMB客户端后,客户端会向服务器发送一系列消息(Message,知道为啥叫“服务器消息块”了吧?),在获得了服务器响应后,继续再发消息到服务器,以完成相应的任务。

从现代计算机设计来看SMB有一些喋喋不休,用我们天津话说叫做“碎嘴子”。SMB的嘴有多碎呢?哪怕传输一个1字节的文件,客户端也要和服务端交互12次。如果文件或者对象比较大,那么SMB就会在传输文件实体数据的时候进入一个单元循环(unitil Loop)

反复的喋喋不休的来回发送和确认数据包。这就是“请求-响应”式协议的固有缺陷了,而在循环中所需要的请求-响应次数则根据系统的最大传输单元(MTU)限制来决定。

这种模式为什么在SMB出现之初没有什么问题呢?原因在于1990年代计算机的存储单元都比较小,iN在1994年购买的电脑只有40MB硬盘,即便是在10Mbps的网络上将硬盘的全部容量传输到另外一台电脑上,也只需要不到一分钟的时间。SMB所带来的额外开销就并不显著了。

但现在,我们拍一张照片也可能达到40MB的容量,即便是网络升级到了1G或者2.5G,但是SMB的这种“请求-响应”的机制并没有变化,而且咱们在讨论SMB标准模型的时候并没有考虑网络的延迟

每次请求和响应之间的延迟也会极大的增加SMB的传输开销,因此无论是在传输大文件或者大量小文件的时候,你都会觉得SMB的效率并不是那么高。——当然了,你得有和其他传输模式的比较,否则,我们的讨论就停留在村里的牛车和马车的讨论上了。

这还不是SMB最糟糕的情况!

SMB是微软的一个私有协议。理论上仅仅可以在微软的Windows系统中使用。那么NAS上的SMB共享协议是什么呢?——这是一个“山寨”货。

1992年还在澳大利亚大学上学的Tridge通过逆向工程(主要是嗅探)的方法实现了在UNIX上实现了一系列的Windows 网络功能,在1993年这些功能逐渐形成了一个unix套件 “netbios for unix”,在1996年这套套件逐步升级发展,发布了Samba 1.9.17,同时这个套件也进入自由软件领域。它的一个最重要功能就是实现了SMB。

由于Tridge在Samba和rsync(没错,常用的rsync也是他写的)上的成就,Tridge在2020年1月26日被授予“澳大利亚勋章”——这是一个澳洲公民的极高荣誉。

当Samba进入自由软件领域后,刚刚发行不久的Red Hat Linux和Debian迅速的将Samba纳入到自己的默认安装选项中。到了今天为止,几乎所有的Linux系统中都有了Samba。unix用户和大量的Linux用户都利用Samba和Windows交换文件。这些用户外加Windows原有的用户也就让SMB成为了目前使用最多的一个文件分享/传输系统。

SMB的真正普遍运用并不是因为SMB本身优异的性能,而是存量用户加上开源社区的推动。

同时,在现在很多利用Linux的设备中(例如我们的很多NAS)也基于Samba的代码实现了文件夹共享功能。

只不过这些linux中的Samba性能比较接近原生的Windows SMB而已,并没有达到100%的Windows SMB性能水平。出现这样的状况的一个主要原因是在于SMB是反向工程的产物,另一个重要的原因是SMB并不完全是依靠C来写的,还有部分是Python代码,这是一种解释性语言代码,本身的效率就有瓶颈。

对于很多NAS的普通用户来说Samba的共享文件夹其实还有性能没有被释放。如果我们打开一个群晖的Samba配置文件——这个文件在/etc/etc/samba目录下:

映入眼帘的就是这部分内容了:在里面写着“IMPORTANT: Synology will not provide technical support for any issues caused by unauthorized modification to the configuration.”翻译过来就是 “重要提示:对配置进行未经授权的修改所引起的任何问题,Synology 将不提供技术支持。”

那么smb.conf是什么呢?这是Samba的配置文件,例如我们的建议配置方式是:

[global] 	log level = 1 	socket options = TCP_NODELAY IPTOS_LOWDELAY 	read raw = yes	write raw = yes	oplocks = yes	max xmit = 65535	dead time = 15	getwd cache = yes	lpq cache = 30[okplace] 	veto oplock files = this/that/theotherfile[badplace] 	oplocks = no

这是基于调试和测试的结果:

同时,也得配合网卡、系统和驱动本身的能力来细微调节,但很多NAS用户根本不做这些优化,或者很多NAS系统会禁止用户做优化,这就让Samba本身就弱的性能更进一步降低。

标签: #pythonsmb