일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- port open
- KVM
- Octavia
- k8s
- Ansible
- Docker
- HTML
- Kubernetes
- kolla
- golang
- pacman
- archlinux
- repository
- yum
- cloud-init
- i3
- Arch
- grafana-loki
- ceph-ansible
- libvirt
- Linux
- ubuntu
- OpenStack
- ceph
- awx
- kolla-ansible
- cephadm
- Kubeflow
- terraform
- nfs-provisioner
- Today
- Total
YJWANG
[Ceph] Map File to Object and OSD (Ceph object 저장 원리 알아보기) 본문
Ceph Client는 Data를 Object단위로 분할하여 Ceph (RADOS)에 저장합니다.
이때 Data는 obj로 변환된 후 해당 Pool에 할당돼있는 pg에 할당되고 그 pg는 replicated rule에 의해 OSD에 분산 저장됩니다.
오늘 포스팅은 해당 과정을 자세히 알아보는 시간을 갖고자합니다.
구성 현황
현재 TEST를 위해 CephFS를 구성해두었습니다.
root@virt-go-u20-20:~# ceph osd pool ls
device_health_metrics
testp1
cephfs.testfs.meta
cephfs.testfs.data
root@virt-go-u20-20:~# ceph fs ls
name: testfs, metadata pool: cephfs.testfs.meta, data pools: [cephfs.testfs.data ]
root@virt-go-u20-20:~# ceph fs status testfs
testfs - 1 clients
======
RANK STATE MDS ACTIVITY DNS INOS DIRS CAPS
0 active testfs.virt-go-u20-30.pmyyzr Reqs: 0 /s 22 16 12 1
POOL TYPE USED AVAIL
cephfs.testfs.meta metadata 408k 37.9G
cephfs.testfs.data data 36.0k 37.9G
STANDBY MDS
testfs.virt-go-u20-20.xoneyi
MDS version: ceph version 16.2.6 (ee28fb57e47e9f88813e24bbf4c14496ca299d31) pacific (stable)
또한 이를 Mount하여 Data를 가진 파일 3개 Data가 없는 파일 2개를 준비해두었습니다
root@virt-go-u20-50:/mnt# ls -l
total 2
-rw-r--r-- 1 root root 6 Dec 3 01:36 data1
-rw-r--r-- 1 root root 6 Dec 3 01:36 data2
-rw-r--r-- 1 root root 6 Dec 3 01:36 data3
-rw-r--r-- 1 root root 0 Dec 3 01:35 no_data1
-rw-r--r-- 1 root root 0 Dec 3 01:35 no_data2
해당 Data들이 osd내에 object 형식으로 pg로 grouping 돼서 잘 저장되어있는지 확인해보겠습니다.
map-obj-to-pool
우선 data pool 내에 3개의 object가 있는지확인합니다. (data가 있어야 data풀에 저장되고 아닌 경우 metadata에 metadata값만 저장됩니다.)
Data pool의 id를 획득합니다.
root@virt-go-u20-20:~# ceph osd pool stats cephfs.testfs.data
pool cephfs.testfs.data id 4
nothing is going on
obj가 id 4번 pool에 저장돼있음을 알 수 있습니다.
map-pg-to-pool
id 4
에 해당하는 pg들을 확인합니다.
pg 개수는 32개임을 확인합니다.
root@virt-go-u20-20:~# ceph osd pool get cephfs.testfs.data pg_num
pg_num: 32
pg의 id 중 .
을 기준으로 앞에있는 id가 pool의 id와 매핑됩니다.
즉, 우리가 원하는 id4의 해당하는 pg는 아래 방법으로 확인할 수 있습니다. (data가 길어 뒷 부분을 잘라냈습니다.)
root@virt-go-u20-20:~# ceph pg ls-by-pool cephfs.testfs.data
PG_STAT OBJECTS MISSING_ON_PRIMARY
4.a 0 0
4.b 0 0
4.8 0 0
4.9 0 0
4.e 0 0
4.f 0 0
4.c 0 0
4.d 0 0
4.2 1 0
4.3 0 0
4.4 0 0
4.5 0 0
4.7 0 0
4.6 0 0
4.1 0 0
4.0 0 0
4.15 0 0
4.14 0 0
4.17 0 0
4.16 0 0
4.11 0 0
4.10 0 0
4.13 0 0
4.12 1 0
4.1d 0 0
4.1c 0 0
4.1f 0 0
4.1e 0 0
4.19 0 0
4.18 1 0
4.1b 0 0
4.1a 0 0
object 수를 확인해보니 3개가 맞습니다.
즉 어떤 obj가 어떤 pg인지 아직은 모르지만 data1, data2, data3
에 해당하는 pg는 4.2, 4.12, 4.18
라고 볼 수 있습니다.
map-pg-to-osd
그럼 해당 pg들이 어떤 osd에 속해있는지 같은 명령으로 확인할 수 있습니다.
PG_STAT UP UP_PRIMARY ACTING ACTING_PRIMARY
4.2 [4,3,0] 4 [4,3,0] 4
4.12 [0,4,3] 0 [0,4,3] 0
4.18 [3,5,2] 3 [3,5,2] 3
아래와 같이 3복제가 이루어지고 있으므로 각각 3개의 OSD목록이 보임을 알 수 있습니다.
root@virt-go-u20-20:~# ceph osd dump
...
pool 4 'cephfs.testfs.data' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 111 flags hashpspool stripe_width 0 application cephfs
즉 4.2 PG
는 OSD 4,3,0
에 나뉘어 저장돼있으며, 그 중 primary OSD는 4번임을 알 수 있습니다.
map-obj-to-pg
rados 명령을 통해 4.2 pg에 속한 object의 hash값을 가져옵니다.
root@virt-go-u20-20:~# rados --pgid 4.2 ls
10000000020.00000000
해당 hash값을 통해 file data를 확인합니다.
root@virt-go-u20-20:~# rados -p cephfs.testfs.data get 10000000020.00000000 -
data2332
결론
data2332의 data를 가지는 data2 파일은
- pg 4.2로 매핑됐고
- pg 4.2는 cephfs.testfs.data pool에 속하며
- OSD 4, 3, 0에 나뉘어 보관된다.
- 그 중 Primary OSD는 4번 OSD이다.
- OSD 4, 3, 0에 나뉘어 보관된다.
- pg 4.2는 cephfs.testfs.data pool에 속하며
Data가 많으면 (파일 내용이 많으면) 위와 같이 object와 File Name에대한 1:1 매핑이 불가할 수 있습니다. 이해를 위한 예시이므로 이해를 위해 참고하시기 바랍니다.