etcd 是另一个 TKV 类的数据库 。支持 etcd 的原因是因为它在容器化场景中流行度非常高,基本上 k8s 都是用 etcd 来管理它的配置 。使用 etcd 作为 JuiceFS 的元数据引擎 , 并不是一个特别适配的场景 。一方面是它的性能一般,另一方面是它有容量限制(默认 2G,最大 8G),之后就难以扩容 。但是它的可靠性和可用性都非常高,而且容器化场景中也很容易部署,因此如果用户只需要一个规模在百万文件级别的文件系统 , etcd 依然是一个不错的选择 。
最后是 SQLite 和 BadgerDB , 它们分别属于 SQL 类和 TKV 类,但使用起来体验却非常类似 , 因为它们都是单机版的嵌入式数据库 。这类数据库的特点是性能中等,但扩展性和可用性都比较差,因为其数据其实就存放在本地系统中 。它们的优势在于非常易用,只需要 JuiceFS 自己的二进制文件,不需要任何额外组件 。用户在某些特定场景或者进行一些简单功能测试时,可以使用这两个数据库 。
02- 典型引擎的性能测试结果我们做过一些典型引擎的性能测试,并将其结果记录在这个文档中 。其中一份从源码接口处测试的最直接结果大致为:Redis > TiKV(3 副本)> MySQL(本地)~= etcd(3 副本),具体如下:
Redis-AlwaysRedis-EverysecTiKVMySQLetcdmkdir600471 (0.8)1614 (2.7)2121 (3.5)2203 (3.7)mvdir878756 (0.9)1854 (2.1)3372 (3.8)3000 (3.4)rmdir785673 (0.9)2097 (2.7)3065 (3.9)3634 (4.6)readdir_10302303 (1.0)1232 (4.1)1011 (3.3)2171 (7.2)readdir_1k16681838 (1.1)6682 (4.0)16824 (10.1)17470 (10.5)mknod584498 (0.9)1561 (2.7)2117 (3.6)2232 (3.8)create591468 (0.8)1565 (2.6)2120 (3.6)2206 (3.7)rename860736 (0.9)1799 (2.1)3391 (3.9)2941 (3.4)unlink709580 (0.8)1881 (2.7)3052 (4.3)3080 (4.3)lookup9997 (1.0)731 (7.4)423 (4.3)1286 (13.0)getattr9189 (1.0)371 (4.1)343 (3.8)661 (7.3)setattr501357 (0.7)1358 (2.7)1258 (2.5)1480 (3.0)access9089 (1.0)370 (4.1)348 (3.9)646 (7.2)setxattr404270 (0.7)1116 (2.8)1152 (2.9)757 (1.9)getxattr9189 (1.0)365 (4.0)298 (3.3)655 (7.2)removexattr21995 (0.4)1554 (7.1)882 (4.0)1461 (6.7)listxattr_18888 (1.0)374 (4.2)312 (3.5)658 (7.5)listxattr_109491 (1.0)390 (4.1)397 (4.2)694 (7.4)link605461 (0.8)1627 (2.7)2436 (4.0)2237 (3.7)symlink602465 (0.8)1633 (2.7)2394 (4.0)2244 (3.7)write613371 (0.6)1905 (3.1)2565 (4.2)2350 (3.8)read_100 (0.0)0 (0.0)0 (0.0)0 (0.0)read_1000 (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-AlwaysRedis-EverysecTiKVMySQLetcdWrite big file565.07 MiB/s556.92 MiB/s553.58 MiB/s557.93 MiB/s542.93 MiB/sRead big file664.82 MiB/s652.18 MiB/s679.07 MiB/s673.55 MiB/s672.91 MiB/sWrite small file102.30 files/s105.80 files/s95.00 files/s87.20 files/s95.75 files/sRead small file2200.30 files/s1894.45 files/s1394.90 files/s1360.85 files/s1017.30 files/sStat file11607.40 files/s15032.90 files/s3283.20 files/s5470.05 files/s2827.80 files/sFUSE operation0.41 ms/op0.42 ms/op0.45 ms/op0.46 ms/op0.42 ms/opUpdate meta3.63 ms/op3.19 ms/op7.04 ms/op8.91 ms/op4.46 ms/op从上表可以看到,读写大文件时使用不同的元数据引擎最后性能是差不多的 。这是因为此时性能瓶颈主要在对象存储的数据读写上,元数据引擎之间虽然时延有点差异,但是放到整个业务读写的消耗上,这点差异几乎可以忽略不计 。当然,如果对象存储变得非常快(比如都用本地全闪部署),那么元数据引擎的性能差异可能又会体现出来 。另外,对于一些纯元数据操作(比如 ls , 创建空文件等),不同元数据引擎的性能差别也会表现的比较明显 。
03-引擎选型的考虑要素根据上文介绍的各引擎特点,用户可以根据自己的情况去选择合适的引擎 。以下简单分享下我们在做推荐时会建议用户考虑的几个要素 。
评估需求:比如想使用 Redis , 需要先评估能否接受少量的数据丢失,短期的服务中断等 。如果是存储一些临时数据或者中间数据的场景,那么用 Redis 确实是不错的选择,因为它性能够好,即使有少量的数据丢失 , 也不会造成很大的影响 。但如果是要存储一些关键数据,Redis 就不适用了 。另外还得评估预期数据的规模 , 如果在 1 亿文件左右,Redis 可以承受;如果预期会有 10 亿文件,那么显然单机 Redis 是难以承载的 。
推荐阅读
- 原神元能尖碑都在哪些地方
- Docker | 容器数据卷详解
- 如何优雅的备份MySQL数据?看这篇文章就够了
- 普通双非学子上岸浙大工程师数据科学项目 计算机保研,maybe this is all you need
- 大数据技术之HBase原理与实战归纳分享-上
- 07 ClickHouseClickHouse数据库引擎解析
- 使用EF Core更新与修改生产数据库
- Jupyter,Matplotlib,Pandas 【机器学习】利用 Python 进行数据分析的环境配置 Windows
- TDengine的数据建模?库、表、超级表是什么?怎么用?
- 利用Pandas处理数据 缺失值的处理 数据库的使用 python-数据描述与分析2