且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Ceph分布式存储实战.

更新时间:2021-12-24 12:54:41

Ceph分布式存储实战.

云计算与虚拟化技术丛书


Ceph分布式存储实战

Ceph中国社区 著






图书在版编目(CIP)数据

Ceph分布式存储实战/Ceph中国社区著. —北京:机械工业出版社,2016.11

(云计算与虚拟化技术丛书)

ISBN 978-7-111-55358-8

I. C… II. C… III. 分布式文件系统 IV. TP316

中国版本图书馆CIP数据核字(2016)第274895号




Ceph分布式存储实战

出版发行:机械工业出版社(北京市西城区百万庄大街22号 邮政编码:100037)

责任编辑:高婧雅 责任校对:殷 虹

印  刷: 版  次:2016年12月第1版第1次印刷

开  本:186mm×240mm 1/16 印  张:19.5

书  号:ISBN 978-7-111-55358-8 定  价:69.00元

凡购本书,如有缺页、倒页、脱页,由本社发行部调换

客服热线:(010)88379426 88361066 投稿热线:(010)88379604

购书热线:(010)68326294 88379649 68995259 读者信箱:hzit@hzbook.com

版权所有·侵权必究

封底无防伪标均为盗版

本书法律顾问:北京大成律师事务所 韩光/邹晓东





Praise 本书赞誉

正如OpenStack日渐成为开源云计算的标准软件栈,Ceph也被誉为软件定义存储开源项目的领头羊。细品本书,慢嗅“基础理论讲解简明扼要,技术实战阐述深入全面”之清香。千言万语,不如动手一战。Ceph爱好者们,请启动机器,拿起本书,早日踏上Ceph专家之路。

—陈绪,博士,英特尔中国云计算战略总监,中国开源软件推进联盟常务副秘书长,2015年中日韩东北亚开源论坛最高奖项“特别贡献奖”获得者


Ceph是主流的开源分布式存储操作系统。我们看到越来越多的云服务商和企业用户开始考察Ceph,把它作为构建“统一存储”和“软件定义存储”的可信赖解决方案。Ceph的CRUSH算法引擎,聪明地解决了数据分布效率问题,奠定了它胜任各种规模存储池集群的坚实基础。过去5年,在Red Hat、Intel等软硬件基础设施领导者的推动下,Ceph开源社区有超过10倍的增长—不仅仅具备广泛的硬件兼容性体系,大量上下游厂商添砖加瓦,也吸引了很多运营商、企业用户参与改进。XSKY很荣幸作为社区的一员,见证与实践着Ceph帮助用户进行存储基础架构革新的历程。我们欣喜地看到由Ceph中国社区撰写的本书的问世,这是一部在立意和实践方面均不输于同期几本英文书籍的作品,深入浅出,娓娓道来,凝结了作者的热情和心血。我们诚挚地向业内技术同行和Ceph潜在用户推荐此书!愿Ceph中国社区在推进开源事业的道路上取得更大的成功!

—胥昕,XSKY星辰天合(北京)数据科技有限公司CEO


在开源软件定义存储(SDS)领域,Ceph是当之无愧的王者项目。随着IaaS技术的火热发展,越来越多的用户开始在生产环境中部署SDS。伴随着基础设施开源化的趋势,很多用户希望部署开源的SDS,Ceph成为了他们的第一选择。跟大多数开源软件项目一样,Ceph具有优秀的技术特性,但也存在着部署难、运维难的问题。在使用开源Ceph发行版时,用户需要对Ceph的实现原理、部署运维***实践有一定了解,才能在生产环境中稳定使用这一开源技术。长期以来,中文技术社区一直没有一本对Ceph的原理、生产实践、运维实践进行剖析的好书,本书的出现填补了这一空白。该书不仅从原理上对Ceph的核心技术进行了讲解,还介绍了将Ceph部署在OpenStack、ZStack等IaaS软件上的生产环境实践,最后着重介绍了Ceph的运维和排错,是一本不可多得的Ceph百科全书,是Ceph用户、IaaS开发人员必备的一本SDS工具书。

—张鑫,前CloudStack核心初创人员,开源IaaS项目ZStack创始人


开源系统是Linux的世界,开源管理平台是OpenStack的世界,开源存储是Ceph的世界。软件定义存储(SDS)是存储发展的必然趋势,***的开源软件定义存储方案无疑就是Ceph,我身边好多朋友已经开始在生产环境中大量部署Ceph,Ceph也表现出卓越的稳定性和性能。但是Ceph的搭建和使用门槛比较高,很高兴看到Ceph中国社区组织编写的本书的出版,为Ceph搭建学习降低了门槛,是国内Ceph爱好者的福音。Ceph中国社区为Ceph在中国的普及做了大量非常重要的工作,本书是一个里程碑,相信Ceph中国社区会继续为Ceph做出更多的贡献。

—肖力,KVM云技术社区创始人


Ceph作为分布式存储开源项目的杰出代表,在各个领域已经得到了充分验证,可以预见,在未来的几年时间内,Ceph一定会得到更广泛的应用。本书作为国内为数不多阐述Ceph的著作,从基础、原理和实践多个层面进行了详尽讲解,是一本快速了解并掌握Ceph的力作。

—孙琦(Ray),北京休伦科技有限公司CTO


软件看开源,SDS看Ceph。Ceph是目前影响力最大的开源软件定义存储解决方案,其应用范围涵盖块存储、文件存储和对象存储,广泛被业界公司所采用。

很荣幸能在第一时间读到这本书,该书从Ceph的部署开始,阐明了Ceph各个主要模块及其功能,介绍了Ceph在块存储、文件存储和对象存储不同场景下的应用方式,指明了Ceph性能调优的方案。尤其是最后的生产环境应用案例,解了使用Ceph的技术人员的燃眉之急,给出了常见问题的解决思路,造福于整个开源云存储界。

无论是售前专家、开发架构师还是运维负责人,读一读Ceph中国社区编写的这本书,都可以细细地品一品,积极地拥抱开源、把握云存储的未来。

—楼炜,盘古数据资深云和大数据架构师


作为一名早期研究Ceph的人员,很高兴看到Ceph在近几年如火如荼的发展状态。在我刚接触Ceph时,很渴望得到系统化的介绍、培训或指导。但当时Ceph在国内还处于小众研究状态,高人难寻,深入全面的介绍资料更是没有。Ceph中国社区的朋友们出版这本介绍Ceph的书籍,为Ceph的广大研究者和爱好者做了一件很有意义的事情。相信本书一定能够成为Ceph发展的强力助推器!

—温涛,新华三集团(H3C公司)ONEStor产品研发负责人 


Ceph因其先进的设计思想,良好的可靠性、可扩展性,成为存储领域的研究热点,被誉为“存储的未来”,得到广泛的部署。由Ceph中国社区组织编写的这本书是国内第一本系统介绍Ceph的书籍,全书从Ceph的历史、架构、原理到部署、运维、应用案例,讲解全面深入,可操作性强。本书非常适合想要了解Ceph、使用Ceph的读者阅读,也可供分布式存储系统设计者参考。

 —汪黎,KylinCloud团队存储技术负责人,Ceph代码贡献者


从实用价值上看,本书从Ceph的基本原理、Ceph的安装部署和Ceph的应用案例等方面进行了深入浅出的讲解,理论和实践完美结合,是难得的系统阐述Ceph的教科书,是广大Ceph爱好者的福音。

从理论价值上看,Ceph是超融合架构下首选的开源存储方案,本书详细阐述了存储相关的基本原理,不仅让你知其然,更能让你知其所以然。

—刘军卫,中国移动苏州研发中心云计算产品部技术总监


Ceph是当前最热门的分布式存储系统,在云技术领域获得了广泛的欢迎和支持。但是目前国内与此相关的书籍非常少。如果想学习Ceph,想更深入地了解Ceph,而又对密密麻麻的英文望而生畏,那么现在救星来了!本书从系统原理、基本架构、性能优化、应用实践、运维部署等各个方面对Ceph进行了全方位的介绍和分析。这是一本从入门到精通的好书,值得拥有! 


—李响,博士,中兴通讯股份有限公司IaaS开源项目总监


一群开源的人用开源的方式去做一件开源的事儿,我想没有比这更合适的事情了。作为一名有着近10年的分布式存储研发和软件定义存储(SDS)产品及技术规划的先行者与践行者,很高兴看到同样已经十几岁的Ceph在众人之力和众人之智的推动下,吐故纳新,正以日新月异的速度蓬勃发展。

Ceph是每一个软件定义存储相关从业人员关注的重点,Ceph中国社区把国内广大的Ceph爱好者聚集到一起,分享“踩坑”的经验,承担了95%以上Ceph文档的本土化(翻译)工作,对Ceph在国内的发展扮演着非常重要的推动作用,非常感谢Ceph中国社区的每一位贡献者。

杉岩数据作为一家商用Ceph解决方案和服务提供商,随着Ceph商用产品越来越多地在企业级用户的生产环境中应用,一直期待能有一本适合国人阅读习惯且浅显易懂的Ceph书籍,让更多的人了解Ceph的功能特性。当我有幸阅读过此书后,我强烈建议广大SDS相关从业人员阅读此书,你一定会收获良多!

—陈坚,深圳市杉岩数据技术有限公司总经理


Ceph从2012年开始拥抱OpenStack到现在已经成为OpenStack的首选后端存储。很高兴看到Ceph中国社区把国内广大的Ceph爱好者聚集到一起,分享技术与经验,对Ceph在国内的发展起到了非常重要的推动和落地作用。也一直期待国内能有一本Ceph入门相关的书籍,看到Ceph中国社区出版的这本书,很是欣慰。国内Ceph资料从稀缺到逐渐完善,这其中离不开Ceph中国社区的贡献和努力。

—朱荣泽,上海优铭云计算有限公司存储架构师


国内第一本对Ceph进行全面剖析的书籍,并辅以大量的实战操作,内容由浅入深,特别适合希望对Ceph进行系统性学习的工程师,是国内Ceph爱好者的福音。

—田亮,北京海云捷迅科技有限公司解决方案总监 


Ceph是开源分布式存储领域的一颗当红明星,随着OpenStack如火如荼的发展,Ceph也逐渐成为了OpenStack的首选后端存储。国内目前缺乏Ceph入门以及相关运维书籍,Ceph中国社区出版的这本书填补了国内Ceph的空白,是国内Ceph爱好者的福音。

—陈沙克,浙江九州云信息科技有限公司副总裁


由于其出色的系统设计,Ceph正广泛部署于各大云计算厂商的生产环境中,为用户提供对象存储、云硬盘和文件系统存储服务。本书理论联系实际,除介绍Ceph的设计理念和原理之外,还系统介绍了Ceph的编程接口、上线部署、性能调优及应用场景,有利于读者快速掌握Ceph的运维和基于Ceph的开发。此书提供了深入理解云存储的捷径。

—吴兴义,乐视云技术经理


Ceph诞生于传统存储行业正处于巅峰之时,短短十多年间,闪存(如SSD)与软件定义存储(SDS)就联手颠覆了存储行业。作为软件定义存储领域的旗帜性项目,Ceph肩负着业界的厚望,也需要“与时俱进”,继续改进和完善,满足目标用户越来越高的要求。

众所周知,Ceph是个开源项目,成型于硬盘仍为主导的年代。如今,市场和用户需要Ceph更加产品化,同时充分利用闪存等固态存储介质带来的性能红利。这就要求业界精简过时的代码和不必要的中间层,并为Ceph加入新的功能和特性,对此,我个人归纳为“先做减法,再做加法”。要达到上述目标,必须让更多的人关注和了解Ceph,特别是吸引有一定存储经验和积累的人或组织加入Ceph生态圈。作为一本不可多得的系统介绍Ceph的书籍,本书的出版正逢其时,定会为Ceph生态的壮大贡献更多的有生力量。

—张广彬,北京企事录技术服务公司创始人






序 Preface

Ceph是目前开源世界在存储领域的里程碑式项目,它所带来的分布式、无中心化设计是目前众多商用分布式存储模仿和学习的对象。Ceph社区经过十多年发展已经成为近几年参与度增长最快的开源社区之一,而Ceph中国社区正是背后的驱动力之一。从2015年开始,Ceph中国社区一直努力在国内普及Ceph的生态,并为广大Ceph爱好者提供了交流平台,使得众多开源爱好者能够进一步了解Ceph的魅力。在过去的10年,开源世界慢慢成为了IT创新的动力,而这10年也是国内技术爱好者受益于开源的***时间。但是,从开源爱好者到社区的深度参与方面,尤其是在世界级开源项目上,我们还存在大缺失,而这些“沟壑”需要像Ceph中国社区这样的组织来弥补。我很欣喜地看到Ceph中国社区能在最合适的时间成立并迅速成长,而且受到Ceph官方社区的认可。

Ceph中国社区从论坛的搭建,微信群的建立,公众号的众包翻译和文章分析,到活动的组织都体现了一个开源社区最富有活力的价值。本书正是Ceph中国社区给国内Ceph爱好者的一份正当其时的“礼物”,本书是多位Ceph实战者在Ceph集群运维和问题讨论中形成的经验和锦囊之集合。毫不夸张地说,本书是我目前看到的最棒的Ceph入门工具书,可以帮助对分布式存储或者Ceph不太熟悉的读者真正零距离地接触并使用它。


王豪迈

2016年9月8日






Foreword 前言

随着信息化浪潮的到来,全球各行各业逐步借助信息技术深入发展。据悉,企业及互联网数据以每年50%的速率在增长。据权威调查机构Gartner预测,到2020年,全球数据量将达到35ZB,相当于80亿块4TB硬盘,数据结构的变化给存储系统带来了全新的挑战。那么有什么方法能够存储这些数据呢?我认为Ceph是解决未来十年数据存储需求的一个可行方案。Ceph是存储的未来!SDS是存储的未来!

为什么写这本书

目前,磁盘具备容量优势,固态硬盘具备速度优势。但能否让容量和性能不局限在一个存储器单元呢?我们很快联想到磁盘阵列技术(Redundant Array of Independent Disk,RAID,不限于HDD)。磁盘阵列技术是一种把多块独立的硬盘按不同的方式组合起来形成一个硬盘组(Disk Group,又称Virtual Disk),从而提供比单个硬盘更高的存储性能与数据备份能力的技术。磁盘阵列技术既可提供多块硬盘读写的聚合能力,又能提供硬盘故障的容错能力。

镜像技术(Mirroring)又称为复制技术(Replication),可提供数据冗余性和高可用性;条带(Striping),可提供并行的数据吞吐能力;纠删码(Erasure Code),把数据切片并增加冗余编码而提供高可用性和高速读写能力。镜像、条带和纠删码是磁盘阵列技术经典的数据分发方式,这3种经典的磁盘技术可通过组合方式提供更加丰富的数据读写性能。

传统的磁盘阵列技术的关注点在于数据在磁盘上的分发方式,随着通用磁盘、通用服务器,以及高速网络的成本降低,使数据在磁盘上的分发扩展到在服务器节点上的分发成为可能。镜像技术、条带技术和纠删码技术基于服务器节点的粒度实现后,这些技术的特点不再局限于单个设备的性能,而是具备“横向扩展”能力。我们暂且认为这是分布式存储本质的体现。

分布式存储解决了数据体量问题,对应用程序提供标准统一的访问接入,既能提升数据安全性和可靠性,又能提高存储整体容量和性能。可以预见,分布式存储是大规模存储的一个实现方向。分布式存储广泛地应用于航天、航空、石油、科研、政务、医疗、视频等高性能计算、云计算和大数据处理领域。目前行业应用对分布式存储技术需求旺盛,其处于快速发展阶段。

Ceph是加州大学圣克鲁兹分校的Sage Weil博士论文的研究项目,是一个使用***开源协议(LGPLv2.1)的分布式存储系统。目前Ceph已经成为整个开源存储行业最热门的软件定义存储技术(Software Defined Storage,SDS)。它为块存储、文件存储和对象存储提供了统一的软件定义解决方案。Ceph旨在提供一个扩展性强大、性能优越且无单点故障的分布式存储系统。从一开始,Ceph就被设计为能在通用商业硬件上高度扩展。

由于其开放性、可扩展性和可靠性,Ceph成为了存储行业中的翘楚。这是云计算和软件定义基础设施的时代,我们需要一个完全软件定义的存储,更重要的是它要为云做好准备。无论运行的是公有云、私有云还是混合云,Ceph都非常合适。国内外有不少的Ceph应用方案,例如美国雅虎公司使用Ceph构建对象存储系统,用于Flickr、雅虎邮箱和Tumblr(轻量博客)的后端存储;国内不少公有云和私有云商选择Ceph作为云主机后端存储解决方案。

如今的软件系统已经非常智能,可以最大限度地利用商业硬件来运行规模庞大的基础设施。Ceph就是其中之一,它明智地采用商业硬件来提供企业级稳固可靠的存储系统。

Ceph已被不断完善,并融入以下建设性理念。

每个组件能够线性扩展。

无任何单故障点。

解决方案必须是基于软件的、开源的、适应性强的。

运行于现有商业硬件之上。

每个组件必须尽可能拥有自我管理和自我修复能力。

对象是Ceph的基础,它也是Ceph的构建部件,并且Ceph的对象存储很好地满足了当下及将来非结构化数据的存储需求。相比传统存储解决方案,对象储存有其独特优势:我们可以使用对象存储实现平台和硬件独立。Ceph谨慎地使用对象,通过在集群内复制对象来实现可用性;在Ceph中,对象是不依赖于物理路径的,这使其独立于物理位置。这种灵活性使Ceph能实现从PB(petabyte)级到EB(exabyte)级的线性扩展。

Ceph性能强大,具有超强扩展性及灵活性。它可以帮助用户摆脱昂贵的专有存储孤岛。Ceph是真正在商业硬件上运行的企业级存储解决方案;是一种低成本但功能丰富的存储系统。Ceph通用存储系统同时提供块存储、文件存储和对象存储,使客户可以按需使用。

由于国内许多企业决策者逐渐认识到Ceph的优势与前景,越来越多来自系统管理和传统存储的工程师使用Ceph,并有相当数量的企业基于Ceph研发分布式存储产品,为了更好地促进Ceph在国内传播和技术交流,我们几个爱好者成立了Ceph中国社区。目前,通过网络交流群、消息内容推送和问答互动社区,向国内关注Ceph技术的同行提供信息交流和共享平台。但是,由于信息在传递过程中过于分散,偶尔编写的文档内容并不完整,导致初学者在学习和使用Ceph的过程中遇到不少疑惑。同时,由于官方文档是通过英文发布的,对英语不太熟悉的同行难于学习。鉴于此,Ceph中国社区组织技术爱好者编写本书,本书主要提供初级和中级层面的指导。根据调查反馈以及社区成员的意见,我们确定了本书内容。

本书特色

在本书中,我们将采用穿插方式讲述Ceph分布式存储的原理与实战。本书侧重实战,循序渐进地讲述Ceph的基础知识和实战操作。从第1章起,读者会了解Ceph的前生今世。随着每章推进,读者将不断学习、不断深入。我希望,到本书的结尾,读者不论在概念上还是实战上,都能够成功驾驭Ceph。每个章节在讲述完基础理论知识后会有对应的实战操作。我们建议读者在自己的电脑上按部就班地进行实战操作。这样,一来读者不会对基础理论知识感到困惑,二来可让读者通过实战操作加深对Ceph的理解。同时,如果读者在阅读过程中遇到困难,我们建议再重温已阅章节或重做实验操作,这样将会加深理解,也可以加入Ceph中国社区QQ群(239404559)进行技术讨论。

读者对象

本书适用于以下读者。

Ceph爱好者。

云平台运维工程师。

存储系统工程师。

系统管理员。

高等院校的学生或者教师。

本书是专门对上述读者所打造的Ceph入门级实战书籍。如果你具备GNU/ Linux和存储系统的基本知识,却缺乏软件定义存储解决方案及Ceph相关的经验,本书也是不错的选择。云平台运维工程师、存储系统工程师读完本书之后能够深入了解Ceph原理、部署和维护好线上Ceph集群。同时,本书也适合大学高年级本科生和研究生作为Ceph分布式存储系统或者云计算相关课程的参考书籍,能够带领你进入一个开源的分布式存储领域,深入地了解Ceph,有助于你今后的工作。

如何阅读本书

由于Ceph是运行在GNU/Linux系统上的存储解决方案,我们假定读者掌握了存储相关知识并熟悉GNU/Linux操作系统。如果读者在这些方面知识有欠缺,可参照阅读其他书籍或专业信息网站。

本书将讲述如下的内容。

第1章 描述Ceph的起源、主要功能、核心组件逻辑、整体架构和设计思想,并通过实战的方式指导我们快速建立Ceph运行环境。

第2章 描述Ceph的分布式本质,深入分析Ceph架构,并介绍如何使用LIBRADOS库。

第3章 描述CRUSH的本质、基本原理,以及CRUSH作用下数据与对象的映射关系。

第4章 描述Ceph FS文件系统、RBD块存储和Object对象存储的建立以及使用。

第5章 描述Calamari的安装过程和基本使用操作。 

第6章 描述Ceph FS作为高性能计算和大数据计算的后端存储的内容。

第7章 描述RBD在虚拟化和数据库场景下的应用,包括OpenStack、CloudStack和ZStack与RBD的结合。

第8章 描述基于Ceph的云盘技术方案和备份方案,描述网关的异地同步方案和多媒体转换网关设计。

第9章 描述Ceph的硬件选型、性能调优,以及性能测试方法。

第10章 描述CRUSH的结构,并给出SSD与SATA混合场景下的磁盘组织方案。

第11章 描述Ceph的缓冲池原理和部署,以及纠删码原理和纠删码库,最后描述纠删码池的部署方案。

第12章 对3种存储访问类型的生产环境案例进行分析。

第13章 描述Ceph日常运维细节,以及常见错误的处理方法。

勘误与支持

在本书的写作过程,我们也参考了Ceph中国社区往期沙龙一线工程师、专家分享的经验和Ceph官方文档。我们热切希望能够为读者呈现丰富而且权威的Ceph存储技术。由于Ceph社区不断发展,版本迭代速度快,笔者水平有限,书中难免存在技术延后和谬误,恳请读者批评指正。可将任何意见和建议发送到邮箱devin@ceph.org.cn或者star.guo@ceph.org.cn,也可以发布到Ceph中国社区问答系统http://bbs.ceph.org.cn/。我们将密切跟踪Ceph分布式存储技术的发展,吸收读者宝贵意见,适时编写本书的升级版本。Ceph中国社区订阅号为:“ceph_community”,二维码为:


欢迎读者扫描关注,“Ceph中国社区订阅号”会定期发送Ceph技术文章、新闻资讯。也欢迎读者通过这个微信订阅号进行本书勘误反馈,本书的勘误和更新也会通过订阅号发布。

致谢

首先要感谢我们社区的全体志愿者,社区的发展离不开全体志愿者们无怨无悔的奉献,正是有了你们才有了社区今日的繁荣,其次要感谢所有支持过我们的企业,是你们的慷慨解囊成就了Ceph中国社区今日的壮大,最后感谢陈晓熹的校稿以及所有为本书编写提供支持、帮助的人。未来,我们也非常欢迎有志将开源事业发扬光大的同学们积极加入我们的社区,和我们一起创造Ceph未来的辉煌。





Contents 目录

本书赞誉

前言

第1章 初识Ceph 1

1.1 Ceph概述 1

1.2 Ceph的功能组件 5

1.3 Ceph架构和设计思想 7

1.4 Ceph快速安装 9

1.4.1 Ubuntu/Debian安装 10

1.4.2 RHEL/CentOS安装 13

1.5 本章小结 16

第2章 存储基石RADOS 17

2.1 Ceph功能模块与RADOS 18

2.2 RADOS架构 20

2.2.1 Monitor介绍 20

2.2.2 Ceph OSD简介 22

2.3 RADOS与LIBRADOS 26

2.4 本章小结 31

第3章 智能分布CRUSH 32

3.1 引言 32

3.2 CRUSH基本原理 33

3.2.1 Object与PG 34

3.2.2 PG与OSD 34

3.2.3 PG与Pool 35

3.3 CRUSH关系分析 37

3.4 本章小结 41

第4章 三大存储访问类型 42

4.1 Ceph FS文件系统 42

4.1.1 Ceph FS和MDS介绍 43

4.1.2 部署MDS 45

4.1.3 挂载Ceph FS 46

4.2 RBD块存储 47

4.2.1 RBD介绍 47

4.2.2 librbd介绍 48

4.2.3 KRBD介绍 48

4.2.4 RBD操作 50

4.2.5 RBD应用场景 56

4.3 Object对象存储 57

4.3.1 RGW介绍 57

4.3.2 Amazon S3简介 58

4.3.3 快速搭建RGW环境 61

4.3.4 RGW搭建过程的排错指南 68

4.3.5 使用S3客户端访问RGW服务 71

4.3.6 admin管理接口的使用 75

4.4 本章小结 78

第5章 可视化管理Calamari 79

5.1 认识Calamari 79

5.2 安装介绍 79

5.2.1 安装calamari-server 80

5.2.2 安装romana(calamari-client) 82

5.2.3 安装diamond 85

5.2.4 安装salt-minion 86

5.2.5 重启服务 87

5.3 基本操作 87

5.3.1 登录Calamari 87

5.3.2 WORKBENCH页面 88

5.3.3 GRAPH页面 89

5.3.4 MANAGE页面 90

5.4 本章小结 92

第6章 文件系统—高性能计算与大数据 93

6.1 Ceph FS作为高性能计算存储 93

6.2 Ceph FS作为大数据后端存储 98

6.3 本章小结 101

第7章 块存储—虚拟化与数据库 102

7.1 Ceph与KVM 102

7.2 Ceph与OpenStack 106

7.3 Ceph与CloudStack 110

7.4 Ceph与ZStack 114

7.5 Ceph提供iSCSI存储  122

7.6 本章小结 128

第8章 对象存储—云盘与RGW异地灾备 129

8.1 网盘方案:RGW与OwnCloud的整合 129

8.2 RGW的异地同步方案 133

8.2.1 异地同步原理与部署方案设计 134

8.2.2 Region异地同步部署实战 137

8.3 本章小结 146

第9章 Ceph硬件选型、性能测试与优化 147

9.1 需求模型与设计 147

9.2 硬件选型 148

9.3 性能调优 151

9.3.1 硬件优化 152

9.3.2 操作系统优化 155

9.3.3 网络层面优化 161

9.3.4 Ceph层面优化 170

9.4 Ceph测试 174

9.4.1 测试前提 175

9.4.2 存储系统模型 175

9.4.3 硬盘测试 176

9.4.4 云硬盘测试 182

9.4.5 利用Cosbench来测试Ceph 185

9.5 本章小结 189

第10章 自定义CRUSH 191

10.1 CRUSH解析 191

10.2 CRUSH设计:两副本实例 201

10.3 CRUSH设计:SSD、SATA混合实例 207

10.3.1 场景一:快–慢存储方案 207

10.3.2 场景二:主–备存储方案 214

10.4 模拟测试CRUSH分布 217

10.5 本章小结 222

第11章 缓冲池与纠删码 223

11.1 缓冲池原理 223

11.2 缓冲池部署 225

11.2.1 缓冲池的建立与管理 226

11.2.2 缓冲池的参数配置 226

11.2.3 缓冲池的关闭 228

11.3 纠删码原理 229

11.4 纠删码应用实践 232

11.4.1 使用Jerasure插件配置纠删码 232

11.4.2 ISA-L插件介绍 234

11.4.3 LRC插件介绍 235

11.4.4 其他插件介绍 235

11.5 本章小结 235

第12章 生产环境应用案例 237

12.1 Ceph FS应用案例 237

12.1.1 将Ceph FS导出成NFS使用 238

12.1.2 在Windows客户端使用Ceph FS 239

12.1.3 OpenStack Manila项目对接Ceph FS案例 242

12.2 RBD应用案例 244

12.2.1 OpenStack对接RBD典型架构 244

12.2.2 如何实现Cinder Multi-Backend 246

12.3 Object RGW应用案例:读写分离方案 248

12.4 基于HLS的视频点播方案 249

12.5 本章小结 251

第13章 Ceph运维与排错 252

13.1 Ceph集群运维 252

13.1.1 集群扩展 252

13.1.2 集群维护 259

13.1.3 集群监控 266

13.2 Ceph常见错误与解决方案 277

13.2.1 时间问题 277

13.2.2 副本数问题 279

13.2.3 PG问题 282

13.2.4 OSD问题 286

13.3 本章小结 292

第1章

初识Ceph

1.1 Ceph概述

1. Ceph简介

从2004年提交第一行代码开始到现在,Ceph已经是一个有着十年之久的分布式存储系统软件,目前Ceph已经发展为开源存储界的当红明星,当然这与它的设计思想以及OpenStack的推动有关。

“Ceph is a unified, distributed storage system designed for excellent performance, reliability and scalability.”这句话说出了Ceph的特性,它是可靠的、可扩展的、统一的、分布式的存储系统。Ceph可以同时提供对象存储RADOSGW(Reliable、Autonomic、Distributed、Object Storage Gateway)、块存储RBD(Rados Block Device)、文件系统存储Ceph FS(Ceph Filesystem)3种功能,以此来满足不同的应用需求。

Ceph消除了对系统单一中心节点的依赖,从而实现了真正的无中心结构的设计思想,这也是其他分布式存储系统所不能比的。通过后续章节内容的介绍,你可以看到,Ceph几乎所有优秀特性的实现,都与其核心设计思想有关。

OpenStack是目前最为流行的开源云平台软件。Ceph的飞速发展离不开OpenStack的带动。目前而言,Ceph已经成为OpenStack的标配开源存储方案之一,其实际应用主要涉及块存储和对象存储,并且开始向文件系统领域扩展。这一部分的相关情况,在后续章节中也将进行介绍。

2. Ceph的发展

Ceph是加州大学Santa Cruz分校的Sage Weil(DreamHost的联合创始人)专为博士论文设计的新一代***软件分布式文件系统。

2004年,Ceph项目开始,提交了第一行代码。

2006年,OSDI学术会议上,Sage发表了介绍Ceph的论文,并在该篇论文的末尾提供了Ceph项目的下载链接。

2010年,Linus Torvalds将Ceph Client合并到内核2.6.34中,使Linux与Ceph磨合度更高。

2012年,拥抱OpenStack,进入Cinder项目,成为重要的存储驱动。

2014年,Ceph正赶上OpenStack大热,受到各大厂商的“待见”,吸引来自不同厂商越来越多的开发者加入,Intel、SanDisk等公司都参与其中,同时Inktank公司被Red Hat公司1.75亿美元收购。

2015年,Red Hat宣布成立Ceph顾问委员会,成员包括Canonical、CERN、Cisco、Fujitsu、Intel、SanDisk和SUSE。Ceph顾问委员会将负责Ceph软件定义存储项目的广泛议题,目标是使Ceph成为云存储系统。

2016年,OpenStack社区调查报告公布,Ceph仍为存储首选,这已经是Ceph第5次位居调查的首位了。

3. Ceph 应用场景

Ceph可以提供对象存储、块设备存储和文件系统服务,其对象存储可以对接网盘(owncloud)应用业务等;其块设备存储可以对接(IaaS),当前主流的IaaS云平台软件,例如OpenStack、CloudStack、Zstack、Eucalyptus等以及KVM等,本书后续章节中将介绍OpenStack、CloudStack、Zstack和KVM的对接;其文件系统文件尚不成熟,官方不建议在生产环境下使用。

4. Ceph生态系统

Ceph作为开源项目,其遵循LGPL协议,使用C++语言开发,目前Ceph已经成为最广泛的全球开源软件定义存储项目,拥有得到众多IT厂商支持的协同开发模式。目前Ceph社区有超过40个公司的上百名开发者持续贡献代码,平均每星期的代码commits超过150个,每个版本通常在2 000个commits左右,代码增减行数在10万行以上。在过去的几个版本发布中,贡献者的数量和参与公司明显增加,如图1-1所示。


图1-1 部分厂商和软件

5. Ceph用户群

Ceph成为了开源存储的当红明星,国内外已经拥有众多用户群体,下面简单说一下Ceph的用户群。

(1)国外用户群

1)CERN:CERN IT部门在2013年年中开始就运行了一个单一集群超过10 000个VM和100 000个CPU Cores的云平台,主要用来做物理数据分析。这个集群后端Ceph包括3PB的原始容量,在云平台中作为1000多个Cinder卷和1500多个Glance镜像的存储池。在2015年开始测试单一30 PB的块存储RBD集群。

2)DreamHost:DreamHost从2012年开始运行基于Ceph RADOSGW的大规模对象存储集群,单一集群在3PB以下,大约由不到10机房集群组成,直接为客户提供对象存储服务。

3)Yahoo Flick:Yahoo Flick自2013年开始逐渐试用Ceph对象存储替换原有的商业存储,目前大约由10机房构成,每个机房在1PB~2PB,存储了大约2 500亿个对象。

4)大学用户:奥地利的因斯布鲁克大学、法国的洛林大学等。

(2)国内用户群

1)以OpenStack为核心的云厂商:例如UnitedStack、Awcloud等国内云计算厂商。

2)Ceph产品厂商:SanDisk、XSKY、H3C、杉岩数据、SUSE和Bigtera等Ceph厂商。

3)互联网企业:腾讯、京东、新浪微博、乐视、完美世界、平安科技、联想、唯品会、***网和魅族等国内互联网企业。

6. 社区项目开发迭代

目前Ceph社区采用每半年一个版本发布的方式来进行特性和功能的开发,每个版本发布需要经历设计、开发、新功能冻结,持续若干个版本的Bug修复周期后正式发布下一个稳定版本。其发布方式跟OpenStack差不多,也是每半年发布一个新版本。

Ceph会维护多个稳定版本来保证持续的Bug修复,以此来保证用户的存储安全,同时社区会有一个发布稳定版本的团队来维护已发布的版本,每个涉及之前版本的Bug都会被该团队移植回稳定版本,并且经过完整QA测试后发布下一个稳定版本。

代码提交都需要经过单元测试,模块维护者审核,并通过QA测试子集后才能合并到主线。社区维护一个较大规模的测试集群来保证代码质量,丰富的测试案例和错误注入机制保证了项目的稳定可靠。

7. Ceph版本

Ceph正处于持续开发中并且迅速提升。2012年7月3日,Sage发布了Ceph第一个LTS版本:Argonaut。从那时起,陆续又发布了9个新版本。Ceph版本被分为LTS(长期稳定版)以及开发版本,Ceph每隔一段时间就会发布一个长期稳定版。Ceph版本具体信息见表1-1。欲了解更多信息,请访问https://Ceph.com/category/releases/。

表1-1 Ceph版本信息

Ceph版本名称 Ceph版本号 发布时间

Argonaut V0.48 (LTS) 2012.6.3

Bobtail V0.56 (LTS) 2013.1.1

Cuttlefish V0.61 2013.5.7

Dumpling V0.67 (LTS) 2013.8.14

Emperor V0.72 2013.11.9

Firefly V0.80 (LTS) 2014.3.7

Giant V0.87.1 2015.2.26

Hammer V0.94 (LTS) 2015.4.7

Infernalis V9.0.0 2015.5.5

Jewel V10.0.0 2015.11

Jewel V10.2.0 2016.3


1.2 Ceph的功能组件

Ceph提供了RADOS、OSD、MON、Librados、RBD、RGW和Ceph FS等功能组件,但其底层仍然使用RADOS存储来支撑上层的那些组件,如图1-2所示。


图1-2 Ceph功能组件的整体架构

下面分为两部分来讲述Ceph的功能组件。

(1)Ceph核心组件

在Ceph存储中,包含了几个重要的核心组件,分别是Ceph OSD、Ceph Monitor和Ceph MDS。一个Ceph的存储集群至少需要一个Ceph Monitor和至少两个Ceph的OSD。运行Ceph文件系统的客户端时,Ceph的元数据服务器(MDS)是必不可少的。下面来详细介绍一下各个核心组件。

Ceph OSD:全称是Object Storage Device,主要功能包括存储数据,处理数据的复制、恢复、回补、平衡数据分布,并将一些相关数据提供给Ceph Monitor,例如Ceph OSD心跳等。一个Ceph的存储集群,至少需要两个Ceph OSD来实现active + clean健康状态和有效的保存数据的双副本(默认情况下是双副本,可以调整)。注意:每一个Disk、分区都可以成为一个OSD。

Ceph Monitor:Ceph的监控器,主要功能是维护整个集群健康状态,提供一致性的决策,包含了Monitor map、OSD map、PG(Placement Group)map和CRUSH map。

Ceph MDS:全称是Ceph Metadata Server,主要保存的是Ceph文件系统(File System)的元数据(metadata)。温馨提示:Ceph的块存储和Ceph的对象存储都不需要Ceph MDS。Ceph MDS为基于POSIX文件系统的用户提供了一些基础命令,例如ls、find等命令。

(2)Ceph功能特性

Ceph可以同时提供对象存储RADOSGW(Reliable、Autonomic、Distributed、Object Storage Gateway)、块存储RBD(Rados Block Device)、文件系统存储Ceph FS(Ceph File System)3种功能,由此产生了对应的实际场景,本节简单介绍如下。

RADOSGW功能特性基于LIBRADOS之上,提供当前流行的RESTful协议的网关,并且兼容S3和Swift接口,作为对象存储,可以对接网盘类应用以及HLS流媒体应用等。

RBD(Rados Block Device)功能特性也是基于LIBRADOS之上,通过LIBRBD创建一个块设备,通过QEMU/KVM附加到VM上,作为传统的块设备来用。目前OpenStack、CloudStack等都是采用这种方式来为VM提供块设备,同时也支持快照、COW(Copy On Write)等功能。

Ceph FS(Ceph File System)功能特性是基于RADOS来实现分布式的文件系统,引入了MDS(Metadata Server),主要为兼容POSIX文件系统提供元数据。一般都是当做文件系统来挂载。

后面章节会对这几种特性以及对应的实际场景做详细的介绍和分析。

1.3 Ceph架构和设计思想

1. Ceph架构

Ceph底层核心是RADOS。Ceph架构图如图1-3所示。


图1-3 Ceph架构图

RADOS:RADOS具备自我修复等特性,提供了一个可靠、自动、智能的分布式存储。

LIBRADOS:LIBRADOS库允许应用程序直接访问,支持C/C++、Java和Python等语言。

RADOSGW:RADOSGW 是一套基于当前流行的RESTful协议的网关,并且兼容S3和Swift。

RBD:RBD通过Linux 内核(Kernel)客户端和QEMU/KVM驱动,来提供一个完全分布式的块设备。

Ceph FS:Ceph FS通过Linux内核(Kernel)客户端结合FUSE,来提供一个兼容POSIX的文件系统。

具体的RADOS细节以及RADOS的灵魂CRUSH(Controlled Replication Under Scalable Hashing,可扩展哈希算法的可控复制)算法,这两个知识点会在后面的第2、3章详细介绍和分析。

2. Ceph设计思想

Ceph是一个典型的起源于学术研究课题的开源项目。虽然学术研究生涯对于Sage而言只是其光辉事迹的短短一篇,但毕竟还是有几篇学术论文可供参考的。可以根据Sage的几篇论文分析Ceph的设计思想。

理解Ceph的设计思想,首先还是要了解Sage设计Ceph时所针对的应用场景,换句话说,Sage当初做Ceph的初衷的什么?

事实上,Ceph最初针对的应用场景,就是大规模的、分布式的存储系统。所谓“大规模”和“分布式”,至少是能够承载PB级别的数据和成千上万的存储节点组成的存储集群。

如今云计算、大数据在中国发展得如火如荼,PB容量单位早已经进入国内企业存储采购单,DT时代即将来临。Ceph项目起源于2004年,那是一个商用处理器以单核为主流,常见硬盘容量只有几十GB的年代。当时SSD也没有大规模商用,正因如此,Ceph之前版本对SSD的支持不是很好,发挥不了SSD的性能。如今Ceph高性能面临的最大挑战正是这些历史原因,目前社区和业界正在逐步解决这些性能上的限制。

在Sage的思想中,我们首先说一下Ceph的技术特性,总体表现在集群可靠性、集群扩展性、数据安全性、接口统一性4个方面。

集群可靠性:所谓“可靠性”,首先从用户角度来说数据是第一位的,要尽可能保证数据不会丢失。其次,就是数据写入过程中的可靠性,在用户将数据写入Ceph存储系统的过程中,不会因为意外情况出现而造成数据丢失。最后,就是降低不可控物理因素的可靠性,避免因为机器断电等不可控物理因素而产生的数据丢失。

集群可扩展性:这里的“可扩展”概念是广义的,既包括系统规模和存储容量的可扩展,也包括随着系统节点数增加的聚合数据访问带宽的线性扩展。

数据安全性:所谓“数据安全性”,首先要保证由于服务器死机或者是偶然停电等自然因素的产生,数据不会丢失,并且支持数据自动恢复,自动重平衡等。总体而言,这一特性既保证了系统的高度可靠和数据绝对安全,又保证了在系统规模扩大之后,其运维难度仍能保持在一个相对较低的水平。

接口统一性:所谓“接口统一”,本书开头就说到了Ceph可以同时支持3种存储,即块存储、对象存储和文件存储。Ceph支持市面上所有流行的存储类型。

根据上述技术特性以及Sage的论文,我们来分析一下Ceph的设计思路,概述为两点:充分发挥存储本身计算能力和去除所有的中心点。

充分发挥存储设备自身的计算能力:其实就是采用廉价的设备和具有计算能力的设备(最简单的例子就是普通的服务器)作为存储系统的存储节点。Sage认为当前阶段只是将这些服务器当做功能简单的存储节点,从而产生资源过度浪费(如同虚拟化的思想一样,都是为了避免资源浪费)。而如果充分发挥节点上的计算能力,则可以实现前面提出的技术特性。这一点成为了Ceph系统设计的核心思想。

去除所有的中心点:搞IT的最忌讳的就是单点故障,如果系统中出现中心点,一方面会引入单点故障,另一方面也必然面临着当系统规模扩大时的可扩展性和性能瓶颈。除此之外,如果中心点出现在数据访问的关键路径上,也必然导致数据访问的延迟增大。虽然在大多数存储软件实践中,单点故障点和性能瓶颈的问题可以通过为中心点增加HA或备份加以缓解,但Ceph系统最终采用Crush、Hash环等方法更彻底地解决了这个问题。很显然Sage的眼光和设想还是很超前的。

1.4 Ceph快速安装

在Ceph官网上提供了两种安装方式:快速安装和手动安装。快速安装采用Ceph-Deploy工具来部署;手动安装采用官方教程一步一步来安装部署Ceph集群,过于烦琐但有助于加深印象,如同手动部署OpenStack一样。但是,建议新手和初学者采用第一种方式快速部署并且测试,下面会介绍如何使用Ceph-Deploy工具来快速部署Ceph集群。

1.4.1 Ubuntu/Debian安装

本节将介绍如何使用Ceph-Deploy工具来快速部署Ceph集群,开始之前先普及一下Ceph-Deploy工具的知识。Ceph-Deploy工具通过SSH方式连接到各节点服务器上,通过执行一系列脚本来完成Ceph集群部署。Ceph-Deploy简单易用同时也是Ceph官网推荐的默认安装工具。本节先来讲下在Ubuntu/Debian系统下如何快速安装Ceph集群。

1)配置Ceph APT源。

root@localhos`t:~# echo deb http://ceph.com/debian-{ceph-stable-release}/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list

2)添加APT源key。

root@localhost:~# wget –q –O -'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/release.asc' | sudo apt-key add -

3)更新源并且安装ceph-deploy。

root@localhost:~# sudo apt-get update &&sudo apt-get install ceph-deploy -y

4)配置各个节点hosts文件。

root@localhost:~# cat /etc/hosts

192.168.1.2  node1

192.168.1.3  node2

192.168.1.4  node3

5)配置各节点SSH无密码登录,这就是本节开始时讲到的Ceph-Deploy工具要用过SSH方式连接到各节点服务器,来安装部署集群。输完ssh-keygen命令之后,在命令行会输出以下内容。

root@localhost:~# ssh-keygen

Generating public/private key pair.

Enter file in which to save the key (/ceph-client/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /ceph-client/.ssh/id_rsa.

Your public key has been saved in /ceph-client/.ssh/id_rsa.pub

6)复制key到各节点。

root@localhost:~# ssh-copy-idnode1

root@localhost:~# ssh-copy-idnode2

root@localhost:~# ssh-copy-idnode3

7)在执行ceph-deploy的过程中会生成一些配置文件,建议创建一个目录,例如my-cluster。

root@localhost:~# mkdir my-cluster

root@localhost:~# cd my-cluster

8)创建集群(Cluster),部署新的monitor节点。

root@localhost:~# ceph-deploy new {initial-monitor-node(s)}

例如:

root@localhost:~# ceph-deploy new node1

9)配置Ceph.conf配置文件,示例文件是默认的,可以根据自己情况进行相应调整和添加。具体优化情况本书后面会介绍。

[global]

fsid = 67d997c9-dc13-4edf-a35f-76fd693aa118

mon_initial_members = node1,node2

mon_host = 192.168.1.2,192.168.1.3

auth_cluster_required = cephx

auth_service_required = cephx

auth_client_required = cephx

filestore_xattr_use_omap = true

<!-----以上部分都是ceph-deploy默认生成的---->

public network = {ip-address}/{netmask}

cluster network={ip-addesss}/{netmask}

<!-----以上两个网络是新增部分,默认只是添加public network,一般生产都是定义两个网络,集群网络和数据网络分开-------->

[osd]

……

[mon]

……

这里配置文件不再过多叙述。

10)安装Ceph到各节点。

root@localhost:~# ceph-deploy install {ceph-node}[{ceph-node} ...]

例如:

root@localhost:~# ceph-deploy install node1 node2 node3

11)获取密钥key,会在my-cluster目录下生成几个key。

root@localhost:~# ceph-deploy mon create-initial

12)初始化磁盘。

root@localhost:~# ceph-deploy disk zap {osd-server-name}:{disk-name}

例如:

root@localhost:~# ceph-deploy disk zap node1:sdb

13)准备OSD。

root@localhost:~# ceph-deploy osd prepare {node-name}:{data-disk}[:{journal-disk}]

例如:

root@localhost:~# ceph-deploy osd prepare node1:sdb1:sdc

14)激活OSD。

root@localhost:~# ceph-deploy osd activate {node-name}:{data-disk-partition}[:{journal-disk-partition}]

例如:

root@localhost:~# ceph-deploy osd activate node1:sdb1:sdc

15)分发key。

root@localhost:~# ceph-deploy admin {admin-node} {ceph-node}

例如:

root@localhost:~# ceph-deploy admin node1 node2 node3

16)给admin key赋权限。

root@localhost:~# sudo chmod +r /etc/ceph/ceph.client.admin.keyring

17)查看集群健康状态,如果是active+clean状态就是正常的。

root@localhost:~# ceph health

安装Ceph前提条件如下。

① 时间要求很高,建议在部署Ceph集群的时候提前配置好NTP服务器。

② 对网络要求一般,因为Ceph源在外国有时候会被屏蔽,解决办法多尝试机器或者代理。

1.4.2 RHEL/CentOS安装

本节主要讲一下在RHEL/CentOS系统下如何快速安装Ceph集群。

1)配置Ceph YUM源。

root@localhost:~# vim /etc/yum.repos.d/ceph.repo

[ceph-noarch]

name=Cephnoarch packages

baseurl=http://ceph.com/rpm-{ceph-release}/{distro}/noarch

enabled=1

gpgcheck=1

type=rpm-md

gpgkey=https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/release.asc

2)更新源并且安装ceph-deploy。

root@localhost:~# yum update &&yum install ceph-deploy -y

3)配置各个节点hosts文件。

root@localhost:~# cat /etc/hosts

192.168.1.2  node1

192.168.1.3  node2

192.168.1.4  node3

4)配置各节点SSH无密码登录,通过SSH方式连接到各节点服务器,以安装部署集群。输入ssh-keygen命令,在命令行会输出以下内容。

root@localhost:~# ssh-keygen

Generating public/private key pair.

Enter file in which to save the key (/ceph-client/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /ceph-client/.ssh/id_rsa.

Your public key has been saved in /ceph-client/.ssh/id_rsa.pub

5)拷贝key到各节点。

root@localhost:~# ssh-copy-id node1

root@localhost:~# ssh-copy-id node2

root@localhost:~# ssh-copy-id node3

6)在执行ceph-deploy的过程中会生成一些配置文件,建议创建一个目录,例如my-cluster。

root@localhost:~# mkdir my-cluster

root@localhost:~# cd my-cluster

7)创建集群(Cluster),部署新的monitor节点。

root@localhost:~# ceph-deploy new {initial-monitor-node(s)}

例如:

root@localhost:~# ceph-deploy new node1

8)配置Ceph.conf配置文件,示例文件是默认的,可以根据自己情况进行相应调整和添加。具体优化情况本书后面会介绍。

[global]

fsid = 67d997c9-dc13-4edf-a35f-76fd693aa118

mon_initial_members = node1,node2

mon_host = 192.168.1.2,192.168.1.3

auth_cluster_required = cephx

auth_service_required = cephx

auth_client_required = cephx

filestore_xattr_use_omap = true

<!-----以上部分都是ceph-deploy默认生成的---->

public network = {ip-address}/{netmask}

cluster network={ip-addesss}/{netmask}

<!-----以上两个网络是新增部分,默认只是添加public network,一般生产都是定义两个网络,集群网络和数据网络分开-------->

[osd]

……

[mon]

……

这里配置文件不再过多叙述。

9)安装Ceph到各节点。

root@localhost:~# ceph-deploy install {ceph-node}[{ceph-node} ...]

例如:

root@localhost:~# ceph-deploy install node1 node2 node3

10)获取密钥key,会在my-cluster目录下生成几个key。

root@localhost:~# ceph-deploy mon create-initial

11)初始化磁盘。

root@localhost:~# ceph-deploy disk zap {osd-server-name}:{disk-name}

例如:

root@localhost:~# ceph-deploy disk zap node1:sdb

12)准备OSD。

root@localhost:~# ceph-deploy osd prepare {node-name}:{data-disk}[:{journal-disk}]

例如:

root@localhost:~# ceph-deploy osd prepare node1:sdb1:sdc

13)激活OSD。

root@localhost:~# ceph-deploy osd activate {node-name}:{data-disk-partition}[:{journal-disk-partition}]

例如:

root@localhost:~# ceph-deploy osd activate node1:sdb1:sdc

14)分发key。

root@localhost:~# ceph-deploy admin {admin-node} {ceph-node}

例如:

root@localhost:~# ceph-deploy admin node1 node2 node3

15)给admin key赋权限。

root@localhost:~# sudo chmod +r /etc/ceph/ceph.client.admin.keyring

16)查看集群健康状态,如果是 active + clean 状态就是正常的。

root@localhost:~# ceph health

1.5 本章小结

本章主要从Ceph的历史背景、发展事件、Ceph的架构组件、功能特性以及Ceph的设计思想方面介绍了Ceph,让大家对Ceph有一个全新的认识,以便后面更深入地了解Ceph。






第2章

存储基石RADOS

分布式对象存储系统RADOS是Ceph最为关键的技术,它是一个支持海量存储对象的分布式对象存储系统。RADOS层本身就是一个完整的对象存储系统,事实上,所有存储在Ceph系统中的用户数据最终都是由这一层来存储的。而Ceph的高可靠、高可扩展、高性能、高自动化等特性,本质上也是由这一层所提供的。因此,理解RADOS是理解Ceph的基础与关键。

Ceph的设计哲学如下。

每个组件必须可扩展。

不存在单点故障。

解决方案必须是基于软件的。

可摆脱专属硬件的束缚即可运行在常规硬件上。

推崇自我管理。

由第1章的讲解可以知道,Ceph包含以下组件。

分布式对象存储系统RADOS库,即LIBRADOS。

基于LIBRADOS实现的兼容Swift和S3的存储网关系统RADOSGW。

基于LIBRADOS实现的块设备驱动RBD。

兼容POSIX的分布式文件Ceph FS。

最底层的分布式对象存储系统RADOS。

2.1 Ceph功能模块与RADOS

Ceph中的这些组件与RADOS有什么关系呢,笔者手绘了一张简单的Ceph架构图,我们结合图2-1来分析这些组件与RADOS的关系。


图2-1 Ceph架构图

Ceph存储系统的逻辑层次结构大致划分为4部分:基础存储系统RADOS、基于RADOS实现的Ceph FS,基于RADOS的LIBRADOS层应用接口、基于LIBRADOS的应用接口RBD、RADOSGW。Ceph架构(见图1-1)我们在第1章有过初步的了解,这里详细看一下各个模块的功能,以此了解RADOS在整个Ceph起到的作用。

(1)基础存储系统RADOS

RADOS这一层本身就是一个完整的对象存储系统,事实上,所有存储在Ceph系统中的用户数据最终都是由这一层来存储的。Ceph的很多优秀特性本质上也是借由这一层设计提供。理解RADOS是理解Ceph的基础与关键。物理上,RADOS由大量的存储设备节点组成,每个节点拥有自己的硬件资源(CPU、内存、硬盘、网络),并运行着操作系统和文件系统。本书后续章节将对RADOS进行深入介绍。

(2)基础库LIBRADOS

LIBRADOS层的功能是对RADOS进行抽象和封装,并向上层提供API,以便直接基于RADOS进行应用开发。需要指明的是,RADOS是一个对象存储系统,因此,LIBRADOS实现的API是针对对象存储功能的。RADOS采用C++开发,所提供的原生LIBRADOS API包括C和C++两种。物理上,LIBRADOS和基于其上开发的应用位于同一台机器,因而也被称为本地API。应用调用本机上的LIBRADOS API,再由后者通过socket与RADOS集群中的节点通信并完成各种操作。

(3)上层应用接口

Ceph上层应用接口涵盖了RADOSGW(RADOS Gateway)、RBD(Reliable Block Device)和Ceph FS(Ceph File System),其中,RADOSGW和RBD是在LIBRADOS库的基础上提供抽象层次更高、更便于应用或客户端使用的上层接口。

其中,RADOSGW是一个提供与Amazon S3和Swift兼容的RESTful API的网关,以供相应的对象存储应用开发使用。RADOSGW提供的API抽象层次更高,但在类S3或Swift LIBRADOS的管理比便捷,因此,开发者应针对自己的需求选择使用。RBD则提供了一个标准的块设备接口,常用于在虚拟化的场景下为虚拟机创建volume。目前,Red Hat已经将RBD驱动集成在KVM/QEMU中,以提高虚拟机访问性能。

(4)应用层

应用层就是不同场景下对于Ceph各个应用接口的各种应用方式,例如基于LIBRADOS直接开发的对象存储应用,基于RADOSGW开发的对象存储应用,基于RBD实现的云主机硬盘等。

下面就来看看RADOS的架构。

2.2 RADOS架构

RADOS系统主要由两个部分组成,如图2-2所示。

1)OSD:由数目可变的大规模OSD(Object Storage Devices)组成的集群,负责存储所有的Objects数据。

2)Monitor:由少量Monitors组成的强耦合、小规模集群,负责管理Cluster Map。其中,Cluster Map是整个RADOS系统的关键数据结构,管理集群中的所有成员、关系和属性等信息以及数据的分发。


图2-2 RADOS系统架构图示

对于RADOS系统,节点组织管理和数据分发策略均由内部的Mon全权负责,因此,从Client角度设计相对比较简单,它给应用提供存储接口。

2.2.1 Monitor介绍

正如其名,Ceph Monitor是负责监视整个群集的运行状况的,这些信息都是由维护集群成员的守护程序来提供的,如各个节点之间的状态、集群配置信息。Ceph monitor map包括OSD Map、PG Map、MDS Map和CRUSH等,这些Map被统称为集群Map。

1)Monitor Map。Monitor Map包括有关monitor节点端到端的信息,其中包括Ceph集群ID,监控主机名和IP地址和端口号,它还存储了当前版本信息以及最新更改信息,可以通过以下命令查看monitor map。

#ceph mon dump

2)OSD Map。OSD Map包括一些常用的信息,如集群ID,创建OSD Map的版本信息和最后修改信息,以及pool相关信息,pool的名字、pool的ID、类型,副本数目以及PGP,还包括OSD信息,如数量、状态、权重、最新的清洁间隔和OSD主机信息。可以通过执行以下命令查看集群的OSD Map。

#ceph  osd dump

3)PG Map。PG Map包括当前PG版本、时间戳、最新的OSD Map的版本信息、空间使用比例,以及接近占满比例信息,同时,也包括每个PG ID、对象数目、状态、OSD的状态以及深度清理的详细信息,可以通过以下命令来查看PG Map。

#ceph pg dump

4)CRUSH Map。CRUSH Map包括集群存储设备信息,故障域层次结构和存储数据时定义失败域规则信息;可以通过以下命令查看CRUSH Map。

#ceph osd crush dump

5)MDS Map。MDS Map包括存储当前MDS Map的版本信息、创建当前Map的信息、修改时间、数据和元数据POOL ID、集群MDS数目和MDS状态,可通过以下命令查看集群MDS Map信息。

#ceph mds dump

Ceph的MON服务利用Paxos的实例,把每个映射图存储为一个文件。Ceph Monitor并未为客户提供数据存储服务,而是为Ceph集群维护着各类Map,并服务更新群集映射到客户机以及其他集群节点。客户端和其他群集节点定期检查并更新于Monitor的集群Map最新的副本。

Ceph Monitor是个轻量级的守护进程,通常情况下并不需要大量的系统资源,低成本、入门级的CPU,以及千兆网卡即可满足大多数的场景;与此同时,Monitor节点需要有足够的磁盘空间来存储集群日志,健康集群产生几MB到GB的日志;然而,如果存储的需求增加时,打开低等级的日志信息的话,可能需要几个GB的磁盘空间来存储日志。

一个典型的Ceph集群包含多个Monitor节点。一个多Monitor的Ceph的架构通过法定人数来选择leader,并在提供一致分布式决策时使用Paxos算法集群。在Ceph集群中有多个Monitor时,集群的Monitor应该是奇数;最起码的要求是一台监视器节点,这里推荐Monitor个数是3。由于Monitor工作在法定人数,一半以上的总监视器节点应该总是可用的,以应对死机等极端情况,这是Monitor节点为N(N>0)个且N为奇数的原因。所有集群Monitor节点,其中一个节点为Leader。如果Leader Monitor节点处于不可用状态,其他显示器节点有资格成为Leader。生产群集必须至少有N/2个监控节点提供高可用性。

2.2.2 Ceph OSD简介

Ceph OSD是Ceph存储集群最重要的组件,Ceph OSD将数据以对象的形式存储到集群中每个节点的物理磁盘上,完成存储用户数据的工作绝大多数都是由OSD deamon进程来实现的。

Ceph集群一般情况都包含多个OSD,对于任何读写操作请求,Client端从Ceph Monitor获取Cluster Map之后,Client将直接与OSD进行I/O操作的交互,而不再需要Ceph Monitor干预。这使得数据读写过程更为迅速,因为这些操作过程不像其他存储系统,它没有其他额外的层级数据处理。

Ceph的核心功能特性包括高可靠、自动平衡、自动恢复和一致性。对于Ceph OSD而言,基于配置的副本数,Ceph提供通过分布在多节点上的副本来实现,使得Ceph具有高可用性以及容错性。在OSD中的每个对象都有一个主副本,若干个从副本,这些副本默认情况下是分布在不同节点上的,这就是Ceph作为分布式存储系统的集中体现。每个OSD都可能作为某些对象的主OSD,与此同时,它也可能作为某些对象的从OSD,从OSD受到主OSD的控制,然而,从OSD在某些情况也可能成为主OSD。在磁盘故障时,Ceph OSD Deamon的智能对等机制将协同其他OSD执行恢复操作。在此期间,存储对象副本的从OSD将被提升为主OSD,与此同时,新的从副本将重新生成,这样就保证了Ceph的可靠和一致。

Ceph OSD架构实现由物理磁盘驱动器、在其之上的Linux文件系统以及Ceph OSD服务组成。对Ceph OSD Deamon而言,Linux文件系统显性地支持了其扩展属性;这些文件系统的扩展属性提供了关于对象状态、快照、元数据内部信息;而访问Ceph OSD Deamon的ACL则有助于数据管理,如图2-3所示。

Ceph OSD操作必须在一个有效的Linux分区的物理磁盘驱动器上,Linux分区可以是BTRFS、XFS或者EXT4分区,文件系统是对性能基准测试的主要标准之一,下面来逐一了解。

1)BTRFS:在BTRFS文件系统的OSD相比于XFS和EXT4提供了***的性能。BTRFS的主要优点有以下4点。

扩展性(scalability):BTRFS最重要的设计目标是应对大型机器对文件系统的扩展性要求。Extent、B-Tree和动态inode创建等特性保证了BTRFS在大型机器上仍有卓越的表现,其整体性能不会随着系统容量的增加而降低。

数据一致性(data integrity):当系统面临不可预料的硬件故障时,BTRFS采用 COW事务技术来保证文件系统的一致性。BTRFS还支持校验和,避免了silent corrupt(未知错误)的出现。而传统文件系统无法做到这一点。

多设备管理相关的特性:BTRFS支持创建快照(snapshot)和克隆(clone)。BTRFS还能够方便地管理多个物理设备,使得传统的卷管理软件变得多余。

结合Ceph,BTRFS中的诸多优点中的快照,Journal of Parallel(并行日志)等优势在Ceph中表现得尤为突出,不幸的是,BTRFS还未能到达生产环境要求的健壮要求。暂不推荐用于Ceph集群的生产使用。

2)XFS:一种高性能的日志文件系统,XFS特别擅长处理大文件,同时提供平滑的数据传输。目前CentOS 7也将XFS+LVM作为默认的文件系统。XFS的主要优点如下。

分配组:XFS文件系统内部被分为多个“分配组”,它们是文件系统中的等长线性存储区。每个分配组各自管理自己的inode和剩余空间。文件和文件夹可以跨越分配组。这一机制为XFS提供了可伸缩性和并行特性——多个线程和进程可以同时在同一个文件系统上执行I/O操作。这种由分配组带来的内部分区机制在一个文件系统跨越多个物理设备时特别有用,使得优化对下级存储部件的吞吐量利用率成为可能。

条带化分配:在条带化RAID阵列上创建XFS文件系统时,可以指定一个“条带化数据单元”。这可以保证数据分配、inode分配,以及内部日志被对齐到该条带单元上,以此最大化吞吐量。

基于Extent的分配方式:XFS文件系统中的文件用到的块由变长Extent管理,每一个Extent描述了一个或多个连续的块。对那些把文件所有块都单独列出来的文件系统来说,Extent大幅缩短了列表。

有些文件系统用一个或多个面向块的位图管理空间分配——在XFS中,这种结构被由一对B+树组成的、面向Extent的结构替代了;每个文件系统分配组(AG)包含这样的一个结构。其中,一个B+树用于索引未被使用的Extent的长度,另一个索引这些Extent的起始块。这种双索引策略使得文件系统在定位剩余空间中的Extent时十分高效。

扩展属性:XFS通过实现扩展文件属性给文件提供了多个数据流,使文件可以被附加多个名/值对。文件名是一个最大长度为256字节的、以NULL字符结尾的可打印字符串,其他的关联值则可包含多达64KB的二进制数据。这些数据被进一步分入两个名字空间中,分别为root和user。保存在root名字空间中的扩展属性只能被超级用户修改,保存在user名字空间中的可以被任何对该文件拥有写权限的用户修改。扩展属性可以被添加到任意一种 XFS inode上,包括符号链接、设备节点和目录等。可以使用attr命令行程序操作这些扩展属性。xfsdump和xfsrestore工具在进行备份和恢复时会一同操作扩展属性,而其他的大多数备份系统则会忽略扩展属性。

XFS作为一款可靠、成熟的,并且非常稳定的文件系统,基于分配组、条带化分配、基于Extent的分配方式、扩展属性等优势非常契合Ceph OSD服务的需求。美中不足的是,XFS不能很好地处理Ceph写入过程的journal问题。

3)Ext4:第四代扩展文件系统,是Linux系统下的日志文件系统,是Ext3文件系统的后继版本。其主要特征如下。

大型文件系统:Ext4文件系统可支持最高1 Exbibyte的分区与最大16 Tebibyte的文件。

Extents:Ext4引进了Extent文件存储方式,以替换Ext2/3使用的块映射(block mapping)方式。Extent指的是一连串的连续实体块,这种方式可以增加大型文件的效率并减少分裂文件。

日志校验和:Ext4使用校验和特性来提高文件系统可靠性,因为日志是磁盘上被读取最频繁的部分之一。

快速文件系统检查:Ext4将未使用的区块标记在inode当中,这样可以使诸如e2fsck之类的工具在磁盘检查时将这些区块完全跳过,而节约大量的文件系统检查的时间。这个特性已经在2.6.24版本的Linux内核中实现。

Ceph OSD把底层文件系统的扩展属性用于表示各种形式的内部对象状态和元数据。XATTR是以key/value形式来存储xattr_name和xattr_value,并因此提供更多的标记对象元数据信息的方法。Ext4文件系统提供不足以满足XATTR,由于XATTR上存储的字节数的限制能力,从而使Ext4文件系统不那么受欢迎。然而,BTRFS和XFS有一个比较大的限制XATTR。

Ceph使用日志文件系统,如增加了BTRFS和XFS的OSD。在提交数据到后备存储器之前,Ceph首先将数据写入称为一个单独的存储区,该区域被称为journal,这是缓冲器分区在相同或单独磁盘作为OSD,一个单独的SSD磁盘或分区,甚至一个文件文件系统。在这种机制下,Ceph任何写入首先是日志,然后是后备存储,如图2-4所示。


图2-4 IO流向图

journal持续到后备存储同步,每隔5s。默认情况下。10GB是该jouranl的常用的大小,但journal空间越大越好。Ceph使用journal综合考虑了存储速度和数据的一致性。journal允许Ceph OSD功能很快做小的写操作;一个随机写入首先写入在上一个连续类型的journal,然后刷新到文件系统。这给了文件系统足够的时间来合并写入磁盘。使用SSD盘作为journal盘能获得相对较好的性能。在这种情况下,所有的客户端写操作都写入到超高速SSD日志,然后刷新到磁盘。所以,一般情况下,使用SSD作为OSD的journal可以有效缓冲突发负载。

与传统的分布式数据存储不同,RADOS最大的特点如下。

① 将文件映射到Object后,利用Cluster Map通过CRUSH计算而不是查找表方式定位文件数据到存储设备中的位置。优化了传统的文件到块的映射和BlockMap管理。

② RADOS充分利用了OSD的智能特点,将部分任务授权给OSD,最大程度地实现可扩展。

2.3 RADOS与LIBRADOS

LIBRADOS模块是客户端用来访问RADOS对象存储设备的。Ceph存储集群提供了消息传递层协议,用于客户端与Ceph Monitor与OSD交互,LIBRADOS以库形式为Ceph Client提供了这个功能,LIBRADOS就是操作RADOS对象存储的接口。所有Ceph客户端可以用LIBRADOS或LIBRADOS里封装的相同功能和对象存储交互,LIBRBD和LIBCEPHFS就利用了此功能。你可以用LIBRADOS直接和Ceph交互(如与Ceph兼容的应用程序、Ceph接口等)。下面是简单描述的步骤。

第1步:获取LIBRADOS。

第2步:配置集群句柄。

第3步:创建IO上下文。

第4步:关闭连接。

LIBRADOS架构图,如图2-5所示。

先根据配置文件调用librados创建一个rados,接下来为这个rados创建一个radosclient,radosclient包含3个主要模块(finisher、Messager、Objector)。再根据pool创建对应的ioctx,在ioctx中能够找到radosclient。再调用osdc对生成对应osd请求,与OSD进行通信响应请求。 

下面分别介绍LIBRADOS的C语言、Java语言和Python语言示例。

1. LIBRADOS C语言示例

下面是LIBRADOS C语言示例。

#include <stdio.h>

#include <string.h>

#include <rados/librados.h>

int main (int argc, char argv**)

{

        /*声明集群句柄以及所需参数 */

        rados_t cluster;

        char cluster_name[] = "ceph";        //集群名称

        char user_name[] = "client.admin";   //指定访问集群的用户,这里用admin

        uint64_t flags;

        rados_ioctx_t io;                    //rados上下文句柄

        char *poolname = "data";             //目标pool名

        char read_res[100];

        char xattr[] = "en_US";

        /* 指定参数初始化句柄*/

        int err;

        err = rados_create2(&cluster, cluster_name, user_name, flags);


        if (err < 0) {

                fprintf(stderr, "%s: Couldn't create the cluster handle! %s\n", argv[0], strerror(-err));

                exit(EXIT_FAILURE);

        } else {

                printf("\nCreated a cluster handle.\n");

        }

        /* 读取配置文件用来配置句柄*/

        err = rados_conf_read_file(cluster, "/etc/ceph/ceph.conf");

        if (err < 0) {

                fprintf(stderr, "%s: cannot read config file: %s\n", argv[0], strerror(-err));

                exit(EXIT_FAILURE);

        } else {

                printf("\nRead the config file.\n");

        }


        /* 分解参数 */

        err = rados_conf_parse_argv(cluster, argc, argv);

        if (err < 0) {

                fprintf(stderr, "%s: cannot parse command line arguments: %s\n", argv[0], strerror(-err));

                exit(EXIT_FAILURE);

        } else {

                printf("\nRead the command line arguments.\n");

        }

        /* 连接集群*/

        err = rados_connect(cluster);

        if (err < 0) {

                fprintf(stderr, "%s: cannot connect to cluster: %s\n", argv[0], strerror(-err));

                exit(EXIT_FAILURE);

        } else {

                printf("\nConnected to the cluster.\n");

        }

       //创建rados句柄上下文

        err = rados_ioctx_create(cluster, poolname, &io);

        if (err < 0) {

                fprintf(stderr, "%s: cannot open rados pool %s: %s\n", argv[0], poolname, strerror(-err));

                rados_shutdown(cluster);

                exit(EXIT_FAILURE);

        } else {

                printf("\nCreated I/O context.\n");

        }


        //写对象

        err = rados_write(io, "hw", "Hello World!", 12, 0);

        if (err < 0) {

                fprintf(stderr, "%s: Cannot write object \"hw\" to pool %s: %s\n", argv[0], poolname, strerror(-err));

                rados_ioctx_destroy(io);

                rados_shutdown(cluster);

                exit(1);

        } else {

                printf("\nWrote \"Hello World\" to object \"hw\".\n");

        }

       //设置对象属性

        err = rados_setxattr(io, "hw", "lang", xattr, 5);

        if (err < 0) {

                fprintf(stderr, "%s: Cannot write xattr to pool %s: %s\n", argv[0], poolname, strerror(-err));

                rados_ioctx_destroy(io);

                rados_shutdown(cluster);

                exit(1);

        } else {

                printf("\nWrote \"en_US\" to xattr \"lang\" for object \"hw\".\n");

        }

        rados_completion_t comp;

       //确认异步rados句柄成功创建

        err = rados_aio_create_completion(NULL, NULL, NULL, &comp);

        if (err < 0) {

                fprintf(stderr, "%s: Could not create aio completion: %s\n", argv[0], strerror(-err));

                rados_ioctx_destroy(io);

                rados_shutdown(cluster);

                exit(1);

        } else {

                printf("\nCreated AIO completion.\n");

        }


        /* Next, read data using rados_aio_read. */

        //异步读对象

        err = rados_aio_read(io, "hw", comp, read_res, 12, 0);

        if (err < 0) {

                fprintf(stderr, "%s: Cannot read object. %s %s\n", argv[0], poolname, strerror(-err));

                rados_ioctx_destroy(io);

                rados_shutdown(cluster);

                exit(1);

        } else {

                printf("\nRead object \"hw\". The contents are:\n %s \n", read_res);

        }

       //等待对象上的操作完成

        rados_wait_for_complete(comp);


        // 释放complete句柄 

        rados_aio_release(comp);

        char xattr_res[100];

       //获取对象

        err = rados_getxattr(io, "hw", "lang", xattr_res, 5);

        if (err < 0) {

                fprintf(stderr, "%s: Cannot read xattr. %s %s\n", argv[0], poolname, strerror(-err));

                rados_ioctx_destroy(io);

                rados_shutdown(cluster);

                exit(1);

        } else {

                printf("\nRead xattr \"lang\" for object \"hw\". The contents are:\n %s \n", xattr_res);

        }

       //移除对象属性

        err = rados_rmxattr(io, "hw", "lang");

        if (err < 0) {

                fprintf(stderr, "%s: Cannot remove xattr. %s %s\n", argv[0], poolname, strerror(-err));

                rados_ioctx_destroy(io);

                rados_shutdown(cluster);

                exit(1);

        } else {

                printf("\nRemoved xattr \"lang\" for object \"hw\".\n");

        }

       //删除对象

        err = rados_remove(io, "hw");

        if (err < 0) {

                fprintf(stderr, "%s: Cannot remove object. %s %s\n", argv[0], poolname, strerror(-err));

                rados_ioctx_destroy(io);

                rados_shutdown(cluster);

                exit(1);

        } else {

                printf("\nRemoved object \"hw\".\n");

        }

    rados_ioctx_destroy(io);                  //销毁io上下文

    rados_shutdown(cluster);                  //销毁句柄

}

2. LIBRADOS Java语言示例

下面是LIBRADOS Java语言示例。

import com.ceph.rados.Rados;

import com.ceph.rados.RadosException;

import java.io.File;

public class CephClient {

        public static void main (String args[]){

                try {

                        //获取句柄

                        Rados cluster = new Rados("admin");

                        System.out.println("Created cluster handle.");


                        File f = new File("/etc/ceph/ceph.conf");

                        //读取配置文件

                        cluster.confReadFile(f);

                        System.out.println("Read the configuration file.");

                       //连接集群

                        cluster.connect();

                        System.out.println("Connected to the cluster.");


                } catch (RadosException e) {

                        System.out.println(e.getMessage()+":"+e.getReturnValue());

                }

        }

}

3. LIBRADOS Python语言示例

下面是LIBRADOS Python语言示例。

#!/usr/bin/python

#encoding=utf-8

import rados, sys

cluster = rados.Rados(conffile='/etc/ceph/ceph.conf')   #获取句柄

print "\n\nI/O Context and Object Operations"

print "================================="

print "\nCreating a context for the 'data' pool"

if not cluster.pool_exists('data'):                  

raise RuntimeError('No data pool exists')

ioctx = cluster.open_ioctx('data')                  #获取pool的io上下文句柄

print "\nWriting object 'hw' with contents 'Hello World!' to pool 'data'."

ioctx.write("hw", "Hello World!")                 #写入对象

print "Writing XATTR 'lang' with value 'en_US' to object 'hw'"

ioctx.set_xattr("hw", "lang", "en_US")          #设置对象的属性

print "\nWriting object 'bm' with contents 'Bonjour tout le monde!' to pool 'data'."

ioctx.write("bm", "Bonjour tout le monde!")

print "Writing XATTR 'lang' with value 'fr_FR' to object 'bm'"

ioctx.set_xattr("bm", "lang", "fr_FR")

print "\nContents of object 'hw'\n------------------------"

print ioctx.read("hw")                   #读取对象

print "\n\nGetting XATTR 'lang' from object 'hw'"

print ioctx.get_xattr("hw", "lang")        #读取对象属性

print "\nContents of object 'bm'\n------------------------"

print ioctx.read("bm")

  print "\nClosing the connection."

ioctx.close()                           #关闭io上下文


print "Shutting down the handle."

cluster.shutdown()                      #销毁句柄

2.4 本章小结

本章从宏观角度剖析了Ceph架构,将Ceph架构分为基础存储系统RADOS、基于RADOS实现的CEPHFS,基于RADOS的LIBRADOS层应用接口、基于LIBRADOS的应用接口RBD、RADOSGW,其中着重讲解了RADOS的组成部分MON、OSD及其功能,最后解析LIBRADOS API的基本用法。





第3章

智能分布CRUSH

3.1 引言

数据分布是分布式存储系统的一个重要部分,数据分布算法至少要考虑以下3个因素。

1)故障域隔离。同份数据的不同副本分布在不同的故障域,降低数据损坏的风险。

2)负载均衡。数据能够均匀地分布在磁盘容量不等的存储节点,避免部分节点空闲,部分节点超载,从而影响系统性能。

3)控制节点加入离开时引起的数据迁移量。当节点离开时,最优的数据迁移是只有离线节点上的数据被迁移到其他节点,而正常工作的节点的数据不会发生迁移。

对象存储中一致性Hash和Ceph的CRUSH算法是使用比较多的数据分布算法。在Aamzon的Dyanmo键值存储系统中采用一致性Hash算法,并且对它做了很多优化。OpenStack的Swift对象存储系统也使用了一致性Hash算法。

CRUSH(Controlled Replication Under Scalable Hashing)是一种基于伪随机控制数据分布、复制的算法。Ceph是为大规模分布式存储系统(PB级的数据和成百上千台存储设备)而设计的,在大规模的存储系统里,必须考虑数据的平衡分布和负载(提高资源利用率)、最大化系统的性能,以及系统的扩展和硬件容错等。CRUSH就是为解决以上问题而设计的。在Ceph集群里,CRUSH只需要一个简洁而层次清晰的设备描述,包括存储集群和副本放置策略,就可以有效地把数据对象映射到存储设备上,且这个过程是完全分布式的,在集群系统中的任何一方都可以独立计算任何对象的位置;另外,大型系统存储结构是动态变化的(存储节点的扩展或者缩容、硬件故障等),CRUSH能够处理存储设备的变更(添加或删除),并最小化由于存储设备的变更而导致的数据迁移。

3.2 CRUSH基本原理

众所周知,存储设备具有吞吐量限制,它影响读写性能和可扩展性能。所以,存储系统通常都支持条带化以增加存储系统的吞吐量并提升性能,数据条带化最常见的方式是做RAID。与Ceph的条带化最相似的是RAID 0或者是“带区卷”。Ceph条带化提供了类似于RAID 0的吞吐量,N路RAID镜像的可靠性以及更快速的恢复能力。

在磁盘阵列中,数据是以条带(stripe)的方式贯穿在磁盘阵列所有硬盘中的。这种数据的分配方式可以弥补OS读取数据量跟不上的不足。

1)将条带单元(stripe unit)从阵列的第一个硬盘到最后一个硬盘收集起来,就可以称为条带(stripe)。有的时候,条带单元也被称为交错深度。在光纤技术中,一个条带单元被叫作段。

2)数据在阵列中的硬盘上是以条带的形式分布的,条带化是指数据在阵列中所有硬盘中的存储过程。文件中的数据被分割成小块的数据段在阵列中的硬盘上顺序的存储,这个最小数据块就叫作条带单元。

决定Ceph条带化数据的3个因素。

对象大小:处于分布式集群中的对象拥有一个最大可配置的尺寸(例如,2MB、4MB等),对象大小应该足够大以适应大量的条带单元。

条带宽度:条带有一个可以配置的单元大小,Ceph Client端将数据写入对象分成相同大小的条带单元,除了最后一个条带之外;每个条带宽度,应该是对象大小的一小部分,这样使得一个对象可以包含多个条带单元。

条带总量:Ceph客户端写入一系列的条带单元到一系列的对象,这就决定了条带的总量,这些对象被称为对象集,当Ceph客户端端写入的对象集合中的最后一个对象之后,它将会返回到对象集合中的第一个对象处。

3.2.1 Object与PG

Ceph条带化之后,将获得N个带有唯一oid(即object的id)。Object id是进行线性映射生成的,即由file的元数据、Ceph条带化产生的Object的序号连缀而成。此时Object需要映射到PG中,该映射包括两部分。

1)由Ceph集群指定的静态Hash函数计算Object的oid,获取到其Hash值。

2)将该Hash值与mask进行与操作,从而获得PG ID。

根据RADOS的设计,假定集群中设定的PG总数为M(M一般为2的整数幂),则mask的值为M–1。由此,Hash值计算之后,进行按位与操作是想从所有PG中近似均匀地随机选择。基于该原理以及概率论的相关原理,当用于数量庞大的Object以及PG时,获得到的PG ID是近似均匀的。

计算PG的ID示例如下。

1)Client输入pool ID和对象ID(如pool=‘liverpool’,object-id=‘john’)。

2)CRUSH获得对象ID并对其Hash运算。

3)CRUSH计算OSD个数,Hash取模获得PG的ID(如0x58)。

4)CRUSH获得已命名pool的ID(如liverpool=4)。

5)CRUSH预先考虑到pool ID相同的PG ID(如4.0x58)。

3.2.2 PG与OSD

由PG映射到数据存储的实际单元OSD中,该映射是由CRUSH算法来确定的,将PG ID作为该算法的输入,获得到包含N个OSD的集合,集合中第一个OSD被作为主OSD,其他的OSD则依次作为从OSD。N为该PG所在POOL下的副本数目,在生产环境中N一般为3;OSD集合中的OSD将共同存储和维护该PG下的Object。需要注意的是,CRUSH算法的结果不是绝对不变的,而是受到其他因素的影响。其影响因素主要有以下两个。

一是当前系统状态。也就是上文逻辑结构中曾经提及的Cluster Map(集群映射)。当系统中的OSD状态、数量发生变化时,Cluster Map可能发生变化,而这种变化将会影响到PG与OSD之间的映射。

二是存储策略配置。这里的策略主要与安全相关。利用策略配置,系统管理员可以指定承载同一个PG的3个OSD分别位于数据中心的不同服务器乃至机架上,从而进一步改善存储的可靠性。

因此,只有在Cluster Map和存储策略都不发生变化的时候,PG和OSD之间的映射关系才是固定不变的。在实际使用中,策略一经配置通常不会改变。而系统状态的改变或者是因为设备损坏,或者是因为存储集群规模扩大。好在Ceph本身提供了对于这种变化的自动化支持,因而,即便PG与OSD之间的映射关系发生了变化,并不会对应用造成困扰。事实上,Ceph正是需要有目的的利用这种动态映射关系。正是利用了CRUSH的动态特性,Ceph才可以将一个PG根据需要动态迁移到不同的OSD组合上,从而自动化地实现高可靠性、数据分布re-blancing等特性。

之所以在此次映射中使用CRUSH算法,而不是其他Hash算法,原因之一是CRUSH具有上述可配置特性,可以根据管理员的配置参数决定OSD的物理位置映射策略;另一方面是因为CRUSH具有特殊的“稳定性”,也就是当系统中加入新的OSD导致系统规模增大时,大部分PG与OSD之间的映射关系不会发生改变,只有少部分PG的映射关系会发生变化并引发数据迁移。这种可配置性和稳定性都不是普通Hash算法所能提供的。因此,CRUSH算法的设计也是Ceph的核心内容之一。

3.2.3 PG与Pool

Ceph存储系统支持“池”(Pool)的概念,这是存储对象的逻辑分区。

Ceph Client端从Ceph mon端检索Cluster Map,写入对象到Pool。Pool的副本数目,Crush规则和PG数目决定了Ceph将数据存储的位置,如图3-1所示。

Pool至少需要设定以下参数。

对象的所有权/访问权。

PG数目。

该pool使用的crush规则。

对象副本的数目。

Object、PG、Pool、OSD关系图,如图3-2所示。


图3-2 映射关系图

Pool相关的操作如下。

1)创建pool。

ceph osd pool create {pool-name} {pg-num} [{pgp-num}] [replicated] \

     [crush-ruleset-name] [expected-num-objects]

ceph osd pool create {pool-name} {pg-num}  {pgp-num}   erasure \

     [erasure-code-profile] [crush-ruleset-name] [expected_num_objects]

2)配置pool配额。

ceph osd pool set-quota {pool-name} [max_objects {obj-count}] [max_bytes {bytes}]

3)删除pool。

ceph osd pool delete {pool-name} [{pool-name} --yes-i-really-really-mean-it]

4)重命名pool。

ceph osd pool rename {current-pool-name} {new-pool-name}

5)展示pool统计。

rados df

6)给pool做快照。

ceph osd pool mksnap {pool-name} {snap-name}

7)删除pool快照。

ceph osd pool rmsnap {pool-name} {snap-name}

8)配置pool的相关参数。

ceph osd pool set {pool-name} {key} {value}

9)获取pool参数的值。

ceph osd pool get {pool-name} {key}

10)配置对象副本数目。

ceph osd pool set {poolname} size {num-replicas}

11)获取对对象副本数目。

ceph osd dump | grep 'replicated size'

3.3 CRUSH关系分析

从本质上讲,CRUSH算法是通过存储设备的权重来计算数据对象的分布的。在计算过程中,通过Cluster Map(集群映射)、Data Distribution Policy(数据分布策略)和给出的一个随机数共同决定数据对象的最终位置。

1. Cluster Map

Cluster Map记录所有可用的存储资源及相互之间的空间层次结构(集群中有多少个机架、机架上有多少服务器、每个机器上有多少磁盘等信息)。所谓的Map,顾名思义,就是类似于我们生活中的地图。在Ceph存储里,数据的索引都是通过各种不同的Map来实现的。另一方面,Map 使得Ceph集群存储设备在物理层作了一层防护。例如,在多副本(常见的三副本)的结构上,通过设置合理的Map(故障域设置为Host级),可以保证在某一服务器死机的情况下,有其他副本保留在正常的存储节点上,能够继续提供服务,实现存储的高可用。设置更高的故障域级别(如Rack、Row等)能保证整机柜或同一排机柜在掉电情况下数据的可用性和完整性。

(1)Cluster Map的分层结构

Cluster Map由Device和Bucket构成。它们都有自己的ID和权重值,并且形成一个以Device为叶子节点、Bucket为躯干的树状结构,如图3-3所示。


图3-3 CRUSH架构图

Bucket拥有不同的类型,如Host、Row、Rack、Room等,通常我们默认把机架类型定义为Rack,主机类型定义为Host,数据中心(IDC机房)定义为Data Center。Bucket的类型都是虚拟结构,可以根据自己的喜好设计合适的类型。Device节点的权重值代表了存储设备的容量与性能。其中,磁盘容量是权重大小的关键因素。

OSD 的权重值越高,对应磁盘会被分配写入更多的数据。总体来看,数据会被均匀写入分布于群集所有磁盘,从而提高整体性能和可靠性。无论磁盘的规格容量,总能够均匀使用。

关于OSD权重值的大小值的配比,官方默认值设置为1TB容量的硬盘,对应权重值为1。

可以在/etc/init.d/ceph 原码里查看相关的内容。

363             get_conf osd_weight "" "osd crush initial weight"

364             defaultweight="$(df -P -k $osd_data/. | tail -1 | awk '{ print sprintf("%.2f",$2/1073741824) }')"  ###此处就是ceph默认权重的设置值

            get_conf osd_keyring "$osd_data/keyring" "keyring"

366             do_cmd_okfail "timeout 30 $BINDIR/ceph -c $conf --name=osd.$id --keyring=$osd_keyring     osd crush create-or-move -- $id ${osd_weight:-${defaultweight:-1}} $osd_location"

(2)恢复与动态平衡

在默认设置下,当集群里有组件出现故障时(主要是OSD,也可能是磁盘或者网络等),Ceph会把OSD标记为down,如果在300s内未能回复,集群就会开始进行恢复状态。这个“300s”可以通过“mon osd down out interval”配置选项修改等待时间。PG(Placement  Groups)是Ceph数据管理(包括复制、修复等动作)单元。当客户端把读写请求(对象单元)推送到Ceph时,通过CRUSH提供的Hash算法把对象映射到PG。PG在CRUSH策略的影响下,最终会被映射到OSD上。

2. Data Distribution Policy

Data Distribution Policy由Placement Rules组成。Rule决定了每个数据对象有多少个副本,这些副本存储的限制条件(比如3个副本放在不同的机架中)。一个典型的rule如下所示。

rule replicated_ruleset {    ##rule名字

    ruleset 0         # rule的Id

    type replicated   ## 类型为副本模式,另外一种模式为纠删码(EC)

    min_size 1        ## 如果存储池的副本数大于这个值,此rule不会应用

    max_size 10       ## 如要存储池的副本数大于这个值,此rule不会应用

    step take default  ## 以default root为入口

    step chooseleaf firstn 0 type host  ## 隔离域为host级,即不同副本在不同的主机上

    step emit        ## 提交

}

根据实际的设备环境,可以定制出符合自己需求的Rule,详见第10章。

3. CRUSH中的伪随机 

先来看一下数据映射到具体OSD的函数表达形式。

CRUSH(x) -> (osd1, osd2, osd3.....osdn)  

CRUSH使用了多参数的Hash函数在Hash之后,映射都是按既定规则选择的,这使得从x到OSD的集合是确定的和独立的。CRUSH只使用Cluster Map、Placement Rules、X。CRUSH是伪随机算法,相似输入的结果之间没有相关性。关于伪随机的确认性和独立性,以下我们以一个实例来展示。

 [root@host-192-168-0-16 ~]# ceph osd tree 

ID WEIGHT  TYPE NAME               UP/DOWN  REWEIGHT  PRIMARY-AFFINITY 

-1 0.35999 root default                                                 

-3 0.09000     host host-192-168-0-17                                   

 2 0.09000         osd.2                   up  1.00000          1.00000 

-4 0.09000     host host-192-168-0-18                                   

 3 0.09000         osd.3                   up  1.00000          1.00000 

-2 0.17999     host host-192-168-0-16                                   

 0 0.09000         osd.0                   up  1.00000          1.00000 

 1 0.09000         osd.1                   up  1.00000          1.00000

以上是某个Ceph集群的存储的CRUSH结构。在此集群里我们手动创建一个pool,并指定为8个PG和PGP。

[root@host-192-168-0-16 ~]# ceph  osd pool create  crush  8   8 

pool 'crush' created

PGP是PG的逻辑承载体,是CRUSH算法不可缺少的部分。在Ceph集群里,增加PG数量,PG到OSD的映射关系就会发生变化,但此时存储在PG里的数据并不会发生迁移,只有当PGP的数量也增加时,数据迁移才会真正开始。关于PG和PGP的关系,假如把PG比作参加宴会的人,那么PGP就是人坐的椅子,如果人员增加时,人的座位排序就会发生变化,只有增加椅子时,真正的座位排序变更才会落实。因此,人和椅子的数量一般都保持一致。所以,在Ceph里,通常把PGP和PG设置成一致的。

可以查看PG映射OSD的集合,即PG具体分配到OSD的归属。

 [root@host-192-168-0-16 ~]# ceph pg dump | grep ^22\. | awk '{print $1 "\t"   $17}'    ## 22 表示 Pool id ##

dumped all in format plain

22.1 [1,2,3]    

22.0   [1,2,3]

22.3  [3,1,2]

22.2  [3,2,0]

22.5 [1,3,2]

22.4  [3,1,2]

22.7  [2,1,3]

22.6  [3,0,2]

上面示例中,第一列是PG的编号(其中22表示的Pool的ID),共计8个,第二列是PG映射到了具体的OSD集合。如“22.1 [1,2,3]”表示PG 22.1分别在OSD1、OSD2和OSD3分别存储副本。

在Ceph集群里,当有数据对象要写入集群时,需要进行两次映射。第一次从object→PG,第二次是PG→OSD set。每一次的映射都是与其他对象无相关的。以上充分体现了CRUSH的独立性(充分分散)和确定性(可确定的存储位置)。

3.4 本章小结

本章主要围绕Ceph的核心——CRUSH展开,讲述了CRUSH的基本原理以及CRUSH的特性。读者可以了解Ceph基本要素的概念,重点应该把握Ceph的Object、PG、Pool等基本核心概念,熟悉读写流程以及CRUSH算法的组成、影响因素及选择流程。基于以上掌握的要点,为后面的深入学习打好坚实的基础。