Ceph入门到精通-恢复BlueStore中对象数据

1.基本原理介绍

1.1 ceph中的对象(object)

在Ceph存储中,一切数据最终都会以对象(Object)的形式存储在硬盘(OSD)上,每个的Object默认大小为4M。

Ceph入门到精通-恢复BlueStore中对象数据_第1张图片

通过rados命令,可以查看一个存储池中的所有object信息,例如下面的命令列出了存储池中的所有object。

rados -p pool-842bd759258f4ec9843afd1e78549350 ls

Ceph入门到精通-恢复BlueStore中对象数据_第2张图片

1.2 rbd块与object之间的对应关系

知道一切数据都会以object的形式存在于硬盘中后,我们还需要了解对象和rbd块之间的对应关系是什么。在ceph存储中,每个rbd块都有一个block_name_prefix。这个值是唯一的,通过rbd info或rados命令可以查询到,每个存储rbd块真实数据的对象会以这个作为名称前缀。所以通过blocak_name_prefix我们可以找到rbd块对应的对象有哪些。

Ceph入门到精通-恢复BlueStore中对象数据_第3张图片

1.3 rbd块中object的先后顺序如何区分

我们知道,一个object的大小为4M,因此一个rbd块对应的object通常会有多个。那么我们如何知道一个object对应rbd块中的哪一部分数据呢?要知道这个,我们就需要了解一下object的命令规则。

Object 名称由三部分组成:

  • rbd_data.:这是 RBD 存储卷的默认块名称前缀,用来标识这个 Object 存储的是一个 RBD 存储卷。
  • 115ea266096aee.:这是 RBD 存储卷的 ID,用来唯一标识一个 RBD 存储卷。每个 RBD 存储卷有一个唯一的 ID,可以通过 rbd info 命令查看。
  • 0000000000000c45:这是块的序号,用于标识这个 Object 存储的是 RBD 存储卷中的第几个块。在 RBD 存储卷中,每个块都有一个唯一的序号。采用的是16进制

所以通过objec的序号,我们可以知道object中保存了rbd块中哪个位置的数据。

Ceph入门到精通-恢复BlueStore中对象数据_第4张图片

2.object操作工具介绍

ceph-objectstore-tool是ceph提供的一个能对osd中存储的object进行增删改查的工具。该工具只能操作处于停止状态的osd。

下面的命令列出osd2中所有的object,包括object所属的pg和位置信息

ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-2 --op list

下面的命令是根据上一条命令获取的信息将object导出到本地的文件test.raw中

ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-2/ --type bluestore --pgid $pgid ‘$Object_attr’ get-bytes > test.raw

Ceph入门到精通-恢复BlueStore中对象数据_第5张图片

3.离线导出数据实战
3.1数据导出整体流程

  1. 通过rbd的name,获取rbd块的object前缀
  2. 停止掉一台服务器上的全部osd,通过object前缀找出rbd相关的所有对象数据并导出。三副本故障域为服务器的情况下,如果ceph集群有四台或以上存储服务器的话,一台服务器上可能不具备一个rbd块的完整副本,需要将多个节点的osd上导出的数据拼成一个完整的副本。
  3. 通过dd命令将所有对象数据拼接成一个完整的rbd卷

3.2手动导出数据

rados -p $pool-name listomapvals rbd_directory|grep $rbd_name -C 5  ##获取rbd块的blocak_name_prefix信息

Ceph入门到精通-恢复BlueStore中对象数据_第6张图片

通过上图可以看到rbd的id为59adb9d46665c,可以得到blocak_name_prefix为rbd_data.59adb9d46665c

接着查询osd2中与rbd块相关的对象,查询前需要先将osd2停,输出的结果中一行为一个对象。

systemctl stop ceph-osd@2
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-2 --op list 2>/dev/null  | grep rbd_data.59adb9d46665c

Ceph入门到精通-恢复BlueStore中对象数据_第7张图片

再通过查询到的object信息,将object数据导出到本地

ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-$i/ --type bluestore --pgid $PGID '$OBJECT_JSON' get-bytes > $RBD_PREFIX/$OID

Ceph入门到精通-恢复BlueStore中对象数据_第8张图片

通过dd命令创建一个新卷,再将object中的数据复制到新卷中,复制对象中的数据时,要根据object的位置调整数据写入的位置,即seek的值。object数据复制操作要执行多次,直到所有object中的数据都复制到创建的新卷中,数据导出操作完成。

dd if=/dev/zero of=rbd_data.1cabc42df0c8c4.raw bs=1 count=0 seek=2147483648  ##创建一个空文件,用来放对象的中的数据


echo $(( 0x00000000000000ff ))  ##16进制转十进制,获取对象在rbd块中的位置信息


dd if=rbd_data.1cabc42df0c8c4.0000000000000000 of=rbd_data.1cabc42df0c8c4.raw seek=0 bs=4M count=1 conv=notrunc   ##将对象中的数据复制到之前创建的空文件中。

Ceph入门到精通-恢复BlueStore中对象数据_第9张图片

数据导出完成后,默认是一个raw格式的文件,可以根据需要转换成qcow2或其他格式的文件。

qemu-img convert -f raw -O qcow2 -p rbd_data.115ea266096aee.build.raw restore.qcow2

Ceph入门到精通-恢复BlueStore中对象数据_第10张图片

3.3通过脚本导出数据

手动导出rbd数据是一个十分繁琐的操作,因此下面提供了两个脚本,可以完成导出对象数据,以及将对象数据合并成一个新卷的操作。

数据导出脚本,将某个rbd中的对象从osd中导出到本地。脚本执行前有两个地方需要修改。RBD_PREFIX的值修改为要导出rbd的blocak_name_prefix。declare osds的值修改为要执行脚本服务器上所有的osd id。

#!/bin/bash
# Export rbd_data.xxxxxxxxx to local file from all inactive osds


# Number of concurrent
N=64
RBD_PREFIX=rbd_data.39c97c1ed6026c 
mkdir $RBD_PREFIX


#all osd id in one ceph node
declare osds=(8 9 10 11) 
for i in ${osds[@]}
do
(echo $RBD_PREFIX in osd $i


echo "Export object..."
for j in $(ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-$i --op list 2>/dev/null|grep $RBD_PREFIX)
do
echo $j
PGID=$(echo $j|jq ".[0]" -r)
OBJECT_JSON=$(echo $j | jq ".[1]")
OID=$(echo $j | jq ".[1].oid" -r)
ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-$i/ --type bluestore --pgid $PGID "$OBJECT_JSON" get-bytes > $RBD_PREFIX/$OID
done
) &


if [[ $(jobs -r -p | wc -l) -ge $N ]]; then
wait
fi
done
wait
echo "All done."

数据合并脚本。将导出到本地的对象中的数据复制到一个新卷中。脚本在执行前需要将RBD_PREFIX的值修改为要导出rbd的blocak_name_prefix。

#!/bin/bash
RBD_PREFIX=rbd_data.3262b63ba984f7
IMAGE_NAME=$RBD_PREFIX.build.raw
rm -f $IMAGE_NAME
dd if=/dev/zero of=$IMAGE_NAME bs=1 count=0 seek=2147483648
for i in $(ls ./$RBD_PREFIX | sort)
do
idx=$(echo $i|awk -F '.' '{print $3}')
idxOct=$(echo $((0x$idx)))
dd if=./$RBD_PREFIX/$i of=$IMAGE_NAME seek=$idxOct bs=4M count=1 conv=notrunc
done

4 总结

ceph本身提供了rbd export命令用来导出rbd块。用命令导出数据的方式更简单直接。本文主要针对某些osd无法启动、rbd命令无法执行的场景,可以通过文中的方式来进行数据导出。同时通过这种导出对象的方式,我们也能了解ceph数据存储的更多细节。

5 参考资料

https://docs.ceph.com/en/pacifi

你可能感兴趣的:(Ceph入门到精通,ceph,服务器,linux)