文件系统是咱们常见的存储模式,外部次要由数据和元数据两局部组成。其中数据是文件的具体内容,通常会间接展示给用户;而元数据是形容数据的数据,用来记录文件属性、目录构造、数据存储地位等。一般来说,元数据有十分显明的特点,即占用空间较小,但拜访十分频繁。
当今的分布式文件系统中,有的(如 S3FS)会将元数据和数据对立治理,以简化零碎设计,不过这样的弊病是某些元数据操作会让用户感触到显著的卡顿,如 ls
大目录,重命名大文件等。更多的文件系统会抉择将这两者离开治理,并依据元数据的特点进行针对性优化。JuiceFS 采纳的就是这种设计,其架构图如下:
其中, 元数据引擎须要是可能反对事务操作的数据库,而数据引擎个别是用对象存储 。目前为止,JuiceFS 曾经反对 10 种以上元数据引擎和 30 种以上数据引擎。
用户在应用 JuiceFS 时能够自在地抉择成熟组件来充当这两个引擎,以应答丰盛多变的企业环境和数据存储需要。然而对于新用户来说,当面对更多抉择时,也带来了一个问题:在我的场景中到底抉择哪一款数据库作为元数据引擎比拟适合?这篇文章将从产品设计角度,为大家介绍 JuiceFS 可应用的元数据引擎类型,以及他们的优劣势。
01-JuiceFS 元数据引擎类型
JuiceFS 当初反对的元数据引擎总共有有三大类。
第一个是 Redis。Redis 是 JuiceFS 开源后最早反对的元数据引擎。首先 Redis 速度够快,这是元数据引擎须要具备的重要能力之一;其次,Redis 受众面广,大部分用户对 Redis 都有实践经验。JuiceFS 对兼容 Redis 协定的数据库也都实现了反对,比方 KeyDB、Amazon MemoryDB 等。
然而,Redis 的可靠性和扩展性容易受限,在一些数据安全性要求较高或规模较大的场景中体现乏善可陈,因而咱们又开发反对了另外两类引擎。
第二个是 SQL 类 。如 MySQL、MariaDB、PostgreSQL 等,它们的特点是风行度较高,且通常具备不错的可靠性与扩展性。另外,还反对了嵌入式数据库 SQLite。
最初一个是 TKV(Transactional Key-Value Database)类 。它们的原生接口比较简单,因而在 JuiceFS 中的定制性更好,相较于 SQL 类个别也能有更高的性能。目前这一类反对的有 TiKV、etcd 和嵌入式的 BadgerDB 等,对 FoundationDB 的反对也在紧锣密鼓地开发中。
以上是依据 JuiceFS 在对接数据库时的协定接口进行的分类。每个大类外面有各种不同的数据库,每种数据库又有其本身的特点,以下依据这些特点对用户罕用的几个选项进行比拟。
元数据引擎比拟
Redis | MySQL/PostgreSQL | TiKV | etcd | SQLite/BadgerDB | |
---|---|---|---|---|---|
性能 | 高 | 低 | 中 | 低 | 中 |
扩展性 | 低 | 中 | 高 | 低 | 低 |
可靠性 | 低 | 高 | 高 | 高 | 中 |
可用性 | 中 | 高 | 高 | 高 | 低 |
风行度 | 高 | 高 | 中 | 高 | 中 |
如上文中提到的,Redis 的最大劣势是性能高,因为它是全内存的数据库。其余几方面它就体现平平。
从扩展性上说,通常单机 Redis 能够反对 1 亿文件左右,超过 1 亿时,Redis 单过程的内存使用量会比拟大,治理性能上也会有所降落。开源版 Redis 反对以集群模式来扩大其可治理的数据总量,但因为集群模式下 Redis 并不反对分布式事务,因而作为 JuiceFS 元数据引擎时,每个 JuiceFS volume 能用的 Redis 过程还是只有一个,单 volume 的扩展性相较于单机 Redis 并没有太大晋升。
从可靠性来看,Redis 默认每秒将数据刷盘,在异样时可能导致小局部数据失落。通过将配置 appendfsync 改为 always,能够让 Redis 在每个写申请后都刷盘,这样数据可靠性能进步,然而性能却会降落。
从可用性来说,部署 Redis 哨兵监控节点和备用节点,能够在主 Redis 节点挂掉后抉择一个备份节点来从新提供服务,肯定水平上进步可用性。然而,Redis 自身并不反对分布式的一致性协定,其备用节点采纳的是异步备份,所以尽管新的节点起来了,然而两头可能会有数据差,导致新起来的数据并不是那么的残缺。
MySQL 和 PostgreSQL 的整体体现比拟相似。它们都是通过大量用户多年工夫验证过的数据库产品,可靠性和可用性都不错,风行度也很高。只是相较于其余元数据引擎,它们的性能个别。
TiKV 本来是 PingCAP TiDB 的底层存储,当初曾经分离出来,成为一个独立的 KV 数据库组件。从咱们的测试后果来看,它用来作为 JuiceFS 的元数据引擎是一个十分杰出的抉择。其自身就有不弱于 MySQL 的数据可靠性和服务可用性,而且在性能与扩展性上体现更好。只是在风行度上,它和 MySQL 还有差距。从咱们与用户交换来看,如果他们曾经是 TiKV 或 TiDB 的用户,那最初通常都会偏差应用 TiKV 来做 JuiceFS 的元数据引擎。但如果他们之前对 TiKV 并不相熟,那要再承受这样一个新的组件就会谨慎许多。
etcd 是另一个 TKV 类的数据库。反对 etcd 的起因是因为它在容器化场景中风行度十分高,基本上 k8s 都是用 etcd 来治理它的配置。应用 etcd 作为 JuiceFS 的元数据引擎,并不是一个特地适配的场景。一方面是它的性能个别,另一方面是它有容量限度(默认 2G,最大 8G),之后就难以扩容。然而它的可靠性和可用性都十分高,而且容器化场景中也很容易部署, 因而如果用户只须要一个规模在百万文件级别的文件系统,etcd 仍然是一个不错的抉择 。
最初是 SQLite 和 BadgerDB,它们别离属于 SQL 类和 TKV 类,但应用起来体验却十分相似,因为它们都是单机版的嵌入式数据库。这类数据库的特点是性能中等,但扩展性和可用性都比拟差,因为其数据其实就寄存在本地零碎中。它们的劣势在于十分易用,只须要 JuiceFS 本人的二进制文件,不须要任何额定组件。用户在某些特定场景或者进行一些简略功能测试时,能够应用这两个数据库。
02- 典型引擎的性能测试后果
咱们做过一些典型引擎的性能测试,并将其后果记录在这个文档中。其中一份从源码接口处测试的最间接后果大抵为:Redis > TiKV(3 正本)> MySQL(本地)~= etcd(3 正本),具体如下:
Redis-Always | Redis-Everysec | TiKV | MySQL | etcd | |
---|---|---|---|---|---|
mkdir | 600 | 471 (0.8) | 1614 (2.7) | 2121 (3.5) | 2203 (3.7) |
mvdir | 878 | 756 (0.9) | 1854 (2.1) | 3372 (3.8) | 3000 (3.4) |
rmdir | 785 | 673 (0.9) | 2097 (2.7) | 3065 (3.9) | 3634 (4.6) |
readdir_10 | 302 | 303 (1.0) | 1232 (4.1) | 1011 (3.3) | 2171 (7.2) |
readdir_1k | 1668 | 1838 (1.1) | 6682 (4.0) | 16824 (10.1) | 17470 (10.5) |
mknod | 584 | 498 (0.9) | 1561 (2.7) | 2117 (3.6) | 2232 (3.8) |
create | 591 | 468 (0.8) | 1565 (2.6) | 2120 (3.6) | 2206 (3.7) |
rename | 860 | 736 (0.9) | 1799 (2.1) | 3391 (3.9) | 2941 (3.4) |
unlink | 709 | 580 (0.8) | 1881 (2.7) | 3052 (4.3) | 3080 (4.3) |
lookup | 99 | 97 (1.0) | 731 (7.4) | 423 (4.3) | 1286 (13.0) |
getattr | 91 | 89 (1.0) | 371 (4.1) | 343 (3.8) | 661 (7.3) |
setattr | 501 | 357 (0.7) | 1358 (2.7) | 1258 (2.5) | 1480 (3.0) |
access | 90 | 89 (1.0) | 370 (4.1) | 348 (3.9) | 646 (7.2) |
setxattr | 404 | 270 (0.7) | 1116 (2.8) | 1152 (2.9) | 757 (1.9) |
getxattr | 91 | 89 (1.0) | 365 (4.0) | 298 (3.3) | 655 (7.2) |
removexattr | 219 | 95 (0.4) | 1554 (7.1) | 882 (4.0) | 1461 (6.7) |
listxattr_1 | 88 | 88 (1.0) | 374 (4.2) | 312 (3.5) | 658 (7.5) |
listxattr_10 | 94 | 91 (1.0) | 390 (4.1) | 397 (4.2) | 694 (7.4) |
link | 605 | 461 (0.8) | 1627 (2.7) | 2436 (4.0) | 2237 (3.7) |
symlink | 602 | 465 (0.8) | 1633 (2.7) | 2394 (4.0) | 2244 (3.7) |
write | 613 | 371 (0.6) | 1905 (3.1) | 2565 (4.2) | 2350 (3.8) |
read_1 | 0 | 0 (0.0) | 0 (0.0) | 0 (0.0) | 0 (0.0) |
read_10 | 0 | 0 (0.0) | 0 (0.0) | 0 (0.0) | 0 (0.0) |
- 上表中记录的是每一个操作的耗时,数值越小越好;括号内数字是该指标比照 Redis-always 的倍数,数值也是越小越好
- Always 和 Everysec 是 Redis 配置项 appendfsync 的可选值,别离示意每个申请都刷盘和每秒刷一次盘
- 能够看到,Redis 在应用 everysec 的时候,性能更好,但与 always 相差的并不大;这是因为测试用的 AWS 机器上的本地 SSD 盘自身 IOPS 性能就比拟高
- TiKV 和 etcd 都应用了三正本,而 MySQL 是单机部署的。即便这样,TiKV 的性能体现还是高于 MySQL,而 etcd 与 MySQL 靠近。
值得一提的是,上文中的测试应用的都是默认配置,并没有对各个元数据引擎去做特定的调优。用户在应用时能够依据本人的需要和实践经验进行配置调整,可能会有不一样的后果 。
另一份测试是通过 JuiceFS 自带的 bench 工具跑的,其运行的是操作系统读写文件的接口,具体后果如下:
Redis-Always | Redis-Everysec | TiKV | MySQL | etcd | |
---|---|---|---|---|---|
Write big file | 565.07 MiB/s | 556.92 MiB/s | 553.58 MiB/s | 557.93 MiB/s | 542.93 MiB/s |
Read big file | 664.82 MiB/s | 652.18 MiB/s | 679.07 MiB/s | 673.55 MiB/s | 672.91 MiB/s |
Write small file | 102.30 files/s | 105.80 files/s | 95.00 files/s | 87.20 files/s | 95.75 files/s |
Read small file | 2200.30 files/s | 1894.45 files/s | 1394.90 files/s | 1360.85 files/s | 1017.30 files/s |
Stat file | 11607.40 files/s | 15032.90 files/s | 3283.20 files/s | 5470.05 files/s | 2827.80 files/s |
FUSE operation | 0.41 ms/op | 0.42 ms/op | 0.45 ms/op | 0.46 ms/op | 0.42 ms/op |
Update meta | 3.63 ms/op | 3.19 ms/op | 7.04 ms/op | 8.91 ms/op | 4.46 ms/op |
从上表能够看到, 读写大文件时应用不同的元数据引擎最初性能是差不多的 。这是因为此时性能瓶颈次要在对象存储的数据读写上,元数据引擎之间尽管时延有点差别,然而放到整个业务读写的耗费上,这点差别简直能够忽略不计。当然,如果对象存储变得十分快(比方都用本地全闪部署),那么元数据引擎的性能差别可能又会体现进去。另外,对于一些纯元数据操作(比方 ls,创立空文件等),不同元数据引擎的性能差异也会体现的比拟显著。
03- 引擎选型的思考因素
依据上文介绍的各引擎特点,用户能够依据本人的状况去抉择适合的引擎。以下简略分享下咱们在做举荐时会倡议用户思考的几个因素。
评估需要 :比方想应用 Redis,须要先评估是否承受大量的数据失落,短期的服务中断等。如果是存储一些长期数据或者两头数据的场景,那么用 Redis 的确是不错的抉择,因为它性可能好,即便有大量的数据失落,也不会造成很大的影响。但如果是要存储一些要害数据,Redis 就不实用了。另外还得评估预期数据的规模,如果在 1 亿文件左右,Redis 能够接受;如果预期会有 10 亿文件,那么显然单机 Redis 是难以承载的。
评估硬件 :比方是否连通外网,是应用托管的云服务,还是在本人机房内公有部署。如果是公有部署,须要评估是否有足够的硬件资源去部署一些相干的组件。无论是用哪一种元数据引擎,基本上都要求有高速的 SSD 盘去运行,不然会对其性能有比拟大的影响。
评估运维能力,这是很多人会漠视的,然而在咱们来看这应该是最要害的因素之一 。对于存储系统来说,稳定性往往才是其上生产后的第一重点。用户在抉择元数据引擎的时候,应该先想想本人对它是不是相熟,在呈现问题时,是否疾速定位解决;团队内是否有足够的教训或精力去把控好这个组件。通常来说,咱们会倡议用户在开始时抉择一个本人相熟的数据库是比拟适合的。如果运维人员不足,那么抉择 JuiceFS 私有云服务也的确是个省心的选项。
最初,分享下社区在应用元数据引擎方面的一些统计数据。
- 目前为止,Redis 的使用者仍然占了一半以上 ,其次是 TiKV 和 MySQL,这两类的使用者的数量占比在逐渐增长。
- 在运行的 Redis 集群的最大文件数大略是在 1.5 亿 ,而且运行状况是比较稳定的,上文提到的举荐的 1 亿文件是倡议值,并不是说无奈超过 1 亿。
- 整体数量规模 Top3,都是应用的 TiKV 而且都超过了 10 亿文件数量 。当初最大的文件系统的文件数量是超了 70 亿文件,总容量超过了 15 PiB,这也从侧面证实了 TiKV 在作为元数据引擎时的扩大能力。咱们本人外部测过应用 TiKV 作为元数据引擎存储 100 亿文件,零碎仍能稳固地运行。所以如果你的整个集群预期的规模会十分大,那么 TiKV 的确是一个很好的抉择。
04- 元数引擎迁徙
文章的最初,为大家介绍元数据引擎迁徙。随着用户业务的倒退,企业对元数据引擎的需要会发生变化,当用户发现现有的元数据引擎不适合了,能够思考将元数据迁徙到另一个引擎中。咱们为用户提供了残缺的迁徙办法,具体能够参考这个文档。
这个迁徙办法有肯定的限度,首先只能迁徙到空数据库,临时无奈将两个文件系统间接合在一起;其次,须要停写,因为数据量会比拟大的状况下,很难在线将元数据残缺的迁徙过去。要做到这点须要加许多限度,从实测来看速度会十分慢。因而,把整个文件系统停掉再去做迁徙是最稳当的。如果说切实须要有肯定的服务提供,能够保留只读挂载,用户读数据并不会影响整个元数据引擎迁徙的动作。
尽管社区提供了全套的迁徙办法,然而还是须要揭示用户,尽量提前对数据量的增长做好布局,尽量不做迁徙或尽早迁徙。当要迁徙的数据规模很大时,耗时也会变长,期间出问题的概率也会变大。
如有帮忙的话欢送关注咱们我的项目 Juicedata/JuiceFS 哟!(0ᴗ0✿)