juicefs
喜欢ceph的话欢迎关注奋斗的cepher微信公众号阅读更多好文!
在很多场景中,业务会倾向于使用成熟方便的文件存储,像本地目录、NFS、smb等等,文件存储有其应用优势,在松鼠哥的课程中对各种存储方式的利弊介绍已经很详细了,本篇我们来介绍juicefs。
ceph虽然支持文件存储cephfs,但是它的稳定性还是不太足够,而且在大规模数据场景下,可靠性还是不太行,时至今日,使用cephfs进行大量数据的文件存储,松鼠哥还是觉得要慎重~
juicefs最开始是听一些朋友介绍,据说性能彪悍,稳定性也不错,所以一直打算调研,终于,有了本篇
开始
首先是ceph的准备,松鼠哥使用ceph 16.2.14
的二进制部署环境,集群是基本的S3对象存储环境,配置了zone
root@debian:~# ceph df
--- RAW STORAGE ---
CLASS SIZE AVAIL USED RAW USED %RAW USED
hdd 60 GiB 58 GiB 1.9 GiB 1.9 GiB 3.21
TOTAL 60 GiB 58 GiB 1.9 GiB 1.9 GiB 3.21
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
device_health_metrics 31 1 0 B 7 0 B 0 19 GiB
juicefs_pool 33 64 36 B 1 12 KiB 0 19 GiB
.rgw.root 34 32 7.3 KiB 22 252 KiB 0 19 GiB
songshuge.rgw.log 35 32 23 KiB 306 1.9 MiB 0 19 GiB
songshuge.rgw.meta 36 32 1.3 KiB 7 72 KiB 0 19 GiB
songshuge.rgw.control 37 32 0 B 8 0 B 0 19 GiB
songshuge.rgw.buckets.non-ec 38 32 0 B 0 0 B 0 19 GiB
songshuge.rgw.buckets.index 39 32 7.7 KiB 11 23 KiB 0 19 GiB
songshuge.rgw.buckets.data 40 32 9.9 MiB 5 30 MiB 0.05 19 GiB
这个测试小集群只有3台机器,为了更贴合应用场景,松鼠哥使用另外一台非集群节点来作为juicefs的客户端节点。
对接S3
在使用juicefs对接ceph的S3前,需要在集群创建用户并在该用户下创建bucket
root@debian:~# radosgw-admin user list
[
"test-1"
]
root@debian:~# radosgw-admin bucket list
[
"test-bucket-pool1"
]
首先要安装一个redis,juicefs可以使用多种存储引擎来存储元数据,松鼠推荐使用redis,无他,性能好
root@debian4:~# apt install redis-server
安装完成后做一下配置,指定它的监听ip,这里是测试环境,安装一个单机的试试,如果要生产用,要考虑高可用
root@debian4:~# grep 'bind' /etc/redis/redis.conf |grep -v '#'
bind 192.168.56.122 ::1
root@debian4:~# redis-cli -h debian4 ping
PONG
redis准备好之后,接下来在节点安装juicefs,使用官方推荐的一键安装
root@debian4:~# apt install curl
root@debian4:~# curl -sSL https://d.juicefs.com/install | sh -
安装完成后,格式化bucket,在这个环境中,使用方式为
root@debian4:~# juicefs format --storage s3 \
--bucket http://test-bucket-pool1.192.168.56.130:7480 \
--access-key KWSCE4FOTTP0PV3LSFUV \
--secret-key ZhIFTSbuO3QEh95wMJ08N1XFpUIVsZFXKvpQ84hq \
redis://192.168.56.122/1 \
myjfs
2024/05/24 09:41:26.390229 juicefs[3253] <INFO>: Meta address: redis://192.168.56.122/1 [interface.go:497]
2024/05/24 09:41:26.390987 juicefs[3253] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [info.go:84]
2024/05/24 09:41:26.391108 juicefs[3253] <INFO>: Ping redis latency: 38.159µs [redis.go:3600]
2024/05/24 09:41:26.391568 juicefs[3253] <INFO>: Data use s3://test-bucket-pool1/myjfs/ [format.go:471]
2024/05/24 09:41:26.529414 juicefs[3253] <INFO>: Volume is formatted as {
"Name": "myjfs",
"UUID": "32bdbc73-0765-4ee6-9dba-6019f1731188",
"Storage": "s3",
"Bucket": "http://test-bucket-pool1.192.168.56.130:7480",
"AccessKey": "KWSCE4FOTTP0PV3LSFUV",
"SecretKey": "removed",
"BlockSize": 4096,
"Compression": "none",
"EncryptAlgo": "aes256gcm-rsa",
"KeyEncrypted": true,
"TrashDays": 1,
"MetaVersion": 1,
"MinClientVersion": "1.1.0-A",
"DirStats": true
} [format.go:508]
- –storage s3 使用后端存储为S3
- –bucket 指定使用的bucket和endpoint,这里就是rgw的ip地址和端口,格式为bucket.endpoint:port
- –access-key和–secret-key
- redis://192.168.56.122/1 指定redis,刚才已经试过了,redis没问题
- myjfs 指定将该bucket格式化为myjfs的文件存储
执行后正常退出,显示已经成功,那么格式化就好了,接下来是挂载
root@debian4:~# juicefs mount --background redis://192.168.56.122/1 ~/jfs
2024/05/24 09:42:58.028457 juicefs[3268] <INFO>: Meta address: redis://192.168.56.122/1 [interface.go:497]
2024/05/24 09:42:58.029364 juicefs[3268] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [info.go:84]
2024/05/24 09:42:58.029745 juicefs[3268] <INFO>: Ping redis latency: 194.984µs [redis.go:3600]
2024/05/24 09:42:58.031031 juicefs[3268] <INFO>: Data use s3://test-bucket-pool1/myjfs/ [mount.go:605]
2024/05/24 09:42:58.049580 juicefs[3268] <INFO>: Disk cache (/var/jfsCache/32bdbc73-0765-4ee6-9dba-6019f1731188/): capacity (102400 MB), free ratio (10%), max pending pages (15) [disk_cache.go:114]
2024/05/24 09:42:58.066535 juicefs[3268] <INFO>: Create session 2 OK with version: 1.1.2+2024-02-04.8dbd89a [base.go:494]
2024/05/24 09:42:58.109605 juicefs[3268] <INFO>: Prometheus metrics listening on 127.0.0.1:9567 [mount.go:160]
2024/05/24 09:42:58.109678 juicefs[3268] <INFO>: Mounting volume myjfs at /root/jfs ... [mount_unix.go:269]
2024/05/24 09:42:58.560840 juicefs[3268] <INFO>: OK, myjfs is ready at /root/jfs [mount_unix.go:48]
最后显示myjfs is ready at /root/jfs
,说明挂载成功了,可以在本地文件系统查看
root@debian4:~# df -h
Filesystem Size Used Avail Use% Mounted on
JuiceFS:myjfs 1.0P 10M 1.0P 1% /root/jfs
测试了一下,拷贝数据进去没有问题。
这里有个小问题,挂载目录后,可用大小显示为1PiB,实际上后端没有这么大的空间,应该是默认写的大小,后端对象存储是不能显式确定可用容量的,这个问题在社区群问过,确认这个是默认值,而且可以配置,比如后端实际10PiB,可以在format的时候指定显示的容量大小,这个设计合不合理,就看个人理解了。
对接librados
既然我们都玩转ceph了,走一层s3似乎没道理,多此一举,要是能够直接操作rados,岂不是更high!
实际上,juicefs支持通过librados直接操作ceph的rados,因为本质上ceph的rados就是一个对象存储,但是,要直接使用juicefs对接rados,现有的二进制包不支持,需要自己重新编译,所幸难度不大,首先下载源代码,这里松鼠哥的系统是Debian Buster 10.13,使用juicefs v1.1.2版本即可
root@debian4:~# git clone https://github.com/juicedata/juicefs.git -b v1.1.2
接下来,配置清华源,然后安装开发包,主要是要用到它的头文件
root@debian4:~# apt install software-properties-common
root@debian4:~# wget -q -O- 'https://download.ceph.com/keys/release.asc' | apt-key add -
root@debian4:~# apt-add-repository 'deb https://mirrors.tuna.tsinghua.edu.cn/ceph/debian-octopus/ buster main'
root@debian4:~# apt update
root@debian4:~# apt-get install librados-dev
当然,少不了go的环境,这里直接下载go的二进制然后配置一下路径,juicefs的编译对go版本有要求,需要1.20以上,另外gcc也要5.4以上
root@debian4:~# wget https://dl.google.com/go/go1.20.4.linux-amd64.tar.gz
root@debian4:~# tar -C /usr/local -xzf go1.20.4.linux-amd64.tar.gz
root@debian4:~# echo export PATH=$PATH:/usr/local/go/bin | sudo tee -a /etc/profile
root@debian4:~# echo export PATH=$PATH:/usr/local/go/bin >> ~/.profile
root@debian4:~# source ~/.profile
root@debian4:~# go version
go version go1.20.4 linux/amd64
root@debian4:~# gcc --version
gcc (Debian 8.3.0-6) 8.3.0
在开始前,还有个步骤,juicefs在编译时会下载很多的其他代码,这些代码如果跑到外面去下载就特别慢,因此在开始前要对go进行加速器的设置,改为国内的加速器
root@debian4:~# go env -w GOPROXY=https://goproxy.cn,direct
环境没问题,那就进入juicefs目录开始编,我们只需要juicefs.ceph,所以直接编
root@debian4:~# cd juicefs-1.1.2/
root@debian4:~/juicefs-1.1.2# make juicefs.ceph
即便松鼠哥用的是很挫的虚拟机,编译速度也挺快的,算上下载,10分钟就好了。
接下来使用这个编译好的juicefs.ceph二进制进行格式化,参数和格式为
root@debian4:~# juicefs format --storage=ceph \
--bucket=ceph://juicefs_pool \
--access-key=ceph \
--secret-key=client.admin \
redis://192.168.56.122/2 \
ceph-volume
2024/05/24 10:08:31.246444 juicefs[3382] <INFO>: Meta address: redis://192.168.56.122/2 [interface.go:497]
2024/05/24 10:08:31.256756 juicefs[3382] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [info.go:84]
2024/05/24 10:08:31.257017 juicefs[3382] <INFO>: Ping redis latency: 67.558µs [redis.go:3600]
2024/05/24 10:08:31.281568 juicefs[3382] <INFO>: Data use ceph://juicefs_pool/ceph-volume/ [format.go:471]
2024/05/24 10:08:31.632920 juicefs[3382] <INFO>: Volume is formatted as {
"Name": "ceph-volume",
"UUID": "1b299ee3-2592-40a6-9196-5ad2e3109b5e",
"Storage": "ceph",
"Bucket": "ceph://juicefs_pool",
"AccessKey": "ceph",
"SecretKey": "removed",
"BlockSize": 4096,
"Compression": "none",
"EncryptAlgo": "aes256gcm-rsa",
"KeyEncrypted": true,
"TrashDays": 1,
"MetaVersion": 1,
"MinClientVersion": "1.1.0-A",
"DirStats": true
} [format.go:508]
- –storage=ceph表示用的librados
- –bucket 这里按照指定的格式填入使用的存储池,ceph://POOL
- –access-key和–secret-key 这里就是指定ceph的用户,不是s3用户是ceph用户
- 其他的与s3无异
讲道理,加一些新的参数是不难的,复用参数这种操作一言难尽=.=
格式化正常返回,没有报错,没问题,接下来是挂载
root@debian4:~/juicefs-1.1.2# ./juicefs.ceph mount --background redis://192.168.56.122/2 ~/rados_jfs
2024/05/24 10:12:26.775101 juicefs[3430] <INFO>: Meta address: redis://192.168.56.122/2 [interface.go:497]
2024/05/24 10:12:26.775732 juicefs[3430] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [info.go:84]
2024/05/24 10:12:26.775961 juicefs[3430] <INFO>: Ping redis latency: 141.329µs [redis.go:3600]
2024/05/24 10:12:26.792678 juicefs[3430] <INFO>: Data use ceph://juicefs_pool/ceph-volume/ [mount.go:605]
2024/05/24 10:12:26.793280 juicefs[3430] <INFO>: Disk cache (/var/jfsCache/1b299ee3-2592-40a6-9196-5ad2e3109b5e/): capacity (102400 MB), free ratio (10%), max pending pages (15) [disk_cache.go:114]
2024/05/24 10:12:27.303125 juicefs[3430] <INFO>: OK, ceph-volume is ready at /root/jfs [mount_unix.go:48]
很顺利,看了一下本地文件系统,挂载没问题
root@debian4:~/juicefs-1.1.2# df -h
Filesystem Size Used Avail Use% Mounted on
JuiceFS:ceph-volume 1.0P 0 1.0P 0% /root/rados_jfs
JuiceFS:myjfs 1.0P 10M 1.0P 1% /root/jfs
测试了一下拷贝数据进去,没问题
最后,如果要卸载juicefs挂载的目录,直接使用本地文件系统的unmount /root/jfs
即可。
总结
相比于cephfs,由于juicefs可以使用高效的源数据库,比如redis,其性能比起cephfs更高,也更灵活,由于松鼠哥的环境是虚拟机的测试环境,所以没有进行性能测试,只是简单地完成了功能测试,都挺顺利的。
fs在很多场景中应用广泛,本篇初步接触juicefs,后续将继续进行性能和稳定性及场景的测试,松鼠哥也想进一步了解这个juicefs的能力,以评估其生产环境的能力。
喜欢ceph的话欢迎关注奋斗的cepher微信公众号阅读更多好文!