FastDFS与Ceph的比较

研究分布式存储只看Ceph是不够的,想有个横向对比,看看各有什么优缺点,从而深入对Ceph和分布式存储的理解。我司图片存储使用的是FastDFS,所以从它看起。 因为没有真正使用过,只是为了了解概念,所以浅尝辄止,参考资料比较单一,可能存在误解,里面甚至有我的很多猜测、思考和问题,请想了解FastDFS的同学绕道。 本质差别 FastDFS和Ceph的本质区别:FastDFS不是一个对象存储,是个分布式的文件存储,虽然和传统的NAS有差别,但其本质还是文件存储。所以这个对比其实不是那么横向,差别太大了: FastDFS以文件为单位,Ceph以Object为存储单位 FastDFS没有strip文件,而Ceph(fs)把文件分成object分布在OSD中,read时可以并发,FastDFS没有这样的功能,性能受限于单机 FastDFS节点 FastDFS的节点有两种:tracker和storage。 Tracker节点负责协调集群运作,storage上报心跳、记录storage所属group等,角色有点类似于Ceph中的MON。这些信息很少,且都可以通过storage上报获得无需持久化,所以都存储在内存中,也使得tracker的集群佷容易扩展,每个tracker是平等的。 这里我有一个疑问,既然是平等的,如何保障一致性?是几个节点同步的,还是storage上报时要多写? 我的猜测是靠同步的,因为下面介绍了写流程之后,你会发现其实一致性并不是很重要。一会儿我们再回到这个问题。 Storage就是存储节点了。 Storage以group为单位,一个group内的storage互为备份。每个storage可以挂不同的盘到不同的*path*。 这种备份是简单的镜像,所以一个group的总容量是最低的那个server决定的,没有Ceph CRUSH map的自动依据硬盘大小的weight功能。 文件上传后以hash为依据分布在storage的文件夹中。 FastDFS上传过程 上传文件时,tracker会选择一个group,可以配置以下方式: - RR,轮询 - Specified,指定一个group - Load balance,剩余空间多的优先 选定group之后选择一个storage。规则是: RR Order by IP Order by priority,优先级排序 问题:既然group内的storage是镜像的,为什么还要选择一个上传呢,随机一个不都可以吗? 然后选定path,也就是同一台storage上不同的数据盘: RR 剩余空间多优先 Storage生成fileid:base64({storage IP}{create time}{file size}{file crc32}{random number})。 接着选定两级子目录,这个不重要且很简单,只是为了避免同个目录下的文件过多。 生成文件名,包含: - group - 目录 - 两级子目录 - fileid - 文件后缀(客户端指定,区分类型) 一个文件名的例子:group1/M00/00/0C/wKjRbExx2K0AAAAAAAANiSQUgyg37275.h。 FastDFS文件同步 文件写入上文规则选出的一个storage server即返回成功,再由后台线程同步到其他节点。而Ceph的要求是写入主primary OSD之后所有副本比如第二第三OSD完成之后才返回成功,数据安全性更高。 只primary写完就返回,那其它同group的storage什么时候能提供服务?这个要靠是否同步完成来判断。同步的进度靠primary storage的binlog记录,binlog会同步到tracker,读请求时tracker根据同步进度选择可读的storage。
Read more...

ARIES数据库恢复算法

Algorithms for Recovery and Isolation Exploiting Semantics(ARIES) 是一种针对非强制(no-force,即当事务提交时不强制立刻写入记录所在的磁盘对象)可窃用(steal,即缓存管理器可强制将任意page刷入磁盘)数据库的恢复算法。ARIES的发明者的描述是,ARIES是一种使用写前日志(WAL)的支持细粒度锁和部分回滚的事务恢复方法。 1. ARIES 三原则 先看看ARIES的三个原则: 写前日志(write-ahead logging,WAL):一个对象的任何修改需要先记录在log中,log在对对象的修改写入磁盘前必须写入到稳定的存储中 Redo时重复历史:崩溃重启时,ARIES分析崩溃前的行为,并把系统恢复到崩溃前的状态,然后undo崩溃时未完成的事务 Undo时记录修改:undo事务时所作的修改写入log,防止不断重启时重复这些操作 2. WAL 为什么要no-force?为什么不直接去修改磁盘上存储的对应的对象,而是先去写WAL呢?我们先看看WAL这个更大的概念。 WAL是一种提供ACID中的原子性和持久性的机制。ACID忘掉的可以点链接复习一下,题外话,以前觉得原子性/atomicity的叫法令人摸不着头脑,这个词和atom(原子)同源自古希腊语一个表示“不可再分”的哲学概念的词,所以原子性就表示一个事务的一系列操作是不可分的一个整体。 WAL除了可以保证原子性,也能提升写性能。因为数据库文件分散在磁盘中,一般场景下update将造成许多随机I/O,造成性能极差,但以追加形式写log文件则是顺序I/O,比随机I/O性能高很多。 Log的形式分为undo(回滚)和redo(重做)两种。Undo log记录事务修改前状态,根据undo log可以将该log造成的更改撤销;Redo log记录事务修改后状态,根据redo log,可以将该log造成的更改重做。一般同时使用两种log,MySQL InnoDB使用的是redo log,磁盘中的ib_logfile0, ib_logfile1就是InnoDB的redo log file。 因为undo / redo log使数据库可以在事务当中恢复到事务前状态,所以说WAL可以保证原子性。 WAL不仅用在数据库中,在文件系统中类似的机制叫journaling,将来有机会可以写写Ceph的Filestore的journal机制。 3. 日志 每个log条目都按序列号(Log Sequence Number,LSN)顺序排列的。为获取写log必要的信息,我们需要两个数据结构: 脏页表(dirty page table, DPT) 事务表(transaction table, TT) 脏页表记录了所有被修改的胆识还未刷入磁盘的脏页和造成脏页的第一个序列号。事务表记录了所有正在进行的事务和它们写入的最后一条log的序列号。 我们以<LSN,事务ID,页ID,Redo,Undo,前一SN>的形式记录log。其中前一LSN指向这个事务产生的前一条log,当事务被取消,就可以用这一项从后往前遍历来回滚。 恢复和回滚未完成的事务时会写补偿log(Compensation Log Record, CLR)来记录被回滚的操作。CLR的一般形式是<LSN,事务ID,页ID,重做,前一SN>。 4. 恢复 恢复的三个阶段: 分析,从logfile里面计算所有需要的信息 Redo,将数据库恢复到崩溃现场,包括崩溃时还未提交的事务 Undo,将未提交的事务回滚,恢复一致性 4.1 分析 分析过程中,buffer中的脏页和崩溃时正在进行的事务将被从log中识别,DPT和TT恢复到崩溃时状态,具体过程如下。
Read more...