Tag Archives: storage

Ceph的架构

介绍

云硬盘是IaaS云平台的重要组成部分,云硬盘给虚拟机提供了持久的块存储设备。目前的AWS 的EBS(Elastic Block store)给Amazon的EC2实例提供了高可用高可靠的块级存储卷,EBS适合于一些需要访问块设备的应用,比如数据库、文件系统等。 在OpenStack中,可以使用Ceph、Sheepdog、GlusterFS作为云硬盘的开源解决方案,下面我们来了解Ceph的架构。

Ceph是统一存储系统,支持三种接口。

  • Object:有原生的API,而且也兼容Swift和S3的API
  • Block:支持精简配置、快照、克隆
  • File:Posix接口,支持快照

Ceph也是分布式存储系统,它的特点是:

  • 高扩展性:使用普通x86服务器,支持10~1000台服务器,支持TB到PB级的扩展。
  • 高可靠性:没有单点故障,多数据副本,自动管理,自动修复。
  • 高性能:数据分布均衡,并行化度高。对于objects storage和block storage,不需要元数据服务器。

ceph-architecture

Continue reading

软件RAID的mdadm使用手册

1. 文档信息

当前版本 1.2
创建人 朱荣泽
创建时间 2011.01.07
修改历史
版本号 时间 内容
1.0 2011.01.07 创建《mdadm详细使用手册》1.0文档
1.1 2011.01.10 增加”实验”内容
1.2 2012.04.13 删除”实验内容”

2. mdadm的主要功能

mdadm是一个用于创建、管理、监控RAID设备的工具,它使用linux中的md驱动。

mdadm程序是一个独立的程序,能完成所有软件RAID的管理功能,主要有7中使用模式。

模式名字

主要功能

(对于存储管理系统)

Create

使用空闲的设备创建一个新的阵列,每个设备具有元数据块

创建RAID时使用的命令

Assemble

将原来属于一个阵列的每个块设备组装为阵列

在存储管理系统一般不使用该模式

Build

创建或组装不需要元数据的阵列,每个设备没有元数据块

在存储管理系统一般不使用该模式

Manage

管理已经存储阵列中的设备,比如增加热备磁盘或者设置某个磁盘失效,然后从阵列中删除这个磁盘

用于增加热备盘

移除失效盘

Misc

报告或者修改阵列中相关设备的信息,比如查询阵列或者设备的状态信息

用于查询RAID信息

Grow

改变阵列中每个设备被使用的容量或阵列中的设备的数目,改变阵列属性(不能改变阵列的级别)

在存储管理系统一般不使用该模式

Monitor

监控一个或多个阵列,上报指定的事件,可以实现全局热备

监控RAID,写入日志

3. 概念解析

/proc/mdstat : 当前md(软RAID)的状态信息

/etc/mdadm.conf : mdadm的配置文件

Active devices : RAID中的活动组件设备

Faulty device : RAID中失效的设备

Spare device : RAID中热备盘

Device Names : RAID设备名、标准格式是”/dev/mdNN”或者”/dev/md/NN”

md : Multiple Devices虚拟块设备(利用底层多个块设备虚拟出一个新的虚拟块设备)。

md driver : MD的驱动

Array : 阵列,跟RAID意思相同

Raid :不解释

md device : 就是使用MD创建的软件RAID

md array :同上

md设备 :同上

4. mdadm各个选项

命令概要: mdadm [模式选项] [RAID设备名] [子选项…] [组件设备名…]

模式选项

子选项

备注

无特定模式

–verbose

显示更详细的信息

用于 –detail –scan 或者 –examine –scan

–force

某些选项强制执行

–config=

指定配置文件,默认是”/etc/mdadm.conf”或者是”/etc/mdadm/mdadm.conf”,假如配置文件名是 “partitions”,则mdadm会读取/proc/partitions的设备用于scan。

假如配置文件名是”none”,则mdadm会认为配置文件是空的。

–scan

从配置文件或者/proc/mdstat中扫描信息。

–metadata=

定义组件设备上超级块的类型。对于–create,默认是0.90。

0,0.90 : 限制一个RAID中的设备数为28个,限制组件设备大小为2TB

1,1.0,1.1,1.2 :不同的子版本号标识在不同的地方存储超级块。1.0在设备的结尾,1.1在设备的开头,1.2在设备的4K处。

–homehost=

在创建一个RAID时,homehost名会记录在超级块中。在1.X超级块中,它是RAID名字的前缀。0.90超级块中,homehost名的的SHA1值会保存在UUID的后半部分。

当使用Auto-Assemble时,只有相同homehost名的RAID才会被组建。

–create

–build

–grow

–raid-devices=

指定一个RAID中active devices的数目。

–spare-devices=

指定创建一个RAID时spare devices中的数目。

–size=

在RAID1/4/5/6中每个设备所能利用的数据容量。这个值必须是 chunk size的整数倍。而且必须留128K的设备空间用于RAID超级块。假如没有指定,则默认使用最小设备空间。

该选项能用–grow 进行扩容。

–chunk=

条带大小

–rounding=

在linear array中的rounding factor,等于条带大小

–level

设置RAID级别,RAID级别有(有些是同义词,比如raid5和5):

Linear,raid0,0,stripe,raid1,1,mirror,raid4,4,raid5,5,raid6,6,raid10,10,multipath,mp,faulty。

–build只支持linear,stripe,raid0,0,raid1,multipath,mp,faulty。

–grow不支持改变RAID级别。

–layout=

(–parity=)

设置RAID5、RAID10数据布局类型,控制faulty级别的failure的模式。

-bitmap=

这个选项对性能可能有影响,具体查看《mdadm手册翻译》

设置一个文件用于保存write-intent位图。

当文件名是”internal”时,位图复制保存在RAID组件设备(一个RAID的所有组件设备)的超级块中。当–grow,文件名是”none”时,位图会被移除。

–bitmap-chunk=

这个选项对性能可能有影响,具体查看《mdadm手册翻译》

设置位图中每位所映射块的大小。

当使用”internal”位图时,映射块的大小是自动设置的(根据超级块中可用空间)。

–write-mostly

–build、–create、–add后的设备都被标记上”wirte-mostly”。这个选项只对RAID1有效,即”md”driver会避免从RAID1的所有设备读取数据。假如镜像的速度很慢,这是非常有用的。

–write-behind=

该选项只对RAID1有效。这个选项会设置最大的写队列深度,默认值是256。使用write-behind的前提是先设置write-intent bitmap,先设置设备为write-mostly。

–assume-clean

告诉mdadm这个array已经clean。当array从一个严重的故障中恢复时,这个选项会保证没有数据会被覆盖。当创建RAID1和RAID10时,这个选项也能避免初始化同步。但是使用该选项必须要很谨慎。

–backup-file=

当使–grow为RAID5增加组件设备数时,该文件保存关键数据。(该文件不能在该RAID5上,以免发生死锁。)

–name

给一个RAID设置名字,只在1.X超级块中有用,它是简单的字符串,用于assembling时识别RAID组件设备。

–run

强制激活RAID。(当一个RAID中的某些组件设备被其他RAID或者文件系统占用时)。使用这个选项,设备上有旧的元数据信息的提示会被忽略。

–force

mdadm无条件接受指定的参数。

使用该选项可以只使用一个设备创建RAID;

创建RAID5时使用该选项,使得RAID5初始化不使用recovery模式,而是校验同步所有组件设备上的数据(比recovery模式要慢)。详情请见命令举例中的创建RAID

–auto=

创建md设备文件。选项是{no,yes,md,mdp,part,p}{NN}。默认是yes。

“yes”要求RAID设备名是标准格式的,然后设备文件类型和minor号会自动确定。

比如RAID设备名是”/dev/mdx” 查看/proc/partitions可以看到mdx的major号是9,minor号是x。

当使用”md”时,RAID设备名可以是非标准格式,比如”/dev/md/zhu”,然后创建两个设备文件/dev/md/zhu 还有 /dev/mdx,并给这两个设备文件分配相同的major号和minor号(也就是这两个设备文件指向同一个设备)。分配minor号的方法是:分配一个没有使用过的minor号,这个minor号就是/dev/mdx中的数字x。查看/proc/partitions和/proc/mdstat,RAID设备名还是/dev/mdx。

当使用”mdp,p,part”时,RAID设备名可以是非标准格式,比如”/dev/md/zhu”,除了创建设备文件/dev/md/zhu 还有 /dev/mdx外,还会创建 /dev/md/zhup1, /dev/md/zhup2, /dev/md/zhup3, /dev/md/zhup4,这些是分区设备文件。

–symlink=no

默认下–auto会创建/dev/md/zhu的软连接 /dev/md_zhu。假如使用该选项,则不会创建软连接。

–assemble

–uuid=

重组RAID,要求组件设备的uuid相同

–super-minor=

minor号会保存在每个组件设备中的超级块中,可以根据这个重组RAID。

–name=

根据RAID名重组RAID。

–force

即使一些超级块上的信息过时了,也可以强制重组。

–run

即使RAID中的组件设备不完整(例如原来创建4块盘的RAID5,现在只发现3块成员盘),RAID也被重组,并启动。

(假如不用–run,RAID只被重组,但是不启动)

–no-degraded

和–scan选项一起使用。

禁止RAID中的组件设备不完整时启动RAID,知道RAID中的组件完整。

–auto

如–create中的 –auto

–bitmap

指定bitmap文件(当RAID创建时所指定的bitmap文件),假如RAID使用internal类型的bitmap,则不需指定。

–backup-file=

当增加RAID5的组件设备数,指定backup-file文件。在RAID5重构过程中,假如系统当机,backup-file文件会保存关键数据,使得重启系统之后,重构可以继续进行。假如没有指定backup-file,mdadm会使用热备盘上的空间作为备份空间。

–update=

更新RAID中每个组件设备的超级块信息。选项有sparc2.2、summaries、uuid、name、homehost、resync、byteorder、super-minor

–auto-update-homehost

只对auto assembly情况下有用。

Manage模式

–add

给RAID在线添加设备(可用于添加热备盘)

–re-add

给RAID重新添加一个以前被移除的设备。

假如一个RAID使用write-intent bitmap时,它的一个设备被移除后又被重新添加,bitmap可以避免完全重建,而是只更新那些设备被移除后已经被更新过的块数据。

–reomve

移除设备,只能移除failed(失效)和spare(热备)设备。(因此假如要移除RAID5中的一个活动设备,需要先使用–fail选项使该设备的状态变成failed,然后才能移除。)

该选项后面跟的是设备名(比如是 /dev/sdc),也可以是faileddetached关键字。Failed使得所以失效的部件被移除,detached使得所以被拔出的硬盘被移除。

–fail

使RAID中某个设备变成failed状态。

该选项后面跟的是设备名(比如是 /dev/sdc),也可以是detached关键字。

Misc模式

–query

查询一个RAID或者一个RAID组件设备的信息

–detail

查询一个RAID的详细信息

–examine

查询组件设备上的超级块信息

–sparc2.2

用于修正超级块信息,详情请见用户手册。

–examnie-bitmap

查看bitmap文件中的信息

–run

启动不完整的RAID(比如本来是有4块盘的RAID5,现在3块盘也可以启动)。

–stop

禁止RAID活动,释放所有资源。但是RAID中组件设备上的超级块信息还在。还可以重新组建和激活RAID。

–readonly

使RAID只能只读

–readwrite

使RAID能读写

–zero-superblock

假如一个组件设备包含有效的超级块信息,那么这个超级块会被写0覆盖。假如使–force选项,则不管超级块中是否有信息,都会被写0覆盖。

–test

假如–detail一起使用,则mdadm的返回值是RAID的状态值。

0 代表正常

1 代表降级,即至少有一块成员盘失效

2 代表有多快成员盘失效,整个RAID也失效了(对于RAID1/5/6/10都适用)。

4 读取raid信息失败

–monitor

(–follow)

–mail

设置警报邮件

–program

当监测到一个事件发生时,关于该事件的信息会作为参数被发给该程序

–syslog

所有事件都会通过syslog报告

–delay

Mdadm会隔多少秒轮询各个RAID,默认是60秒

–daemonise

Mdadm会创建一个子进行作为后台监控程序。该子进程的PID号会输入到stdout上。

–pid-file

当–daemonise一起使用时,子进程的PID号会写入该文件中

–oneshot

只会检测RAID一次。它会检测NewArray、DegradedArray、SparesMissing事件。

在cron脚本中运行”mdadm –monitor –scan –oneshot”会定期报告。

–test

对每个RAID产生TestMessage,用于测试mail、program是否正确。

5. 各种模式的使用

Assemble模式

用法:mdadm –assemble md-devices options-and-component-devices…

例子:#mdadm –assemble /dev/md0 /dev/sda1 /dev/sdb1

说明:把sda1和sdb1重组成/dev/md0。

用法:mdadm –assemble –scan md-devices-and-options…

例子:#mdadm –assemble –scan /dev/md0

说明:从配置文件读出设备列表,根据超级块中的信息,重组/dev/md0。

用法:mdadm –assemble –scan options…

例子:#mdadm –assemble –scan –uuid=xxxxxxx

说明:从配置文件读出设备列表,根据超级块中的uuid信息,重组uuid是xxxxxxx的RAID。

假如#mdadm –assemble –scan命令后面没有设备列表,mdadm会读取配置文件中所列的RAID信息,并尝试重组。假如系统中没有/etc/mdadm.conf配置文件,则会从/proc/partitions中读取设备列表。因此使用mdadm时,必须保证mdadm中的状态信息(/proc/mdstat)和/etc/mdadm.conf配置文件一致,否则重启操作系统后,会出现问题。

Create模式

用法:mdadm –create md-device –chunk=X –level=Y –raid-devices=Z devices

例子:# mdadm –create /dev/md0 –chunk=64 –level=0 –raid-devices=2 /dev/sda1 /dev/sdb1

说明:使用sda1和sdb1创建RAID0,条带大小是64KB。

例子:#mdadm –create /dev/md1 –chunk=64 –level=1 –raid-devices=1 /dev/sdc1 missing

说明:创建一个降级的RAID1,同样可以使用missing创建降级的RAID4/5/6。

Misc模式

用法:mdadm options… devices..

例子:#mdadm –detail –test /dev/md0

说明:这条命令的返回值:0代表md0正常;1代表md0至少有一个failed的组件设备;2代表md0有多个failed组件设备,这个md0已经不能使用,即失效(md0是raid1、raid5、raid6、raid10时);4代表获取md0设备信息错误。

Monitor模式 (只监控raid1/5/6/10,不监控raid0)

用法: mdadm –monitor options… devices..

说明:mdadm除了报告事件以外,mdadm还可以把一个RAID中的热备盘移动到另一个没有热备盘的RAID中,前提条件是这些RAID都属于同一个spare-group(RAID的spare-group可以在配置文件里设置)。

说明:当命令中有设备列表时,mdadm只会监控这些设备。当没有设备列表时,配置文件中的所有RAID都会被监控。当使用–scan选项时,/proc/mdstat中的设备也会被监控。

说明:传给program的三个参数是事件名、涉及到的md device名、涉及到的其他设备(比如组件设备失效)。

说明:监控的事件有

DeviceDisappeared 当RAID0和linear中某个设备失效时,就会出现RAID消失。

RebuildStarted 重建RAID

RebuildNN 重建百分比,NN代表20,40,60,80

RebuildFinished 重建结束

Fail RAID中某个活动组件设备失效

FailSpare RAID中某个热备盘失效

SpareActive RAID中热备盘启用,用于重建RAID

NewArray 在/proc/mdstat中监控到有新的RAID被创建

DegradedArray RAID降级

MoveSpare 热备盘从一个RAID中移动到另外一个RAID中,前提是这两个RAID属于同个spare-group

SparesMissing 发现RAID中的热备盘数比配置文件中的少

TestMessage 测试

说明:只有Fail、FailSpare、DegradedArray、SparesMissing、TestMessage事件才会触发发送Email。

Grow模式

说明:能改变RAID1、5、6中的”size”属性。

说明:能改变RAID1、5中的”raid-disks”属性。

说明:增加移除RAID中的write-intent bitmap。

6. 命令举例

创建配置文件

例子:#echo ‘DEVICE /dev/hd*[0-9] /dev/sd*[0-9]’ > mdadm.conf #mdadm –detail –scan >> mdadm.conf

说明:创建配置文件的原型。

创建RAID

例子:#mdadm –create /dev/md0 –chunk=64 –level=1 –raid-devices=2 /dev/sda1 /dev/sb1

说明:创建md0,RAID级别是RAID1,条带大小事64KB,成员盘是sda1、sdb1

给RAID增加热备盘

例子:#mdadm /dev/md0 -add /dev/sdc1

说明:给md0增加热备盘sdc1。

查看RAID信息和组件设备信息

例子:#cat /proc/mdstat

说明:查看当前所有RAID的状态

例子:#mdadm –detail /dev/md0

说明:查看md0的详细信息

例子:#mdadm –examine /dev/sda1

说明:查看组件设备sda1中超级块的信息和状态

删除RAID

例子:#mdadm –stop /dev/md0

说明:停止md0的运行

例子:#mdadm — zero-superblock /dev/sda1

说明:清除组件设备sda1中超级块的信息

监控RAID

7. 配置文件详解

格式简要说明

格式说明:SYNTAX xxx xxx xxx xxx xxx

注释说明:#This is a comment.

多行说明:假如任意一行中开头是以空白开头的(space/tab),这行被看做是上一行的延续。

空行说明:空行被忽略。

关键字说明

DEVICE

该关键字后面跟的是设备列表(设备和分区),这些设备可能是某个md设备的组件。当要查找某个RAID的组件设备时,mdadm会扫描这些设备。

例子:DEVICE /dev/hda* /dev/hdc*

例子:DEVICE /dev/hd*[0-9] /dev/sd*[0-9]

例子:DEV /dev/sd*

例子:DEVICE /dev/discs/disc*/disc

例子:DEVICE partitions

说明:mdadm会读取/proc/partitions中的设备。假如在配置文件中没有DEVICE关键字,

则假定”DEVICE partitions”,也就是默认会读取/proc/partitions中的设备。

ARRAY

例子:

说明:关键字ARRAY标识一个活动的RAID,ARRAY后面跟着的是RAID的名字。RAID名字后面跟着的是RAID的属性值,这些属性值标识一个RAID,或者标识一个组的成员RAID(spare-group)。假如给出了多个属性值,则每个组件设备中的超级块信息必须匹配属性值。

属性值如下:

uuid=

128bit的值,用16进制表示。

name=

当创建RAID时使用–name指定的名字(跟RAID设备名概念不一样)。不是所有的超级块版本都支持–name。

super-minor=

当一个RAID,该RAID的设备名是/dev/mdX,minor号码就是X。

devices=

该属性值后面跟着设备名或者设备名模式(它们用逗号隔开)。注意:这些设备名必须包含在DEVICE中。

level=

RAID的级别

num-devices=

一个完整的RAID中活动设备数。

spares=

RAID中所设定的热备盘数目。

spare-group=

RAID组名,所有具有相同spare-group名的RAID会共享热备盘(前提是使用mdadm –monitor监控RAID)。mdadm会自动把一个RAID中的热备盘移动到另一个RAID(这个RAID有faild盘或者missing盘,而且没有热备盘)中。

auto=
bitmap=

指定write-intent bitmap文件。功能跟”–assemble –bitmap-file”一样。

metadata=

指定超级块版本。

MAILADDR

使用monitor模式(同时也使–scan选项)时,警报事件发送到的Email地址。

MAILFROM

邮件地址。

PROGRAM

“mdadm –monitor”监测到的事件都会发送给这个程序。

只能有一个程序。

CREATE

该行中是创建RAID时使用的默认值。

owner=

代替系统默认的USER ID(root)

group=

代替系统默认的GROUP ID(disk)

mode=

权限

auto=

metadata=

超级块的版本

symlinks=no

不用软连接

配置文件例子

DEVICE /dev/sd[bcdjkl]1 DEVICE /dev/hda1 /dev/hdb1 # /dev/md0 is known by it’s UID. ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 # /dev/md1 contains all devices with a minor number of # 1 in the superblock. ARRAY /dev/md1 superminor=1 # /dev/md2 is made from precisey these two devices ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 # /dev/md4 and /dev/md5 are a spare-group and spares # can be moved between them ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df spare-group=group1 ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 spare-group=group1 # /dev/md/home is created if need to be a partitionable md array # any spare device number is allocated. ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b auto=part MAILADDR root@mydomain.tld PROGRAM /usr/sbin/handle-mdadm-events CREATE group=system mode=0640 auto=part-8 HOMEHOST
  1. 注意事项

当系统中不存在配置文件/etc/mdadm.conf、/etc/mdadm/mdadm.conf时,系统启动时,md驱动会自动查找分区为FD格式的磁盘。所以一般会使用fdisk工具将hd磁盘和sd磁盘分区,再设置为FD的磁盘分区。因此假如直接使用/dev/sda、/dev/sdb创建RAID,系统重启后,不会重组该RAID。

AWS EBS介绍

AWS Elastic Block Store – 写于2011年12月

目录
  • AWS Elastic Block Store
    • EBS介绍
    • EBS特点
    • 使用EBS
    • EBS的快照
    • EBS的性能
    • EBS的耐久性
    • 架构
      • 整体架构
      • 快照架构
    • 测试
      • 性能测试
      • 快照测试

EBS介绍

AWS 的EBS(Elastic Block store)给Amazon的EC2实例提供了高可用高可靠的块级存储卷。EBS适合于一些需要访问块设备的应用,比如数据库、文件系统等。

EBS特点

  • 提供1GB到1TB的容量。
  • 存储卷像裸块设备一样,有块设备接口,可以在卷上创建文件系统。
  • 每个EBS volume是存放在一个Availability Zone中,只有同一个Availability Zone中的EC2 instance才能访问。
  • 每个volume在同一个Availability Zone中有多个副本,这可以保证当单个硬件失效时,数据不会丢失。
  • EBS可以创建当前时间点的快照,快照是保存在S3中。这些快照可用于创建新的EBS volume(volume上的数据和快照的数据相同)。快照可以长时间保存数据。同一个快照可以实例化多个volume。
  • volume可以从公共数据集中实例化(比如保存有基因数据的快照)。
  • Amazon CloudWatch可以监控EBS volume,监控的指标有带宽、吞吐量、延迟、队列深度。并提供API接口。

使用EBS

  • 每个volume只能挂载在一个EC2 instance上。每个EC2 instance可以挂载多个volume,这样可用于数据条带化(做软件RAID0),以此提高I/O性能和吞吐率。这对于像数据库这种典型应用(频繁随机读写操作)很有帮助。
  • EBS volume可以用作EC2 instance的启动分区,这样就能保存启动分区上的数据,并制作你的AMI。

EBS的快照

  • EBS volume支持创建快照,并把快照存放S3上。
  • EBS volume上的第一个快照是全备份快照,以后的快照是增量备份的。只意味着只有被改变的数据才会被保存。
  • 虽然快照是增量快照,但是删除一个快照时,只有对其他快照没用的数据才被删除。不管哪个快照被删除,所有活动的快照都包含了restore the volume所需的信息。而且,不管从哪个快照恢复(使用快照创建volume,也就是实例化volume),所花的时间都是一样的。
  • 快照能用于实例化多个新的volume,这些新的volume的容量可以大于快照的原volume的容量,而且这些新的volume可以在其他 Availability Zone。当创建一个新的volume时,可以选择保存在S3上的不同快照来创建。在这种情况下,新的volume实际上是快照的副本,但是可以是不同容 量(只能大于原volume)、不同Availability Zone。这种功能可以用于对旧的volume进行扩容,或者在不同的Availability Zone上复制volume。
  • 从S3上的快照创建的新volume的载入方式是”load lazily”。当一个volume从一个快照上创建时,并不需要等待把S3上所有的数据都传送到EBS volume上。只有当你的EC2 instance开始访问这个volume时(访问某一数据块时),这个volume才开始从S3传输数据,并在后台持续加载这个volume的所有数 据。
  • EBS的快照可以支持共享。这样可以共享你的数据给你的同事,而且还可以把快照共享给所有AWS用户。
  • 共享快照的操作可以通过AWS管理控制台或者API来执行。

EBS的性能

  • EBS volume适合于几乎所有方式的存储。你可以挂载多个volume在一个EC2 instance上,并条带化数据(做软件RAID,或者用LVM)。这种方式可以提高I/O性能,特别是大量随机访问。
  • 实际的性能依赖于具体的应用。因为EBS的volume需要网络访问,在大型EC2实例上,速度更快、吞吐率更高。

EBS的耐久性

  • EBS volume的耐久性(durability)跟volume的大小和最近快照之后所修改数据的大小有关。假如一个20GB的volume,最近快照之后 只修改了很少的数据,它的AFR(年故障率 annual failure rate)是0.1%~0.5%。而一个普通硬盘的AFR是4%。
  • 在同一个Availability Zone对volume做镜像并不能提高它的耐久性。但是可以对volume创建快照(快照保存在S3上,S3上的副本是保存在多个Availability Zone上),因此频繁创建快照可以提高数据的耐久性。
  • 当你的EBS volueme失效时,该volume的所有快照都是完整的,你可以基于这些快照创建新的volume。

架构

整体架构

  • 每个EBS cluster管理一群EBS nodes,这些node之间是对等的。
  • 每个EBS node保存有EBS volume数据的副本,并响应EC2 instance的读写请求。
  • EBS volume data被复制到多个EBS node上,保证durability和availability。
  • EBS node采用快速的故障转移策略(fast failover strategy),并主动选择新的副本(当一个副本不能同步或者不可用时)。
  • EBS node和EBS node、EC2 instance、EBS control plane services通过高带宽网络(Hign Bandwidth Network)进行通信。一个冗余的低带宽网络(Replication Network)用于EBS node间通信(可以用于副本的复制)。
  • 假如A EBS node和保存有数据副本的B node失去连接,则该A认为B已经失效。为了保证数据的耐久性(durability),A必须找到一个新的node,然后复制副本(称为re- mirroring)。在re-mirroring过程中,A在EBS cluster中搜寻另外一个有足够空间的node,然和跟这个node建立连接,然后复制数据到这个node上。
  • EBS control plane接收用户的requests,并转发到相应的EBS cluster。每个EC2 Region上有一套EBS control plane。EBS control plane分布在多个Availability Zones上,具有高可用性、高容错性。EBS control plane还要帮EBS cluster 上的volume data选择primary replicas(为了保证一致性,每个volume在某个时刻只有一个primary replica)。control plane上还有其他服务。
  • 当数据被re-mirroring的时候,所有保存这个数据副本的nodes会一直持有数据副本,直到它们确定其他节点已经接管了它们的工作(保存副 本),这样可以提供数据保护。但在volume中的数据在re-mirroring时,访问这些数据是会被阻塞的,直到系统确定一个新的 primary(or writable) 副本(replica)。这个限制可以保证在所有潜在的失效模型中,EBS volume中的数据是一致的。但是从EC2实例的角度去观察,当在一个volume上执行I/O时发生re-mirroring操作,这个volume 就表现为阻塞。

快照架构

  • 每个volume被分成多个blocks。当创建volume的第一个快照时,所有的blocks都会被保存到S3上,快照的指针表也被保存到S3上。当 创建这个volume的第二个快照时,只有被修改过的blocks才被保存到S3上,相应的指针表也被保存到S3上。第三个快照创建过程相同。
  • 增量快照(依赖快照)的优点是节约时间和空间。创建增量快照是非常块的,因为它只保存被修改过的blocks到S3上。创建快照的时候要注意一致性,当需要创建快照时,需要先冻结数据库、文件系统,然后创建快照,最后解冻。快照的性能跟S3的性能相同。
  • 通过快照,可以从其他Availability Zone获得一个volume的数据(因为快照是保存在S3上,S3是跨多个Availability Zones)。你可以在一个volume上创建快照,然后在另外一个Zone上创建一个新volume(并选择快照)。

   

测试

测试结果文档是AWS EBS测试记录。测试结果和测试工具、测试环境、AWS运行状况(多少个用户在使用EBS服务)等因素有关,因此此次测试结果并不代表EBS的平均性能。 可以对比的测试结果有 磁盘阵列测试文档盛大云硬盘测试文档

性能测试

  • 测试环境:在AWS上建立一个t1.micro的机器(615M内存),安装windows2008。
  • 测试对象:在AWS上创建一个10GB大小的EBS volume(和EC2 instance在同一个Availability Zone)。
  • 测试设置:把volume挂载到EC2 instance上,并格式化。
  • 测试工具:IOmeter
  • 测试参数:1个worker。IOmeter测试前会在volume上创建并充填一个8GB大小的文件,这样减少了EBS按需分配特性对测试结果的影响。

测试内容

  1. 顺序读的MBPS
  2. 顺序写的MBPS
  3. 顺序读的IOPS
  4. 顺序写的IOPS
  5. 随机读的IOPS
  6. 随机写的IOPS
  7. 文件服务器负载的IOPS
  8. 工作站负载的IOPS
  9. 数据库负载的IOPS

测试结果

顺序读的MBPS
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
512B 1 2552.614510 1.246394 0.391199
1KB 1 2524.156227 2.464996 0.395633
2KB 1 2350.644532 4.591103 0.424932
4KB 1 2072.339333 8.095076 0.482010
8KB 1 2039.289339 15.931948 0.489753
16KB 1 1630.023004 25.469109 0.612951
32KB 1 1183.749847 36.992183 0.844174
64KB 1 840.482779 52.530174 1.189014
128KB 1 524.162471 65.520309 1.906990
256KB 1 311.572372 77.893093 3.207976
512KB 1 172.817188 86.408594 5.783251
1MB 1 93.531282 93.531282 10.689385
2MB 1 48.517478 97.034956 20.603371
4MB 1 24.702554 98.810217 40.448923
8MB 1 12.671283 101.370263 78.904828
16MB 1 6.462593 103.401494 154.324245
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
64KB 1 849.835394 53.114712 1.176043
64KB 2 662.967552 41.435472 3.015535
64KB 4 1427.675388 89.229712 2.801068
64KB 8 1483.053670 92.690854 5.393741
64KB 16 1551.874317 96.992145 10.306176
64KB 32 1701.659058 106.353691 18.799876
64KB 64 1641.108362 102.569273 38.980397
64KB 128 1700.012987 106.250812 75.204437
64KB 256 1656.129006 103.508063 154.246022
顺序写的MBPS
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
512B 1 1274.010536 0.622075 0.784215
1KB 1 1405.586809 1.372643 0.710890
2KB 1 329.071429 0.642718 3.038028
4KB 1 305.100347 1.191798 3.276715
8KB 1 213.994582 1.671833 4.671948
16KB 1 225.008289 3.515755 4.442891
32KB 1 177.171213 5.536600 5.642789
64KB 1 155.261980 9.703874 6.439292
128KB 1 88.958616 11.119827 11.238242
256KB 1 55.986377 13.996594 17.857944
512KB 1 34.848074 17.424037 28.692845
1MB 1 24.591388 24.591388 40.640801
2MB 1 15.409959 30.819918 64.867947
4MB 1 8.218889 32.875558 121.635786
8MB 1 4.246041 33.968326 235.503735
16MB 1 1.038540 16.616641 941.911582
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
64KB 1 151.999081 9.499943 6.576373
64KB 2 152.297533 9.518596 13.132747
64KB 4 515.797143 32.237321 7.752766
64KB 8 282.601043 17.662565 28.295228
64KB 16 153.960955 9.622560 103.914596
64KB 32 153.934640 9.620915 207.635532
64KB 64 153.565797 9.597862 415.295611
64KB 128 153.072994 9.567062 827.534323
64KB 256 152.089254 9.505578 1645.074171
顺序读的IOPS
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
512B 1 2623.937138 1.281219 0.380500
512B 2 2924.002741 1.427736 0.683421
512B 4 5281.204203 2.578713 0.756876
512B 8 9442.143799 4.610422 0.846785
512B 16 15710.583835 7.671184 1.017935
512B 32 16533.778754 8.073134 1.934920
512B 64 12102.555239 5.909451 5.285980
512B 128 13126.756871 6.409549 9.737574
512B 256 16076.423785 7.849816 15.920638
顺序写的IOPS
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
512B 1 1629.355523 0.795584 0.613216
512B 2 1724.400716 0.841993 1.159318
512B 4 1350.314974 0.659333 2.961708
512B 8 1645.572631 0.803502 4.860792
512B 16 3131.141970 1.528878 5.109576
512B 32 5487.106291 2.679251 5.831239
512B 64 5436.232458 2.654410 11.769855
512B 128 5232.818035 2.555087 24.452925
512B 256 5116.757847 2.498417 50.006771
随机读的IOPS
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
512B 1 514.083543 0.251017 1.944495
512B 2 525.098368 0.256396 3.808146
512B 4 975.315686 0.476228 4.100013
512B 8 1104.889829 0.539497 7.239507
512B 16 1115.011082 0.544439 14.348814
512B 32 1088.295950 0.531395 29.414582
512B 64 1087.907633 0.531205 58.817419
512B 128 1105.796372 0.539940 115.645245
512B 256 1106.769817 0.540415 230.405567
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
4KB 1 388.525085 1.517676 2.572896
4KB 2 402.284369 1.571423 4.970561
4KB 4 805.948351 3.148236 4.961784
4KB 8 874.052415 3.414267 9.150627
4KB 16 866.534046 3.384899 18.465952
4KB 32 850.703072 3.323059 37.611484
4KB 64 831.472540 3.247940 76.908969
4KB 128 839.688149 3.280032 152.087256
4KB 256 822.089988 3.211289 310.311784
随机写的IOPS
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
512B 1 96.503149 0.047121 10.360601
512B 2 98.621325 0.048155 20.276820
512B 4 100.934031 0.049284 39.607770
512B 8 104.181319 0.050870 76.778951
512B 16 110.957958 0.054179 144.199395
512B 32 107.146756 0.052318 298.740650
512B 64 108.161191 0.052813 588.390351
512B 128 104.039996 0.050801 1213.382441
512B 256 101.893613 0.049753 2419.665037
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
4KB 1 98.432005 0.384500 10.157615
4KB 2 96.816930 0.378191 20.652090
4KB 4 107.852760 0.421300 37.098685
4KB 8 104.088110 0.406594 76.806699
4KB 16 101.127657 0.395030 158.338818
4KB 32 94.930524 0.370822 337.534401
4KB 64 95.691460 0.373795 665.235826
4KB 128 94.706141 0.369946 1330.134074
4KB 256 93.288342 0.364408 2637.288612
文件服务器负载的IOPS
文件服务器负载参数
所占百分比 数据块大小 读比例 随机比例
10% 0.5KB 80% 100%
5% 1KB 80% 100%
5% 2KB 80% 100%
60% 4KB 80% 100%
2% 8KB 80% 100%
4% 16KB 80% 100%
4% 32KB 80% 100%
10% 64KB 80% 100%
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
1 158.645113 1.697243 6.302122
2 173.501218 1.904440 11.524715
4 296.531083 3.152971 13.487062
8 326.156931 3.533370 24.521028
16 319.605897 3.471420 50.039720
32 288.254950 3.124912 110.995466
64 301.723392 3.272893 211.613380
128 306.735611 3.289809 415.098553
256 310.350024 3.337515 815.767888
工作站负载的IOPS
工作站负载参数
所占百分比 数据块大小 读比例 随机比例
100% 8KB 80% 80%
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
1 200.456374 1.566065 4.987198
2 203.397170 1.589040 9.831918
4 274.902475 2.147676 14.549520
8 325.505376 2.543011 24.569315
16 371.631791 2.903373 43.040322
32 378.742493 2.958926 84.493637
64 387.630832 3.028366 164.880733
128 385.078953 3.008429 331.252311
256 383.486685 2.995990 661.003607
数据库负载的IOPS
数据库负载参数
所占百分比 数据块大小 读比例 随机比例
100% 8KB 67% 100%
块大小 队列深度 IOPS MBPS 平均响应时间(ms)
1 170.188475 1.329597 5.874187
2 170.703080 1.333618 11.713854
4 289.670329 2.263049 13.807330
8 291.521447 2.277511 27.436836
16 260.296964 2.033570 61.472165
32 286.074512 2.234957 111.862068
64 270.296803 2.111694 236.589546
128 276.839849 2.162811 460.416307
256 273.369444 2.135699 925.519759

快照测试

创建一个EC2 instance,安装Red Hat 6.1。

创建快照的所花时间

  1. 创建一个2GB大小的EBS volume,然后挂载在Linux主机上。格式化这个volume,然后在上面创建填充一个1GB大小的文件。
  2. 给EBS volume创建第一个快照Snap_01,快照的状态从pending变成completed花了十几分钟。
  3. 写256MB的数据到文件上,然后创建第二个快照Snap_02,快照的状态从pending变成completed花了两分钟。
  4. 写256MB的数据到文件上,然后创建第三个快照Snap_02,,快照的状态从pending变成completed花了两分钟。
  5. 写1GB的数据到这个文件上,卸载这个volume,然后删除这个卷。

从同一个Availability Zone中恢复快照所花时间

分别从不同的快照上创建新的volome,共创建3个volume,然后把这3个volume挂载到Linux主机上。
volume名 快照名 盘符
vol-2dd44f40 Snap_01 /dev/xvdl
vol-03d44f6e Snap_02 /dev/xvdm
vol-fdd44f90 Snap_03 /dev/xvdn
  • 首先算出/dev/xvdl盘上文件的md5值(使用md5sum工具,md5sum会读取文件,然后计算md5值),用了20秒(因为从把/dev /xvdl挂载到/mnt/xvdl目录开始,S3就开始把数据复制到EBS volume上,因此恢复快照时间为20+秒)。
  • 然后算出/dev/xvdm盘上文件的md5值,用了4秒(md5sum计算文件的md5值花了4秒)。
  • 最后算出/dev/xvdn盘上文件的md5值,用了4秒。

删除这3个volume,然后删除Linux主机。

从不同Availability Zone中恢复快照所花时间

在不同的Availability Zone中创建Linux主机,然后分别从不同的快照上创建新的volome,共创建3个volume,最后把这3个volume挂载到Linux主机上。
volume名 快照名 盘符
vol-edfa6180 Snap_01 /dev/xvdl
vol-c5fa61a8 Snap_02 /dev/xvdm
vol-d3fa61be Snap_03 /dev/xvdn
  • 首先算出/dev/xvdl盘上文件的md5值(使用md5sum工具,md5sum会读取文件,然后计算md5值),用了66秒(因为从把/dev /xvdl挂载到/mnt/xvdl目录开始,S3就开始把数据复制到EBS volume上,因此恢复快照时间为66+秒)。
  • 然后算出/dev/xvdm盘上文件的md5值,用了3秒。
  • 最后算出/dev/xvdn盘上文件的md5值,用了3秒。

删除这3个volume,然后删除Linux主机。

ceph peering state model

描述”ceph peering state model”的dot文件

digraph G {
    size="7,7" compound=true;
    subgraph cluster0 {
        label = "RecoveryMachine";
        color = "blue";
        Crashed;
        Initial[shape=Mdiamond];
        Reset;
        subgraph cluster1 {
            label = "Started";
            color = "blue";
            Start[shape=Mdiamond];
            subgraph cluster2 {
                label = "Primary";
                color = "blue";
                WaitActingChange;
                Incomplete;
                subgraph cluster3 {
                    label = "Peering";
                    color = "blue";
                    GetInfo[shape=Mdiamond];
                    GetLog;
                    GetMissing;
                    WaitUpThru;
                }
                Active;
            }
            ReplicaActive;
            Stray;
        }
    }
    Initial -> Reset [label="Load",];
    GetInfo -> WaitActingChange [label="NeedActingChange",ltail=cluster2,];
    GetMissing -> WaitUpThru [label="NeedUpThru",];
    GetInfo -> Active [label="Activate",ltail=cluster3,];
    Stray -> ReplicaActive [label="Activate",];
    Initial -> GetInfo [label="MNotifyRec",lhead=cluster2,];
    Initial -> Stray [label="MLogRec",];
    GetInfo -> GetLog [label="GotInfo",];
    Start -> GetInfo [label="MakePrimary",lhead=cluster2,];
    Reset -> Start [label="ActMap",lhead=cluster1,];
    Start -> Reset [label="AdvMap",ltail=cluster1,];
    GetInfo -> Reset [label="AdvMap",ltail=cluster3,];
    WaitActingChange -> Reset [label="AdvMap",];
    Start -> Stray [label="MakeStray",];
    Initial -> Crashed [label="boost::statechart::event_base",];
    Reset -> Crashed [label="boost::statechart::event_base",];
    Start -> Crashed [label="boost::statechart::event_base",ltail=cluster1,];
    Initial -> Start [label="Initialize",lhead=cluster1,];
    Initial -> Stray [label="MInfoRec",];
    GetInfo -> Incomplete [label="IsIncomplete",ltail=cluster2,];
    GetLog -> GetMissing [label="GotLog",];
}

生成图片

把上面内容复制到peering.dot文件中 #sudo apt-get install graphviz #dot -Tsvg peering.dot -o peering.svg

打开peering.svg图片,就可以看到peering的状态机了。

peering

ceph的CRUSH数据分布算法介绍

CRUSH是ceph的一个模块,主要解决可控、可扩展、去中心化的数据副本分布问题。

1 摘要

随着大规模分布式存储系统(PB级的数据和成百上千台存储设备)的出现。这些系统必须平衡的分布数据和负载(提高资源利用率),最大化系统的性能,并要处理系统的扩展和硬件失效。ceph设计了CRUSH(一个可扩展的伪随机数据分布算法),用在分布式对象存储系统上,可以有效映射数据对象到存储设备上(不需要中心设备)。因为大型系统的结构式动态变化的,CRUSH能够处理存储设备的添加和移除,并最小化由于存储设备的的添加和移动而导致的数据迁移。

2 简介

对象存储设备(object-based storage devices)管理磁盘数据块的分配,并提供对象的读写接口。在一些对象存储系统中,每个文件的数据被分成多个对象,这些对象分布在整个存储集群中。对象存储系统简化了数据层(把数据块列表换成对象列表,并把低级的数据块分配问题交个各个设备)。对象存储系统的基本问题是如何分布数据到上千个存储设备上。

一个robust解决方案是把数据随机分布到存储设备上,这个方法能够保证负载均衡,保证新旧数据混合在一起。但是简单HASH分布不能有效处理设备数量的变化,导致大量数据迁移。ceph开发了CRUSH(Controoled Replication Under Scalable Hashing),一种伪随机数据分布算法,它能够在层级结构的存储集群中有效的分布对象的副本。CRUSH实现了一种伪随机(确定性)的函数,它的参数是object id或object group id,并返回一组存储设备(用于保存object副本)。CRUSH需要cluster map(描述存储集群的层级结构)、和副本分布策略(rule)。

CRUSH有两个关键优点:

  • 任何组件都可以独立计算出每个object所在的位置(去中心化)。
  • 只需要很少的元数据(cluster map),只要当删除添加设备时,这些元数据才需要改变。

3 CRUSH算法

CRUSH算法通过每个设备的权重来计算数据对象的分布。对象分布是由cluster map和data distribution policy决定的。cluster map描述了可用存储资源和层级结构(比如有多少个机架,每个机架上有多少个服务器,每个服务器上有多少个磁盘)。data distribution policy由placement rules组成。rule决定了每个数据对象有多少个副本,这些副本存储的限制条件(比如3个副本放在不同的机架中)。

CRUSH算出x到一组OSD集合(OSD是对象存储设备):

(osd0, osd1, osd2 … osdn) = CRUSH(x)

CRUSH利用多参数HASH函数,HASH函数中的参数包括x,使得从x到OSD集合是确定性的和独立的。CRUSH只使用了cluster map、placement rules、x。CRUSH是伪随机算法,相似输入的结果之间没有相关性。

3.1 层级的Cluster map

Cluster map由device和bucket组成,它们都有id和权重值。Bucket可以包含任意数量item。item可以都是的devices或者都是buckets。管理员控制存储设备的权重。权重和存储设备的容量有关。Bucket的权重被定义为它所包含所有item的权重之和。CRUSH基于4种不同的bucket type,每种有不同的选择算法。

3.2 副本分布

副本在存储设备上的分布影响数据的安全。cluster map反应了存储系统的物理结构。CRUSH placement policies决定把对象副本分布在不同的区域(某个区域发生故障时并不会影响其他区域)。每个rule包含一系列操作(用在层级结构上)。

这些操作包括:

  • tack(a) :选择一个item,一般是bucket,并返回bucket所包含的所有item。这些item是后续操作的参数,这些item组成向量i。
  • select(n, t):迭代操作每个item(向量i中的item),对于每个item(向量i中的item)向下遍历(遍历这个item所包含的item),都返回n个不同的item(type为t的item),并把这些item都放到向量i中。select函数会调用c(r, x)函数,这个函数会在每个bucket中伪随机选择一个item。
  • emit:把向量i放到result中。

存储设备有一个确定的类型。每个bucket都有type属性值,用于区分不同的bucket类型(比如”row”、”rack”、”host”等,type可以自定义)。rules可以包含多个take和emit语句块,这样就允许从不同的存储池中选择副本的storage target。

3.3 冲突、故障、超载

select(n, t)操作会循环选择第 r=1,…,n 个副本,r作为选择参数。在这个过程中,假如选择到的item遇到三种情况(冲突,故障,超载)时,CRUSH会拒绝选择这个item,并使用r'(r’和r、出错次数、firstn参数有关)作为选择参数重新选择item。

  • 冲突:这个item已经在向量i中,已被选择。
  • 故障:设备发生故障,不能被选择。
  • 超载:设备使用容量超过警戒线,没有剩余空间保存数据对象。

故障设备和超载设备会在cluster map上标记(还留在系统中),这样避免了不必要的数据迁移。

 3.4 MAP改变和数据迁移

当添加移除存储设备,或有存储设备发生故障时(cluster map发生改变时),存储系统中的数据会发生迁移。好的数据分布算法可以最小化数据迁移大小。

3.5 Bucket的类型

CRUSH映射算法解决了效率和扩展性这两个矛盾的目标。而且当存储集群发生变化时,可以最小化数据迁移,并重新恢复平衡分布。CRUSH定义了四种具有不同算法的的buckets。每种bucket基于不同的数据结构,并有不同的c(r,x)伪随机选择函数。

不同的bucket有不同的性能和特性:

  • Uniform Buckets:适用于具有相同权重的item,而且bucket很少添加删除item。它的查找速度是最快的。
  • List Buckets:它的结构是链表结构,所包含的item可以具有任意的权重。CRUSH从表头开始查找副本的位置,它先得到表头item的权重Wh、剩余链表中所有item的权重之和Ws,然后根据hash(x, r, item)得到一个[0~1]的值v,假如这个值v在[0~Wh/Ws)之中,则副本在表头item中,并返回表头item的id。否者继续遍历剩余的链表。
  • Tree Buckets:链表的查找复杂度是O(n),决策树的查找复杂度是O(log n)。item是决策树的叶子节点,决策树中的其他节点知道它左右子树的权重,节点的权重等于左右子树的权重之和。CRUSH从root节点开始查找副本的位置,它先得到节点的左子树的权重Wl,得到节点的权重Wn,然后根据hash(x, r, node_id)得到一个[0~1]的值v,假如这个值v在[0~Wl/Wn)中,则副本在左子树中,否者在右子树中。继续遍历节点,直到到达叶子节点。Tree Bucket的关键是当添加删除叶子节点时,决策树中的其他节点的node_id不变。决策树中节点的node_id的标识是根据对二叉树的中序遍历来决定的(node_id不等于item的id,也不等于节点的权重)。
  • Straw Buckets:这种类型让bucket所包含的所有item公平的竞争(不像list和tree一样需要遍历)。这种算法就像抽签一样,所有的item都有机会被抽中(只有最长的签才能被抽中)。每个签的长度是由length = f(Wi)*hash(x, r, i) 决定的,f(Wi)和item的权重有关,i是item的id号。c(r, x) = MAXi(f(Wi) * hash(x, r, i))。

Tree Buckets

图1 Tree Buckets的结构

bucket比较

图2 不同Bucket的算法复杂度和数据迁移大小

4 结论

要根据存储系统中设备的情况和预期扩展计划来选择不同的bucket。