TUX Web服务器为何已死?是否被Nginx/Lighttpd/Epoll/Kqueue所代替?

8
我还记得Linux上一个叫"TUX"的非常快速的内核模块,用于静态文件服务以解决"C10K问题"并提高IIS相对于Linux的静态文件服务性能。现在我经常看到以下几个:
  1. Nginx
  2. Lighttpd
  3. CDN
它们都可以用于“快速静态文件服务”。如果你的操作系统具有正确的特性,那么快速地服务静态文件就不难。自从IO完成端口、重叠I/O等技术发明以来,Windows也可以做到这一点。
Tux是因为安全方面的影响而消失了吗?它是否已经过时,被Kqueue / Epoll和Sendfile等新特性取代?针对100%的静态内容(例如50张图像的快照),最佳解决方案是什么呢?
我知道这是一个与服务器相关的问题,但它也是理论性的。如果内容完全是静态的,使用CDN真的会更好吗?

我在这方面不是专家,但你最后的问题对我来说似乎很奇怪... CDN不只是多个静态文件服务器和一些负载均衡吗?你只需告诉客户端连接哪个服务器(通过最低延迟/最不繁忙的服务器/最近的服务器等),就可以了。单个服务器迟早会无法满足需求,但如果你像CDN一样有几个服务器,你只需在它们之间分配负载即可。 - cen
1
我认为这个问题没有问题,尽管我稍微混淆了一下问题。你不需要一个用户空间线程来发送文件。内核可以做到这一点。问题是你需要一个线程来处理应用程序逻辑,所以许多网站只创建第二个域名 images.example.com,并在其前面添加CDN。它会缓存它,所以服务器不会再次看到请求。假设CDN必须使用像Tux这样的超级优化工具来提供静态文件,因为这是他们所做的全部。我怀疑他们使用Nginx等其他原因,但因为Nginx并不早于CDN的普及。 - Jaimie Sirovich
3个回答

4
大多数是因为Ingo Molnár停止了对它的工作。为什么?我相信这是因为内核版本2.2实现了sendfile(2)调用,它(大约)匹配了之前由Tux实现的巨大性能优势。请注意Tux 2.0参考手册的日期为2001年。

1
我提到了sendfile()。问题在于你仍然需要一个线程来调用sendfile(),所以它不能是全部解决方案。我假设你真正的意思是sendfile()+epoll/kqueue。即使如此,在没有任何应用程序逻辑的情况下仅提供静态内容会更重。这正是Facebook和Myspace为隐私倡导者所不悦的原因。如果你知道文件名,就可以查看任何人的照片。从他们的角度来看,文件名就是密码,但你可以理解为什么CDN可能不想在任何地方引入应用程序逻辑。Sendfile()并不是全部解决方案。 - Jaimie Sirovich
直到2.5.44才引入了epoll,而当时Tux已经不再被开发。kqueue是在FreeBSD 4.1中添加的,对Linux内核服务器也没有影响。而且我们谈论的是一个从未被主线内核接受的Linux内核服务器。 - Elliott Frisch
我提到kqueue是因为它看起来类似于epoll。你说得对,它只在FreeBSD上可用。我应该把它去掉的。sendfile()永远无法接近Tux的速度,因为你需要1:1线程与文件配对,或者使用select/poll(),不是吗?我不认为这能够接近Tux的速度。 - Jaimie Sirovich
不,它不是1:1的内核:用户线程;你有没有注意到在sendfile()手册页中 - sendfile() 在一个文件描述符和另一个文件描述符之间复制数据。因为这个复制是在内核内完成的... - 它都在内核空间中完成。 - Elliott Frisch
因为我们所讨论的文件描述符是客户端套接字和我们正在发送的文件。例如,它现在在内核中。 - Elliott Frisch
显示剩余2条评论

1
提供静态文件服务需要三个步骤:决定要发送哪个文件、决定是否发送该文件、发送文件。现在Tux在发送文件方面做得非常好,但在决定要发送哪个文件和是否发送文件方面做得一般。这些决策属于政策范畴,应在用户空间中完成。添加sendfile功能后,我可以编写一个服务器,在短时间内几乎与Tux一样出色,并且可以添加新功能而无需重新编译内核,例如SQL日志记录。仅想到从内核调用用户空间的SQL调用就让我眼皮跳动。

1
但是除了sendfile(),你还会使用什么?显然它需要是非阻塞的,但也要知道何时完成。Windows中的I/O完成端口可以做到这一点。在*nix中似乎不太清楚。我喜欢I/O完成端口的想法,因为它是一个线程池,“以防万一”它被阻塞,并采用零拷贝技术和TransmitFile()。我看到的另一个问题是SSL怎么办?你需要在内核中具有SSL才能有效地传输,而不需要用户空间线程和拷贝。 - Jaimie Sirovich
2
Tux也没有ssl,但内核级加密将允许更容易的硬件加速(自从我听说过pgp手机以来就一直在梦想)。至于阻止,这取决于您的进程模型。 - hildred
既然我们试图用类似Nginx的东西来模拟Tux,那么假设进程模型意味着需要多少个线程就有多少个线程,这可能大约是1个——因为大部分工作可以由操作系统完成。但是为了保持最佳状态,它也可能更多,因为在将其交给内核之前会有一点点开销。sendfile()并不能解决所有问题。一个naive的sendfile()使用方式只会为每个连接生成1个线程,调用sendfile()并阻塞。这样可以节省内存(零拷贝),但仍会为C10k实验创建大量线程。 - Jaimie Sirovich
这里有一个非常有趣的反驳,说明为什么1:1可能是可以接受的。值得一提的是,他说得有道理。如果线程库变得更好,所有O(N)的东西都消失了,那还有什么关系呢?https://www.usenix.org/legacy/events/hotos03/tech/full_papers/vonbehren/vonbehren.pdf - Jaimie Sirovich
我从未使用过Tux,因为每次我们考虑重新设计时,楼上的某个人都会添加一个要求,即出于某些其他原因,不使用用户空间进程不是一个选项,并且为了遵循我们的策略(通常使用旧版非线程库),我们使用已经存在的进程。事件循环与TSR完全不同,但它们各有其美。 - hildred
显示剩余9条评论

1
由于sendfile()的存在,Tux不再是必需品。 Nginx充分利用了这一点,我认为它是最适合静态或非静态内容的最佳Web服务器之一。 我发现lighttpd存在内存问题,但情况因人而异。
CDN的整个目的是将“Web服务器”移动到最终用户的浏览器附近。 这意味着网络跳数和往返延迟减少,而您无需承担在全球范围内托管多个Web服务器并使用地理DNS将用户发送到最近位置的大量成本。 请注意,由于这些Web服务器不在您的控制范围内,如果它们的网络过载,它们可能会超载,并且跳数减少的好处可能会减少。 CDN通常是DDOS攻击的目标,您可能会卷入与您的内容无关的事情中。

1
Sendfile()不是全部。这也不是CDN的(唯一)重点 - 恕我直言。CDN还针对大量静态内容进行了优化,而不仅仅是网络问题。至少这是我的经验。 - Jaimie Sirovich
当使用while open()+loop(sendfile())+close()时,系统调用开销大约可以减少50%(对于大文件),并且对于小文件也可以减少大约25%,相比之下,tux可以将系统调用开销降低100%(无论是小文件还是大文件)...因此,Tux仍然比nginx更具优势。(两种方法都可以将用户空间<->内核的memcpy减少大约100%) - hanshenrik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接