ceph学习:
ceph 存储集群:
配置与部署:
准备硬盘:
操作系统和 Ceph OSD 守护进程数据分别放到不同的硬盘。如果必须把数据和系统放在同一硬盘里,最好给数据分配一个单独的分区!
文件系统:
OSD 守护进程有赖于底层文件系统的扩展属性( XATTR )存储各种内部对象状态和元数据。底层文件系统必须能为 XATTR 提供足够容量, btrfs 没有限制随文件的 xattr 元数据总量; xfs 的限制相对大( 64KB ),多数部署都不会有瓶颈; ext4 的则太小而不可用。
使用 ext4 文件系统时,一定要把下面的配置放于 ceph.conf 配置文件的 [osd] 段下;用 btrfs 和 xfs 时可以选填。
filestore xattr use omap = true
配置文件:
Ceph 配置文件使用 ini 风格的语法,以分号 (;) 和井号 (#) 开始的行是注释
确定 pg_num 取值是强制性的,因为不能自动计算。下面是几个常用的值:
少于 5 个 OSD 时可把 pg_num 设置为 128
OSD 数量在 5 到 10 个时,可把 pg_num 设置为 512
OSD 数量在 10 到 50 个时,可把 pg_num 设置为 4096
OSD 数量大于 50 时,你得理解权衡方法、以及如何自己计算 pg_num 取值
为 S3 访问创建 RADOSGW 用户
sudo radosgw-admin user create --uid="testuser" --display-name="First User"
存储池在建中
创建存储池时,它会创建指定数量的归置组。 Ceph 在创建一或多个归置组时会显示 creating ;创建完后,在其归置组的 Acting Set 里的 OSD 将建立互联;
一旦互联完成,归置组状态应该变为 active+clean ,意思是 Ceph 客户端可以向归置组写入数据了
http://docs.ceph.org.cn/rados/operations/monitoring-osd-pg/
运行时¶
如果你想查看一进程的运行时配置,必须先登录对应主机,然后执行命令:
ceph daemon {daemon-name} config show | less
例如:
ceph daemon osd.0 config show | less
集群运行图¶:
Ceph 依赖于 Ceph 客户端和 OSD ,因为它们知道集群的拓扑,这个拓扑由 5 张图共同描述,统称为“集群运行图”:
Montior Map: 包含集群的 fsid 、位置、名字、地址和端口,也包括当前版本、创建时间、最近修改时间。要查看监视器图,用 ceph mon dump 命令。
OSD Map: 包含集群 fsid 、创建时间、最近修改时间、存储池列表、副本数量、归置组数量、 OSD 列表及其状态(如 up 、 in )。要查看OSD运行图,用 ceph osd dump 命令。
PG Map::** 包含归置组版本、其时间戳、最新的 OSD 运行图版本、占满率、以及各归置组详情,像归置组 ID 、 up set 、 acting set 、 PG 状态(如 active+clean ),和各存储池的数据使用情况统计。
CRUSH Map::** 包含存储设备列表、故障域树状结构(如设备、主机、机架、行、房间、等等)、和存储数据时如何利用此树状结构的规则。要查看 CRUSH 规则,执行 ceph osd getcrushmap -o {filename} 命令;然后用 crushtool -d {comp-crushmap-filename} -o {decomp-crushmap-filename} 反编译;然后就可以用 cat 或编辑器查看了。
MDS Map: 包含当前 MDS 图的版本、创建时间、最近修改时间,还包含了存储元数据的存储池、元数据服务器列表、还有哪些元数据服务器是 up 且 in 的。要查看 MDS 图,执行 ceph mds dump 。
Cephx 用共享密钥来认证,即客户端和监视器集群各自都有客户端密钥的副本。这样的认证协议使参与双方不用展现密钥就能相互认证,就是说集群确信用户拥有密钥、而且用户相信集群有密钥的副本。
调用 ceph auth get-or-create-key 来生成一个用户及其密钥
存储池至少可设置以下参数:
对象的所有权/访问权限;
归置组数量;以及,
使用的 CRUSH 规则集。
radosgw充分利用了librados底层的4类API完成数据存储的目的,实际上radosgw用的是C++ API,但是这里使用C API便于说明问题
rados_read/rados_write 这组API主要用来存储对象的实际内容,他会根据用户对象的名称生产oid,然后映射到多个osd上,然后写入实际数据, 比较简单, 对应于rados命令行的
rados put/get
rados_write_op_omap_set/rados_read_op_omap_get_vals 这组API主要用来存储bucket的元数据。 每个ceph osd在初始化的时候会生产一个嵌入式的数据库. (filestore对应leveldb,bluestore对应rocksdb。用这组API 可以给object设置key-value值。这个API在radosgw里面主要存储重要的bucket下有哪些文件。比如S3里面有一个bucket叫document,里面有3个文件,名字分别是 :
A
B
C
那么对应的在.rgw.index的pool里面会有一个叫document.XXXX,这里面的XXXX是bucket的instance ID,他的omap对应的就是
KEY VALUE
A value
B value
C value
在ceph的J版本之前的,bucket下的文件列表都是由一个object对应的omap记录的。在后续的版本中加入bucket sharding的功能,让文件列表可以由 多个嵌入式KV存储。
rados_getxattrs/rados_setxattrs 这个API主要存储每个对象的元数据,包括每个分片的信息,ACL,contentType这些信息都用这组API存储和读取。 它们对应的就是filestore的xfs使用的xattrs,或者bluestore的rocksdb里面的kv对。
rados_exec 参考文档cls,传统上增删改查的操作并不以一定满足所有需求。 比如需要一个计数器,原子的记录一个object访问次数。或者需要在osd上计算一个object的md5,而不需要下载到客户端再进行计算。 所有的cls操作都是对一个object原子的。用户可以自己编写cls plugins,在osd启动的时候加载。之前只能用c++写,现在从J版本以后开始支持用 lua写的plugin了。
radosgw使用这个API做原子的操作,或者记录日志
对于大文件,相比与radosgw每次使用512K的buf,用rados_write的API写入ceph集群,yig使用动态的buf,根据用户上传的速度的大小调整buf在(512K~1M)之间。 并且使用rados striping的API提高写入的并发程度。让更多的OSD参与到大文件的写入,提高并发程度。 拆分方法如图:
问题:
bucket sharding
filestore对应leveldb,bluestore对应rocksdb。
为什么radosgw存储小文件会有性能问题?
从上面的rados存储原理可以看到,要在一个S3兼容的系统里存储数据,它需要存储
数据本身
元数据(ACL,contentype,分片信息)
修改bucket的元数据(bucket下面多了一个Key) 所以可以看出,尽管用户只上传了一个几百字节的文件,甚至还没有一个sector大。但是ceph的多个osd都要发生写操作。如果这是一个大文件,比如 4M,这些overhead就完全可以忽略。文件越小,数量越大,硬盘的随机读写越多。
这种情况在filestore的情况尤其糟糕,filestore所有的写入都先写入自己的jouranl,然后在fflush到文件系统。这种情况在bluestore会好一些, 因为S3的写入都是新文件,没有覆盖或者更新的情况,所有不用写journal,数据直接下盘