JuiceFS你应该知道的一些事

这篇文章主要内容来自A distributed Posix file system built on top of Redis and S3 (github.com/juicedata)。我看完后觉得讨论中不少问答很精彩,很棒,所以摘出来,加上我自己的理解,然后从

  1. 诞生背景
  2. 安全性
  3. POSIX兼容性
  4. 可用性/稳定性
  5. 云原生支持
  6. 成本
  7. 性能

等七个方面进行探讨,以帮助大家更好的去理解JuiceFS,以及他解决的技术问题。

JuiceFS的意义

在存储和计算分离的大趋势下,一个比较明显的例子是,越来越多的云端对象存储涌现,同时也有大量私有的HDFS集群会一直存在下去。新的模式往往会带来新的挑战,而这些挑战往往可能需要引入一个中间层来解决,JuiceFS其实就是在这种背景下诞生的。

我个人认为,JuiceFS更多的是面向于大数据领域的应用,尽管因为它通过FUSE提供了本机挂载并且具有非常好的POSIX接口兼容性也能用被用于别的用途。

使用JuiceFS可以让你获得如下收益:

  1. 应用层不用自己去适配各种对象存储亦或是HDFS,只需要面向JuiceFS即可
  2. JuiceFS可以有效的提高对象存储的读取性能
  3. 提升对象存储元数据操作的性能(0.x毫秒级别),无论读写。
  4. 解决对象存储原子性问题,以及只是实现最终一致性问题而带来的问题(尽管AWS已经宣称解决了)
  5. 解决了众多已有库可以不加修改的使用对象存储。典型的比如AI应用中的众多Python库,类似模型保存等等。
  6. 降低对象存储成本,减少多种对象存储付费API的使用,减少GET请求数带来的费用。

在文章的性能部分,我们可以看到即使是没有命中缓存,也可以接近HDD的响应延迟。同时,这也为计算引擎的提速提供了更好的切面,未来可能包括自动Prefetch(cache)所有Parquet Footer等。

而元数据如果还能加上Client端缓存,则可获得更大的提升。

尽管JuiceFS拥有很多的优点,而且很努力的去逼近本地存储的性能,但网络延迟,IOPS以及对象存储自身的限制,在写方面,依然和本地存储(SSD)有接近百倍的性能差距,这对于很多OLTP数据库是有比较大的影响的,但对读的优化,使得其对于OLAP等以读多的引擎则帮助巨大。

安全性

JuiceFS使用Redis做文件元信息存储,实际数据则是存储在背后的对象存储里,而对象存储的安全是由云厂商或者内部自己保证的。尽管如此,文件元信息依然也需要得到足够的安全保证。因为JuiceFS目前支持Redis,那么我们可以利用Redis自身安全特性来保证安全。

  1. 使用rediss://host:port/ 去开启TLS加密。
  2. 关闭所有non-TLS 端口,启动时添加参数:-port 0 -tls-port 6379

未来如果适配更多元数据存储引擎,那么可以使用对应的引擎的安全特性。

POSIX 兼容性

在软件开发领域,我们可能难以100%完全兼容,总有你没有测试到的场景没有得到兼容。那么JuiceFS 对POSIX的兼容性到底如何呢?JuiceFS选择使用第三方的测试集来测试兼容性,比如JuiceFS通过了pjdfstest最新的8813个测试。

值得一提的,JuiceFS还支持常见的操作如mmap等。具体列表如下:

  1. 关闭再打开数据一致性。一旦一个文件写入完成并关闭,之后的打开和读操作就可以访问之前写入的数据。如果是在同一个挂载点,所有写入的数据都可以立即读。
  2. 重命名以及所有其他元数据操作都是原子的,由 Redis 的事务机制保证。
  3. 当文件被删除后,同一个挂载点上如果已经打开了,文件还可以继续访问。
  4. 支持 mmap
  5. 支持 fallocate 以及空洞
  6. 支持扩展属性
  7. 支持 BSD 锁(flock)
  8. 支持 POSIX 记录锁(fcntl)

可用性和稳定性

因为使用了Redis事务,所以目前来说Reids只能单实例,那我们该如何面对比如断电,系统异常导致的可能的数据loss或者损害?如何实现高可用呢?

下面一些点值得参考:

  1. Redis可以使用RDB/AOF持久化数据
  2. 如果你使用了托管的Redis服务,那么服务商会保证稳定性
  3. Redis最新特性redis raft 也值得期待
  4. 未来可能会使用其他元数据存储引擎,他们可能会带来更好的可用性和稳定性

另外,通用的NFS,网络稳定可能严重影响系统的稳定性,比如网络的不稳定可能导致一些操作执行缓慢亦或是被hang住,但是我们可能无法中断或者结束这个操作。JuiceFS针对这个难题,尽可能保证大部分操作都是可以中断的,然而依然有例外,譬如close方法是无法中断的,尽管如此,我们可以终止FUSE的连接亦或是杀死JuiceFS的进程,这样就会取消相关的操作。总体而言,因为构建基于FUSE,所以我们可以更好的控制他。

云原生支持

JuiceFS使用Go开发,轻量易于使用。 Kubernetes CSI Driver也正在路上,你可以用更加K8s的方法通过JuiceFS挂载对象存储.

成本

使用JuiceFS的成本由四部分组成:

  1. 引入后对已有应用的侵入性有多大,这意味着改造适配成本。
  2. Redis存储成本,无论使用托管还是自建
  3. 数据存储会不会有额外的数据膨胀亦或是压缩,有没有自动清理功能,从而增加或是节省了对象存储的成本
  4. 有没有使用对象存储的付费API 譬如s3的list目录等

针对第一个问题,对于原先就使用HDFS亦或是单机本地文件系统的,对应用基本没有迁移成本。

对于类似ES/ClickHouse之类集群类应用,他们自己管理shard以及裸磁盘,则有一定的修改成本。譬如ES通常每个实例配置的数据目录都是一致的,如果使用对象存储后可能会导致覆盖写,另外还有就是故障恢复,冗余度等问题值得关注。

第二个问题,Redis存储成本也很容易衡量,通常3GB内存可以存储稳定数量1000万Inode节点。

第三个问题,JuiceFS只是把对象存储当成一个chunk存储器,按4M大小的Block写入。读取文件的时候,会根据元信息去取多个chunk,从而完成文件的还原。这点非常类似HDFS的block管理。另外对于chunk的存储会使用LZ4压缩,所以应该可以获得不错的空间节省效果。

第四个问题,可以减少使用对象存储的付费API,因为文件元信息已经都自己管理了,而数据缓存的存在,则可以减少GET调用量。

性能

JuiceFS对读有较大的优化,对写则和原生的对对象存储写差距不会太大,尽管我们可能可以牺牲一些特性然后使用譬如异步写,批量写去提升写性能(本地文件系统也是利用相同的技术,譬如只有close,fsync才会刷盘)。相比原生的本地文件系统(SSD磁盘),写操作则依然有近乎百倍差距,这主要是因为fsync会比原生的SSD慢很多(20ms vs 100us)。而对于读,平均可以接近HDD磁盘的效率,如果命中cache(我们假设你使用SSD盘做缓存),那么基本可以接近本地存储的速度(SSD)。

还有一些数据值得参考,在同一个Rack,文件元信息操作(和Redis通讯,比如罗列一个目录等),latency可以控制0.2ms - 0.5ms。未来如果使用client cache,可以进一步降低。

读取性能,在没有命中cache的情况下,获取AWS的第一个byte,延迟大概是20-30ms,这几乎等价于HDD磁盘的性能,而对象存储可以获取更好的吞吐,当然,你依然可以对此数据表示疑惑,譬如有人认为HDD的平均延迟是2-3ms,而AWS 20-30ms的延迟其实是中位数,这意味着会出现更长的延迟。实际上,通过缓存以及预读,我们是完全鞥能够获得接近本地的磁盘性能的。

总结

云厂商是目前是推进存储和分离的主要动力,大数据领域领域则是最积极的响应者,尽管现在也有非常多的人在努力在OLTP领域尝试存储和分离,比如AWS的Aurora等。JuiceFS就是存储和计算分离而催生出来的技术,如果你还在为使用对象存储而面临性能低下,跨云存储兼容等问题而苦恼时,不妨回过头来看看这个项目。

results matching ""

    No results matching ""