【问题标题】:What would you use to implement a fast and lightweight file server?您将使用什么来实现快速、轻量级的文件服务器?
【发布时间】:2010-10-20 02:16:29
【问题描述】:

我需要一个文件服务器作为桌面应用程序的一部分,它应该尽可能快地响应文件传输请求(来自远程客户端,通常位于同一 LAN 上)。小文件会有很多文件请求。服务器应该能够提供上传和下载服务。

我不拘泥于任何特定技术,因此我对任何编程语言、工具包、库都持开放态度,只要它们可以在 Windows 上运行。

我最初的想法是使用 Windows 套接字实现 C/C++ 或使用 Boost(asio 等)等库提供的服务。我也想到了 Erlang,但我必须学习,因此性能优势应该证明由于必须学习该语言而增加的开发时间是合理的。

后期编辑:我很欣赏那些说使用 FTP 或 HTTP 或基本上已经创建的任何东西的答案,但考虑到您仍想从头开始编写一个,您会怎么做?

【问题讨论】:

  • 好的,说出原因也很有启发性
  • 您似乎只是为了流行语效应而提到它,而没有考虑到 Erlang 的使用实际上与您出于某种原因重新发明的解决方案有何关系。
  • 不是真的,我提到它是因为它支持并发编程。有用 Erlang (YAWS) 编写的网络服务器。如果您没有得到答案,您可能应该先询问,然后做出假设。
  • 如果您需要服务器用于真实场景,而不仅仅是作为编程练习,我强烈建议您使用任何已建立的协议库。如果没有必要,不要发明轮子。
  • 我在考虑使用 Boost,现在我被使用 POCO 的想法所吸引。

标签: c++ sockets fileserver


【解决方案1】:

为什么不直接选择FTP?您应该能够找到任何语言的适当服务器实现,以及客户端访问库。

这听起来像是很多轮子改造。诚然,FTP 并不理想,并且有一些奇怪的地方,但是……它就在那里,它是标准的、众所周知的,并且已经非常广泛地实施了。

【讨论】:

    【解决方案2】:

    听起来您应该使用SFTP (SSH) server,它是防火墙/NAT 安全、可靠的,并且已经可以满足您的需求等等。您还可以使用 SAMBA 或 windows 文件共享来实现更简单的实现。

    【讨论】:

      【解决方案3】:

      如果所有机器都在同一个 LAN 上的 Windows 上运行,为什么还需要服务器?为什么不简单地使用 Windows 文件共享?

      【讨论】:

      • 这很可能是一个更好的解决方案,特别是在 Windows Server 200x 范围内,因为文件共享中使用了高吞吐量 API(TransmitFile/TransmitPacket 等)。
      • 我可以看到使用 Windows 文件共享会造成管理上的麻烦——最终用户(或管理员)碰巧配置了它,这可能与要求不兼容.
      • 这将是一个 srhink 包装的产品,共享不是 MarkR 指出的选项
      【解决方案4】:

      为什么不使用现有的东西,例如普通的 Web 服务器可以非常快速地处理大量小文件(图像)。

      很多人已经花时间优化代码。

      第二个好处是传输是通过已建立的协议 HTTP 完成的。如果您需要更高的安全性,可以轻松切换到 SSL。

      对于上传,脚本或自定义模块也没有问题 - 使用相同的方法您还可以添加授权。

      只要您不需要动态查找文件,我想这将是最好的解决方案之一。

      【讨论】:

        【解决方案5】:

        我建议不要使用 FTP、SFTP 或任何其他面向连接的技术。相反,请选择无连接协议或技术。

        原因是,如果您需要上传或下载大量小文件,并且响应应该尽可能快,您希望避免建立和破坏连接的成本。

        我建议您考虑使用现有实现或实现您自己的 HTTP 或 HTTPS 服务器/服务。

        【讨论】:

        • 实现我自己的 HTTP 对我来说似乎有点矫枉过正,因为我需要 HTTP 服务器功能的一小部分,而我的身份验证模型将完全不同(并且更简单)。感谢您的回答。
        【解决方案6】:

        它是现有桌面应用程序的新组成部分?服务器的目标是什么?它是否保护上传/下载的文件并提供身份验证和/或授权?它是否为要存储的上传内容提供某种结构?

        一种选择可能是在机器上安装 Apache HTTP Server 并通过它提供文件。使用 POST 上传,使用 GET 下载。

        如果客户端位于 LAN 内,您是否可以不共享一个驱动器?

        【讨论】:

        • 这是一个新的收缩包装的桌面应用程序。还没有写一行代码。由于部署/设置原因,共享不是一种选择。之前有人建议过 HTTP。我会调查的。谢谢
        【解决方案7】:

        您的瓶颈可能来自以下来源之一:

        • 硬盘 I/O - WD velociraptor 应该具有大约 100MB/s 的随机访问速度。此外,重要的是您是否将其设置为 RAID0、1、5 或其他。有些人读得快,写得慢。权衡取舍。

        • 网络 I/O - 假设您在快速 RAID 设置中拥有最快的硬盘,除非您使用 Gbit I/O,否则您的网络将会很慢。如果您的管道很大,您仍然需要为其提供数据。

        • 内存缓存 - 内存中文件系统缓存需要足够大以缓冲所有网络 I/O,以免降低速度。对于您正在查看的工作,这将需要大量内存。

        • 文件系统结构 - 假设您有千兆字节的内存,那么瓶颈很可能是您用于文件系统的数据结构。如果文件系统结构很麻烦,它会拖慢你的速度。

        假设所有其他问题都已解决,那么您是否担心您的应用程序本身。请注意,大多数瓶颈都超出了您的软件控制范围。因此,无论您是使用 C/C++ 编写代码还是使用特定的库,您仍然会受制于操作系统和硬件。

        【讨论】:

          【解决方案8】:

          对于频繁上传小文件,最快的方法是实现您自己的专有协议,但这需要大量工作 - 而且它是非标准的,这意味着未来的集成将很困难,除非您是能够在您将支持的任何客户端中实现您的协议。如果你还是选择这样做,这是我对简单协议的建议:

          1. 命令:1 个字节用于标识将要执行的操作:(0x01 表示上传请求,0x02 表示下载请求,0x11 表示上传响应,0x12 表示下载响应等)。
          2. 文件名:可以是固定大小或以字节为前缀长度(假设名称小于 255 字节)
          3. 校验和,例如 MD5(如果上传请求或下载响应)
          4. 文件大小(如果上传请求或下载响应)
          5. 有效负载(如果是上传请求或下载响应)

          这可以在一个简单的 TCP 套接字之上实现。您也可以使用 UDP,避免建立连接的成本,但在这种情况下,您必须处理重传控制。

          在决定实现自己的协议之前,先看看像 libcurl 这样的 HTTP 库,你可以让你的服务器使用标准的 HTTP 命令,比如 GET 来下载和 POST 来上传。这将节省大量工作,并且您可以使用任何网络浏览器测试下载。

          另一个提高性能的建议是使用文件存储库而不是文件系统,而是使用 SQLite 之类的东西。您可以创建一个表,其中包含一个用于文件名的 char 列和一个用于文件内容的 blob 列。由于 SQLite 是轻量级的并且可以进行高效的缓存,因此您可以在大多数情况下避免磁盘访问开销。

          我假设您不需要客户端身份验证。

          最后:尽管 C++ 是您的首选,可以为您提供原始本机代码速度,但这很少是此类应用程序的主要瓶颈。很可能是磁盘访问和网络带宽。我之所以提到这一点,是因为在 Java 中,您可能能够用不到 100 行代码制作一个 servlet 来做完全相同的事情(使用 HTTP GET 进行下载和 POST 进行上传)。在这种情况下使用 Derby 而不是 SQLite,将该 servlet 放入任何容器(Tomcat、Glassfish 等)中,然后就完成了。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-22
            • 2017-08-30
            • 1970-01-01
            • 2012-09-16
            • 1970-01-01
            • 2011-01-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多