跳转至

ceph

Ceph是一个分布式存储系统,诞生于2004年,最早致力于开发下一代高性能分布式文件系统的项目。经过多年的发展之后,已得到众多云计算和存储厂商的支持,成为应用最广泛的开源分布式存储平台。随着云计算的发展,ceph乘上了OpenStack的春风,进而成为了开源社区受关注较高的项目之一。Ceph可以将多台服务器组成一个超大集群,把这些机器中的磁盘资源整合到一块儿,形成一个大的资源池(PB级别),然后按需分配给应用使用。

Ceph的主要架构

  • Ceph的最底层是RADOS(分布式对象存储系统),它具有可靠、智能、分布式等特性,实现高可靠、高可拓展、高性能、高自动化等功能,并最终存储用户数据。RADOS系统主要由两部分组成,分别是OSD和Monitor。
  • RADOS之上是LIBRADOS,LIBRADOS是一个库,它允许应用程序通过访问该库来与RADOS系统进行交互,支持多种编程语言,比如C、C++、Python等。
  • 基于LIBRADOS层开发的有三种接口,分别是RADOSGW、librbd和MDS。
  • RADOSGW是一套基于当前流行的RESTFUL协议的网关,支持对象存储,兼容S3和Swift。
  • librbd提供分布式的块存储设备接口,支持块存储。
  • MDS提供兼容POSIX的文件系统,支持文件存储。

Ceph的功能模块

Ceph的核心组件包括Client客户端、MON监控服务、MDS元数据服务、OSD存储服务,各组件功能如下:

  • Client客户端:负责存储协议的接入,节点负载均衡。
  • MON监控服务:负责监控整个集群,维护集群的健康状态,维护展示集群状态的各种图表,如OSD Map、Monitor Map、PG Map和CRUSH Map。
  • MDS元数据服务:负责保存文件系统的元数据,管理目录结构。
  • OSD存储服务:主要功能是存储数据、复制数据、平衡数据、恢复数据,以及与其它OSD间进行心跳检查等。一般情况下一块硬盘对应一个OSD。

Ceph的资源划分

Ceph采用crush算法,在大规模集群下,实现数据的快速、准确存放,同时能够在硬件故障或扩展硬件设备时,做到尽可能小的数据迁移,其原理如下

  • 当用户要将数据存储到Ceph集群时,数据先被分割成多个object,(每个object一个object id,大小可设置,默认是4MB),object是Ceph存储的最小存储单元。
  • 由于object的数量很多,为了有效减少了Object到OSD的索引表、降低元数据的复杂度,使得写入和读取更加灵活,引入了pg(Placement Group ):PG用来管理object,每个object通过Hash,映射到某个pg中,一个pg可以包含多个object。
  • Pg再通过CRUSH计算,映射到osd中。如果是三副本的,则每个pg都会映射到三个osd,保证了数据的冗余。

各层次之间的映射关系:

  • file -> object object的最大size是由RADOS配置的,当用户要存储一个file,需要将file切分成几个object。
  • object -> PG 每个object都会被映射到一个PG中,然后以PG为单位进行备份以及进一步映射到具体的OSD上。
  • PG -> OSD 根据用户设置的冗余存储的个数r,PG会最终存储到r个OSD上,这个映射是通过一种伪随机的映射算法 CRUSH 来实现的,这个算法的特点是可以进行配置。

Ceph的数据写入

Ceph数据的写入流程:

  • 数据通过负载均衡获得节点动态IP地址;
  • 通过块、文件、对象协议将文件传输到节点上;
  • 数据被分割成4M对象并取得对象ID;
  • 对象ID通过HASH算法被分配到不同的PG;
  • 不同的PG通过CRUSH算法被分配到不同的OSD;

Ceph的特点

  • Ceph支持对象存储、块存储和文件存储服务,故称为统一存储;
  • 采用CRUSH算法,数据分布均衡,并行度高,不需要维护固定的元数据结构;
  • 数据具有强一致,确保所有副本写入完成才返回确认,适合读多写少场景;
  • 去中心化,MDS之间地位相同,无固定的中心节点;

Ceph存在一些缺点

  • 去中心化的分布式解决方案,需要提前做好规划设计,对技术团队的要求能力比较高。
  • Ceph扩容时,由于其数据分布均衡的特性,会导致整个存储系统性能的下降。

Ceph日常操作命令

  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
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
查看状态命令:
查看ceph集群状态:ceph -s
查看mon状态:ceph mon stat
查看msd状态:ceph msd stat
查看osd状态:ceph osd stat
查看osd目录树(可以查看每个osd挂在哪台机,是否已启动):ceph osd tree

启动ceph进程命令:
需要在对应的节点进行启动(如果对应节点没有该服务,会进行提示)
启动mon进程:service ceph start mon.ceph-node1
启动msd进程:service ceph start msd.ceoh-node1
启动osd进程:service ceph start osd.0(在ceph-node1上)
启动osd进程:service ceph start osd.1(在ceph-node2上)
启动osd进程:service ceph start osd.2(在ceph-node3上)

查看机器的监控状态
# ceph health

查看ceph的实时运行状态
# ceph -w

检查信息状态信息
# ceph -s

查看ceph存储空间
[root@client ~]# ceph df

删除一个节点的所有的ceph数据包
# ceph-deploy purge ceph-node1
# ceph-deploy purgedata ceph-node1

为ceph创建一个admin用户并为admin用户创建一个密钥,把密钥保存到/etc/ceph目录下:
# ceph auth get-or-create client.admin mds 'allow' osd 'allow ' mon 'allow ' > /etc/ceph/ceph.client.admin.keyring
# ceph auth get-or-create client.admin mds 'allow' osd 'allow ' mon 'allow ' -o /etc/ceph/ceph.client.admin.keyring

为osd.0创建一个用户并创建一个key
# ceph auth get-or-create osd.0 mon 'allow rwx' osd 'allow *' -o /var/lib/ceph/osd/ceph-0/keyring

为mds.node1创建一个用户并创建一个key(ceph-node1是节点名称)
# ceph auth get-or-create mds.node1 mon 'allow rwx' osd 'allow ' mds 'allow ' -o /var/lib/ceph/mds/ceph-ceph-node1/keyring

查看ceph集群中的认证用户及相关的key
ceph auth list

删除集群中的一个认证用户
ceph auth del osd.0

查看集群的详细配置(ceph-node1是节点名称)
# ceph daemon mon.ceph-node1 config show | more

查看集群健康状态细节
# ceph health detail

查看ceph log日志所在的目录
# ceph-conf –name mon.node1 –show-config-value log_file

=================关于mon节点的相关操作命令====================
查看mon的状态信息
# ceph mon stat

查看mon的选举状态
# ceph quorum_status

查看mon的映射信息
# ceph mon dump

删除一个mon节点
# ceph mon remove node1

获得一个正在运行的mon map,并保存在1.txt文件中
# ceph mon getmap -o 1.txt

查看上面获得的map
# monmaptool --print 1.txt

map注入新加入的节点(如新节点主机名为ceph-node4)
# ceph-mon -i ceph-node4 --inject-monmap 1.txt

查看mon的amin socket
# ceph-conf --name mon.ceph-node1 --show-config-value admin_socket

查看mon的详细状态(ceph-node1为mon节点主机名)
# ceph daemon mon.ceph-node1 mon_status

删除一个mon节点(ceph-node1为mon节点主机名)
# ceph mon remove ceph-node1

=================msd节点相关操作命令====================
查看msd状态
# ceph mds stat

查看msd的映射信息
# ceph mds dump

删除一个mds节点
# ceph mds rm 0 mds.ceph-node1

=================osd节点相关操作命令====================
查看ceph osd运行状态
# ceph osd stat

查看osd映射信息
# ceph osd dump

查看osd的目录树
# ceph osd tree

down掉一个osd硬盘(比如down掉osd.0节点磁盘)
# ceph osd down 0    

在集群中删除一个osd硬盘
# ceph osd rm 0

在集群中删除一个osd 硬盘 crush map
# ceph osd crush rm osd.0

在集群中删除一个osd的host节点
# ceph osd crush rm node1

查看最大osd的个数(默认最大是4个osd节点)
# ceph osd getmaxosd

设置最大的osd的个数(当扩大osd节点的时候必须扩大这个值)
# ceph osd setmaxosd 10

设置osd crush的权重为1.0
ceph osd crush set {id} {weight} [{loc1} [{loc2} ]]
例如:
[root@ceph-node1 ~]# ceph osd crush set 3 3.0 host=ceph-node4
set item id 3 name 'osd.3' weight 3 at location {host=node4} to crush map
[root@ceph-node1 ~]# ceph osd tree
# id weight type name up/down reweight
-1 6 root default
-2 1 host ceph-node1
0 1 osd.0 up 1
-3 1 host ceph-node2
1 1 osd.1 up 1
-4 1 host ceph-node3
2 1 osd.2 up 1
-5 3 host ceph-node4
3 3 osd.3 up 0.5

或者用下面的方式
[root@ceph-node1 ~]# ceph osd crush reweight osd.3 1.0
reweighted item id 3 name 'osd.3' to 1 in crush map
[root@ceph-node1 ~]# ceph osd tree
# id weight type name up/down reweight
-1 4 root default
-2 1 host node1
0 1 osd.0 up 1
-3 1 host node2
1 1 osd.1 up 1
-4 1 host node3
2 1 osd.2 up 1
-5 1 host node4
3 1 osd.3 up 0.5


设置osd的权重

[root@ceph-node1 ~]# ceph osd reweight 3 0.5
reweighted osd.3 to 0.5 (8327682)
[root@ceph-node1 ~]# ceph osd tree
# id weight type name up/down reweight
-1 4 root default
-2 1 host node1
0 1 osd.0 up 1
-3 1 host node2
1 1 osd.1 up 1
-4 1 host node3
2 1 osd.2 up 1
-5 1 host node4
3 1 osd.3 up 0.5

把一个osd节点逐出集群

[root@ceph-node1 ~]# ceph osd out osd.3
marked out osd.3.
[root@ceph-node1 ~]# ceph osd tree
# id weight type name up/down reweight
-1 4 root default
-2 1 host node1
0 1 osd.0 up 1
-3 1 host node2
1 1 osd.1 up 1
-4 1 host node3
2 1 osd.2 up 1
-5 1 host node4
3 1 osd.3 up 0
# osd.3的reweight变为0了就不再分配数据,但是设备还是存活的

把逐出的osd加入集群

[root@ceph-node1 ~]# ceph osd in osd.3
marked in osd.3.
[root@ceph-node1 ~]# ceph osd tree
# id weight type name up/down reweight
-1 4 root default
-2 1 host node1
0 1 osd.0 up 1
-3 1 host node2
1 1 osd.1 up 1
-4 1 host node3
2 1 osd.2 up 1
-5 1 host node4
3 1 osd.3 up 1

暂停osd (暂停后整个集群不再接收数据)
[root@ceph-node1 ~]# ceph osd pause
# set pauserd,pausewr

再次开启osd (开启后再次接收数据)
[root@ceph-node1 ~]# ceph osd unpause
# unset pauserd,pausewr

查看一个集群osd.2参数的配置
# ceph –admin-daemon /var/run/ceph/ceph-osd.2.asok config show | less

======================PG组相关操作命令=======================
查看pg组的映射信息
# ceph pg dump

查看一个PG的map

[root@client ~]# ceph pg map 0.3f
osdmap e88 pg 0.3f (0.3f) -> up [0,2] acting [0,2]
#其中的[0,2]代表存储在osd.0、osd.2节点,osd.0代表主副本的存储位置

查看PG状态
[root@client ~]# ceph pg stat
v1164: 448 pgs: 448 active+clean; 10003 MB data, 23617 MB used, 37792 MB / 61410 MB avail

查询一个pg的详细信息
[root@client ~]# ceph pg 0.26 query

查看pg中stuck的状态
[root@client ~]# ceph pg dump_stuck unclean
ok
[root@client ~]# ceph pg dump_stuck inactive
ok
[root@client ~]# ceph pg dump_stuck stale
ok

显示一个集群中的所有的pg统计
# ceph pg dump –format plain

恢复一个丢失的pg
# ceph pg {pg-id} mark_unfound_lost revert

显示非正常状态的pg
# ceph pg dump_stuck inactive|unclean|stale

======================pool相关操作命令========================
查看ceph集群中的pool数量
[root@ceph-node1 ~]# ceph osd lspools
0 data,1 metadata,2 rbd,

在ceph集群中创建一个pool
# ceph osd pool create kevin 100
这里的100指的是PG组,kevin是集群名称

为一个ceph pool配置配额
# ceph osd pool set-quota data max_objects 10000

在集群中删除一个pool(集群名字需要重复两次)
# ceph osd pool delete kevin kevin --yes-i-really-really-mean-it


显示集群中pool的详细信息
[root@ceph-node1 ~]# rados df
pool name category KB objects clones degraded unfound rd rd KB wr wr KB
data - 475764704 116155 0 0 0 0 0 116379 475764704
metadata - 5606 21 0 0 0 0 0 314 5833
rbd - 0 0 0 0 0 0 0 0 0
total used 955852448 116176
total avail 639497596
total space 1595350044
[root@ceph-node1 ~]#

给一个pool创建一个快照
[root@ceph-node1 ~]# ceph osd pool mksnap data date-snap
created pool data snap date-snap

删除pool的快照
[root@ceph-node1 ~]# ceph osd pool rmsnap data date-snap
removed pool data snap date-snap

查看data池的pg数量
[root@ceph-node1 ~]# ceph osd pool get data pg_num
pg_num: 64

设置data池的最大存储空间为100T(默认是1T)
[root@ceph-node1 ~]# ceph osd pool set data target_max_bytes 100000000000000
set pool 0 target_max_bytes to 100000000000000

设置data池的副本数是3
[root@ceph-node1 ~]# ceph osd pool set data size 3
set pool 0 size to 3

设置data池能接受写操作的最小副本为2
[root@ceph-node1 ~]# ceph osd pool set data min_size 2
set pool 0 min_size to 2

查看集群中所有pool的副本尺寸
[root@admin mycephfs]# ceph osd dump | grep 'replicated size'
pool 0 'data' replicated size 3 min_size 2 crush_ruleset 0 object_hash rjenkins pg_num 64 pgp_num 64 last_change 26 owner 0 flags hashpspool crash_replay_interval 45 target_bytes 100000000000000 stripe_width 0
pool 1 'metadata' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 64 pgp_num 64 last_change 1 owner 0 flags hashpspool stripe_width 0
pool 2 'rbd' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 64 pgp_num 64 last_change 1 owner 0 flags hashpspool stripe_width 0

设置一个pool的pg数量
[root@ceph-node1 ~]# ceph osd pool set data pg_num 100
set pool 0 pg_num to 100

设置一个pool的pgp数量
[root@ceph-node1 ~]# ceph osd pool set data pgp_num 100
set pool 0 pgp_num to 100

=================================rados指令====================================
查看ceph集群中有多少个pool (只是查看pool)
[root@ceph-node1 ~]# rados lspools
rbd
cephfs_data
cephfs_metadata

查看ceph集群中有多少个pool,并且每个pool容量及利用情况
[root@ceph-node1 ~]# rados df
pool name                 KB      objects       clones     degraded      unfound           rd        rd KB           wr        wr KB
cephfs_data                0            0            0            0           0            0            0            0            0
cephfs_metadata           21           20            0            0           0            0            0           45           36
rbd                        0            0            0            0           0            0            0            0            0
  total used        15833064           20
  total avail       47044632
  total space       62877696

创建一个pool,名称为kevin
[root@ceph-node1 ~]# rados mkpool kevin
successfully created pool kevin

查看ceph pool中的ceph object (这里的object是以块形式存储的)
[root@ceph-node1 ~]# rados ls -p kevin|more

创建一个对象object(下面的kevin是pool名称)
[root@ceph-node1 ~]# rados create kevin-object -p kevin
[root@ceph-node1 ~]# rados -p kevin ls
kevin-object

删除一个对象
[root@ceph-node1 ~]# rados rm kevin-object -p kevin
[root@ceph-node1 ~]# rados -p kevin ls

=================================rbd命令的用法=====================================
查看ceph中一个pool里的所有镜像
# rbd ls kevin     //kevin是一个pool名
或者
# rbd list kevin

查看ceph pool中一个镜像的信息(kevin是pool名,wangshibo是镜像名)
[root@ceph ~]# rbd info -p kevin --image wangshibo

在kevin池中创建一个命名为wangshibo的10000M的镜像
[root@ceph-node1 ~]# rbd create -p kevin --size 10000 wangshibo
[root@ceph-node1 ~]# rbd -p kevin info wangshibo                 //查看新建的镜像的信息
rbd image 'wangshibo':
   size 10000 MB in 2500 objects
   order 22 (4096 kB objects)
   block_name_prefix: rb.0.1079.2ae8944a
   format: 1

删除一个镜像
[root@ceph-node1 ~]# rbd rm -p kevin wangshibo
Removing image: 100% complete...done.

调整一个镜像的尺寸(前提是wangshibo镜像已经创建并没有被删除)
[root@ceph-node1 ~]# rbd resize -p kevin --size 20000 wangshibo
Resizing image: 100% complete...done.

查看调整后的wangshibo镜像大小
[root@ceph-node1 ~]# rbd -p kevin info wangshibo
rbd image 'wangshibo':
   size 20000 MB in 5000 objects
   order 22 (4096 kB objects)
   block_name_prefix: rb.0.107d.2ae8944a
   format: 1

给一个镜像创建一个快照(如下,池/镜像@快照 [root@ceph-node1 ~]# rbd snap create kevin/wangshibo@wangshibo123

查看快照
[root@ceph-node1 ~]# rbd info kevin/wangshibo@wangshibo123
rbd image 'wangshibo':
   size 20000 MB in 5000 objects
   order 22 (4096 kB objects)
   block_name_prefix: rb.0.107d.2ae8944a
   format: 1
   protected: False

查看一个镜像文件的快照
[root@ceph-node1 ~]# rbd snap ls -p kevin wangshibo
SNAPID NAME             SIZE
     4 wangshibo123 20000 MB

删除一个镜像文件的一个快照
[root@ceph-node1 ~]# rbd snap rm kevin/wangshibo@wangshibo123
[root@ceph-node1 ~]# rbd snap ls -p kevin wangshibo        //wangshibo123快照已经被删除

如果发现不能删除显示的报错信息是此快照备写保护了,下面命令是删除写保护后再进行删除。
# rbd snap unprotect kevin/wangshibo@wangshibo123
# rbd snap rm kevin/wangshibo@wangshibo123

删除一个镜像文件的所有快照
[root@ceph-node1 ~]# rbd snap purge -p kevin wangshibo
Removing all snapshots: 100% complete...done.

把ceph pool中的一个镜像导出
[root@ceph-node1 ~]# rbd export -p kevin --image wangshibo
Exporting image: 100% complete...done.

把一个镜像导入ceph中 (但是直接导入是不能用的,因为没有经过openstack,openstack是看不到的)
[root@ceph-node1 ~]# rbd import /root/ceph_test.img -p kevin --image wangshibo