Rustatic——一个小巧快速的文件服务器!

首先是性能对比:

大约提升了41%的性能,考虑到cache buffer预热之后,属于纯内存拷贝操作,符合预期。

为什么做这个

之前做了一个纯静态的网站,因为上面放的是自己摄影的作品,想要一个保存图片的功能,于是想着自己做一个小图床,但是后来觉得既然做,就索性追求性能好了。

设计

考虑到主要的功能都是静态文件操作,所以想要提升性能,就要从"不必要的操作"下手。毕竟在磁盘性能固定,带宽都一样拉的情况下,减少服务端的活就成了近乎唯一的选择,当然客户端也需要,但收益就小了很多。

在服务端想做到静态文件上传,似乎没什么好的做法,就是纯粹的读取,写入,无非设置buffer大小这种炼丹级别的做法。后来也有调查过Linux文件预分配,之后使用mmap进行减少拷贝,考虑到上传是一次操作,所以为了减少开发难度,决定暂时搁置。

但是文件下载则是一个值得考究的问题,因为有零拷贝zero-copy技术可以用。

在文件下载的选择上,有mmapsplicesendfile三种选择。

首先是mmap,对用户空间和内核空间映射,减少一次内核到用户的拷贝。

之后是splice,直接建立文件FD与SocketFD之间的管道,减少内核到用户,cache buffer到Socket buffer两次拷贝。

最后是我们选择的sendfile。它可以减少一次内核到用户的拷贝,如果DMA支持的话,甚至可以减少内核之间的拷贝(cache buffer -> socker buffer)。

为什么不选择mmap呢?因为会引入多一次的系统调用,在mmap之后,还需要调用write进行写入。其次呢,mmap更加复杂,有更多的参数需要设置。

mmap更适合内存共享,而sendfile天然适合文件传输,尤其是大文件。

至于splice,首先是不方便,然后是不如sendfile稳定,这点在网上可以找到Linus的回复,并且StackOverflow有一些论证,表明它是不建议使用的。

为什么不用io_uring

因为不方便。在Rust中使用io_uring首先就是库不成熟,各大运行时都有自己的实现,但更多像打补丁似的兼容实现,性能是个问题。但是更重要的是,io_uring的文件操作并不全是类似IOCP那种全异步的实现,内部也是线程池实现,介于此(复杂的使用和并不完美的文件操作),最终决定放弃。

既然确定了技术方案,剩下的就是搭建了。

首先使用两个TCP连接去处理,一个当作控制连接,一个数据连接,为什么不用UDP?是因为sendfile需要文件FD作为目标,而UDP无连接的特性不支持。

其次两个连接方便分别处理,隔离出来专门的数据路和请求路。

在监控Socket读写之后,需要把实际的文件读写放到线程处理,因为阻塞Reactor会导致后续所有其他连接被阻塞。目前Rust异步运行时均为此模型,所以就引入了线程池的使用。

整体逻辑为:

  • 双连接建立,控制连接生成标识符,用户发送标识符到数据连接,进行二者的配对。
  • 用户请求控制连接,产生的数据或者需要接收的数据通过数据连接发送和接收。

既然需要使用线程池去处理数据连接产生的文件读写,选择一个或者设计一个线程池就显得很有必要了。

其中Automatic是为了此项目设计的线程池,Unblocking则是smol旗下的,还有经典的Threadpool以及Rayon。

第一张图是对于固定耗时5微秒的任务执行情况,第二张图则是纯粹的调度对比。

均为1024个异步Task,每个10次调用,可以看到Automatic还是很强劲的。

其内部使用了ThreadLocal技术,外加TaskStealing进行合理的任务分配。

有了上述设计,便可以设计用户交互的接口了。

UI设计

这里采用终端交互的形式,包括登陆,注册,上传,下载,列表等操作。

项目地址

相关推荐
RoyLin10 小时前
Rust 编写的 40MB 大小 MicroVM 运行时,完美替代 Docker 作为 AI Agent Sandbox
后端·架构·rust
班公湖里洗过脚14 小时前
《通过例子学Rust》第20章 标准库更多介绍
rust
班公湖里洗过脚14 小时前
《通过例子学Rust》第21章 测试
rust
班公湖里洗过脚1 天前
《通过例子学Rust》第19章 标准库类型
rust
键盘鼓手苏苏1 天前
Flutter for OpenHarmony:git 纯 Dart 实现的 Git 操作库(在应用内实现版本控制) 深度解析与鸿蒙适配指南
开发语言·git·flutter·华为·rust·自动化·harmonyos
初恋叫萱萱1 天前
基于 Rust 与 DeepSeek V3.2 构建高性能插件化 LLM 应用框架深度解析
网络·人工智能·rust
码农葫芦侠1 天前
Rust学习教程2:基本语法
开发语言·学习·rust
键盘鼓手苏苏1 天前
Flutter for OpenHarmony 实战:Envied — 环境变量与私钥安全守护者
开发语言·安全·flutter·华为·rust·harmonyos
马克Markorg2 天前
使用rust实现的高性能api测试工具
开发语言·测试工具·rust·postman
中国胖子风清扬2 天前
GPUI 在 macOS 上编译问题排查指南
spring boot·后端·macos·小程序·rust·uni-app·web app