21 个版本 (1 个稳定版)
使用旧 Rust 2015
1.0.0 | 2019 年 1 月 12 日 |
---|---|
1.0.0-beta | 2018 年 2 月 3 日 |
0.12.0 | 2017 年 12 月 27 日 |
0.11.1 | 2017 年 11 月 27 日 |
#372 在 缓存 中
每月 74 次下载
74KB
1K SLoC
Rocket 文件缓存
用于 Rocket 网页框架的并发、内存文件缓存。
Rocket 文件缓存可以用作 Rocket 的 NamedFile 的替代品,用于提供文件服务。
此代码来自 Rocket 的 静态文件 示例
#[get("/<file..>")]
fn files(file: PathBuf) -> Option<NamedFile> {
NamedFile::open(Path::new("static/").join(file)).ok()
}
fn main() {
rocket::ignite().mount("/", routes![files]).launch();
}
可以通过通过缓存获取文件来加速
#[get("/<file..>")]
fn files(file: PathBuf, cache: State<Cache> ) -> CachedFile {
CachedFile::open(Path::new("static/").join(file), cache.inner())
}
fn main() {
let cache: Cache = CacheBuilder::new()
.size_limit(1024 * 1024 * 40) // 40 MB
.build()
.unwrap();
rocket::ignite()
.manage(cache)
.mount("/", routes![files])
.launch();
}
使用场景
Rocket 文件缓存将一组频繁访问的文件保存在内存中,这样您的网络服务器就不必等待磁盘读取文件。这应该会提高磁盘 I/O 瓶颈系统的延迟和吞吐量。
如果您提供已知大小的静态文件(index.html、js 包、一些资产),应尝试设置缓存的最大大小,以使它们全部适合,特别是如果所有这些文件在每次有人访问您的网站时都提供。
如果您提供的静态文件总大小大于适合内存的大小,但您有一些比其他内容访问更频繁的内容,应指定足够的缓存空间,以便最流行的内容可以适合。如果您的热门内容随时间变化,并且您希望缓存反映当前最热门的内容,可以使用 alter_all_access_counts()
方法减少当前缓存中所有项的访问次数,从而使新内容更容易进入缓存。
如果您提供用户创建的文件,关于文件流行度的相同逻辑适用,只是您可能希望每10000个请求左右启动一个线程,该线程将使用alter_all_access_counts()
来减少缓存中项目的访问次数。
性能
基准测试试图从任何来源获取文件,无论是缓存还是文件系统,并将它读取一次到内存中。错过衡量的是缓存意识到文件未存储并从磁盘读取文件所需的时间。在AWS EC2 t2微实例(82 MB/s HDD)上运行基准测试返回了以下结果
test cache::tests::cache_get_10mb ... bench: 1,444,068 ns/iter (+/- 251,467)
test cache::tests::cache_get_1mb ... bench: 79,397 ns/iter (+/- 4,613)
test cache::tests::cache_get_1mb_from_1000_entry_cache ... bench: 79,038 ns/iter (+/- 1,751)
test cache::tests::cache_get_5mb ... bench: 724,262 ns/iter (+/- 7,751)
test cache::tests::cache_miss_10mb ... bench: 3,184,473 ns/iter (+/- 299,657)
test cache::tests::cache_miss_1mb ... bench: 806,821 ns/iter (+/- 19,731)
test cache::tests::cache_miss_1mb_from_1000_entry_cache ... bench: 1,379,925 ns/iter (+/- 25,118)
test cache::tests::cache_miss_5mb ... bench: 1,542,059 ns/iter (+/- 27,063)
test cache::tests::cache_miss_5mb_from_1000_entry_cache ... bench: 2,090,871 ns/iter (+/- 37,040)
test cache::tests::in_memory_file_read_10mb ... bench: 7,222,402 ns/iter (+/- 596,325)
test cache::tests::named_file_read_10mb ... bench: 4,908,544 ns/iter (+/- 581,408)
test cache::tests::named_file_read_1mb ... bench: 893,447 ns/iter (+/- 18,354)
test cache::tests::named_file_read_5mb ... bench: 1,605,741 ns/iter (+/- 41,418)
可以看出,在磁盘读取速度较慢的服务器上,小型文件的访问时间相对于磁盘有了大幅提高。大文件似乎也受益,尽管程度较小。可以设置最小和最大文件大小,以保持文件在缓存中的大小限制。
对于将检索缓存条目的查询,每个额外文件在缓存中都没有时间惩罚。缓存中的项目越多,缓存未命中时的时间惩罚就越大。
需求
- Rocket >= 0.3.6
- Nightly Rust
备注
如果您有任何功能请求,发现任何错误,或者文档中的任何内容不清楚,请打开一个Issue,我将尽快回复。
这个crate的开发已经放缓,但在达到1.0.0版本之前,您应该期待一些破坏性的变更。您可以通过变更日志来保持更新。
替代方案
- Nginx
- 自己编写。这里的大部分工作集中在何时替换缓存中的项目。如果您知道您将永远不会增长或缩小文件缓存,您只需要一个
Mutex<HashMap<PathBuf, Vec<u8>>>
,一个impl Responder<'static> for Vec<u8> {...}
,以及一些粘合逻辑来在内存中保存您的文件并将它们作为响应提供。 - 依赖设置缓存控制HTTP头部来导致文件在最终用户浏览器和它们与服务器之间的互联网基础设施中缓存。此策略可以与Rocket File Cache一起使用。
依赖项
~10MB
~216K SLoC