ceph学习笔记和基础知识

ceph源码下载:

http://ceph.com/download/

主要文档下载连接:

http://download.csdn.net/detail/skdkjxy/8149989

/*******************/
Time:2014-11-6
Author:skdkjzz
/******************/
1、unified中何为radosgw、rbd、ceph-dfs、rados?
2、distributed中spof?
{
 
http://article.yeeyan.org/view/258596/225158
 单点故障
}
3、ceph中何为paxos?
4、ceph包括四个部分--moniters(ceph-mon)、object_storage_daemons(ceph-osd)、clients(librados、librbd)、metadata_servers(ceph-mds)
5、posix语义?
6、rados_object_storage_model--include “pools” “objects”
7、object_storage--何为btrfs、xfs?online fsck 硬盘坏轨检查?
8、objects are automatically placed放置, balanced均衡, migrated迁移 in a dynamic cluster动态集群
9、CRUSH伪随机放置算法(pseudo-random placement algorithm)
10、3 replicas, same row, different racks(3个副本、同行、不同机架)
11、coordinate_peers(协调节点?)
12、何为openstack、RESTful、S3?
13、何为ACL_route_base(路由策略)?
14、何为rbd – rados block device --rbd?
15、基于内核的虚拟机(K Virtual Machine)--kvm
16、何为librbd、libvirt
17、shared cluster-coherent file system (共享集群一致?连贯?文件系统)?
18、动态子目录树分区特性--高效、可扩展、动态、自适应(均衡整个集群)
19、recursive_accounting--递归运算
20、Linux_kernel_client--Samba(CIFS)、export(NFS)
21、NFS-GANESHA 是一个用户空间服务器,支持NFSv2、NFSv3和NFSv4。它支持的运行平台包括Linux,BSD variants和POSIX-compliant Unixes。
22、何为poc?
{
POC测试,即Proof of Concept,是业界流行的针对客户具体应用的验证性测试,根据用户对采用系统提出的性能要求和扩展需求的指标,在选用服务器上进行真实数据的运行,
对承载用户数据量和运行时间进行实际测算,并根据用户未来业务扩展的需求加大数据量以验证系统和平台的承载能力和性能变化。
}
23、needs testing, deliberate qa effort for production(需要进行测试,为深思熟虑的品质做出努力)

/*******************/
Time:2014-11-7
Author:skdkjzz
/******************/
1、跟随魏盟去存储技术实验室
2、何为Lustre、GlusterFS和OrangeFS?
3、预计下周一进行疑惑解决,然后深入ceph框架
/========================================================================/
HardDisk:
4、预计下周一进行ceph安装文档阅读:
5、均衡日志和OSD性能相当重要
6、不顾分区而在单个硬盘上运行多个OSD,这样不明智!
7、不顾分区在运行了OSD的硬盘上监视器或者元数据服务器,也是不明智!
8、存储驱动器受限于寻道时间、访问时间、读写时间、还有总吞吐量,这些物理局限性影响着整体系统性能,尤
其在系统恢复期间。因此我们推荐独立的驱动器用于安装操作系统和软件,另外每个OSD守护进程占用一个驱动器。
大多数“slow OSD”问题的起因都是在相同的硬盘上运行了操作系统、多个OSD和/或多个日志文件。鉴于解决性能问题
的成本差不多会超过另外增加磁盘驱动器,你应该在设计时就避免增加 OSD 存储驱动器的负担来提升性能。
9、ceph允许你在每块硬盘驱动器上运行多个OSD,但这会导致资源竞争并降低总体吞吐量;ceph也允许把日志
和对象数据存储在相同驱动器上,但这会增加记录写日志并回应客户端的延时,因为ceph必须先写入日志才会回应确认了写动作。
btrfs文件系统能同时写入日志数据和对象数据,xfs和ext4却不能。
10、ceph最佳实践指示,你应该分别在单独的硬盘运行操作系统、OSD数据和OSD日志。
/========================================================================/

/*******************/
Time:2014-11-8
Author:skdkjzz
/******************/
SSD:
1、一种提升性能的方法是使用固态硬盘(SSD)来降低随机访问时间和读延时,同时增加吞吐量。SSD和硬盘相
比每GB成本通常要高10倍以上,但访问时间至少比硬盘快100倍。
2、SSD局限性在于顺序读写性能,SSD没有可移动机械部件,所以不存在和硬盘一样的局限性。但SSD也有局限性,评估SSD时,顺序读写性
能很重要,在为多个OSD存储日志时,有着400MB/s顺序读写吞吐量的SSD其性能远高于120MB/s的。
3、在大量投入SSD前,我们强烈建议核实SSD的性能指标,并在测试环境下衡量性能。
4、SSD没有移动机械部件,很适合ceph中不需要太多存储空间的地方,但是对SSD性能衡量需要注意一下几点:
 4.1)IOPS指标,又何为IOPS指标?
 4.2)写密集语义:记日志涉及写密集语义,所以你要确保选用的SSD写入性能和硬盘相当或好于硬盘。廉价SSD可能在加速访问的同时
 引入写延时,有时候高性能硬盘的写入速度可以和便宜SSD相媲美。又何为写密集语义?
 4.3)顺序写入:在一个SSD上为多个OSD存储多个日志时也必须考虑SSD的顺序写入极限,因为它们要同时处理多个OSD日志的写入请求。
 4.4)分区对齐:采用了SSD的一个常见问题是人们喜欢分区,却常常忽略了分区对齐,这会导致SSD的数据传输速率慢很多,所以请确保分区对齐了。
5、SSD用于对象存储太昂贵了,但是把OSD的日志存到SSD、把对象数据存储到独立的硬盘可以明显提升性能。osd_journal选项的默认值是
/var/lib/ceph/osd/$cluster-$id/journal,你可以把它挂载到一个SSD或SSD分区,这样它就不再是和对象数据一样存储在同一个硬盘上的文件了 。
6、提升CephFS文件系统性能的一种方法是从CephFS文件内容里分离出元数据。ceph提供了默认的metadata存储池来存储CephFS元数据,所以你不需要给
CephFS元数据创建存储池,但是可以给它创建一个仅指向某主机SSD的CRUSH运行图。又何为CRUSH运行图?

Controller:
1、优秀的ceph的性能问题探讨可以参考ceph相关blog--见ceph-docs_zh-v1.3.pdf,页码为p23
2、硬盘控制器对写吞吐量有显著影响,需慎重选择,以免造成性能瓶颈(bottleneck)

Others_Notes:
1、可以在同意主机运行多个osd,但是需保证osd硬盘吞吐量不超过为客户端提供读写服务所需网络带宽。
2、还应考虑集群在每台主机上存储的数据占总体的百分比,如果一台主机所占百分比太多而挂了,那么就可能导致诸如full ratio(满载满负荷)的问题,
那么ceph会中止运行来防止数据丢失。
3、如果每台主机运行多个osd,请保证内核是最新的,来确保硬件性能可达期望值。

Network:
1、建议每台机器最少两个千兆网卡,现在大多数机械硬盘都能达到大概100MB/s的吞吐量,网卡应该能处理所有OSD硬盘总吞吐量,所以推荐最少两个千兆网卡,
分别用于公网(前端)和集群网络(后端)。集群网络(最好别连接到国际互联网)用于处理由数据复制产生的额外负载,而且可防止拒绝服务攻击,拒绝服务攻击
会干扰数据归置组,使之在OSD数据复制时不能回到active+clean状态。请考虑部署万兆网卡。通过1Gbps网络复制1TB数据耗时3小时,而3TB(典型配置)需要9小时,
相比之下,如果使用10Gbps复制时间可分别缩减到20分钟和1小时。在一个PB级集群中,OSD磁盘失败是常态,而非异常;在性价比合理的的前提下,系统管理员
想让PG尽快从degraded(降级)状态恢复到 active+clean 状态。另外,一些部署工具(如Dell的Crowbar)部署了5个不同的网络,但使用了VLAN以提高网络和硬件可管理性。
VLAN使用802.1q协议,还需要采用支持VLAN功能的网卡和交换机,增加的硬件成本可用节省的运营(网络安装、维护)成本抵消。使用VLAN来处理集群和计算栈
(如 OpenStack、 CloudStack 等等)之间的VM流量时,采用10G网卡仍然值得。每个网络的机架路由器到核心路由器应该有更大的带宽,如40Gbps到100Gbps。
又何为VM流量?
2、服务器应配置底板管理控制器(Baseboard Management Controller, BMC),管理和部署工具也应该大规模使用BMC,所以请考虑带外网络管理的成本/效益平衡,
此程序管理着SSH访问、VM映像上传、操作系统安装、端口管理、等等,会徒增网络负载。运营3个网络有点过分,但是每条流量路径都指示了部署一个大型数据集群前
要仔细考虑的潜能力、吞吐量、性能瓶颈。

Failure_Domain:
1、故障域指任何导致不能访问一个或多个OSD的故障,可以是主机上停止的进程、硬盘故障、操作系统崩溃、有问题的网卡、损坏的电源、断网、断电等等。规划硬件需求时,
要在多个需求间寻求平衡点,像付出很多努力减少故障域带来的成本削减、隔离每个潜在故障域增加的成本。

HardWare_choose:
1、参考文档ceph-docs_zh-v1.3.pdf,页码为p24。
2、如果在只有一块硬盘的机器上运行OSD,要把数据和操作系统分别放到不同分区;一般来说,我们推荐操作系统和数据分别使用不同的硬盘。

/*******************/
Time:2014-11-9
Author:skdkjzz
/******************/
OS_Recommentdations:
1、推荐在较新的Linux发行版上部署ceph。
2、在btrfs上运行ceph,推荐使用Linux内核版本高于v3.5。又何为btrfs?
3、syncfs(2):对非btrfs文件系统(像XFS和ext4)而言,在一台服务器上运行了多个ceph-osd守护进程时,ceph使用syncfs(2)系统调用时效率高
得多(此功能在2.6.39内核和glibc-2.14加入)。又何为syncfs(2)?

Platfrom:
1、一般来说,ceph对Linux内核和系统初始化阶段的依赖很少(sysvinit、upstart、systemd)。又何为sysvinit、upstart、systemd?
2、Notes:
 2.1)默认内核的btrfs版本较老,不推荐用于ceph-osd储存节点,要升级到推荐的内核,或者改用xfs或ext4。
 2.2)默认内核带的ceph客户端较老,不推荐做内核空间客户端(内核rbd或ceph文件系统),请升级至推荐内核。
 2.3)已安装glibc版本不支持syncfs(2)系统调用,同一台机器上使用xfs或ext4的ceph-osd守护进程性能一般,它可以更好。

Testing:
1、我们持续地在这个平台上编译所有分支、做基本单元测试;也为这个平台构建可发布软件包。
2、我们在这个平台上做基本的安装和功能测试。
3、我们在这个平台上持续地做全面的功能、退化、压力测试,包括开发分支、预发布版本、正式发布版本。

Installing Ubuntu/debian Packages:p27

1、install release key:
 1.1)软件包都使用进行release.asc密钥加密签名过,把发布密钥添加到系统可信密钥列表中可避免安全警告,运行命令如下:
 wget -q -O- 'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/release.asc' | sudo apt-key add
2、Add release packeages:
 2.1)稳定版-bobtail是ceph最新的主要发布,适用任何想在生产环境下部署ceph,重大的bug已经修复。把软件库添加到apt源列表,运行命令如下:
 echo deb 
http://ceph.com/debian-bobtail/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
 2.2)稳定版-argonaut是ceph前一个的主要发布,适用已经在生产环境下部署了argonaut又没准备好升级。把软件库添加到apt源列表,运行命令如下:
 echo deb 
http://ceph.com/debian-argonaut/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
3、install packages-ceph:
 3.1)把正式发布或者开发包添加到apt源列表中,要更新apt数据库,在安装ceph。运行命令如下:
 sudo apt-get update && sudo apt-get install ceph

 
RPM packages install-centos&redhat:
1、rpm安装和ubuntu下类似,详见p29

Update Ceph:
1、可以逐个升级集群中的守护进程:
 1.1)登录主机升级ceph包
 1.2)重启ceph守护进程
 1.3)确认集群是健康,运行正常
 1.4)Notes:important-->一旦升级守护进程就无法降级!

2、depend relation,升级顺序如下:
 2.1)Monitors(or Osds)
 2.2)Osds(or Monitors)
 2.3)Metadata Servers
 2.4)RADOS Gateway
 Notes:
 作为一般规则,推荐一次性升级同一类型的所有守护进程(如所有ceph-osd守护进程、所有ceph-mon等等)以保证它们都处于同一版本。同时建议
 您升级完集群中的所有守护进程后再练习那个版本的新功能。
3、Upgrading OSD Steps:
 3.1)Upgrade the OSD package--> ssh {osd-host} && sudo apt-get update && sudo apt-get install ceph
 3.2)Restart the OSD, where N is the OSD number--> service ceph restart osd.N
 3.3)Ensure the upgraded OSD has rejoined the cluster--> ceph osd stat
 3.4)成功升级一个OSD后,再继续其它的,直到完成所有OSD。
4、Upgrading Monitors:
 4.1)Upgrade the ceph package--> ssh {mon-host} && sudo apt-get update && sudo apt-get install ceph
 4.2)Restart the monitor--> service ceph restart mon.{name}
 4.3)Ensure the monitor has rejoined the quorum--> ceph mon stat
 4.4)成功升级一个监视器后,再继续其它的,直到完成所有监视器。
5、Upgrading a Metadata Server:
 5.1)Upgrade the ceph package--> ssh {mds-host} && sudo apt-get update && sudo apt-get install ceph
 5.2)Restart the metadata server--> service ceph restart mds.{name}
 5.3)Ensure the metadata server is up and running--> ceph mds stat  
 5.4)成功升级一个元数据服务器后,再继续其它的,直到完成所有元数据服务器。
6、Upgrading a Client:
 6.1)Upgrade the package--> ssh {client-host} && apt-get update && sudo apt-get install ceph-common librados2 librbd1 python-ceph
 6.2)Ensure that you have the latest version--> ceph --version

Argonaut update to Bobtail:
1、Notes:
 1.1)现在默认开启了认证,但以前默认关闭
 1.2)监视器使用了新的内部on-wire协议(一个时间同步协议?)
 1.3)使用RBD format 2格式的映像前要先升级完所有OSD。
 1.4)bobtail版支持format 2格式的映像!若ceph-osd未完全升级完成,不可以使用format 2格式。检查集群版本命令如下:
 ceph osd ls 和 ceph tell osd.N version ,其中ceph osd ls 会列出集群里所有OSD的ID,循环脚本示例:
 {
 for i in $(ceph osd ls); do
  ceph tell osd.${i} version
 done
 }
 1.5)具体开始细节见p33。

Build Ceph Prerequisites,in other words,Cpeh depend other libs or tools:
1、在 Ubuntu上,执行sudo apt-get install安装缺失依赖,运行命令如下:
 1.1)sudo apt-get install autotools-dev autoconf automake cdbs gcc g++ git libboost-dev libedit-dev libssl-dev libtool libfcgi libfcgi-dev libfuse-dev linux-kernel-headers libcrypto++-dev libcrypto++ libexpat1-dev
 1.2)sudo apt-get install uuid-dev libkeyutils-dev libgoogle-perftools-dev libatomic-ops-dev libaio-dev libgdata-common libgdata13 libsnappy-dev libleveldb-dev

Building Ceph:
1、具体安装步骤及注意事项如下:
 1.1):进入ceph source,执行命令如下
 {
  cd ceph
  ./autogen.sh
  ./configure --prefix=?
  make
 }
 1.2)根据你的系统可以用 make -j 同时运行多个任务,例如make -j4在双核CPU上会编译得更快。
 1.3)安装ceph到本地,执行命令--> sudo make install

Installing Oprofile:
1、分析ceph CPU消耗情况的最简方法就是用系统级的oprofile--> sudo apt-get install oprofile oprofile-gui

Compiling Ceph for Profiling:
1、编译适合分析的ceph:
 1.1)先清理先前编译--> make distclean
 1.2)查看输出调用图--> export CFLAGS="-fno=omit-frame-pointer -O2 -g"
 1.3)最终编译-->
 {
  ./autogen.sh
  ./configure
  make
 }
 1.4)超线程编译选项-->make -j4
 
/*******************/
Time:2014-11-10
Author:skdkjzz
/******************/
RADOS About:
1、ceph 集群可以包含数千个存储节点,最小系统至少需要二个OSD才能做到数据复制。要配置OSD集群,你得把配置写入
配置文件,ceph对很多选项提供了默认值,你可以在配置文件里覆盖它们;另外,你可以使用命令行工具修改运行时配置。
2、ceph 启动时要激活三种守护进程:
 2.1)ceph-osd
 2.2)ceph-mon
 2.3)ceph-mds
3、Hard disk prep:
 3.1)如果文件系统日志在原始硬盘上,就需要禁用写缓存:新的内核(big than v2.6.33)不需要禁用
 3.2)禁用硬盘的写缓存功能--> sudo hdparm -W 0 /dev/hda 0
 3.3)在生产环境,建议您在系统盘运行OSD,在另外的硬盘里放数据。如果必须把数据和系统放在一个硬盘里,最好给数据分配一个单独的分区。
4、Fs depend:
 4.1)ceph的OSD依赖于底层文件系统的稳定性和性能。
 4.2)当前,我们推荐部署生产系统时使用xfs文件系统,建议用btrfs做测试、开发和其他不太要紧的部署。我们相信,长期来看btrfs适合ceph的功能需求和发展方向,
 但是xfs和ext4能提供当前部署所必需的稳定性。btrfs开发在迅速推进,用户应该有能力经常更新到最新内核发布,而且能跟踪严重bug的修正进度。
 4.3)ceph的OSD有赖于底层文件系统的扩展属性(XATTR)存储各种内部对象状态和元数据。底层文件系统必须给XATTR提供足够容量,btrfs没有限制
 随文件存储的xattr元数据;xfs的限制相对大(64KB),多数部署都不会有瓶颈;ext4的则太小而不可用。
 4.4)要用这些文件系统,你得把下面这行写入ceph.conf的[osd]段里--> filestore xattr use omap = true
5、xfs、btrfs比较:
 5.1)xfs和btrfs相比较ext3/4而言,在高伸缩性数据存储方面有几个优势,xfs和btrfs都是日志文件系统,这使得在崩溃、断电后恢复时更健壮,
 因为文件系统在写入数据前会先记录所有变更。
 5.2)xfs由Silicon Graphics开发,是一个成熟、稳定的文件系统。相反,btrfs是相对年轻的文件系统,它致力于实现系统管理员梦寐以求的大规模数据存储基础,
 和其他Linux文件系统相比它有独一无二的功能和优势。
 5.3)btrfs是写时复制(copy-on-write, cow)文件系统,它支持文件创建时间戳和校验和(可校验元数据完整性)功能,所以它能探测到数据坏副本,
 并且用好副本修复。写时复制功能是说btrfs支持可写文件系统快照。btrfs也支持透明压缩和其他功能。
 5.4)btrfs也集成了多设备管理功能,据此可以在底层支持异质硬盘存储,和数据分配策略。未来开发社区还会提供fsck、拆分、数据加密功能,这些诱人的功能正是ceph集群的理想选择。
 
Configure Ceph:
1、典型的ceph集群中至少要运行下面四种守护进程中的一种:
 1.1)ceph-osd 对象存储设备
 1.2)ceph-mon 监视器
 1.3)ceph-mds 元数据服务器
 1.4)radosgw(ceph gateway) ceph网关
 1.5)为方便起见,每个守护进程都有一系列默认值(参见 ceph/src/common/config_opts.h),你可以用ceph配置文件覆盖这些设置。

2、configfile--> ceph.conf:
 2.1)启动ceph集群时,每个守护进程都从ceph.conf里查找它自己的配置。
 2.2)手动配置时,你需要创建ceph.conf来配置集群-->详见p43。
 2.3)ceph文件使用ini风格的语法,以分号(;)和井号(#)开始的行是注释。
 2.4)一个例程由类型和它的例程编号(ID)确定,OSD的例程ID只能是数字,监视器和元数据服务器的ID可包含字母和数字。
 2.5)元变量大大简化了集群配置,ceph会把配置的元变量展开为具体值;元变量功能很强大,可以用在[global] 、[osd] 、
 [mon] 、[mds]段里,类似于bash的shell扩展-->详见p45。
 2.6)理想情况下一台主机应该只 运行一类进程,例如:一台主机运行着ceph-osd进程,另一台主机运行着ceph-mds进程,ceph-mon进程又在另外一台主机上。
 2.7)每个主机都有一个标识名称(系统配置),监视器可用addr选项指定网络地址和端口(如域名或IP地址),基本配置可以只指定最小配置。例如:
 {
  [mon.a]
   host = hostName
   mon addr = 150.140.130.120:6789
  [osd.0]
   host = hostName
  
  Notes:
  2.7.1)主机名设置是主机的短名字,不是正式域名FQDN,也不是IP地址;在执行hostname -s就可以得到短名字。
  此设置只在mkcephfs和手动部署时用到,用chef部署ceph时不必要。
 }
 2.8)监视器默认监听 6789 端口,元数据服务器和OSD监听从6800开始的第一个可用端口;要确保监听6789端口的是监视器进程,每个OSD或元数据服务器进程
 监听了从6800开始的端口。每个主机使用的端口数量都是确定的,所以你没必要多开端口。但有些时候进程失败后重启却没释放旧端口,就会绑定到了新端口,
 所以要多留些端口作备用。如果你的部署区分了集群网和公网,你也许需要给每个网络写相应配置。网络端口配置示例命令:
 iptables -A INPUT -m multiport -p tcp -s {ip-address}/{netmask} --dports 6789,6800:6810 -j ACCEPT
 2.9)使用两个分开的网络:
  2.9.1)OSD给客户端做数据复制时,如果副本数大于1,客户端和ceph集群间的网络负载会很容易增大,这会导致延时增大和性能下降,ceph处于Degrade。
  2.9.2)拒绝服务攻击(DoS),当攻击OSD间的流量中断时,归置组就再也不能进入active+clean状态了,它也会阻止用户读写数据。
  2.9.3)最好的办法就是彻底分开集群网和公网。详见p47
  {
   2.9.3.1)要配置这样的网络,把下面的选项加到ceph.conf里的[global]段下:
   {
   [global]
     public network {public-network-ip-address/netmask}
     cluster network {enter cluster-network-ip-address/netmask}
   }
   2.9.3.2)要让ceph主机使用分开的网络,把下面的选项设置在守护进程例程下面:
   {
   [osd.0]
    public addr {host-public-ip-address}
    cluster addr {host-cluster-ip-address}   
   }
  }
 2.10)典型的ceph生产集群至少部署3个监视器来确保高可靠性,它允许一个监视器例程崩溃。奇数个监视器确保PAXOS算法能确定
 一批监视器里哪个版本的集群运行图是最新的。
 2.11)一个ceph 集群可以只有一个监视器,但是如果它失败了,因没有监视器数据服务就会中断。
 2.12)ceph监视器默认监听6789端口:
 {
  [mon.a]
    host = hostName
    mon addr = 150.140.130.120:6789
  Notes:
  1)默认情况下,ceph会在下面的路径存储监视器数据--> /var/lib/ceph/mon/$cluster-$id
  2)你必须自己创建对应的目录,前述的元变量必须先展开,名为ceph的集群将展开为--> /var/lib/ceph/mon/ceph-a
  3)你可以用mon data选项更改默认路径,但我们不推荐修改。用下面的命令在新监视器主机上创建默认目录,运行命令如下:
  ssh {new-mon-host} && sudo mkdir -p /var/lib/ceph/mon/ceph-{mon-letter}
 }
 2.13)典型的生产集群里,一个数据盘上运行一个OSD进程;典型部署要指定日志尺寸、文件存储的扩展属性(XATTR)是否使用对象图(如运行在ext4之上),例如:
 {
 [osd]
  osd journal size = 10000
  filestore xattr use omap = true #enables the object map. Only if running ext4.
 [osd.0]
  hostname = {hostname}
 Notes:
  1)默认ceph认为你把OSD数据存储在下面的路径下:--> /var/lib/ceph/osd/$cluster-$id
  2)你必须创建对应目录,名字为ceph的集群其元变量完全展开后,前述的目录将是--> /var/lib/ceph/osd/ceph-0
  3)你可以用mon data选项更改默认路径,但我们不推荐修改。用下面的命令在新监视器主机上创建默认目录,运行命令如下:
  ssh {new-osd-host} && sudo mkdir -p /var/lib/ceph/osd/ceph-{osd-number}
  4)osd data路径应该指向一个硬盘的挂载点,这个硬盘应该独立于操作系统和守护进程所在硬盘。按下列步骤准备好并挂载:
  ssh {new-osd-host} && sudo mkfs -t {fstype} /dev/{disk} && sudo mount -o user_xattr /dev/{hdd} /var/lib/ceph/osd/ceph-{osd-number}
  5)我们推荐用xfs或btrfs文件系统,命令是mkfs
  6)ceph默认把OSD日志存储在下面的路径--> /var/lib/ceph/osd/$cluster-$id/journal
  7)没有性能优化时,ceph把日志和OSD数据存储相同的硬盘上;要优化OSD性能,可以把日志分离到单独的硬盘上(例如,固态硬盘能提供高日志性能)。
  8)ceph的osd journal size默认值是0,所以你得在 ceph.conf里设置,日志尺寸应该至少2倍于filestore min sync interval的值和预计吞吐量的乘积:
  osd journal size = {2 * (expected throughput * filestore min sync interval)}
  9)预计吞吐量应该包括硬盘吞吐量(持续的数据传输速度)和网络吞吐量,例如,7200转的硬盘速度大概是100MB/s,取硬盘和网络吞吐量中较小的一个
  应该能提供合理的预计吞吐量。一些用户以 10GB 起步,例如--> osd journal size = 10000 (unit is MB?)
 }
 2.14)journal and debug:
  2.14.1)为打 ceph的调试输出(例如,dout()),你可以在配置文件里添加调试选项。ceph的日志级别在 1 到 20 之间,1 是简洁、20 是详细。对每个
  进程都相同的子系统可以在[global]下配置,对特定守护进程的子系统要配置在进程段下,如[mon] 、[osd] 、[mds] 下。 例如:
  {
   [global]
     debug ms = 1
   [mon]
     debug mon = 20
     debug paxos = 20
     debug auth = 20
   [osd]
     debug osd = 20
     debug filestore = 20
     debug journal = 20
     debug monc = 20
   [mds]
     debug mds = 20
     debug mds balancer = 20
     debug mds log = 20
     debug mds migrator = 20
   Notes:
   1)你的系统运行良好的时候,应该选择合适的日志级别、关闭不必要的调试设置来确保集群运行在最佳状态。记录调试输出相 对慢,且浪费资源。
   2)每个子系统的日志都有它自己的输出级别、和内存存留级别。你可以给每个子系统分别设置不同的日志文件和内存日志级别,例如:
   {
    debug {subsystem} {log-level}/{memory-level}
    #for example
    debug mds log 1/20 (log/memory level)
   }
  }
 2.15)EXAMPLE CEPH.CONF:
 {
  [global]
   auth supported = cephx
  [osd]
   osd journal size = 1000
   # uncomment the following line if you are mounting with ext4
   # filestore xattr use omap = true
  [mon.a]
   host = myserver01
   mon addr = 10.0.0.101:6789
  [mon.b]
   host = myserver02
   mon addr = 10.0.0.102:6789
  [mon.c]
   host = myserver03
   mon addr = 10.0.0.103:6789
  [osd.0]
   host = myserver01
  [osd.1]
   host = myserver02
  [osd.2]
   host = myserver03
  [mds.a]
   host = myserver01
 }
 2.16)Running Changes:
  2.16.1)ceph可以在运行时更改ceph-osd、ceph-mon、ceph-mds守护进程的配置:
  ceph {daemon-type} tell {id or *} injectargs '--{name} {value} [--{name} {value}]'
  2.16.2)用osd、mon、mds中的一个替代{daemon-type},你可以用星号(*)或具体进程ID(其数字或字母)把运行时配置应用到一类进程的所有例程,
  例如增加名为osd.0的ceph-osd进程的调试级别的命令如下--> ceph osd tell 0 injectargs '--debug-osd 20 --debug-ms 1'
  2.16.3)在ceph.conf文件里配置时用空格分隔关键词,但在命令行使用的时候要用下划线或连字符(_或-)分隔,例如--> debug osd 变成 debug-osd。
 2.17)viewing Configuration at Runtime:
  2.17.1)如果你的ceph集群在运行,而你想看一个在运行进程的配置,用下面的命令:
  ceph --admin-daemon {/path/to/admin/socket} config show | less
  2.17.2)每个守护进程的管理套接字默认路径如下--> /var/run/ceph/$cluster-$name.asok
  2.17.3)元变量将展开为实际的集群名和进程名,例如如果集群名是ceph(默认值),你可以用下面的命令检索osd.0的配置:
  ceph --admin-daemon /var/run/ceph/ceph-osd.0.asok config show | less
 2.18)ceph-Filestore-config:
  2.18.1)扩展属性(XATTR)是配置里的重要方面。一些文件系统XATTR大小有限制,而且在一些情况下文件系统存储XATTR的速度
  不如其他方法,下面的设置通过使用独立于文件系统的存储方法能帮你提升性能。详见p64
  2.18.2)filestore需要周期性地静默写入、同步文件系统,这创建了一个提交点,然后就能释放相应的日志条目了。较大的同步频率
  可减小执行同步的时间及保存在日志里的数据量;较小的频率使得后端的文件系统能优化归并较小的数据和元数据写入,因此可能使同步更有效。
  2.18.3)文件存储回写器强制使用同步文件排列来写出大块数据,这样处理有望减小最终同步的代价。实践中,禁用 "filestore flusher"有时候能提升性能。
  2.18.4)QUEUE-->可以设置文件存储队列的相关属性,详见p65
  2.18.5)TIMEOUT-->可以设置关于线程超时值以及提交操作超时值。
  2.18.6)btrfs相关配置
  2.18.7)Journal相关配置
 2.19)Journal-config:
  2.19.1)ceph的OSD使用日志的原因有二:速度和一致性。
  2.19.2)速度:日志允许OSD快速地提交小块数据的写入,ceph把小片、随机IO依次写入日志,这样,后端文件系统就有机会归并写入动作,并最终提升并发承载力。
  因此,使用OSD日志能展现出优秀的瞬间写性能,实际上却没有任何写动作,因 为文件系统把它们捕捉到了日志。
  2.19.3)一致性:ceph的OSD需要一个能保证原子操作的文件系统接口。OSD把一个操作的描述写入日志,然后把操作应用到文件系统,这需要原子更新一个对象
  (例如归置组元数据)。每隔一段filestore max sync interval和filestore min sync interval之间的时间,OSD停止写入、把日志同步到文件系统,这样允许OSD
  修整日志里的操作并重用空间。失败后,OSD从上次的同步点开始重放日志。详见p96

Ceph deployment:
 1、你可以用很多其它部署系统(如Chef、Juju、Puppet、Crowbar)安装chef,如果你只想测试一下,ceph提供了最小化安装工具,它只依赖SSH和DNS。你得手动设置SSH和DNS。
 2、提供了轻量级部署脚本供您评估ceph,专业的部署应该考虑用专业的部署系统,像Chef、Juju、Puppet、Crowbar。
 3、要配置一个测试或开发集群,你可以用mkcephfs工具。
  3.1)允许以root身份登录集群主机。详见p75
  3.2)ceph的mkcephfs 脚本不会把管理主机上创建的配置文件拷贝到OSD主机,所以你得手动拷贝,例如:
  ssh myserver01 sudo tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
  3.3)创建默认目录--> sudo mkdir /var/lib/ceph/mon/ceph-a
  3.4)如果你在每台主机上都要运行多个OSD进程,应该先把这些硬盘分别挂载到其数据目录下。
 4、运行mkcephfs:
  4.1)cd /etc/ceph && sudo mkcephfs -a -c /etc/ceph/ceph.conf -k ceph.keyring(这个脚本把一个管理密钥添加到了ceph.keyring 里,它和root密码的功能类似)
  4.2)启动或关闭集群时不必使用sudo或者提供密码--> service ceph -a start
  
Install chef:
 1、chef定义了三种实体:
  1.1)cheh节点:运行chef-client客户端,用来安装和管理软件
  1.2)chef服务器:在chef节点上和chef-client交互
  1.3)chef工作站:管理chef服务器
 2、Create ceph user:
  2.1)chef-client命令需要合适的特权才能安装和管理软件,他应该有所有 root 特权,例如:
  ssh 
user@chef-node && sudo useradd -d /home/chef -m chef && sudo passwd chef
  2.2)执行下面的命令给chef用户分配所有特权--> echo "chef ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/chef && sudo chmod 0440 /etc/sudoers.d/chef
  2.3)如果你所用的sudo不能包含其它配置文件,你要把下面这行添加到/etc/sudoers--> chef ALL = (root) NOPASSWD:ALL
  2.4)Important--> 不要更改/etc/sudoers的权限位,请用visudo或sudoedit编辑
  2.5)为chef客户端生成ssh密钥,详见p78
  2.6)chef依赖 Ruby,选择适合您当前发行版的Ruby版本并且安装到所有主机--> sudo apt-get update && sudo apt-get install ruby
  2.7)chef服务器托管在Opscode,记录chef服务器的正式域名或IP地址,knife和chef-client要用到。详见p79
  2.8)在chef服务器上安装Opscode密钥环、hef和chef服务器--> sudo apt-get update && sudo apt-get upgrade && sudo apt-get install opscode-keyring chef chefserver
  2.9)安装器完成、启动chef服务器后,你可以在浏览器输入正式域名或者IP地址启动chef的WEB界面--> 
http://fqdn-or-ip-address.com:4000
  2.10)配置knife:
  {
   2.10.1)chef服务器安装完后,要在chef工作站安装knife。如果chef服务器是远程主机,先ssh登录--> ssh 
[email protected]
   2.10.2)在/home/chef目录下创建隐藏目录--> mkdir -p ~/.chef
   2.10.3)服务器会给chef服务器安装者生成认证和web UI证书,并设置合适的读写权限位,把它们 从/etc/chef拷贝到~/.chef,然后把所有者改为当前用户:
   sudo cp /etc/chef/validation.pem /etc/chef/webui.pem ~/.chef && sudo chown $(id -u):$(id -g) ~/.chef/*.pem
   2.10.4)在当前用户的目录下,用一个初始化API客户端配置knife--> knife configure -i
   */???~skdkjzz
  }
  2.11)add a cookbook path:
   2.11.1)在你的chef工作站上把cookbook_path添加到 ~/.chef/knife.rb 配置文件里,例如--> cookbook_path '/home/{user-name}/chef-cookbooks/'
   2.11.2)路径不存在的话先创建--> mkdir /home/{user-name}/chef-cookbooks (本地副本位置,稍后上传到chef服务器)
   2.11.3)把validation.pem拷贝到所有节点,把chef服务器上的/etc/chef/validation.pem文件拷贝到每个chef节点,在chef服务器上的命令行shell执行
   下面的命令(用节点主机名替代{nodename}):
   {
    sudo cat /etc/chef/validation.pem | ssh {nodename} "exec sudo tee /etc/chef/validation.pem >/dev/null"
   }
   2.11.4)在每个节点运行chef-client,以注册到chef服务器--> ssh chef-node && sudo chef-client
   2.11.5)检查下是否安装好了所有chef节点--> knife node list
   
ceph Deploying with chef;
 1、To get the cookbooks for Ceph
 {
  cd ~/chef-cookbooks
  git clone 
https://github.com/opscode-cookbooks/apache2.git
  git clone https://github.com/ceph/ceph-cookbooks.git ceph
 }
 2、Add The Required Cookbook Paths:
  2.1)如果你安装chef的时候添加了默认菜谱路径,knife无需过多配置就可以上传克隆的菜谱了。
  2.2)如果你要使用另一个路径,或者克隆的菜谱仓库树结构不同,把路径添加到你的knife.rb文件里,cookbook_path可以是字符串或字符串阵列,例如:
  cookbook_path '/home/{user-name}/chef-cookbooks/' --> change to:
  {
   cookbook_path [
    '/home/{user-name}/chef-cookbooks/',
    '/home/{user-name}/chef-cookbooks/{another-directory}/',
    '/some/other/path/to/cookbooks/'
   ]
  }
  2.3)install cookbook_path:
   2.3.1)要安装ceph,你必须把ceph和Apache菜谱(RADOSGW依赖)上传到chef服务器--> knife cookbook upload apache2 ceph
 3、configure your ceph environment:
  3.1)chef支持多种环境下的软件安装,你给ceph创建的环境需要一个fsid、监视器的密钥(如果启用了cephx认证)、监视器的短主机名。
  3.2)至于文件系统ID,可以用uuid-runtime包里的uuidgen工具生成一个唯一的标识符-->  uuidgen -r
  3.3)用ceph-authtool为监视器生成密钥:
  {
   sudo apt-get update
   sudo apt-get install ceph-common
   ceph-authtool /dev/stdout --name=mon. --gen-key
   Notes:
   3.3.1)密钥是"key = "右边的值, 长相如下:
     AQBAMuJPINJgFhAAziXIrLvTvAz4PRo5IK/Log==
  }
  3.4)要给ceph创建环境,先设置一个命令行编辑器,例如:
   export EDITOR=vim
  3.5)用knife创建环境:
   knife environment create {env-name} :example--> knife environment create Ceph
 4、configure roles:
  4.1)分别用它们的角色文件给 OSD、监视器、元数据服务器、RADOS网关创建角色:
  {
   cd ~/chef-cookbooks/ceph
   knife role from file roles/ceph-osd.rb
   knife role from file roles/ceph-mon.rb
   knife role from file roles/ceph-mds.rb
   knife role from file roles/ceph-radosgw.rb
  }
 5、Configure Nodes:
  5.1)每个规划到ceph集群里的节点都必需配置,用下面的命令标识节点--> knife node list
  5.2)对规划的ceph集群的每个节点,都要用下面的命令配置--> knife node edit {node-name}
  5.3)要配置的节点的配置信息应该出现在文本编辑器里,把chef_environment的值改为ceph(你给ceph环境设置的名字)
  5.4)在所有节点的run_list里添加"recipe[ceph::apt]",这是第一个配置,这样chef就能安装或更新必要的软件包了。至少然后添加下面几行中的一个:
  {
  "role[ceph-mon]"
  "role[ceph-osd]"
  "role[ceph-mds]"
  "role[ceph-radosgw]"
  }
  5.5)如果你添加的角色不止一个,要用逗号分隔。用hostname命令的结果替换配置里name的值{hostname}作为节点的主机名:
  {//alter by kj 
   {
    "chef_environment": "Ceph",
    "name": "{hostname}",
    "normal": {
    "tags": [
    ]
    },
    "run_list": [
    "recipe[ceph::apt]",
    "role[ceph-mon]",
    "role[ceph-mds]"
    ]
   }
  }//end alter by kj 
 6、Prepare Osd Disks:
  6.1)给一个节点配置了OSD角色意味着这个节点要运行至少一个OSD 进程,你可以在一台主机上运行很多OSD,例如,
  你可以给系统里每个数据盘配置一个ceph-osd守护进程。这个步骤准备好OSD硬盘并且告诉chef这个节点将运行多少个OSD。
  6.2)ceph版本是0.48时要安装gdisk--> sudo apt-get install gdisk
  6.3)对ceph0.48版来说,用下面的命令配置每个OSD所用的存储数据硬盘,用uuidgen -r命令生成的UUID替{fsid}:
  sudo sgdisk /dev/{disk} --zap-all --clear --mbrtogpt --largest-new=1 --change-name=1:'ceph data' --typecode=1:{fsid}
  6.4)创建文件系统、然后把它分配给集群,执行ceph-disk-prepare的时候要指定一个文件系统(如 ext4、xfs或btrfs),记得用uuidgen -r生成的UUID替代{fsid}:
  {
   sudo mkfs -t ext4 /dev/{disk}
   sudo mount -o user_xattr /dev/{disk} /mnt
   sudo ceph-disk-prepare --cluster-uuid={fsid} /mnt
   sudo umount /mnt
  }
  6.5)最后,模拟一个热插拔事件--> sudo udevadm trigger --subsystem-match=block --action=add
  6.6)完成前面的步骤后,必须在每个节点运行chef-client--> sudo chef-client
  6.7)
 
Operated cluster:
高级操作:
 高级集群操作主要包括用服务管理脚本启动、停止、重启集群、和集群健康状态检查、监控和操作集群。
 1、ceph服务提供了启动、重启、停止ceph集群,每次执行的时候必须指定至少一个选项和一个命令,还必须指定一个守护进程类型或例程名称:
 sudo service ceph [options] [commands] [daemons]
 2、较老版本可以使用--> sudo /etc/init.d/ceph [options] [commands] [daemons]
 3、ceph服务的选项包括:
 {
  Option Shortcut Description
  --verbose   -v   Use verbose logging.
        详细的日志。
  
  --valgrind   N/A  (Dev and QA only) Use Valgrind debugging.
        (只适用于开发者和品质保证人员)使用Valgrind调试。
  
  --allhosts   -a   Execute on all hosts in ceph.conf.  Otherwise, it only executes on localhost.
        在ceph.conf里配置的所有主机上执行,否则它只在本机执行。
  
  --restart   N/A  Automatically restart daemon if it core dumps.
        核心转储后自动重启。
  
  --norestart  N/A  Don’t restart a daemon if it core dumps.
        核心转储后不自动重启。
  
  --conf    -c   Use an alternate configuration file.
        使用另外一个配置文件。
 }
 4、ceph服务的命令包括:
 {
  Command    Description
  start     Start the daemon(s).
  stop     Stop the daemon(s).
  forcestop    Force the daemon(s) to stop. Same as kill -9
  killall    Kill all daemons of a particular type.
  cleanlogs    Cleans out the log directory.
  cleanalllogs   Cleans out everything in the log directory.
 }
 5、至于子系统操作,ceph服务能指定守护进程类型,在[daemons]处指定守护进程类型就行了,守护进程类型包括--> mon、osd、mds:
  5.1)ceph服务的[daemons]设置也可以指定一个具体例程--> sudo /etc/init.d/ceph -a start osd.0 (这里osd.0是集群里的第一个OSD)
 6、Starting A Cluster:
  6.1)要启动ceph集群,执行ceph的时候加上start命令--> sudo service ceph start [options] [start|restart] [daemonType|daemonID]
   较老的版本可以执行--> sudo /etc/init.d/ceph [options] [start|restart] [daemonType|daemonID]
  6.2)典型用法:
  {
   sudo service ceph -a start
   sudo /etc/init.d/ceph -a start   
  }
  6.3)使用-a选项可操作整个集群,你也可以指定一个具体的守护进程例程把操作限制到一个单独的例程:
  sudo /etc/init.d/ceph start osd.0
 7、Stoping A Cluster:
  7.1)要停止ceph集群可以在执行ceph时加上stop命令--> sudo service ceph [options] stop [daemonType|daemonID]
   较老版本可以执行--> sudo /etc/init.d/ceph -a stop
   较新版本直接执行--> sudo service ceph -a stop 
 8、Monitoring A Cluster:
  集群运行起来后,你可以用ceph工具来监控,典型的监控包括检查OSD状态、监视器状态、归置组状态和元数据服务器状态
  8.1)要在交互模式下运行ceph,不要带参数运行ceph:
  {
   ceph
   ceph> health
   ceph> status
   ceph> quorum_status
   ceph> mon_status
  }
  8.2)启动集群后、读写数据前,先检查下集群的健康状态--> ceph health
  8.3)如果你的ceph.conf或密钥环不在默认路径下,你得指定--> ceph -c /path/to/conf -k /path/to/keyring health
  8.4)集群起来的时候,你也许会碰到像HEALTH_WARN XXX num placement groups stale 这样的健康告警,等一会再检查下。
  集群准备好的话ceph health会给出像HEALTH_OK一样的消息,这时候就可以开始使用集群了。
  8.5)要观察集群内正发生的事件,打开一个新终端,然后输入--> ceph -w
  {
   ceph 会打印 每个归置组版本和它们 的状态, 例如一个包括 1 个监视器、 1 个元数据服务器和 2 个 OSD 的小型
   ceph 集群可能会打印 下面的 :
   health HEALTH_OK
   monmap e1: 1 mons at {a=192.168.0.1:6789/0}, election epoch 0, quorum 0 a
   osdmap e13: 2 osds: 2 up, 2 in
   placement groupmap v9713: 384 placement groups: 384 active+clean; 8730 bytes data, 22948 MB used,
   264 GB / 302 GB avail
   mdsmap e4: 1/1/1 up {0=a=up:active}
    2012-08-01 11:33:53.831268 mon.0 [INF] placement groupmap v9712: 384 placement groups: 384
   active+clean; 8730 bytes data, 22948 MB used, 264 GB / 302 GB avail
    2012-08-01 11:35:31.904650 mon.0 [INF] placement groupmap v9713: 384 placement groups: 384
   active+clean; 8730 bytes data, 22948 MB used, 264 GB / 302 GB avail
    2012-08-01 11:35:53.903189 mon.0 [INF] placement groupmap v9714: 384 placement groups: 384
   active+clean; 8730 bytes data, 22948 MB used, 264 GB / 302 GB avail
    2012-08-01 11:37:31.865809 mon.0 [INF] placement groupmap v9715: 384 placement groups: 384
   active+clean; 8730 bytes data, 22948 MB used, 264 GB / 302 GB avail
  }
  8.6)要检查集群的状态,执行下面的命令--> ceph status or ceph -s:
  {
   ceph 将打印 集群状态, 例如一个包括 1 个监视器、 1 个元数据服务器和 2 个 OSD 的小型 ceph 集群可能打印 :
   health HEALTH_OK
   monmap e1: 1 mons at {a=192.168.0.1:6789/0}, election epoch 0, quorum 0 a
   osdmap e13: 2 osds: 2 up, 2 in
   placement groupmap v9754: 384 placement groups: 384 active+clean; 8730 bytes data, 22948 MB used,
   264 GB / 302 GB avail
   mdsmap e4: 1/1/1 up {0=a=up:active}
  }
  8.7)OSD 状态是集群内(in)或集群外(out)状态,而且是活着且在运行(up)或挂了且不在运行(down)。如果一个OSD活着它也可以是在集群内(你可以读写数据)
  或者不在集群内;如果它挂了,它应该在集群外,如果它挂了且在集群内,肯定有问题。
   8.7.1)你可以执行下列命令来确定OSD活着且在集群里--> ceph osd stat (or) ceph osd dump 
   8.7.2)你也可以根据OSD在CRUSH 图里的位置来查看--> ceph osd tree;
   {
   ceph 会打印 CRUSH 的树状态、 它 的 OSD 例程、状态、 权重:
   #   id  weight type  name     up/down  reweight
    -1  3   pool  default
    -3  3     rack mainrack
    -2  3      host osd-host
    0  1        osd.0  up     1
    1  1        osd.1 up     1
    2  1        osd.2  up     1
   }
  8.8)如果你有多个监视器(很可能),你启动集群后、读写数据前应该检查监视器法定人数状态。多个监视器必须活着、且在运行,
  要周期性检查监视器状态来确定它们在运行。
   8.8.1)要查看监视器图,执行下面的命--> ceph mon stat (or) ceph mon dump
   8.8.2)要检查监视器的法定人数状态,执行下面的命令--> ceph quorum_status:
   {//alter by kj 
    ceph 会返回 法定人数状态, 例如, 包含 3 个监视器的 ceph 集群可能返回 下面的 :
    { "election_epoch": 10,
     "quorum": [
     0,
     1,
     2],
     "monmap": { "epoch": 1,
     "fsid": "444b489c-4f16-4b75-83f0-cb8097468898",
     "modified": "2011-12-12 13:28:27.505520",
     "created": "2011-12-12 13:28:27.505520",
     "mons": [
     { "rank": 0,
     "name": "a",
     "addr": "127.0.0.1:6789\/0"},
     { "rank": 1,
     "name": "b",
     "addr": "127.0.0.1:6790\/0"},
     { "rank": 2,
     "name": "c",
     "addr": "127.0.0.1:6791\/0"}
     ]
     }
    }
   }//end alter by kj
  8.9)元数据服务器为ceph文件系统提供元数据服务,元数据服务器有两种状态:up|down 和 活跃| 不活跃,执行下面的命令来确保元数据服务器活着且活跃:
  ceph mds stat,要展示元数据集群的详细状态,执行下面的命令--> ceph mds dump
   8.10)归置组把对象映射到OSD,归置组的状态应该是活跃且未污染的,其它的PG状态请参见(Placement Group States)

/*******************/
Time:2014-11-11
Author:skdkjzz
/******************/
Profile Ceph of Cpu Usage:
 1、你首次使用oprofile的时候要初始化,找到对应于当前运行内核的vmlinux位置:
 {
  ls /boot
  sudo opcontrol --init
  sudo opcontrol --setup --vmlinux={path-to-image} --separate=library --callgraph=6
 }
 2、执行下面的命令启动opeofile--> opcontrol --start
 3、执行下面的命令停止oprofile--> opcontrol --stop
 4、要查看cmon最近的结果,执行下面的命令--> opreport -gal ./cmon | less
 5、要检索cmon最近的调用图结果,执行下面的命令--> opreport -cal ./cmon | less
 6、回顾结果后,重新剖析前应该先重置,重置动作从会话目录里删除了数据。
 7、要重置oprofile,执行下面的命令--> sudo opcontrol --reset(你应该分析后再重置,以免混合不同的剖析结果。)

Resolve daemon operations issues:
 1、ceph-osd挂的时候,监视器将了解ceph-osd的存活情况,且通过ceph health命令报告:
 {
  ceph health
  HEALTH_WARN 1/3 in osds are down
 }
 2、有ceph-osd进程标记为in且down的时候,你会得到警告,你可以用下面的命令得知哪个ceph-osd进程挂了:
 {
  ceph health detail
  HEALTH_WARN 1/3 in osds are down
  osd.0 is down since epoch 23, last address 192.168.106.220:6800/11080
 }
 3、一般情况下,简单地重启ceph-osd进程可使之重新加入集群并且恢复,如果有个硬盘失败或其它错误使ceph-osd不能正常运行或重启,
 一条错误信息将会出现在日志文件/var/log/ceph/里。
 4、如果守护进程因心跳失败、或者底层文件系统无响应而停止,查看dmesg获取硬盘或者内核错误。
 5、如果集群填满了,监视器将阻止新数据写入,系统会把ceph-osd分为两类:快满了和满了,它们都有可配置的阀值(默认分别是80%和90%),
 满了的ceph-osd会被ceph health报告:
 {
  ceph health
  HEALTH_WARN 1 nearfull osds
  osd.2 is near full at 85%
  
  (or)
  
  ceph health
  HEALTH_ERR 1 nearfull osds, 1 full osds
  osd.2 is near full at 85%
  osd.3 is full at 97%
  
  Resolve:
  5.1)处理这种情况的最好方法就是增加新的ceph-osd,这允许集群把数据重分布到新OSD里。
 }
 6、拥有归置组拷贝的OSD都可以失败,在这种情况下,那一部分的对象存储不可用,监视器就不会收到那些归置组的状态更新了。为检测这种情况,
 监视器把任何主OSD失败的归置组标记为stale(不新鲜),例如:
 {
  ceph health
  HEALTH_WARN 24 pgs stale; 3/300 in osds are down
 }
 7、你能找出哪些归置组不新鲜、和存储这些归置组的最新OSD,命令如下:
 {
  ceph health detail
  HEALTH_WARN 24 pgs stale; 3/300 in osds are down
  ...
  pg 2.5 is stuck stale+active+remapped, last acting [2,0]
  ...
  osd.10 is down since epoch 23, last address 192.168.106.220:6800/11080
  osd.11 is down since epoch 13, last address 192.168.106.220:6803/11539
  osd.12 is down since epoch 24, last address 192.168.106.220:6806/11861
  
  Notes:
  7.1)如果想使归置组2.5重新在线,例如,上面的输出告诉我们它最后由osd.0 和 osd.2处理,重启这些ceph-osd将恢复之(还有其它的很多PG)。
 }
 8、有失败时归置组进入“degraded”(降级)或“peering”(连接建立中 )状态,这事时有发生,通常这些状态意味着正常的失败恢复正在进行。然而,
 如果一个归置组长时间处于某个这些状态就意味着有更大的问题,因此监视器在归置组卡(stuck)在非最优状态时会警告,具体地,我们检查:
 {
  inactive(不活跃) ——归置组长时间无活跃(例如它不能提供读写服务了 ) ;
  unclean(不干净)——归置组长时间不干净(例如它未能从前面的失败完全恢复) ;
  stale(不新鲜)——归置组状态没有被 ceph-osd 更新, 表明 存储这个归置组的所有节点可能都挂了。
  8.1)你可以明确列出卡住的归置组:
  {
   ceph pg dump_stuck stale
   ceph pg dump_stuck inactive
   ceph pg dump_stuck unclean
  }
  8.2)归置组不同的状态,造成的原因如下;
  {
   处于stuck stale状态的归置组通过修复ceph-osd进程通常可以修复
   处于stuck inactive状态的归置组通常是连接建立问题
   处于stuck unclean状态的归置组通常是由于某些东西阻止了恢复的完成,像未找到的对象。  
  }
 }
 9、在某些情况下,ceph-osd连接建立进程会遇到问题,使PG不能活跃、可用,例如ceph health也许显示:
 {
  ceph health detail
  HEALTH_ERR 7 pgs degraded; 12 pgs down; 12 pgs peering; 1 pgs recovering; 6 pgs stuck unclean;
  114/3300 degraded (3.455%); 1/3 in osds are down
  ...
  pg 0.5 is down+peering
  pg 1.4 is down+peering
  ...
  osd.1 is down since epoch 69, last address 192.168.106.220:6801/8651
  
  Notes:
  9.1)可以查询到PG为何被标记为down:
  {//alter by kj 
   ceph pg 0.5 query
   { "state": "down+peering",
    ...
    "recovery_state": [
    { "name": "Started\/Primary\/Peering\/GetInfo",
    "enter_time": "2012-03-06 14:40:16.169679",
    "requested_info_from": []},
    { "name": "Started\/Primary\/Peering",
    "enter_time": "2012-03-06 14:40:16.169659",
    "probing_osds": [
    0,
    1],
    "blocked": "peering is blocked due to down osds",
    "down_osds_we_would_probe": [
    1],
    "peering_blocked_by": [
    { "osd": 1,
    "current_lost_at": 0,
    "comment": "starting or marking this osd lost may let us proceed"}]},
    { "name": "Started",
    "enter_time": "2012-03-06 14:40:16.169513"}
    ]
   }
  }//end alter by kj
  9.2)recovery_state段告诉我们连接建立因ceph-osd进程挂了而被阻塞,本例是osd.1挂了,启动这个进程应该就可以恢复。
  9.3)如果osd.1是灾难性的失败(如硬盘损坏),我们可以告诉集群它丢失了,让集群尽力完成副本拷贝。集群不能保证其它数据副本是一致且最新就危险了!
  9.4)无论如何让ceph继续--> ceph osd lost 1
 }
 10、某几种失败相组合可能导致ceph抱怨有对象丢失:
 {
  ceph health detail
  HEALTH_WARN 1 pgs degraded; 78/3778 unfound (2.065%)
  pg 2.4 is active+degraded, 78 unfound
  
  10.1)这意味着存储集群知道一些对象(或者存在对象的较新副本)存在,却没有找到它们的副本。下例展示了这种情况是如何发生的,一个 PG的数据存储
  在ceph-osd 1 和 2上:
  {
  1 挂了;
  2 独自处理一些写动作;
  1 启动了;
  1 和 2重新建立连接,1上面丢失的对象加入队列准备恢复;
  新对象还未拷贝完,2挂了。这时,1知道这些对象存在,但是活着的ceph-osd都没有副本,这种情况下,读写这些对象的IO就会被阻塞,集群只能
  指望节点早点恢复。这时我们假设用户希望先得到一个IO错误。
  }
  10.2)首先,你应该确认哪些对象找不到了:
  {//alter by kj 
   ceph pg 2.4 list_missing [starting offset, in json]
   { "offset": { "oid": "",
    "key": "",
    "snapid": 0,
    "hash": 0,
    "max": 0},
   "num_missing": 0,
   "num_unfound": 0,
   "objects": [
    { "oid": "object 1",
    "key": "",
    "hash": 0,
    "max": 0 },
    ...
   ],
   "more": 0}
   
  }//end alter by kj
  10.3)其次,你可以找出哪些OSD上探测到、或可能包含数据:
  {//alter by kj 
   ceph pg 2.4 query
   "recovery_state": [
    { "name": "Started\/Primary\/Active",
    "enter_time": "2012-03-06 15:15:46.713212",
    "might_have_unfound": [
    { "osd": 1,
    "status": "osd is down"}]},
    
    Notes:
    10.3.1)集群知道osd.1可能有数据,但它挂了。所有可能的状态有:
    {
     1)? already probed(已经探测到了 )
     2)? querying(在查询)
     3)? osd is down(OSD 挂了 )
     4)? not queried (yet)(尚未查询)
     5)? 还有一种可能性,对象存在于其它位置却未被列出 ,例如,集群里的一个ceph-osd停止且被剔出,然后完全恢复了;后来的失败、
     恢复后仍有未找到的对象,它也不会觉得早已死亡的ceph-osd上仍可能包含这些对象。(这种情况几乎不太可能发生)。
    }
  }//end alter by kj 
  10.4)如果所有位置都查询过了仍有对象丢失,那就得放弃丢失的对象了。这仍可能是罕见的失败组合导致的,集群在写入完成前,未能得知写入是否已执行。 
  以下命令把未找到的(unfound)对象标记为 丢失(lost)--> ceph pg 2.5 mark_unfound_lost revert
  {
   Notes:上述最后一个参数告诉集群应如何处理丢失的对象。当前只支持revert选项,它使得回滚到对象的前一个版本(如果它是新对象)或完全忽略它。
   要谨慎使用,它可能迷惑那些期望对象存在的应用程序。
  }
  10.5)如果某些因素导致ceph-osd对别人的请求响应缓慢,它将生成日志,抱怨请求花的时间太长,这个告警阀值是30秒。可通过osd op complaint time选项配置,
  这事发生的时候,集群日志系统将收到类似下面的消息:
  {
   osd.0 192.168.106.220:6800/18813 312 : [WRN] old request osd_op(client.5099.0:790 fatty_26485_object789 [write 0~4096] 2.5e54f643) v4
   received at 2012-03-06 15:42:56.054801 currently waiting for sub ops
   
   Notes:
    10.5.1)可能的起因包括:
    {
     ? bad disk (check dmesg output)
     ? kernel file system bug (check dmesg output)
     ? overloaded cluster (check system load, iostat, etc.)
     ? ceph-osd bug
    }

  }
  10.6)如果有东西导致OSD摆动(反复地被标记为down,然后又up),你可以强制监视器停止:
  {
   ceph osd set noup # prevent osds from getting marked up
   ceph osd set nodown # prevent osds from getting marked down
   
   Notes:
   10.6.1)这些标记记录在osdmap数据结构里:
   {
    ceph osd dump | grep flags
    flags no-up,no-down   
   }
   10.6.2)下列命令可清除标记:
   {
    ceph osd unset noup
    ceph osd unset nodown
   }
   10.6.3)还支持其它两个标记noin和noout,它们分别可阻止OSD被标记为in、死亡的ceph-osd被标记为out(不管mon osd down out interval的值是什么)。
   10.6.4)注意,noup、noout和nodown从某种意义上说是临时的,一旦标记清除了,它们被阻塞的动作短时间内就会发生;相反,noin标记阻止
   ceph-osd启动时进入集群,任何设置了此标记的守护进程启动后都维持原样。
  }
  10.7)在生产集群,我们推荐至少要运行3个监视器。这样单个监视器失败不会拖垮整个监视器集群,因为大部分仍可用,这样剩余节点仍能形成法定人数。
  {
   10.7.1)检查集群健康状况的时候,也许会看到一个监视器失败了,例如:
   {
    ceph health
    HEALTH_WARN 1 mons down, quorum 0,2   
   }
   10.7.2)额外详情可检查集群状态:
   {
    ceph status
    HEALTH_WARN 1 mons down, quorum 0,2
    mon.b (rank 1) addr 192.168.106.220:6790/0 is down (out of quorum)
   }
   10.7.3)大多情况下,都可以简单地重启相应节点,例如--> service ceph -a restart {failed-mon}
   10.7.4)如果监视器数量不足以形成法定人数,ceph命令将拦截你的操作尝试,你得先启动足够的ceph-mon守护进程来形成法定人数,才能在集群里做其它的事。
  }
 }

Debugging and logging:
 1、你可以在默认位置/var/log/ceph 下翻阅ceph的日志。
 2、调试也许要求你捕捉内存和线程问题,你可以在Valgrind下运行单个、一类守护进程、或者整个集群。你应该只在开发、调试期间使用Valgrind,它需要大量计算,
 会减慢你的系统。Valgrind消息记录在标准错误。
 
Data Placement: 
 1、你的集群启动并运行后,你就可以研究数据放置了,ceph支持PB级数据存储集群,是因为存储池和归置组用CRUSH算法在集群内分布数据。
 2、ceph通过RADOS集群动态地存储、复制和重新均衡数据对象。很多不同用户因不同目的把对象存储在不同的存储池里,而它们都坐落于无数的OSD之上,所以
 ceph的运营需要些数据归置计划。ceph的数据归置计划概念主要有:
 {
  2.1)存储池:ceph在存储池内存储数据,它是对象存储的逻辑组;存储池管理着归置组数量、复制数量、和存储池规则集。要往存储池里存数据,用户必须认证过、
  且权限合适,存储池可做快照,它未来将支持名称空间功能。
  2.2)归置组:ceph把对象映射到归置组(PG),归置组是一系列逻辑对象池的片段,这些对象分组后再存储到OSD,归置组减少了每对象元数据数量,更多的归置组
  (如每OSD包括100个)使得均衡更好。
  2.3)CRUSH图:CRUSH是使ceph能伸缩自如而没有性能瓶颈、没有扩展限制、没有单点故障,它为CRUSH算法提供集群的物理拓扑,以此确定一个对象的数据及它的副本
  应该在哪里、怎样才能越过故障域保证数据安全。
  2.4)起初安装测试集群的时候,可以使用默认值。但开始规划一个大型ceph集群,做数据归置操作的时候会涉及存储池、归置组、和CRUSH。
 }
 
Pools:
 1、开始部署集群时没有创建存储池,ceph则用默认存储池存数据。存储池不同于CRUSH基于位置的桶,它没有单独的物理位置,而且存储池提供了一些额外的功能:
 {
  1.1)复制:你可以设置一个对象期望的副本数量。典型配置存储一个对象和一个它的副本(如size = 2),但你可以更改副本的数量。
  1.2)归置组:你可以设置一个存储池的归置组数量。典型配置在每个OSD上使用大约100个归置组,这样,不用过多计算资源就得到了较优的均衡。设置多个存储池的时候,
  要注意为这些存储池和集群设置合理的归置组数量。
  1.3)CRUSH规则:当你在存储池里存数据的时候,映射到存储池的CRUSH规则集使得CRUSH确定一条规则,用于集群内主对象的归置和其副本的复制。
  你可以给存储池定制CRUSH 规则。
  1.4)快照:你用ceph osd pool mksnap创建快照的时候,实际上创建了一小部分存储池的快照。
  1.5)设置所有者:你可以设置一个用户ID为一个存储池的所有者。
  1.6)要把数据组织到存储池里,你可以列出、创建、删除存储池,也可以查看每个存储池的利用率。
 }
 2、要列出集群的存储池,命令如下:
 {
  ceph osd lspools

  Notes:
   2.1)默认存储池:
   {
    data
    metadata
    rbd
   }
 }
 3、要创建一个存储池,执行:
 {
  ceph osd pool create {pool-name} {pg-num} [{pgp-num}]
  {
   Option implication:
    {pool-name}--> 存储池名称,必须唯一。
    {pg-num}--> 存储池拥有的归置组总数。
    {pgp-num}--> 用于归置的归置组总数。
  }
  3.1)创建存储池时应该设置归置组数量。
  3.2)创建存储池后,内中包含的归置组数量不可更改。
 }
 4、删除一个存储池,执行:
 {
  ceph osd pool delete {pool-name}
  
  Notes:
   4.1)如果你给自建的存储池创建了定制的规则集,你不需要存储池时最好删除它。如果你曾严格地创建了用户及其权限给一个存储池,
   但存储池已不存在,最好也删除那些用户 。
 }
 5、要重命名一个存储池,执行:
 {
  ceph osd pool rename {current-pool-name} {new-pool-name}
  
  Notes:
   5.1)如果重命名了一个存储池,且认证用户有每存储池能力,那你必须用新存储池名字更新用户的能力(如caps)。
 }
 6、要查看某存储池的使用统计信息,执行命令--> rados df
 7、要拍下某存储池的快照,执行命令--> ceph osd pool mksnap {pool-name} {snap-name}
 8、要删除某存储池的一个快照,执行命令--> ceph osd pool rmsnap {pool-name} {snap-name}
 9、要设置一个存储池的选项值,执行命令--> ceph osd pool set {pool-name} {key} {value}
 {
  你可以设置下列键的值:
  key-name:      value:
  size       设置存储池中对象的副本数
  min_size      允许客户端重放确认而未提交请求的秒数
  pgp_num       计算数据归置时使用的有效归置组数量
  crush_ruleset     集群内映射对象归置时使用的规则集 
 }
 10、要获取一个存储池设置值,执行命令--> ceph osd pool get {pool-name} {key}
 {
  你可以获取下列键的值:
  key-name:      value:
  pg_num       存储池的归置组数量
  pgp_num       计算数据归置时使用的归置组有效数量
 }
 11、要设置对象副本数,执行命令--> ceph osd pool set {poolname} size {num-replicas}
 {
  ceph osd pool set data size 3
  
  Notes:
  11.1) pool size是倾向于尽最大努力的设置:一个处于降级模式的对象其副本数小于设置值,但仍可接受IO请求。min_size选项可设置必需给IO的最小副本数。
  {
   ceph osd pool set data min_size 2 --> 这确保数据存储池里任何副本数小于min_size的对象都不会收到IO了。
  }
 }
 12、要获取对象副本数,执行命令--> ceph osd dump | grep 'rep size' (ceph会列出存储池,且高亮'rep size'属性,它创建了一个对象的两个副本(两份拷贝))

Placement Groups:
 一个归置组(PG)把一系列对象汇聚到一组,并且把这个组映射到一系列OSD。跟踪每个对象的位置和元数据需要大量计算。例如,一个拥有数百万对象的系统,
不可能在每个对象级追踪位置。归置组可应对这个影响性能和扩展性的问题,另外,归置组减小了ceph存储、检索数据时必须追踪的每个对象元数据的处理量和尺寸。
 1、每个归置组都需要一定量系统资源:
 {
  1.1)直接地:每个PG需要一些内存和CPU;
  1.2)间接地:PG总量增加了连接建立数量;
  1.3)增加PG数量能减小集群内每个OSD间的变迁,我们推荐每个OSD大约50-100个归置组,以均衡内存、CPU需求、和每个OSD负载。对于单存储池里的对象,
  你可用下面的公式:
      (OSDs * 100)
   Total PGs = ------------
      Replicas
  1.4)当用了多个数据存储池来存储数据时,你得确保均衡每个存储池的归置组数量、且归置组数量分摊到每个OSD,这样才能达到较合理的归置组总量,
  并因此使得每个OSD无需耗费过多系统资源或拖慢连接进程就能实现较小变迁。
 }
 2、你必须在创建存储池时设置一个存储池的归置组数量:
 {
  2.1)要获取一个存储池的归置组数量,执行命令--> ceph osd pool get {pool-name} pg_num
  2.2)要获取集群里归置组的统计信息,执行命令--> ceph pg dump [--format {format}] (可用格式有纯文本(默认)和json)
  2.3)要获取所有卡在某状态的归置组统计信息,执行命令--> ceph pg dump_stuck inactive|unclean|stale [--format <format>] [-t|--threshold <seconds>]
  {
   2.3.1)inactive(不活跃)归置组不能处理读写,因为它们在等待一个有最新数据的OSD复活且进入集群。
   2.3.2)unclean(不干净)归置组含有复制数未达到期望数量的对象,它们应该在恢复中。
   2.3.3)stale(不新鲜)归置组处于未知状态:存储它们的OSD有段时间没向监视器报告了(由mon_osd_report_timeout配置)。
   2.3.4)可用格式有纯文本(默认)和json。 阀值定义的是,归置组被认为卡住前等待的最小时间(默认300秒)。
  }
  2.4)要获取一个具体归置组的归置组图,执行命令--> ceph pg map {pg-id}:
  {
   Example--> ceph pg map 1.6c
   Notes: 
    2.4.1)ceph将返回归置组图、归置组、和OSD状态--> osdmap e13 pg 1.6c (1.6c) -> up [1,0] acting [1,0]
  }
  2.5)要查看一个具体归置组的统计信息,执行命令--> ceph pg {pg-id} query
  2.6)Scrub a placement group--> ceph pg scrub {pg-id}
  {
   Example--> ceph pg scrub {pg-id}
   Notes:
    2.6.1)ceph检查原始的和任何复制节点,生成归置组里所有对象的目录,然后再对比,确保没有对象丢失或不匹配并且它们的内容一致。
  }
  2.7)Revert Lost:如果集群丢了一或多个对象,而且必须放弃搜索这些数据,你就要把未找到的对象标记为丢失。如果所有可能的位置都查询过了,而仍找不到这些对象,
  你也许得放弃它们了。这可能是罕见的失败组合导致的,集群在写入完成前,未能得知写入是否已执行:
  {
   2.7.1)当前只支持revert选项,它使得回滚到对象的前一个版本(如果它是新对象)或完全忽略它。要把unfound对象标记为lost,执行命令:
    ceph pg {pg-id} mark_unfound_lost revert
  }  
 }

CRUSH Maps:
 1、CRUSH算法通过计算数据存储位置来确定如何存储和检索。CRUSH授权ceph客户端直接连接OSD,而非通过一个中央服务器或经纪人。数据存储、检索算法的使用,使ceph
 避免了单点失败、性能瓶颈、和伸缩的物理限制。CRUSH需要一张集群的地图,且使用CRUSH把数据伪随机地存储、检索于整个集群的OSD里。
 2、CRUSH图包含OSD列表、把设备汇聚为物理位置的“桶” 列表、和指示CRUSH如何复制存储池里的数据的规则列表。由于对所安装底层物理组织的表达,CRUSH能模型化、
 并因此定位到潜在的相关失败设备源头,典型的源头有物理距离、共享电源、和共享网络,把这些信息编码到集群图里,CRUSH归置策略可把对象副本分离到不同的失败域,
 却仍能保持期望的分布。例如,要定位同时失败的可能性,可能希望保证数据复制到的设备位于不同机架、不同托盘、不同电源、不同控制器、甚至不同物理位置。
 3、当你写好配置文件,用mkcephfs部署ceph后,它生成了一个默认的CRUSH图,对于你的沙盒环境来说它很好。然而,部署一个大规模数据集群的时候,应该好好设计自己的
 CRUSH图,因为它帮你管理ceph集群、提升性能、和保证数据安全性:
 {
  3.1)如果一个OSD挂了,CRUSH图可帮你定位此事件中OSD所在主机的物理数据中心、房间、行和机架,据此你可以请求在线支持或替换硬件。
  3.2)CRUSH可帮你更快地找出问题。例如,如果一个机架上的所有OSD同时挂了,问题可能在于机架的交换机或电源,而非OSD本身。
  3.3)定制的 RUSH图也能在归置组降级时,帮你找出冗余副本所在主机的物理位置。
 }
 4、要编辑现有的CRUSH图:
 {
  Get the CRUSH Map.         获取
  Decompile the CRUSH Map.       反编译
  Edit at least one of Devices, Buckets and Rules. 至少编辑一个设备、桶、规则
  Recompile the CRUSH Map.       重新编译
  Set the CRUSH Map.         应用
  
  Notes:
  4.1)要激活CRUSH图里某存储池的规则,找到通用规则集编号,然后把它指定到那个规则集。详情参见设置存储池的值。
  4.2)要获取集群的CRUSH图,执行命令:
  {
   ceph osd getcrushmap -o {compiled-crushmap-filename}
   Explain--> ceph将把CRUSH输出(-o)到你指定的文件,由于CRUSH图是已编译的,所以编辑前必须先反编译。
  }
  4.3)要反编译CRUSH图,执行命令:
  {
   crushtool -d {compiled-crushmap-filename} -o {decompiled-crushmap-filename}
   Explain--> ceph将反编译(-d)二进制CRUSH图,且输出(-o)到你指定的文件。
  }
  4.4)要编译CRUSH图,执行命令:
  {
   crushtool -c {decompiled-crush-map-filename} -o {compiled-crush-map-filename}
   Explain--> ceph将把已编译的CRUSH图保存到你指定的文件。
  }
  4.5)要把CRUSH图应用到集群,执行命令:
  {
   ceph osd setcrushmap -i {compiled-crushmap-filename}
   Explain--> ceph将把你指定的已编译CRUSH图输入到集群。
  }
 }
 5、CRUSH图主要有3个主要段落:
 {
  devices  由任意对象存储设备组成,如对应一个ceph-osd 进程的硬盘;
  buckets  由分级汇聚的存储位置(如行、机架、主机等)及其权重组成;
  rules   由选择桶的方法组成。
 }
 6、Crush Map Devices:
 {
  6.1)为把归置组映射到OSD,CRUSH图需要OSD列表(如OSD守护进程名称),所以它们首先出现在CRUSH图里:
  {
   #devices
   device {num} {osd.name}
   
   Example:
   {
    #devices
    device 0 osd.0
    device 1 osd.1
    device 2 osd.2
    device 3 osd.3
   }
   
   Notes:
   6.1.1)一般来说,一个OSD映射到一个单独的硬盘或RAID
  }
 }
 7、Crush Map Buckets:
 {
  7.1)CRUSH图支持bucket概念,可以认为是把其他桶汇聚为分级物理位置的节点,OSD设备是此分级结构的叶子,下表列出了默认类型。详见p108
  7.2)ceph部署工具生成的CRUSH图包含:每个主机一个桶、名为default的存储池(对默认数据、元数据、rbd存储池有用),其余桶类型提供的存储信息是关于节点、
  桶的物理位置的,它简化了OSD、主机、网络硬件故障时集群管理员处理的步骤。
  7.3)一个桶有类型、 唯一的名字(字符串 )、表示为负数的唯一ID、和能力相关的权重、桶算法(默认微不足道)、和哈希(默认0,反映 CRUSH Hash rjenkins1)。
  一个桶可能有一或多个条目。条目由其他桶或OSD组成,也可以有反映条目相对权重的权重:
  {//alter by kj 
   [bucket-type] [bucket-name] {
    id [a unique negative numeric ID]
    weight [the relative capacity/capability of the item(s)]
    alg [the bucket type: uniform | list | tree | straw ]
    hash [the hash type: 0 by default]
    item [item-name] weight [weight]
   }
  }//alter by kj 
  7.4)下例阐述了你该如何用桶汇聚存储池和物理位置,像数据中心、房间、机架、机架行:
  {
   host ceph-osd-server-1 {
     id -17
     alg straw
     hash 0
     item osd.0 weight 1.00
     item osd.1 weight 1.00
   }
   row rack-1-row-1 {
     id -16
     alg straw
     hash 0
     item ceph-osd-server-1 2.00
   }
   rack rack-3 {
     id -15
     alg straw
     hash 0
     item rack-3-row-1 weight 2.00
     item rack-3-row-2 weight 2.00
     item rack-3-row-3 weight 2.00
     item rack-3-row-4 weight 2.00
     item rack-3-row-5 weight 2.00
   }
   rack rack-2 {
     id -14
     alg straw
     hash 0
     item rack-2-row-1 weight 2.00
     item rack-2-row-2 weight 2.00
     item rack-2-row-3 weight 2.00
     item rack-2-row-4 weight 2.00
     item rack-2-row-5 weight 2.00
   }
   rack rack-1 {
     id -13
     alg straw
     hash 0
     item rack-1-row-1 weight 2.00
     item rack-1-row-2 weight 2.00
     item rack-1-row-3 weight 2.00
     item rack-1-row-4 weight 2.00
     item rack-1-row-5 weight 2.00
   }
   room server-room-1 {
     id -12
     alg straw
     hash 0
     item rack-1 weight 10.00
     item rack-2 weight 10.00
     item rack-3 weight 10.00
   }
   datacenter dc-1 {
     id -11
     alg straw
     hash 0
     item server-room-1 weight 30.00
     item server-room-2 weight 30.00
   }
   pool data {
     id -10
     alg straw
     hash 0
     item dc-1 weight 60.00
     item dc-2 weight 60.00
   } 
  }
 }
 8、Crush Map Rules:
 {
  8.1)CRUSH图支持CRUSH规则概念,用以确定一个存储池里数据的归置。对大型集群来说,你可能创建很多存储池,且每个存储池都有它自己的CRUSH规则集和规则。
  默认的CRUSH图里,每个存储池有一条规则、一个规则集被分配到每个默认存储池,它们有:
  {
   ? data
   ? metadata
   ? rbd
   
   Notes:
    8.1.1)大多数情况下,你都不需要修改默认规则。新创建存储池的默认规则集是0,规则格式如下:
    {
     rule [rulename] {
       ruleset [ruleset]  --> 区分一条规则属于某个规则集合的手段。在存储池里设置ruleset后激活
       type [type]   --> 为硬盘(复制的)或RAID写一条规则
       min_size [min-size] --> 如果一个归置组副本数小于此数,CRUSH将不应用此规则
       max_size [max-size] --> 如果一个归置组副本数大于此数,CRUSH将不应用此规则
       step [step]
       {
        step take {bucket}       --> 选取桶名并类推到树底
        step choose firstn {num} type {bucket-type} --> (选取指定类型的桶数量,这里N是可用选择的数量,如果{num}>0 && <N 就选择那么多
                    的桶;如果{num}<0它意为 N-{num};如果{num}==0 选择N个桶(所有可用的)。)
        step emit         --> 输出当前值并清空堆栈,通常用于规则末尾,也适用于相同规则应用到不同树的情况
        
       }
      }
      
     Notes:
      8.1.1.1)要把规则集编号设置到存储池,才能用一个通用规则集编号激活一或多条规则。
    }
    
  }
 }
 9、Add or del an osd:
 {
  9.1)要增加或删除在线集群里的OSD对应的CRUSH图条目,执行命令:
  ceph osd crush set {id} {name} {weight} pool={pool-name} [{bucket-type}={bucket-name} ...]
  {
   id     --> OSD的数字标识符
   name    --> OSD的全名
   weight    --> OSD的CRUSH权重
   pool    --> 默认情况下,CRUSH分级结构的根是default存储池
   bucket-type   --> 定义OSD在CRUSH分级结构中的位置
   
   Notes:
    9.1.1)下例把osd.0添加到分级结构里、或者说从前一个位置挪动一下:
     ceph osd crush set 0 osd.0 1.0 pool=data datacenter=dc1 room=room1 row=foo rack=bar host=foo-bar-1
  }
 }
 10、要调整在线集群中OSD的CRUSH权重,执行命令:
 {
  ceph osd crush reweight {name}   {weight}
        osd全名  osdCrush权重
 }
 11、要从在线集群里把OSD踢出CRUSH图,执行命令:
 {
  ceph osd crush remove {name}
         osd全名
 }
 12、要把一个桶挪动到CRUSH图里的不同位置,执行命令:
 {
  ceph osd crush move {bucket-name} {bucket-type}={bucket-name}, [...]
  {bucket-name} -->要移动到的桶名。
  {bucket-type} -->你可以指定桶在CRUSH分级结构里的位置
 }
 13、(可调选项p113)遗留值导致几个不当行为:
 {
  13.1)如果分级结构的支部只有少量设备,一些PG的副本数小于期望值,这通常出现在一些子结构里,host节点下少数OSD嵌套到了其他OSD里。
  13.2)大型集群里,小部分PG映射到的OSD数目小于期望值,有多层结构(如:机架行、机架、主机、OSD)时这种情况更普遍。当一些OSD标记为out时,
  数据倾向于重分布到附近OSD而非整个分级结构。
  13.3)调整这些值将使一些PG在存储节点间移位,如果ceph集群已经存储了大量数据,可能移动一部分数据。 一旦ceph-osd 和 ceph-mon收到了更新的地图,
  它们对新建连接就开始要求CRUSH_TUNABLES功能了,然而,之前已经连接的客户端如果不支持新功能将行为失常。
  13.4)如果CRUSH可调值更改过、然后又改回了默认值,ceph-osd守护进程将不要求支持此功能,然而,OSD连接建立进程要能检查和理解旧地图。因此,
  集群如果用过非默认CRUSH值就不应该再运行版本小于0.48.1的ceph-osd,即使最新版地图已经回滚到了遗留默认值。
  13.5)如果你能保证所有客户端都运行最新代码,你可以这样调整可调值:从集群抽取CRUSH图 、修改值、重注入:
  {
   13.5.1)抽取最新CRUSH图--> ceph osd getcrushmap -o /tmp/crush
   13.5.2)调整可调参数。这些值在我们测试过的大、小型集群上都有最佳表现。在极端情况下,你需要给crushtool额外指定--enable-unsafe-tunables参数才行:
   {
    crushtool -i /tmp/crush --set-choose-local-tries 0 --set-choose-local-fallback-tries 0 --setchoose-total-tries 50 -o /tmp/crush.new
   }
   13.5.3)重注入修改的地图--> ceph osd setcrushmap -i /tmp/crush.new   
  }
  13.6)CRUSH可调参数的遗留值可以用下面命令设置:
  {
   crushtool -i /tmp/crush --set-choose-local-tries 2 --set-choose-local-fallback-tries 5 --setchoose-total-tries 19 -o /tmp/crush.legacy
   
   Notes:
   13.6.1)再次申明,--enable-unsafe-tunables是必需的,而且前面也提到了,回退到遗留值后慎用旧版ceph-osd进程,因为此功能位不是完全强制的。
  }
 }

Ceph authentication & authorization:
 1、ceph是一个分布式存储系统,其典型部署包含相对少量的监视器、许多元数据服务器(MDS)和数千OSD守护进程,它们运行于很多主机或节点,共同构成了
 ceph对象存储的服务器部分;ceph客户端如CephFS、Ceph块设备和 Ceph网关与 ceph对象存储交互,所有客户端都用librados库和ceph对象存储交互:
 {
  1.1)ceph一个主要伸缩功能就是避免了对象存储的中央接口,这就要求ceph客户端能直接和OSD交互。Ceph通过cephx认证系统保护数据,它也认证运行ceph客户端的用户,
  cephx协议运行机制类似Kerberos。
  1.2)用户/参与者通过调用ceph客户端来联系监视器,不像Kerberos,每个监视器都能认证用户、发布密钥,所以使用cephx时不会有单点故障或瓶颈。
  1.3)监视器返回一个类似Kerberos票据的认证数据结构,它包含一个可用于获取ceph服务的会话密钥,会话密钥是用户的永久私钥自加密过的,只有此用户能从ceph监视器
  请求服务。
  1.4)客户端用会话密钥向监视器请求需要的服务,然后监视器给客户端一个凭证用以向实际持有数据的OSD认证。
  1.5)ceph的监视器和OSD共享相同的密钥,所以集群内任何OSD或元数据服务器都认可客户端从监视器获取的凭证。
  1.6)像Kerberos一样cephx凭证也会过期,以使攻击者不能用 暗中得到的过期凭证或会话密钥。
  1.7)要使用cephx,管理员必须先设置好用户。client.admin用户从命令行调用ceph auth getor-create-key来生成一个用户及其密钥,ceph的认证子系统生成了用户名
  和密钥、 副 本存到监视器然后把此用户的密钥回传给client.admin用户,也就是说客户端和监视器共享着相同的密钥。详见p118
  1.8)认证提供的保护位于ceph客户端和服务器间,没有扩展到ceph客户端之外。如果用户从远程主机访问ceph客户端,ceph认证就不管用了,它不会影响到用户主机和客户端主机间的通讯。
 }
 2、ceph用能力(caps)来描述给认证用户的授权,这样才能使用监视器、OSD、和元数据服务器的功能。能力也能限制到一或多个存储池的访问:
 {
  2.1)ceph使用能力来设置、控制ceph客户端和服务器例程间的相互访问,并且不管哪种客户端访问ceph对象存储。CephFS内部给文件和目录用了不同于CephFS文件系统
  的另外一种能力,CephFS访问控制和CephFS有关,但不是块设备或RESTful网关。
  2.2)给用户设置能力的时候,ceph也支持把能力限制于某存储池。意思是你可以完全地访问一些存储池、访问其他存储池却是受限的(或未受限):
  ceph-authtool -n client.foo --cap osd 'allow rwx' pool=customer-pool
  2.3)cephx协议提供ceph客户端和服务器间的相互认证,并没打算认证人类用户或者应用程序。
  2.4)用于认证ceph客户端和服务器的密钥通常以纯文本存储在权限合适的文件里,此文件保存于可信主机上。
  2.5)ceph没有自己加密对象的功能。在ceph里存储敏感数据的用户应该考虑存入ceph集群前先加密。
 }

Cephx Guide:
 1、ceph提供了两种认证模式:
 {
  1.1)none --> 任何用户无需认证就能访问数据
  1.2)cephx --> ceph要求用户认证,机制类似Kerberos。
  
  Notes:
   1.3)如果你要禁用cephx,就不需要按前述生成密钥;如果你重新启用cephx且已然生成了密钥,也无需再次生成。
 }
 2、要为集群及其守护进程启用cephx协议,有几个重要步骤必须遵循:
 {
  2.1)必须给默认的client.admin生成密钥,以便管理员执行ceph命令。
  {
   2.1.1)下列命令将在监视器上生成并注册一个具有管理能力的client.admin 密钥,并将之写入本地文件系统的keyring,如果密钥已存在,将返回其值:
   {
    sudo ceph auth get-or-create client.admin mds 'allow' osd 'allow *' mon 'allow *' > /etc/ceph/keyring
   }   
  }
  2.2)必须生成一个监视器密钥,并发布到集群内的所有监视器。
  {
   2.2.1)ceph的监视器需要一个密钥环,用ceph-authtool命令生成密钥和密钥环--> sudo ceph-authtool {keyring} --create-keyring --gen-key -n mon.
   2.2.2)有多个监视器的集群,其所有监视器的密钥环必须相同,所以你必须把下列目录里的密钥环拷到每个监视器--> /var/lib/ceph/mon/$cluster-$id
  }  
  2.3)你要完成启用cephx里的剩余步骤
 }
 3、启用cephx:
 {
  3.1)启用cephx后,ceph将在默认搜索路径(/etc/ceph/keyring)里查找密钥环。你可以在配置文件的[global]段里添加keyring选项来修改,但不推荐。
  3.2)创建client.admin密钥,并为客户端保存此密钥的副本:
   ceph auth get-or-create client.admin mon 'allow *' mds 'allow *' osd 'allow *' -o /etc/ceph/keyring
  3.3)生成给监视器的mon.密钥--> ceph-authtool --create --gen-key -n mon. /tmp/monitor-key
  3.4)把mon密钥环拷贝到keyring文件,再拷到每个监视器的mon数据目录下--> cp /tmp/monitor-key /var/lib/ceph/mon/ceph-a/keyring
  3.5)为每个OSD生成密钥,{id}是OSD编号--> ceph auth get-or-create osd.{$id} mon 'allow rwx' osd 'allow *' -o /var/lib/ceph/osd/ceph-{$id}/keyring
  3.6)为每个MDS生成密钥,{id}是MDS的标识字母--> ceph auth get-or-create mds.{$id} mon 'allow rwx' osd 'allow *' mds 'allow *' -o /var/lib/ceph/mds/ceph-{$id}/keyring
  3.7)0.51以上版本启用cephx时,要在配置文件的[global]段下添加如下内容:
  {
   auth cluster required = cephx
   auth service required = cephx
   auth client required = cephx
  }
  3.8)0.50以下版本启用cephx时,要在配置文件的[global]段下添加以下--> auth supported = cephx
  3.9)启动或重启ceph集群:
  {
   sudo service ceph -a start
   sudo service ceph -a restart  
  }
  3.10)在0.51及以上禁用cephx认证,要在配置文件的[global]段下设置:
  {
   auth cluster required = none
   auth service required = none
   auth client required = none 
  }
  3.11)在0.50及以下禁用cephx,要在配置文件的[global]段下设置--> auth supported = none
  3.12)除监视器外,守护进程密钥环和用户密钥环生成方法一样,默认情况下,守护进程把密钥环保存在它们的数据目录下,默认密钥环位置、和
  守护进程发挥作用必需的能力展示如下:
  {
   ceph-mon
   Location: $mon_data/keyring
   Capabilities: N/A
   
   ceph-osd
   Location: $osd_data/keyring
   Capabilities: mon 'allow rwx' osd 'allow *'
   
   ceph-mds
   Location: $mds_data/keyring
   Capabilities: mds 'allow rwx' mds 'allow *' osd 'allow *'
   
   radosgw
   Location: $rgw_data/keyring
   Capabilities: mon 'allow r' osd 'allow rwx'
   
   Notes:
    3.12.1)监视器密钥环包含一个密钥,但没有能力,且不是集群认证数据库的一部分。
    3.12.2)守护进程数据目录位置默认格式如下:
    {
     /var/lib/ceph/$type/$cluster-$id
     Example--> /var/lib/ceph/osd/ceph-12
    }
  }
  3.13)具体用户根据分配给密钥的能力可获得监视器、元数据服务器和集群的访问。能力是字符串,它给某类服务器指定访问权限,每种服务器都各有其字符串。
  在命令行下,所有能力都可成对地表示为 {type}和{capability}:
  {
   sudo ceph auth get-or-create-key client.{username} {daemon1} {cap1} {daemon2} {cap2} ...
   Example--> 要创建一个用户client.foo,他对osd有rw权限、对mon有r权限--> sudo ceph auth get-or-create-key client.foo osd rw mon r > keyring.foo
  }
  3.14)要删除一个用户或守护进程的密钥,用ceph auth del指令:
  {
   ceph auth del {daemon-type}.{ID|username}
   
   Notes:
    3.14.1){daemon-type}是客户端、osd、mon、mds中一个
    3.14.2){ID|username}是守护进程或用户名的ID。
  }
  3.15)要列出集群内注册的密钥--> sudo ceph auth list
  3.16)cephx命令行选项,详见p125
  3.17)要防止新服务器和旧服务器交互,在配置文件的[global]下添加下列这行,要加到启用cephx之后--> cephx require signatures = true
 }

Add Del Osd:
 1、在ceph里,一个OSD一般是一个ceph-osd守护进程,它运行在硬盘之上,如果你有多个硬盘,可以给每个硬盘启动一个ceph-osd 守护进程:
 {
  1.1)不要等空间满了再增加OSD,空间使用率达到near full ratio值后,OSD失败可能导致集群空间占满。
  1.2)对于用chef部署的集群,要在主机上创建一个cheg用户、配置SSH密钥对、安装 Ruby、安装chef客户端。
  1.3)添加OSD:
  {
   1.3.1)创建数据目录:
   {
    1.3.1.1)在新OSD主机上创建默认目录:
    {
     ssh {new-osd-host}
     sudo mkdir /var/lib/ceph/osd/ceph-{osd-number}
    }
   }
   1.3.2)把硬盘挂载到目录:
   {
    1.3.2.1)如果给OSD用的是单独的而非系统盘,先把它挂载到刚创建的目录下:
    {
     ssh {new-osd-host}
     sudo mkfs -t {fstype} /dev/{disk}
     sudo mount -o user_xattr /dev/{hdd} /var/lib/ceph/osd/ceph-{osd-number}
    }
   }
   1.3.3)把OSD添加到配置文件:
   {
    1.3.3.1)登录到保存ceph.conf主拷贝的主机上:
    {
     ssh {admin-host}
     cd /etc/ceph
     vim ceph.conf 
    }
    1.3.3.2)把新OSD添加到ceph.conf文件里:
    {
     [osd.123]
     host = {hostname}
    }
    1.3.3.3)从保存集群ceph.conf主拷贝的主机上,把更新过的ceph.conf拷贝到新OSD主机和其他主机的/etc/ceph/目录下:
    {
     ssh {new-osd} sudo tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
    }
   }
   1.3.4)把OSD加入集群:
   {
    1.3.4.1)创建OSD:
    {
     ceph osd create {osd-num}
     ceph osd create 123 #for example
    }
    1.3.4.2)初始化OSD数据目录:
    {
     ssh {new-osd-host}
     ceph-osd -i {osd-num} --mkfs --mkkey 
     
     Notes:
      1.3.4.2.1)运行ceph-osd时目录必须是空的。
    }
    1.3.4.3)注册OSD认证密钥,ceph-{osd-num}路径里的ceph值应该是$cluster-$id,如果你的集群名字不是ceph,那就用改过的名字:
    {
     ceph auth add osd.{osd-num} osd 'allow *' mon 'allow rwx' -i /var/lib/ceph/osd/ceph-{osd-num}/keyring
    }
   }
   1.3.5)把OSD加入CRUSH图
   {
    1.3.5.1)把OSD加入CRUSH图以便它接收数据,也可以反编译CRUSH图、把OSD加入device list、以桶的形式加入主机(如果它没在CRUSH图里)、以条目
    形式把设备加入主机、分配权重、重编译并应用它:
    {
     ceph osd crush set {id} {name} {weight} pool={pool-name} [{bucket-type}={bucket-name} ...]
    }
    1.3.5.2)往CRUSH图里添加OSD时建议设置权重,硬盘容量每年增长40%,所以较新的OSD主机拥有更大的空间(如他们可以有更大的权重)
   }
  }
  1.4)添加osd by chef:
  {
   1.4.1)执行chef-client来注册为chef节点。
   1.4.2)进入chef环境,把"role[ceph-osd]"添加到运行列表。
   1.4.3)执行chef-client调用运行列表。
  }
  1.5)Start Osd:
  {
   1.5.1)把OSD加入ceph后,OSD就在配置里了。然而,它还没运行,其状态为down且out,开始收数据前必须先启动。可以用管理主机上的服务、或从OSD所在主机启动:
   {
    service ceph -a start osd.{osd.num}
    #or alternatively
    ssh {new-osd-host}
    sudo /etc/init.d/ceph start osd.{osd-num}
   }
  }
  1.6)Put the osd into the cluster:
  {
   1.6.1)启动OSD后,它是up且out的,你得把它推入集群,ceph才能向其写入数据--> ceph osd in {osd-num}
   1.6.2)把新OSD加入CRUSH图后,ceph会重新均衡服务器,一些归置组会迁移到新OSD里,你可以用ceph命令观察此过程--> ceph -w
   1.6.3)你会看到归置组状态从active+clean变为active、一些降级的对象、且迁移完成后回到active+clean状态--> Ctrl-c 退出
  } 
 }
 2、删除OSD前,它通常是up且in的,要先把它踢出集群,以使ceph启动重新均衡、把数据拷贝到其他OSD:
 {
  ceph osd out {osd-num}
  2.1)把OSD踢出集群后,它可能仍在运行,就是说其状态为up且out。删除前要先停止OSD进程:
  {
   ssh {new-osd-host}
   sudo /etc/init.d/ceph stop osd.{osd-num}
  }
  2.2)接下依次完成以步骤,彻底把一个osd删除:
  {
   2.2.1)把一个OSD移出集群CRUSH图:
   {
    2.2.1.1)删除CRUSH图的对应OSD条目,它就不再接收数据了。你也可以反编译CRUSH图、删除device列表条目、删除对应的host桶条目或删除host桶
    (如果它在CRUSH图里,而且你想删除主机),重编译CRUSH图并应用它:
    {
     ceph osd crush remove {name}
    }
   }
   2.2.2)删除认证密钥:
   {
    2.2.2.1)删除OSD认证密钥-->  ceph auth del osd.{osd-num}
   }
   2.2.3)删除OSD图条目
   {
    2.2.3.1)删除OSD:
    {
     ceph osd rm {osd-num}
     #for example
     ceph osd rm 123  
    }
   }
   2.2.4)删除ceph.conf条目
   {
    2.2.4.1)登录到保存ceph.conf主拷贝的主机:
    {
     ssh {admin-host}
     cd /etc/chef
     vim ceph.conf
    }
    2.2.4.2)从ceph.conf配置文件里删除对应条目:
    {
     [osd.123]
     host = {hostname}
    }
    2.2.4.3)从保存ceph.conf主拷贝的主机,把更新过的ceph.conf拷贝到集群其他主机的/etc/ceph目录下:
    {
     ssh {osd} sudo tee /etc/ceph/ceph.conf < /etc/ceph/ceph.conf
    }
   }
   2.2.5)如果主机有多个硬盘,每个硬盘对应的OSD都得重复此步骤
  }
 }

Adding removing monitors:
 1、ceph监视器是轻量级进程,它维护着集群运行图的副本。一个集群可以只有一个监视器,我们推荐生产环境至少3个监视器。ceph使用PAXOS
 算法对主集群运行图达成共识,它要求大部分监视器在运行,以达到关于集群运行图建立共识所需的法定人数(如 1、5 个中的3个、6个中的4个等等):
 { 
  1.1)要确立法定人数,集群内的大部分监视器必须互相可达。
  1.2)创建ceph-mon数据目录:
  {
   1.2.1)在新监视器上创建默认目录:
   {
    ssh {new-mon-host}
    sudo mkdir /var/lib/ceph/mon/ceph-{mon-letter}
   }
   1.2.2)创建临时目录--> mkdir /tmp/
  }
  1.3)获取监视器运行图:
  {
   1.3.1)获取监视器运行图,{tmp}是获取到的监视器运行图、{filename}是包含监视器运行图的文件名:
   {
    ceph mon getmap -o {tmp}/{filename}
   }
  }
  1.4)监视器密钥环:
  {
   1.4.1)获取监视器密钥环,{tmp}是密钥环文件保存路径、{filename}是包含密钥的文件名:
   {
    ceph auth get mon. -o {tmp}/{filename}
   }
  }
  1.5)增加一个ceph-mon守护进程:
  {
   1.5.1)准备第一步创建的监视器数据目录。必须指定监视器运行图路径,这样才能获得监视器法定人数和它们fsid的信息;还要指定监视器密钥环路径:
   {
    sudo ceph-mon -i {mon-letter} --mkfs --monmap {tmp}/{filename} --keyring {tmp}/{filename}
   }
   1.5.2)把新监视器的[mon.{letter}]条目添加到ceph.conf文件里:
   {
    [mon.c]
     host = new-mon-host
     addr = ip-addr:6789
   }
   1.5.3)把新监视器添加到集群的监视器列表里(运行时),这允许其它节点开始启动时使用这个节点--> ceph mon add <name> <ip>[:<port>]
   1.5.4)启动新监视器,它会自动加入机器。守护进程需知道绑定到哪个地址,通过--public-addr {ip:port}或在ceph.conf里的相应段设置mon addr可以指定:
   {
    ceph-mon -i newname --public-addr {ip:port}
   }
  }  
 }
 2、从集群删除监视器时,必须认识到,ceph监视器用PASOX算法关于主集群运行图达成共识。必须有足够多的监视器才能对集群运行图达成共识。
 3、从集群删除ceph-mon守护进程,如果此步骤导致只剩2个监视器了,你得另外增加一或多个监视器,直到达成法定人数所必需的ceph-mon数量:
 {
  3.1)停止监视器--> service ceph -a stop mon.{mon-letter}
  3.2)从集群删除监视器--> ceph mon remove {mon-letter}
  3.3)删除ceph.conf对应条目
 }
 4、从不健康集群中删除Monitors,即集群有些归置组永久偏离active+clean:
 {
  4.1)找出活着的监视器--> ceph mon dump
  4.2)进入幸存监视器的monmap目录:
  {
   ssh {mon-host}
   cd /var/lib/ceph/mon/ceph-{mon-letter}/monmap
  }
  4.3)列出目录内容,找出最后提交的运行图。目录内容是运行图的数字列表:
  {
   ls
   1 2 3 4 5 first_committed last_committed last_pn latest
  }
  4.4)找出最近提交的运行图--> sudo cat last_committed
  4.5)把最近提交的文件拷到一个临时目录--> cp /var/lib/ceph/mon/ceph-{mon-letter}/monmap/{last_committed} /tmp/surviving_map
  4.6)删除死亡监视器。例如,假设你有3个监视器,mon.a、mon.b和mon.c,其中只有mon.a要保留,如下:
  {
   4.6.1)删除不保留的监视器:
   {
    monmaptool /tmp/surviving_map --rm {mon-letter}
    #for example
    monmaptool /tmp/surviving_map --rm b
    monmaptool /tmp/surviving_map --rm c
   }
   4.6.2)停止所有监视器--> service ceph -a stop mon
   4.6.3)把找出的幸存运行图注入保留的监视器,例如,要把运行图注入mon.a,模仿如下:
   {
    ceph-mon -i {mon-letter} --inject-monmap {map-path}
    #for example
    ceph-mon -i a --inject-monmap /etc/surviving_map
   }
  }
 }
 
Change Monitors IP Addr:
 1、ceph客户端及其它ceph守护进程用ceph.conf发现监视器,然而,监视器之间用监视器运行图发现对方,而非ceph.conf
 2、监视器是ceph集群的关键组件,它们要维护一个法定人数,这样整个系统才能正常工作。要确立法定人数,监视器得互相发现对方,ceph对监视器的发现要求严格。
 3、Consistency Requirements:
 {
  3.1)监视器发现集群内的其它监视器时总是参照monmap的本地副本,用monmap而非ceph.conf可避免因配置错误(例如在ceph.conf里指定监视器地址或端口时拼写错误)
  而损坏集群。正因为监视器用monmaps相互发现、且共享于客户端和其它ceph守护进程间,所以monmap以苛刻的一致性提供监视器。
  3.2)苛刻的一致性要求也适用于monmap的更新,因为任何有关监视器的更新、monmap的更改都通过名为Pasox的分布式一致性算法运行。为保证法定人数里的
  所有监视器都持有同版本monmap,所有监视器都要赞成monmap的每一次更新,像增加、删除监视器。monmap的更新是增量的,这样监视器都有最近商定的版本以及
  一系列之前版本,这样可使一个有较老monmap的监视器赶上集群当 前的状态。
  3.3)如果监视器通过ceph配置文件而非monmap相互发现,就会引进额外风险,因为ceph配置文件不会自动更新和发布。监视器有可能用了较老的ceph.conf而导致
  不能识别某监视器、掉出法定人数、或者发展为一种Paxos不能精确确定当前系统状态的情形。总之,更改现有监视器的IP地址必须慎之又慎。
 }
 4、Changing a Monitor’s IP address (The Right Way):
 {
  4.1)仅仅在ceph.conf里更改监视器的IP不足以让集群内的其它监视器接受更新。要更改一个监视器的IP地址,你必须以先以想用的IP地址增加一个监视器(见增加监视器)
  ,确保新监视器成功加入法定人数,然后删除用旧IP的监视器,最后更新ceph.conf以确保客户端和其它守护进程得知新监视器的IP地址。
  4.2)例如,我们假设有3个监视器,如下:
  {
   [mon.a]
    host = host01
    addr = 10.0.0.1:6789
   [mon.b]
    host = host02
    addr = 10.0.0.2:6789
   [mon.c]
    host = host03
    addr = 10.0.0.3:6789
    
   Notes:
    4.2.1)要把host04上mon.c的IP改为10.0.0.4,按照增加监视器(手动)里的步骤增加一个新监视器 mon.d,确认它运行正常后再删除 mon.c,
    否则会破坏法定人数;最后依照删除监视器(手动)删除mon.c。3个监视器都要更改的话,每次都要重复一次。    
  }
 }
 
Control commands:
 命令格式通常是(不总是)--> ceph {subsystem} {command}
 1、监视器命令用ceph工具执行--> ceph [-m monhost] {command}
 2、ceph系统命令:
 {
  2.1)显示集群状态:
  {
   ceph -s
   ceph status
  }
  2.2)显示集群状态的运行摘要、及主要事件--> ceph -w
  2.3)显示监视器法定人数状态,包括哪些监视器参与着、哪个是首领--> ceph quorum_status
  2.4)查询单个监视器状态,包括是否在法定人数里--> ceph [-m monhost] mon_status
 }
 3、Authentication Subsystem:
 {
  3.1)查询单个监视器状态,包括是否在法定人数里--> ceph [-m monhost] mon_status
  3.2)列出集群的密钥及其能力,执行下列命令--> ceph auth list
 }
 4、Placement Group Subsystem:
 {
  4.1)显示所有归置组的统计信息,执行下列命令--> ceph -- pg dump [--format {format}]
  4.2)显示卡在某状态的所有归置组,执行下列命令:
  {
   ceph -- pg dump_stuck inactive|unclean|stale [--format {format}] [-t|--threshold {seconds}]
   Option:
   --format   可以是plain(默认)或json
   --threshold  定义了多久算“卡”(默认300秒)
   inactive   归置组不能处理读或写,因为它们在等待数据及时更新的OSD回来。
   unclean   归置组包含副 本数未达期望值的对象,它们应该在恢复中。
   stale    归置组处于未知状态——归置组所托付的OSD有一阵没向监视器报告了(由mon osd report timeout 置)。
  }
  4.3)把“丢失” 对象恢复到其先前状态,可以是前一版本、或如果刚创建就干脆删除--> ceph pg {pgid} mark_unfound_lost revert
 }
 5、Osd Subsystem:
 {
  5.1)查询OSD子系统状态--> ceph osd stat
  5.2)最新的OSD运行图拷贝到一个文件,参见osdmaptool--> ceph osd getmap -o file
  5.3)最新OSD运行图拷出CRUSH图--> ceph osd getcrushmap -o file
  5.4)前述功能等价于:
  {
   ceph osd getmap -o /tmp/osdmap
   osdmaptool /tmp/osdmap --export-crush file
  }
  5.5)转储OSD运行图,-f的可用格式有plain和json如未指定--format则转储为纯文本--> ceph osd dump [--format {format}]
  5.6)把OSD运行图转储为树,每个OSD一行、包含权重和状态--> ceph osd tree [--format {format}]
  5.7)找出某对象在哪里或应该在哪里--> ceph osd map <pool-name> <object-name>
  5.8)增加或挪动一个新OSD条目,要给出id/name/weight、和位置参数--> ceph osd crush set {id} {weight} [{loc1} [{loc2} ...]]
  5.9)从现有CRUSH图删除存在的条目--> ceph osd crush remove {id}
  5.10)把有效的桶从分级结构里的一个位置挪到另一个--> ceph osd crush move {id} {loc1} [{loc2} ...]
  5.11)设置{name}所指条目的权重为{weight}--> ceph osd crush reweight {name} {weight}
  5.12)创建集群快照--> ceph osd cluster_snap {name}
  5.13)把OSD标记为丢失,有可能导致永久性数据丢失,慎用--> ceph osd lost [--yes-i-really-mean-it]
  5.14)创建新OSD。如果未指定ID,有可能的话将自动分配个新ID--> ceph osd create [{id}]
  5.15)删除指定OSD--> ceph osd rm [{id}...]
  5.16)查询OSD运行图里的max_osd参数--> ceph osd getmaxosd
  5.17)导入指定OSD运行图。注意,此动作有风险,因为OSD运行图包含当前OSD在线、离线的动态状态,只可用于相当新的副本--> ceph osd setmap -i file
  5.18)导入指定CRUSH图--> ceph osd setcrushmap -i file
  5.19)设置OSD运行图的max_osd参数,扩展存储集群时有必要--> ceph osd setmaxosd
  5.20)把ID为{osd-num}的OSD标记为down--> ceph osd down {osd-num}
  5.21)把OSD{osd-num}标记为数据分布之外(如不给分配数据)--> ceph osd out {osd-num}
  5.22)把OSD{osd-num}标记为数据分布之内(如分配了数据)--> ceph osd in {osd-num}
  5.23)列出ceph集群载入的类--> ceph class list
  5.24)设置或清空OSD运行图里的暂停标记。若设置了,不会有IO请求发送到任何OSD;用unpause清空此标记,会导致重发未决的请求:
  {
   ceph osd pause
   ceph osd unpause 
  }
  5.25)把{osd-num}的权重设置为{weight},权重相同的两个OSD大致会收到相同的I/O请求、并存储相同数量的数据--> ceph osd reweight {osd-num} {weight}
  5.26)重设所有滥用OSD的权重,它默认向下调整达到120%利用率的OSD,除非你指定了threshold值--> ceph osd reweight-by-utilization [threshold]
  5.27)增加、删除黑名单里的地址。增加地址的时候可以指定有效期,否则有效期为1小时。黑名单里的地址不允许连接任何OSD,此技术常用于防止滞后的元数据
  服务器“错爱” OSD上的数据:
  {
   ceph osd blacklist add ADDRESS[:source_port] [TIME]
   ceph osd blacklist rm ADDRESS[:source_port]
  }
  5.28)创建/删除存储池快照:
  {
   ceph osd pool mksnap {pool-name} {snap-name}
   ceph osd pool rmsnap {pool-name} {snap-name}
  }
  5.29)创建/删除/重命名存储池:
  {
   ceph osd pool create {pool-name} pg_num [pgp_num]
   ceph osd pool delete {pool-name}
   ceph osd pool rename {old-name} {new-name}
  }
  5.30)更改存储池设置:
  {
   ceph osd pool set {pool-name} {field} {value}
   可用的 field 有:
   size      ——设置存储池内数据的副本数;
   crash_replay_interval  ——允许客户端重放确 认而未提交的请求前等待的时间,秒;
   pg_num      ——归置组数量;
   pgp_num     ——计算归置组存放的有效数量;
   crush_ruleset    ——用于归置映射的规则号。
  }
  5.31)获取存储池配置值:
  {
   ceph osd pool get {pool-name} {field}
   可用的 field 有:
   pg_num      ——归置组数量;
   pgp_num      ——计算归置组存放的有效数量;
   lpg_num     ——本地归置组数量;
   lpgp_num     ——用于存放本地归置组的数量。
  }
  5.32)向OSD{osd-num}下达一个洗刷命令,用通配符*把命令下达到所有OSD--> ceph osd scrub {osd-num}
  5.33)向osdN下达修复命令,用*下达到所有OSD--> ceph osd repair N
  5.34)在osdN上进行个简单的吞吐量测试,每次写入BYTES_PER_WRITE、一共写入TOTAL_BYTES。默认以4MB增量写入1GB:
  {
   ceph osd tell N bench [BYTES_PER_WRITE] [TOTAL_BYTES]
  }
 }
 6、Mds Subsystem:
 {
  6.1)更改在运行mds的参数:
  {
   ceph mds tell {mds-id} injectargs '--{switch} {value} [--{switch} {value}]' 
   Example--> ceph mds tell 0 injectargs '--debug_ms 1 --debug_mds 10' (打开了调试消息)
  }
  6.2)显示所有元数据服务器状态--> ceph mds stat  
 }
 7、Mon Subsystem:
 {
  7.1)查看监视器状态:
  {
   ceph mon stat
    2011-12-14 10:40:59.044395 mon {- [mon,stat]
    2011-12-14 10:40:59.057111 mon.1 -} 'e3: 5 mons at
    {a=10.1.2.3:6789/0,b=10.1.2.4:6789/0,c=10.1.2.5:6789/0,d=10.1.2.6:6789/0,e=10.1.2.7:6789/0},
    election epoch 16, quorum 0,1,2,3' (0)
   
   Notes:
   7.1.1)末尾的法定人数列表列出了当 前法定人数里的监视器节点
   7.1.2)也可以更直接地获取:
   {
    $ ./ceph quorum_status
     2011-12-14 10:44:20.417705 mon {- [quorum_status]
     2011-12-14 10:44:20.431890 mon.0 -}
     '{ "election_epoch": 10,
      "quorum": [
      0,
      1,
      2],
      "monmap": { "epoch": 1,
      "fsid": "444b489c-4f16-4b75-83f0-cb8097468898",
      "modified": "2011-12-12 13:28:27.505520",
      "created": "2011-12-12 13:28:27.505520",
      "mons": [
      { "rank": 0,
      "name": "a",
      "addr": "127.0.0.1:6789\/0"},
      { "rank": 1,
      "name": "b",
      "addr": "127.0.0.1:6790\/0"},
      { "rank": 2,
      "name": "c",
      "addr": "127.0.0.1:6791\/0"}]}}' (0)
   }
   7.1.3)如果法定人数未形成,上述命令会一直等待。
  }
  7.2)你刚刚连接的监视器的状态(用-m HOST:PORT 另 外指定):
  {
   ceph mon_status
    2011-12-14 10:45:30.644414 mon {- [mon_status]
    2011-12-14 10:45:30.644632 mon.0 -}
    '{ "name": "a",
     "rank": 0,
     "state": "leader",
     "election_epoch": 10,
     "quorum": [
     0,
     1,
     2],
     "outside_quorum": [],
     "monmap": { "epoch": 1,
     "fsid": "444b489c-4f16-4b75-83f0-cb8097468898",
     "modified": "2011-12-12 13:28:27.505520",
     "created": "2011-12-12 13:28:27.505520",
     "mons": [
     { "rank": 0,
     "name": "a",
     "addr": "127.0.0.1:6789\/0"},
     { "rank": 1,
     "name": "b",
     "addr": "127.0.0.1:6790\/0"},
     { "rank": 2,
     "name": "c",
     "addr": "127.0.0.1:6791\/0"}]}}' (0)
  }
  7.3)监视器状态转储:
  {
   ceph mon dump
    2011-12-14 10:43:08.015333 mon {- [mon,dump]
    2011-12-14 10:43:08.015567 mon.0 -} 'dumped monmap epoch 1' (0)
    epoch 1
    fsid 444b489c-4f16-4b75-83f0-cb8097468898
    last_changed 2011-12-12 13:28:27.505520
    created 2011-12-12 13:28:27.505520
    0: 127.0.0.1:6789/0 mon.a
    1: 127.0.0.1:6790/0 mon.b
    2: 127.0.0.1:6791/0 mon.c 
  }
 }

APIS:
 1、大多数ceph部署都要用到ceph块设备、网关或CephFS文件系统,你也可以开发程序直接和ceph对象存储交互。
 2、ceph的RADOS对象存储提供了消息传递层协议,用于客户端和ceph监视器和OSD交互,librados以库形式为对象存储客户端提供了这个功能。所有ceph客户端
 可以用librados或 librados里封装的相同功能和对象存储交互,例如librbd和libcephfs就利用了此功能。你可以用librados直接和ceph交互(如和ceph兼容的应用程序、
 你自己的ceph接口、等等)。
 3、librados提供了RADOS服务的底层访问功能。
 
Mount ceph fs with the kernel driver:
 1、要挂载ceph文件系统,如果你知道监视器IP地址可以用mount命令、或者用mount.ceph工具来自动解析监视器IP地址。例如:
 {
  1.1)直接挂载未cephx认证:
  {
   sudo mkdir /mnt/mycephfs
   sudo mount -t ceph 192.168.0.1:6789:/ /mnt/mycephfs 
  }
  1.2)要挂载启用了cephx认证的ceph文件系统,你必须指定用户名、密码:
  {
   sudo mount -t ceph 192.168.0.1:6789:/ /mnt/mycephfs -o name=admin,secret=AQATSKdNGBnwLhAAnNDKnH65FmVKpXZJVasUeQ== (密码遗留在bash历史里,不安全)
   sudo mount -t ceph 192.168.0.1:6789:/ /mnt/mycephfs -o name=admin,secretfile=/etc/ceph/admin.secret (从文件中读取密码,更安全)
  }
  1.3)要卸载ceph文件系统,可以用unmount命令,例如--> sudo umount /mnt/mycephfs (执行此命令前确保你不在此文件系统目录下)
 }
 2、要把ceph文件系统挂载为用户空间文件系统(File System in User Space, FUSE),可以用ceph-fuse命令,例如:
 {
  sudo mkdir /home/usernname/cephfs
  sudo ceph-fuse -m 192.168.0.1:6789 /home/username/cephfs
  
  Notes:
   2.1)如果启用了cephx认证,ceph-fuse会从密钥环自动检索用户名、密码
 }
 3、如果你从文件系统表挂载,ceph文件系统将在启动时自动挂载。要从文件系统表挂载Ceph FS按下列格式添加到 /etc/fstab:
 {
  {ipaddress}:{port}:/ {mount}/{mountpoint} {filesystem-name} [name=username,secret=secretkey|
  secretfile=/path/to/secretfile],[{mount.options}]
  Example:
  {
   10.10.10.10:6789:/ /mnt/ceph ceph
   name=admin,secretfile=/etc/ceph/secret.key,noauto,rw,noexec,nodev,noatime,nodiratime 0 2
  }
  
  Notes:
  3.1)启用了认证时,name及secret或secretfile选项是强制的。
 }
 4、cephfs是个控制工具,用于访问和修改ceph分布式文件系统内的文件布局及位置信息,可用命令有下面3个:
 {
  cephfs [ path command options ]
  
  ? show_layout    查看一个文件或目录的布局信息;
  ? set_layout    设置一个文件或目录的布局信息;
  ? show_location   查看一个文件的位置信息;
  ? map      查看一个文件分片信息,包括其对象及所在归置组、OSD。
  
  Notes:详见p183
 }
 5、eph-fuse是一个Ceph分布式文件系统的用户空间(FUSE, File system in USErspace)客户端,它会把ceph文件系统(用 -m 选项指定)挂载到指定挂载点:
 {
  ceph-fuse [ -m monaddr:port ] mountpoint [ fuse options ]
  
  5.1)用下面的命令卸载文件系统--> fusermount -u mountpoint
  
  Notes:详见p185
 }
 6、mount.ceph是个简单的助手程序,用于在Linux主机上挂载Ceph文件系统。其作用是把监视器主机名解析为IP地址、并从硬盘读取认证密钥,Linux内核客户端
 组件完成了大多数实际工作:
 {
  mount -t ceph 1.2.3.4:/ mountpoint
  
  6.1)每个监视器地址monaddr格式都是 host[:port],如果未指定端口,就用默认端口6789。
  6.2)挂载整个文件系统--> mount.ceph monhost:/ /mnt/foo
  6.3)若有多个监视器--> mount.ceph monhost1,monhost2,monhost3:/ /mnt/foo
  6.4)ceph-mon(8)运行在非标准端口上--> mount.ceph monhost1:7000,monhost2:7000,monhost3:7000:/ /mnt/foo
  6.5)只挂载名字空间的一部分--> mount.ceph monhost1:/some/small/thing /mnt/thing
  6.6)mount.ceph(8)正确安装了,它会被mount(8)自动调用,像这样--> mount -t ceph monhost:/ /mnt/foo
  6.7)
 }

Block Devices:
 1、块是一个字节序列(例如,一个512字节的一块数据),基于块的存储接口是最常见的存储数据方法,它们基于旋转媒体,像硬盘、CD、软盘、甚至传统的9磁道磁带。
 无处不在的块设备接口使虚拟块设备成为与ceph这样的海量存储系统交互的理想之选。
 2、ceph块设备是精简的、大小可调且数据条带化到集群内的多个OSD。ceph块设备均衡多个RADOS能力,如快照、复制和一致性,ceph的RADOS块设备
 (RADOS Block Devices, RBD)用内核模块或librbd库与OSD交互。
 3、内核模块可使用Linux页缓存。对基于librbd的应用程序,ceph可提供RBD缓存。
 4、Ceph块设备靠无限伸缩性提供了高性能,如向内核模块、或向KVM(如Qemu、依赖libvirt和Qemu的OpenStack和CloudStack云计算系统都可与Ceph 块设备集成)。
 你可以用同一个集群同时运行Ceph RADOS网关、CephFS文件系统、和ceph块设备。
 5、要使用RBD,你必须有一个在运行的ceph集群。
 
RADOS GateWay:
 1、RADOS网关是构建于librados之上的对象存储接口,可为应用程序提供到RADOS集群的RESTful网关,它现在提供了2个接口:
 {
  S3 兼容:用 兼容大量亚马逊 S3 RESTful API 的接口 提供了 块存储功能。
  Swift 兼容:用 兼容大量 OpenStack Swift API 的接口 提供了 块存储功能。
 }
 2、RADOS网关是个与librados交互的FastCGI模块。因为它提供了与OpenStack Swift和Amazon S3兼容的接口,RADOS要有它自己的用户管理。RADOS网关可在存储Ceph FS
 客户端或RADOS块设备数据的集群里存储数据。S3和Swift API共用一个名字空间,所以你可以用一个API写、然后用另一个检索。
 3、RADOS网关不使用CephFS元数据服务器。

Architecture:
 1、CEPH提供了一个可无限伸缩的对象存储系统,它基于RADOS。它的高级功能包括:基于librados的对象存储系统原生接口、和多种服务接口:
 {
  1.1)块设备:RBD服务提供了大小可调、精炼、支持快照和克隆的块设备。为提供高性能,ceph把块设备条带化。ceph同时支持直接使用librbd的内核对象(KO)和QEMU
  管理程序——避免了虚拟系统上的内核模块开销。
  1.2)RESTful网关:RADOS网关(RADOS Gateway, RGW)服务提供了和Amazon S3和OpenStack Swift兼容的RESTful API。
  1.3)Ceph文件系统:Ceph文件系统兼容POSIX,可以直接挂载或挂载为用户空间文件系统(FUSE)。
  1.4)Ceph的OSD把所有数据以对象形式保存在对象存储系统中——不论它来自RBD、RGW还是CephFS。Ceph可运行多个OSD、MDS和监视器例程,以保证伸缩性和高可用性。 
 }
 2、Ceph用了全新的方法,其客户端联系ceph监视器并获得一份集群运行图拷贝。CRUSH算法让客户端计算数据应该存在哪里、并允许它联系主OSD来存储或检索数据。OSD
 也用CRUSH算法,但是用于计算数据副本应该存到哪里(或用于重均衡)。
 3、Ceph存储系统支持“池”概念,它是存储对象数据的逻辑分区。存储池设置了所有者及访问权限、对象副本数、归置组数量、要用的CRUSH规则集。每个存储池都有一定
 数量的归置组动态地映射到OSD,客户端存数据时,CRUSH把对象数据映射到归置组。
 4、把对象映射到归置组而不是直接到OSD,由此在OSD和客户端间产生了一个间接层。由于集群必须能增大或缩小、并动态地重均衡数据,如果客户端“知道”哪个OSD有数据,
 这将会导致客户端和OSD间密耦合,相反,CRUSH算法把数据映射到归置组、然后再把归置组映射到一或多个OSD。这个间接层可以让ceph在OSD上线时动态地重均衡。
 5、用一份集群运行图的拷贝和CRUSH算法,客户端能准确计算出到哪个OSD读、写数据片段。
 6、在一个典型的写入场景中,一客户端用CRUSH算法计算往哪里存数据、映射数据到归置组、然后参阅CRUSH图找到归置组的主OSD;客户端把数据写入目标归置组的主OSD,
 然后这个主OSD再用它的CRUSH图副本找出用于放副本的第二、第三个OSD,并把数据复制到适当的归置组所对应的第二、第三OSD(要多少副本就有多少OSD),最终,确认
 数据成功存储后反馈给客户端。
 7、由于任何网络设备都有其支持的最大并发连接限制,规模巨大时一个中央化的系统其物理局限性就暴露了。Ceph允许客户端直接和节点联系,这在消除单故障点的同时,
 提升了性能和系统总容量。Ceph客户端可按需维护和某OSD的会话,而不是一个中央服务器。
 8、在很多集群化体系结构中,设计集群成员的主要目的是让中央接口知道它能访问哪些主机。ceph向前迈进了一步:ceph的节点会感知集群,每个节点都知道集群内的其它
 节点,这使得ceph的监视器、OSD、和元数据服务器守护进程可以直接互相沟通。这种方法的一个主要优势是,ceph能很容易地利用其节点的CPU和内存资源执行任务,
 而这样的任务会拖垮中央服务器。
 9、Ceph的OSD加入集群后会持续报告自己的状态。在最低水平,OSD状态为up或down,反应了它是否在运行、能否提供服务。如果一个OSD状态为down且in,表明OSD可能有故障。
 10、有了邻居感知功能,为执行任务OSD能和其它OSD和监视器通讯。OSD根据客户端请求向存储池内的归置组读取或写入数据。当一客户端向某个主OSD请求写入数据时,主
 OSD知道如何确定哪个OSD持有用于副本的归置组,继而更新那些OSD。这意味着OSD也能接受其他OSD的请求,用散布于多个OSD的多份数据副本,OSD也能通过相互查询来确保
 归置组同步无误。
 11、如果一OSD没在运行(比如,它崩溃了 ),这个OSD就不能告诉监视器它挂了。监视器可以周期性地ping一个OSD来确保它在运行,即便这样,ceph也授权OSD们探测它的
 邻居OSD是否还活着,以此来更新集群运行图并报告给监视器。一个OSD 挂了时, 对应归置组里的数据就降级了,如果OSD状态为down且in,但随后被踢出了集群,其余OSD会
 收到一个集群运行图更新,并自动重均衡集群内的归置组。
 12、OSD在扁平的名字空间里把所有数据存储为对象(例如,没有目录层次)。对象包含一个标识符、二进制数据、和由名字/值配对组成的元数据,语义完全取决于客户端。
 13、作为维护工作的一部分,不但要保证数据的一致性和清洁性,OSD也能洗刷数据,就是说,Ceph OSD能比较对象元数据的几个副本以捕捉OSD缺陷或文件系统错误(每天)。
 OSD也能做深度洗刷,即按字节比较对象中的数据以找出轻度洗刷(每周)时未发现的硬盘坏扇区。
 14、ceph的监视器维护着集群运行图的原稿,所以ceph守护进程和客户端只是周期性地联系监视器以保证他们有运行图的最新副本。ceph监视器是轻量级进程,但是增强了
 可靠性和容错能力,ceph 持分布式监视器。不管Ceph集群状态如何,其不同监视器例程必须达成一致,为此,ceph总是使用奇数个监视器(如:1、 3、 5、 7……)和Paxos
 算法来达成一致意见。
 15、Ceph文件系统服务由名为ceph-mds的守护进程提供,它使用RADOS存储所有文件系统元数据(目录、文件所有者、访问权限等等),并指导客户端直接访问RADOS获取文件
 内容。Ceph力争兼容POSIX。ceph-mds可以只运行一个,也可以分布于多台物理机器,以获得高可用性或伸缩性:
 {
  15.1)高可用性:多余的ceph-mds例程可处于standby(待命)状态,随时准备替下之前处于active(活跃)状态的失败ceph-mds。这可以轻易做到,因为所有数据、
  包括日志都存储在RADOS上,这个转换过程由ceph-mon自动触发。
  15.2)可伸缩性:多个ceph-mds例程可以处于active状态,并且它们会把目录树分割为子树(和单个忙碌目录的碎片),在所有活跃服务器间高效地均衡负载。
  15.3)待命和活跃MDS可组合,例如,运行3个活跃ceph-mds例程以实现扩展、和1个待命例程以实现高可用性。
 }
 16、ceph客户端能通过ceph监视器、OSD和元数据服务器认证它们的用户,通过认证的用户获得读、写和执行ceph命令的授权。cephx认证系统和Kerberos相似,但消除了
 单故障点,进而保证了可扩展性和高可用性。
 17、RBD把一个设备映像条带化到集群内的多个对象,其中每个对象都被映射到一个归置组并分布出去,这些归置组会散播到整个集群的某些ceph-osd守护进程。
 条带化会使 RBD 块设备比单台服务器运行的更好。
 18、RBD的简配、可快照块设备对虚拟化和云计算很有吸引力。在虚拟机场景中,人们一般会用Qemu/KVM中的rbd网络驱动部署RBD,虚拟主机用librbd向客户提供块设备服务;
 很多云计算堆栈用libvirt和管理程序集成,你可以用RBD的简配块设备搭配Qemu 和 libvirt来支持OpenStack 和 CloudStack。
 19、RADOS网关守护进程是radosgw,它是一个FastCGI服务,提供了RESTful HTTP API用于存储对象和元数据。它坐落于RADOS之上,有自己的数据格式,并维护着自己的
 用户数据库、认证、和访问 控制。RADOS网关使用统一的名字空间,也就是说,你可以用OpenStack Swift兼容的API或者Amazon S3兼容的API;例如,你可以用一个程序以
 S3兼容API写入数据、然后用另一个程序以Swift兼容API读出。 

猜你喜欢

转载自blog.csdn.net/yuxin6866/article/details/79664424
今日推荐