zoukankan      html  css  js  c++  java
  • ceph源码之一

    转自于:http://blog.csdn.net/changtao381/article/details/8698935

    一、概述:

     其结构如下:在src 里,

      网络通信:  msg  里面 包括了网络传输的代码, message 目录里定义了 传输的消息格式。
      元数据服务器:
                        mds  目录 包括了metadata server 的代码
      数据服务器:
                       os     目录里包含了 object store 的代码
                       osd  目录包括了 object storage device 的代码
      客户端:
                       osdc  目录里包括跨网络访问 osd的 代码
                       librados 包括了对象存储的客户端操作的代码
                       librbd,rgw, client  客户端代码,其代码都是基于librados之上。
      监控:Ceph Monitor      
                       mon 目录里包括了 Ceph Monitor的代码                 
      CRUSH 算法:
                cursh  目录里包括了 cursh 算法的代码
      核心就是上述的代码,当然还有其它一些的辅助性的代码:
        common: 一些公用的类和函数
      cls: OSD的一个插件机制,可以在对象上原子的执行一些复杂的操作。 感觉有点像OpenC++的反射机制,总之是一种测试和调试机制。

    二、架构设计 

      特点

        Ceph最大的特点是分布式的元数据服务器  通过CRUSH,一种拟算法来分配文件的locaiton,其核心是 RADOS(resilient automatic distributed object storage),一个对象集群存储,本身提供对象的高可用,错误检测和修复功能。

      其设计思想有一些创新点:

      第一,数据的定位是通过CRUSH算法来实现的。

        传统的,或者通常的并行文件系统,数据的定位的信息是保存在文件的metadata 中的, 也就是inode结构中,通过到metadata server上去获取数据分布的信息。而在Ceph中,是通过CRUSH 这个算法来提供数据定位的;

        这和GlusterFS的思想是相同的,GlusterFS 是通过Elastic Hash,类似于DHT的算法实现的。这就有点像P2P存储,所谓的完全对称的存储,这种设计架构最大的优点是,其理论上可以做到 线性扩展的能力(line scale)。

        在GlusterFS架构中,是完全去掉了metadata server,这就导致GlusterFS文件系统上的元数据操作,例如ls, stat操作非常慢,要去各个stripe的节点上收集相关的元数据信息后聚合后的结果。在Ceph中,为了消除完全的p2p设计,提供了metadata     server 服务,提供文件级别的元数据服务,而元数据服务中的文件数据定位由CRUSH算法代替。

      第二,元数据服务器可以提供集群metadata server 服务。

        只要当我们了解了其结构后,感觉并没有太大的特点。元数据服务器一般就用来存储文件和目录的信息,提供统一的命名服务。 在Ceph中,元数据 的存储inode 和 dentry的,以及日志都是在 对象存储集群RADOS中存储,这就使得 metadata的 持久化都 是在远程的RADOS中完成,metadata server 不保存状态,只是缓存最近的inode 和 dentry项,当metadata server 失效后,其所所有信息都可以从RADOS中获取,可以比较容易恢复。

        其实, 也上两点,并没有什么特别的地方。 我觉得,CEPH最核心的,就是RADOS就是RADOS(resilient automatic distributed object storage). 其resilient 指的是可以轻松扩展,automatic 指的是其对象存储集群可以处理failover, failure recovery。RADOS 对象集群其对外提供了一个高可用的,可扩展的,对象集群,从客户端的角度看,就是一个统一命名空间的对象存储。

      下面我们重点介绍一下RADOS这个Ceph的核心系统。 

    RADOS对象存储集群

     Ceph 的Monitor

      用来监控集群中所有节点的状态信息,完成类似配置服务的功能。在Ceph里,配置主要就是cluster map ,其保存集群所有节点信息,并和所有的节点保持心跳,来监控所有的节点状态。

    其通过Paxos算法实现实现自身的高可用,也就是说,这个Ceph Monitor是不会有单点问题的。目前流行的zookeeper 的功能,以及实现都类似。

    对象存储

      Ceph文件系统中的数据和元数据都保存在对象中。 对于对象存储,通常的定义是:一个Object,由三部分组成(id,metadata,data),id是对象的标识,这个不必多说。所谓的metadata,就是key/value的键值存储,至于用来保存什么信息,由文件系统的语义定义。data就是实际存储的数据。

      Ceph的对象,包括四个部分(id,metadata,attribute,data),在Ceph里,一个Object,实际就对应本地文件系统的一个文件,一个对象的attribute,也是key/value的键值对,其保存在本地文件系统的文件的扩展属性中。对象的metadata就是key/value的键值对,目前Ceph保存在google开源的一个key/value存储系统leveldb中,或者自己写的一个key/value 存储系统中。数据就保存在对象的文件中。对于一个对象的更新,都需要写日志中来保持一个Object数据的一致性(consistence),日志有一个单独的设备或者文件来保存。

    副本存储

      一个PG(placement group)由一个OSD列表组成,OSD的个数,就是对象的副本数,一个三副本的PG就是一个主,两个副本的OSD列表组成。

      一个PG和OSD列表的映射关系,是通过CRUSH算法计算的,知道PG的id,和当前的cluster map,就可以通过CRUSH算法,计算出OSD列表。特别强调的是,一个PG是逻辑层概念,也就是说,一个OSD,可能同时是一个或者多个PG的主,同时是另一个PG的从。一个OSD处于多个PG组中。一个PG就是复制和修复的基本单位。每个OSD本地保存其所在的PG列表就可以了,其它OSD可以通过输入当前的该OSD保存的cluster map 和 PG 的id ,通过CRUSH计算得出。

    Ceph的容错处理

      对于Ceph文件系统,错误分两类:一类是磁盘错误或者数据损坏( disk error or  corruptted data), 这类错误OSD会自己报告和处理。(self report ); 第二类是OSD失去网络连接导致该OSD不可达(unreachable on the network)这种情况下需要主动检测(active monitor),在同一个PG组中的其它OSD会发心跳信息互相检测。 这种检测的一个优化的方法就是,当replication复制操作时,就可以顺带检测,不用发单独的消息来检测,只有一段时间没有replication 操作时,才发ping消息里检测。

      OSD的失效状态有两种:一种是down状态,这种状态下,被认为是临时错误。 在这种情况下,如果是primay,其任务由下一个replicate接手。如果该OSD没有迅速恢复(quickly recovery),那么就被标记为out状态,在这种状态下,将有新的osd加入这个PG中。

      如何标记一个OSD 从down状态 标记为out状态?由于网络分区的问题,需要通过 Ceph Monitor 来裁定。

    Ceph 的写流程

       客户端先写主副本,然后同步到两个从副本。主副本等待从副本的ack消息和apply消息。当主副本收到ack消息,说明写操作已经写在内存中完成,收到apply 消息,说明已经apply到磁盘上了。

      如果在写的过程中,主副本失效,按顺序下一个从副本接管主副本的工作,这个时候是否返回给客户端写正确?在这种情况下,客户端只是判断正常工作的(acting)的 OSD的返回结果,只要所有正常工作的OSD返回即认为成功,虽然这时候可能只有两副本成功。同时该临时primay必须保存所有操作的recovey队列里,如果原primay恢复,可以replay所有recovery队列里的操作,如果主副本从down到out状态,也即是永久失效,临时primay转正,由临时primay为正式primay,只是需要加入一个新的OSD到该PG中。

    如果是从副本失效,就比较简单。临时失效,主replay所有写操作,如过永久失效,新加入一个OSD到PG中就可以了。

    恢复

       当有OSD失效,恢复或者增加一个新的OSD时,导致OSD cluster map的变换。Ceph处理以上三种情况的策略是一致的。为了恢复,ceph保存了两类数据,一个是每个OSD的一个version,另一个是PG修改的log,这个log包括PG修改的object 的名称和version。

    当一个OSD接收到cluster map的更新时:

    1)检查该OSD的所属的PG,对每个PG,通过CRUSH算法,计算出主副本的三个OSD

    2)如何该PG里的OSD发生了改变,这时候,所有的replicate向主副本发送log,也就是每个对象最后的version,当primay 决定了最后各个对象的正确的状态,并同步到所有副本上。

    3)每个OSD独立的决定,是从其它副本中恢复丢失或者过时的(missing or outdated)对象。 (如何恢复? 好像是整个对象全部拷贝,或者基于整个对象拷贝,但是用了一些类似于rsync的算法?目前还不清楚)

    4)当OSD在恢复过程中,delay所有的请求,直到恢复成功。

  • 相关阅读:
    MVC ORM 架构
    Kubernetes 第八章 Pod 控制器
    Kubernetes 第七章 Configure Liveness and Readiness Probes
    Kubernetes 第六章 pod 资源对象
    Kubernetes 第五章 YAML
    Kubernetes 核心组件
    Kubernetes 架构原理
    Kubernetes 第四章 kubectl
    Kubernetes 第三章 kubeadm
    yum 配置及yum 源配置
  • 原文地址:https://www.cnblogs.com/chris-cp/p/4503724.html
Copyright © 2011-2022 走看看