如何设置元数据引擎
META_PASSWORD
是 JuiceFS v1.0 新增功能,旧版客户端需要升级后才能使用。
JuiceFS 采用数据和元数据分离的存储架构,元数据可以存储在任意支持的数据库中,称为「元数据存储引擎」。JuiceFS 支持众多元数据存储引擎,各个数据库 性能、易用性、场景均有区别,具体性能对比可参考该文档。
元数据存储用量
元数据所需的存储空间跟文件名的长度、文件的类型和长度以及扩展属性等相关,无法准确地估计一个文件系统的元数据存空间需求。简单起见,我们可以根据没有扩展属性的单个小文件所需的存储空间来做近似:
- 键值(Key-Value)数据库(如 Redis、TiKV):300 字节/文件
- 关系型数据库(如 SQLite、MySQL、PostgreSQL):600 字节/文件
当平均文件更大(超过 64MB),或者文件被频繁修改导致有很多碎片,或者有很多扩展属性,或者平均文件名很长(超过 50 字节),都会导致需要更多的存储空间。
当你需要在两种类型的元数据引擎之间迁移时,就可以据此来估算所需的存储空间。例如,假设你希望将元数据引擎从一个关系型数据库(MySQL)迁移到键值数据库(Redis),如果当前 MySQL 的用量为 30GB,那么目标 Redis 至少需要准备 15GB 以上的内存。反之亦然。
Redis
JuiceFS 要求使用 4.0 及以上版本的 Redis。JuiceFS 也支持使用 Redis Cluster 作为元数据引擎,但为了避免在 Redis 集群中执行跨节点事务,同一个文件系统的元数据总会坐落于单个 Redis 实例中。
为了保证元数据安全,JuiceFS 需要 maxmemory-policy noeviction
,否则在启动 JuiceFS 的时候将会尝试将其设置为 noeviction
,如果设置失败将会打印告警日志。更多可以参考 Redis 最佳实践。
创建文件系统
使用 Redis 作为元数据存储引擎时,通常使用以下格式访问数据库:
- TCP
- Unix socket
redis[s]://[<username>:<password>@]<host>[:<port>]/<db>
unix://[<username>:<password>@]<socket-file-path>?db=<db>
其中,[]
括起来的是可选项,其它部分为必选项。
- 如果开启了 Redis 的 TLS 特性,协议头需要使用
rediss://
,否则使用redis://
。 <username>
是 Redis 6.0 之后引入的,如果没有用户名可以忽略,但密码前面的:
冒号需要保留,如redis://:<password>@<host>:6379/1
。- Redis 监听的默认端口号为
6379
,如果没有改变默认端口号可以不用填写,如redis://:<password>@<host>/1
,否则需要显式指定端口号。 - Redis 支持多个逻辑数据库,请将
<db>
替换为实际使用的数据库编号。 - 如果需要连接 Redis 哨兵(Sentinel),元数据 URL 的格式会稍有不同,具体请参考「Redis 最佳实践」。
- 如果 Redis 的用户名或者密码中包含特殊字符,需要使用单引号进行封闭,避免 shell 进行解释。或者使用环境变量
REDIS_PASSWORD
进行传递。
一个 Redis 实例默认可以创建 16 个逻辑数据库,而一个逻辑数据库可以创建一个 JuiceFS 文件系统。也就是说,在默认情况下,你可以使用一个 Redis 实例创建 16 个 JuiceFS 文件系统。需要注意,用于 JuiceFS 的逻辑数据库不要和其他应用共享,否则可能会造成数据混乱。
例如,创建名为 pics
的文件系统,使用 Redis 的 1
号数据库存储元数据:
juicefs format \
--storage s3 \
... \
"redis://:mypassword@192.168.1.6:6379/1" \
pics
安全起见,建议使用环境变量 META_PASSWORD
或 REDIS_PASSWORD
传递数据库密码,例如:
export META_PASSWORD=mypassword
然后就无需在元数据 URL 中设置密码了:
juicefs format \
--storage s3 \
... \
"redis://192.168.1.6:6379/1" \
pics
挂载文件系统
如果需要在多台服务器上共享同一个文件系统,必须确保每台服务器都能访问到存储元数据的数据库。
juicefs mount -d "redis://:mypassword@192.168.1.6:6379/1" /mnt/jfs
挂载文件系统也支持用 META_PASSWORD
或 REDIS_PASSWORD
环境变量传递密码:
export META_PASSWORD=mypassword
juicefs mount -d "redis://192.168.1.6:6379/1" /mnt/jfs
设置 TLS
JuiceFS 同时支持 Redis 的 TLS 单向加密认证和 mTLS 双向加密认证连接。通过 TLS 或 mTLS 连接到 Redis 时均使用 rediss://
协议头,但是在使用 TLS 单向加密认证时,不需要指定客户端证书和私钥。
对 Redis mTLS 功能的支持需要使用 1.1.0 及以上版本的 JuiceFS
当通过 mTLS 连接 Redis 时,需要提供客户端证书和私钥,以及签发客户端证书的 CA 证书进行连接。在 JuiceFS 中,可以通过以下方式设置 mTLS 需要的客户端证书:
juicefs format --storage s3 \
... \
"rediss://192.168.1.6:6379/1?tls-cert-file=/etc/certs/client.crt&tls-key-file=/etc/certs/client.key&tls-ca-cert-file=/etc/certs/ca.crt"
pics
上面的示例代码使用 rediss://
协议头来开启 mTLS 功能,然后使用以下选项来指定客户端证书的路径:
tls-cert-file=<path>
指定客户端证书的路径tls-key-file=<path>
指定客户端密钥的路径tls-ca-cert-file=<path>
指定签发客户端证书的 CA 证书路径,它是可选的,如果不指定,客户端会使用系统默认的 CA 证书进行验证。insecure-skip-verify=true
可以用来跳过对服务端证书的验证
在 URL 指定选项时,以 ?
符号开头,使用 &
符号来分隔多个选项,例如:?tls-cert-file=client.crt&tls-key-file=client.key
。
上例中的 /etc/certs
只是一个目录,实际使用时请替换为你的证书目录,可以使用相对路径或绝对路径。
KeyDB
KeyDB 是 Redis 的开源分支,在开发上保持与 Redis 主线对齐。KeyDB 在 Redis 的基础上实现了多线程支持、更好的内存利用率和更大的吞吐量,另外还支持 Active Replication,即 Active Active(双活)功能。
KeyDB 的数据复制是异步的,使用 Active Active(双活)功能可能导致数据一致性问题,请务必充分验证、谨慎使用!
在用于 JuiceFS 元数据存储时,KeyDB 与 Redis 的用法完全一致,这里不再赘述,请参考 Redis 部分使用。
PostgreSQL
PostgreSQL 是功能强大的开源关系型数据库,有完善的生态和丰富的应用场景,也可以用来作为 JuiceFS 的元数据引擎。
许多云计算平台都提供托管的 PostgreSQL 数据库服务,也可以按照使用向导自己部署一个。
其他跟 PostgreSQL 协议兼容的数据库(比如 CockroachDB 等) 也可以这样使用。
创建文件系统
使用 PostgreSQL 作为元数据引擎时,需要提前手动创建数据库,使用如下的格式来指定参数:
- TCP
- Unix socket
postgres://[username][:<password>]@<host>[:5432]/<database-name>[?parameters]
postgres://[username][:<password>]@/<database-name>?host=<socket-directories-path>[¶meters]
其中,[]
括起来的是可选项,其它部分为必选项。
例如:
juicefs format \
--storage s3 \
... \
"postgres://user:mypassword@192.168.1.6:5432/juicefs" \
pics
更安全的做法是可以通过环境变量 META_PASSWORD
传递数据库密码:
export META_PASSWORD="mypassword"
juicefs format \
--storage s3 \
... \
"postgres://user@192.168.1.6:5432/juicefs" \
pics
- JuiceFS 默认使用的 public schema ,如果要使用非
public schema
,需要在连接字符串中指定search_path
参数,例如postgres://user:mypassword@192.168.1.6:5432/juicefs?search_path=pguser1
- 如果
public schema
并非是 PostgreSQL 服务端配置的search_path
中第一个命中的,则必须在连接字符串中明确设置search_path
参数 search_path
连接参数原生可以设置为多个 schema,但是目前 JuiceFS 仅支持设置一个。postgres://user:mypassword@192.168.1.6:5432/juicefs?search_path=pguser1,public
将被认为不合法- 密码中的特殊字符需要进行 url 编码,例如
|
需要编码为%7C
。
挂载文件系统
juicefs mount -d "postgres://user:mypassword@192.168.1.6:5432/juicefs" /mnt/jfs
挂载文件系统也支持用 META_PASSWORD
环境变量传递密码:
export META_PASSWORD="mypassword"
juicefs mount -d "postgres://user@192.168.1.6:5432/juicefs" /mnt/jfs
故障排除
JuiceFS 客户端默认采用 SSL 加密连接 PostgreSQL,如果连接时报错 pq: SSL is not enabled on the server
说明数据库没有启用 SSL。可以根据业务场景为 PostgreSQL 启用 SSL 加密,也可以在元数据 URL 中添加参数禁用加密验证:
juicefs format \
--storage s3 \
... \
"postgres://user@192.168.1.6:5432/juicefs?sslmode=disable" \
pics
元数据 URL 中还可以附加更多参数,查看详情。
MySQL
MySQL 是受欢迎的开源关系型数据库之一,常被作为 Web 应用程序的首选数据库。
创建文件系统
使用 MySQL 作为元数据存储引擎时,需要提前手动创建数据库,通常使用以下格式访问数据库:
- TCP
- Unix socket
mysql://<username>[:<password>]@(<host>:3306)/<database-name>
mysql://<username>[:<password>]@unix(<socket-file-path>)/<database-name>
- 不要漏掉 URL 两边的
()
括号 - 密码中的特殊字符不需要进行 url 编码
例如:
juicefs format \
--storage s3 \
... \
"mysql://user:mypassword@(192.168.1.6:3306)/juicefs" \
pics