ファイル システムは、主にデータとメタデータの 2 つの部分で構成される一般的なストレージ形式です。その中で、データは通常ユーザーに直接表示されるファイルの特定のコンテンツであり、メタデータはデータを記述するデータであり、ファイルの属性、ディレクトリ構造、データの保存場所などを記録するために使用されます。一般に、メタデータには非常に特徴的な特性があります。つまり、占有するスペースは少ないですが、非常に頻繁にアクセスされます。
今日の分散ファイル システムでは、メタデータとデータを統一された方法で管理してシステム設計を簡素化するls
もの等 より多くのファイル システムが、2 つを別々に管理し、メタデータの特性に従って的を絞った最適化を実行することを選択します。JuiceFS はこの設計を採用しており、そのアーキテクチャ図は次のとおりです。
その中で、メタデータ エンジンはトランザクション操作をサポートできるデータベースである必要があり、データ エンジンは一般的にオブジェクト ストレージを使用します。これまでのところ、JuiceFS は 10 を超えるメタデータ エンジンと 30 を超えるデータ エンジンをサポートしています。
JuiceFS を使用する場合、ユーザーはこれら 2 つのエンジンとして機能する成熟したコンポーネントを自由に選択して、豊富で変化しやすいエンタープライズ環境とデータ ストレージ要件に対処できます。ただし、新しいユーザーにとって、より多くの選択肢に直面すると、次のような疑問も生じます。このシナリオでメタデータ エンジンとして選択するのに適しているデータベースはどれでしょうか? この記事では、JuiceFS で使用できるメタデータ エンジンの種類と、製品設計の観点からの長所と短所を紹介します。
01-JuiceFS メタデータ エンジンの種類
JuiceFS で現在サポートされているメタデータ エンジンには 3 つのカテゴリがあります。
1 つ目は Redis です。Redis は、オープン ソース化された後、JuiceFS でサポートされる最も初期のメタデータ エンジンです。まず第一に、Redis は十分に高速であり、これはメタデータ エンジンに必要な重要な機能の 1 つです; 第二に、Redis には幅広いユーザーがいて、ほとんどのユーザーは Redis の実際の使用経験があります。JuiceFS は、Redis プロトコルと互換性のあるデータベース (KeyDB や Amazon MemoryDB など) もサポートしています。
ただし、Redis の信頼性とスケーラビリティは簡単に制限され、高いデータ セキュリティ要件や大規模なシナリオではパフォーマンスが低下するため、別の 2 種類のエンジンを開発してサポートしました。
2 つ目は SQL クラスです。MySQL、MariaDB、PostgreSQL など、人気が高いのが特徴で、通常は信頼性とスケーラビリティに優れています。さらに、組み込みデータベース SQLite もサポートされています。
最後は TKV (Transactional Key-Value Database) クラスです。それらのネイティブ インターフェイスは比較的単純であるため、JuiceFS でよりカスタマイズしやすく、一般的に SQL クラスよりもパフォーマンスが高くなります。現在、このタイプのサポートには、TiKV、etcd、組み込み BadgerDB などが含まれます。FoundationDB のサポートも集中的に開発中です。
上記はJuiceFSのデータベース接続時のプロトコルインターフェースによる分類です。各カテゴリにはさまざまなデータベースがあり、それぞれのデータベースには独自の特徴があります. 以下では、これらの特徴に基づいて、ユーザーが一般的に使用するいくつかのオプションを比較します.
メタデータ エンジンの比較
レディス | MySQL/PostgreSQL | TiKV | etcd | SQLite/BadgerDB | |
---|---|---|---|---|---|
パフォーマンス | 高い | 低い | 真ん中 | 低い | 真ん中 |
スケーラビリティ | 低い | 真ん中 | 高い | 低い | 低い |
信頼性 | 低い | 高い | 高い | 高い | 真ん中 |
可用性 | 真ん中 | 高い | 高い | 高い | 低い |
人気 | 高い | 高い | 真ん中 | 高い | 真ん中 |
前述のように、Redis の最大の利点は、フルメモリ データベースであるため、パフォーマンスが高いことです。他の点では平凡です。
スケーラビリティの観点から、通常、1 つの Redis でサポートできるファイル数は 1 億程度ですが、1 億を超えると、1 つの Redis プロセスのメモリ使用量が相対的に大きくなり、管理パフォーマンスも低下します。Redis のオープン ソース バージョンは、管理できるデータの総量を拡張するためにクラスター モードをサポートしています. ただし、Redis は JuiceFS メタデータ エンジンとしてクラスター モードでの分散トランザクションをサポートしていないため、JuiceFS ごとに使用できる Redis プロセスは 1 つだけです。 volume. 、単一ボリュームのスケーラビリティは、単一の Redis と比較してあまり改善されていません。
信頼性の観点から、Redis はデフォルトで毎秒データをフラッシュします。これにより、例外が発生した場合に少量のデータが失われる可能性があります。appendfsync の設定を always に変更すると、各書き込み要求の後に Redis をフラッシュできるため、データの信頼性パフォーマンスは向上しますが、パフォーマンスは低下します。
可用性の面では、Redis Sentinel 監視ノードとスタンバイ ノードをデプロイすると、メインの Redis ノードがハングアップした後、バックアップ ノードを選択してサービスを再度提供できるため、可用性がある程度向上します。ただし、Redis 自体は分散コンセンサス プロトコルをサポートしておらず、そのバックアップ ノードは非同期バックアップを使用しているため、新しいノードが起動しても途中でデータ ギャップが発生し、データが不完全になる可能性があります。
MySQL と PostgreSQL の全体的なパフォーマンスは似ています。いずれも長年にわたり多くのユーザーに検証され、信頼性と可用性が高く、人気の高いデータベース製品です。他のメタデータ エンジンと比較してパフォーマンスが平均的であるというだけです。
TiKV はもともと PingCAP TiDB の基盤となるストレージでしたが、現在は分離され、独立した KV データベース コンポーネントになっています。私たちのテスト結果から、これは JuiceFS メタデータ エンジンの優れた選択肢です。データの信頼性とサービスの可用性は MySQL に劣らず、パフォーマンスとスケーラビリティの面で優れています。人気の点でのみ、MySQL との間にはまだギャップがあります。ユーザーとのやり取りによると、ユーザーがすでに TiKV または TiDB ユーザーである場合、通常、最終的に JuiceFS のメタデータ エンジンとして TiKV を使用することを好みます。しかし、以前に TiKV に慣れていない場合は、そのような新しいコンポーネントを受け入れることにはるかに慎重になるでしょう。
etcd は、もう 1 つの TKV に似たデータベースです。etcd をサポートする理由は、コンテナー化のシナリオで非常に一般的であるためです. 基本的に、k8s は etcd を使用してその構成を管理します。JuiceFS のメタデータ エンジンとして etcd を使用することは、特に適切なシナリオではありません。一方ではそのパフォーマンスは平均的であり、他方では容量制限があり (デフォルト 2G、最大 8G)、後で拡張することは困難です。ただし、その信頼性と可用性は非常に高く、コンテナー化されたシナリオで簡単に展開できるため、ユーザーが 100 万ファイル規模のファイル システムしか必要としない場合でも、etcd は適切な選択です.
最後に、それぞれ SQL クラスと TKV クラスに属する SQLite と BadgerDB がありますが、これらはすべてスタンドアロンの組み込みデータベースであるため、使用感は非常に似ています。このタイプのデータベースは、中程度のパフォーマンスを特徴としていますが、そのデータは実際にはローカル システムに格納されているため、スケーラビリティと可用性が低くなります。JuiceFS 独自のバイナリのみを必要とし、追加のコンポーネントを必要とせず、非常に使いやすいという利点があります。ユーザーは、これら 2 つのデータベースを特定の特定のシナリオで、または単純な機能テストを実行するときに使用できます。
02- 一般的なエンジンの性能試験結果
いくつかの典型的なエンジン パフォーマンス テストを実施し、その結果をこのドキュメントに記録しました。ソース インターフェイス テストからの最も直接的な結果の 1 つは、おおまかに次のように、 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) |
mvです | 878 | 756 (0.9) | 1854 (2.1) | 3372 (3.8) | 3000 (3.4) |
RMです | 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) |
作成 | 591 | 468 (0.8) | 1565 (2.6) | 2120 (3.6) | 2206 (3.7) |
名前を変更 | 860 | 736 (0.9) | 1799 (2.1) | 3391 (3.9) | 2941 (3.4) |
リンクを解除 | 709 | 580 (0.8) | 1881 (2.7) | 3052 (4.3) | 3080 (4.3) |
見上げる | 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) |
アクセス | 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) |
リンク | 605 | 461 (0.8) | 1627 (2.7) | 2436 (4.0) | 2237 (3.7) |
シンボリックリンク | 602 | 465 (0.8) | 1633 (2.7) | 2394 (4.0) | 2244 (3.7) |
書く | 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 のオプションの値で、それぞれ各リクエストがフラッシュされ、毎秒フラッシュされることを示します
- テストに使用した AWS マシンのローカル SSD ディスク自体の IOPS パフォーマンスが比較的高いため、Redis は everysec を使用した場合の方がパフォーマンスは優れていますが、常にとあまり変わらないことがわかります。
- TiKV と etcd はどちらも 3 つのコピーを使用しますが、MySQL は単一のマシンにデプロイされます。それでも、TiKV のパフォーマンスは MySQL よりも高く、etcd は MySQL に近いです。
上記のすべてのテストでデフォルト構成が使用されており、各メタデータ エンジンに対して特定の調整が行われていないことに注意してください。ユーザーは、自分のニーズと使用時の実際の経験に応じて構成および調整でき、結果が異なる場合があります。
別のテストは、オペレーティング システムのインターフェイスを実行してファイルの読み取りと書き込みを行う JuiceFS に付属のベンチ ツールを使用して実行されました。具体的な結果は次のとおりです。
Redis-Always | Redis-Everysec | TiKV | MySQL | etcd | |
---|---|---|---|---|---|
大きなファイルを書き込む | 565.07 MiB/秒 | 556.92 MiB/秒 | 553.58 MiB/秒 | 557.93 MiB/秒 | 542.93 MiB/秒 |
大きなファイルを読む | 664.82 MiB/秒 | 652.18 MiB/秒 | 679.07 MiB/秒 | 673.55 MiB/秒 | 672.91 MiB/秒 |
小さなファイルを書き込む | 102.30 ファイル/秒 | 105.80 ファイル/秒 | 95.00 ファイル/秒 | 87.20 ファイル/秒 | 95.75 ファイル/秒 |
小さなファイルを読む | 2200.30 ファイル/秒 | 1894.45 ファイル/秒 | 1394.90 ファイル/秒 | 1360.85 ファイル/秒 | 1017.30 ファイル/秒 |
統計ファイル | 11607.40 ファイル/秒 | 15032.90 ファイル/秒 | 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✿)