System Notes


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

linux块设备IO栈浅析

发表于 2015-08-06 | 分类于 storage

块存储,简单来说就是使用块设备为系统提供存储服务。块存储分多种类型,有单机块存储,网络存储(如NAS,SAN等),分布式块存储(目前主流的如AWS的EBS,青云的云硬盘,阿里云的云磁盘,网易云硬盘等)。通常块存储的表现形式就是一块设备,用户看到的就是类似于sda,sdb这样的逻辑设备。本文主要介绍Linux块设备,对Linux的块设备I/O栈进行分析。

1.块设备基本概念

块设备将信息存储在固定大小的块中,每个块都有自己的地址。对操作系统而言,块设备是以字符设备的外观展现的,例如/dev/sda,虽然对这种字符设备可以按照字节为单位访问,但是实际上到块设备上却是以块为单位(最小512byte,即一个扇区),这之间的转换是由操作系统来实现的。
下面介绍几个块设备的基本概念:
1)扇区:磁盘盘片上的扇形区域,逻辑化数据,方便管理磁盘空间,是硬件设备数据传送的基本单位,一般512Byte;
2)块:块是VFS和文件系统数据传送的基本单位,必须是扇区的整数倍,格式化文件系统时,可以指定块大小(一般512,1024,2048,4096字节);
3)段:一个内存页或者内存页中的一部分,包含一些相邻磁盘扇区中的数据;磁盘的每个I/O操作就是在磁盘与一些RAM单元之间相互传一些相邻扇区的内容,大多数情况下,磁盘控制器采用DMA方式进行数据传送。如果不同的段在RAM中相应的页框是连续的并且在磁盘上相应的数据块也是相邻的,就可以在通用块层合并它们,产生更大的内存区域,这个区域称为物理段。
通常情况下,我们是通过文件系统来访问块设备,也可以直接使用裸设备,通过指定偏移和大小来读写裸设备。
常见的块存储设备就是物理磁盘,在Linux系统下,还提供基于其他块设备之上的逻辑设备,如Device Mapper,软RAID等。

阅读全文 »

Blizzard Fast, Cloud-scale Block Storage for Cloud-oblivious Applications

发表于 2015-08-06 | 分类于 paper

有些应用容许少量的数据丢失来换取高吞吐量,有些应用如数据库,邮件服务器是不容许一点数据丢失的。
posix应用使用刷盘(disk flush)来保证写的顺序,从而确保即使崩溃了仍然能够保证一致性,但是flush会有write barrier的问题,降低了并发性。
Blizzard并行地把对虚拟盘的读写发到远程disk上,有几个特性:
1)架构在CLOS网络上,全对分网络,读写每块disk都能达到全速,每个server
2)Nested striping,传统的会存在IOp convoy dilation问题,大的io会被文件系统拆分成小io,这些小io会从客户端发到一个远程disk,这些io都属于一个大的io操作,网络抖动,客户端服务器的调度异常都会使得请求间的间隔增加,而Bllizard使用Nested striping来解决这个问题,提高并发性,减少磁盘的热点。其实就是说一个大的用户io会拆分成多个小的io,但是这些io分别到达远程disk,如果这些请求到达远程disk时间间隔很短,远程disk就可以进行合并,然后一次寻道就可以读写,但是如果网络抖动,客户端服务器的调度异常都会使得请求间的间隔增加,这样就会造成远程disk要多次io,降低了性能。
3)Fast flushes with prefix write commits(异步刷数据),当收到flush请求时,立即返回给客户端,然后在后台异步地执行flush。即使客户端或者虚拟卷崩溃,该盘仍然能够恢复到一致的状态,不同flush epoch的写操作不会相互混乱,不过某个epoch之后的数据会丢失。使用异步写来提供性能,不过会有数据丢失的可能。

阅读全文 »

petal:Distributed Virtual Disks

发表于 2015-08-06 | 分类于 paper

花瓣系统是一个分布式虚拟盘,具有如下特点:

  • 单盘支持2^64 byte 的存储空间;
  • 无单点
  • 在线扩展(新增server和disk)
  • 按需分配空间
  • load balance
  • 支持备份和恢复,快照。

    系统概貌

    petal-arch
    petal使用rpc调用访问虚拟盘,全局的状态在每台server里都有记录,通过paxos协议确保一致,clients保存少量的映射信息来决定请求分发到哪台服务器,如果这样请求失败,服务器会返回error,然后client更新映射,并且重试请求。
阅读全文 »

tgt程序框架

发表于 2014-08-23 | 分类于 storage , iscsi

tgt是用户态实现的iscsi target,而iet(iscsi enterprise target)是在内核态实现的target,tgt相比于iet来说,因为其用户态实现,方便调试,新加入一些功能等,不过性能相比iet来说要稍差一点。下面就介绍一下tgt的程序框架(略过iscsi协议解析处理部分),以便于整体把握tgt的代码,方便后续的一些修改。

1.整体框架

这里借用tgt官网给出的一张图。
tgt-arch
tgt中命令的操作,与initiator端的通信都是通过epoll来实现的,下面分别对这两部分进行说明。

阅读全文 »

bcache浅析

发表于 2014-06-20 | 分类于 storage

1.简介

bcache是linux内核块设备层cache,类似于flashcache使用ssd作为hdd的缓存方案,相比于flashcache,bcache更加灵活,支持ssd作为多块hdd的共享缓存,并且还支持多块ssd(还未完善),能够在运行中动态增加,删除缓存设备和后端设备。从3.10开始,bcache进入内核主线。bcache支持writeback、writethrough、writearoud三种策略,默认是wriththrough,可以动态修改,缓存替换方式支持lru、fifo和random三种。下面从几个方面介绍bcache的实现机制。

2.总体结构

bcache的整体结构如图所示。
arch
bcache中是以cache set来划分不同存储集合,一个cache set中包含一个或多个缓存设备(一般是ssd),一个或多个后端设备(一般是hdd)。bcache对外输出给用户使用的是/dev/bcache这种设备,每个bcache设备都与一个后端物理盘一一对应。用户对不同bcache设备的io会缓存在ssd中,刷脏数据的时候就会写到各自对应的后端设备上。因此,bcache扩容很容易,只要注册一个新的物理设备即可。

阅读全文 »

bcache使用

发表于 2014-05-29 | 分类于 storage

1.编译安装

1
# git clone http://evilpiepirate.org/git/bcache-tools.git

安装前需要两个依赖包pkg-config和libblkid-dev

1
# apt-get install pkg-config libblkid-dev

然后编译

1
2
3
4
5
6
7
8
9
10
11
12
13
# make
cc -O2 -Wall -g `pkg-config --cflags uuid blkid` make-bcache.c bcache.o `pkg-config --libs uuid blkid` -o make-bcache
cc -O2 -Wall -g `pkg-config --cflags uuid blkid` probe-bcache.c `pkg-config --libs uuid blkid` -o probe-bcache
cc -O2 -Wall -g -std=gnu99 bcache-super-show.c bcache.o `pkg-config --libs uuid` -o bcache-super-show
# make install
install -m0755 make-bcache bcache-super-show /usr/sbin/
install -m0755 probe-bcache bcache-register /lib/udev/
install -m0644 69-bcache.rules /lib/udev/rules.d/
install -T -m0755 initramfs/hook /usr/share/initramfs-tools/hooks/bcache
if [ -d /lib/dracut/modules.d ]; \
then install -D -m0755 dracut/module-setup.sh /lib/dracut/modules.d/90bcache/module-setup.sh; \
fi
install -m0644 -- *.8 /usr/share/man/man8/

阅读全文 »

direct IO中io合并的奇怪现象分析

发表于 2014-05-19 | 分类于 storage

在上一篇《块设备内核参数max_segments和max_sectors_kb解析》介绍了max_sectors_kb这个参数对device mapper设备和软raid设备的影响,实际在测试时,发现另外一个奇怪的现象:一块物理盘,在这个盘上创建一个device mapper设备,然后对这个设备使用direct IO进行随机大块写或者顺序大块写(随机读和顺序读没这个问题),块大小要大于dm设备的max_sectors_kb,但是小于dm底层设备(这里是物理磁盘)的max_sectors_kb,测试结果发现在3.2内核里落到物理盘上的io并没有合并,但是在3.10内核下落到物理盘上的io确是合并了(合并后的大小为用户发的io块大小)。具体现象下面以例子进行说明。

1.不同内核下的表现

这里选取3.2.57内核和3.10.11内核作为对比。

1.1 3.2.57内核下测试

物理盘sdg,在其上创建的10G的device mapper设备dmtest1,对应的设备为dm-71
1)默认的参数设置

1
2
3
4
5
6
7
8
# cat /sys/block/sdg/queue/max_sectors_kb
512
# cat /sys/block/sdg/queue/max_segments
128
# cat /sys/block/dm-71/queue/max_sectors_kb
512
# cat /sys/block/dm-71/queue/max_segments
128

阅读全文 »

块设备内核参数max_segments和max_sectors_kb解析

发表于 2014-05-12 | 分类于 storage

在DMA设备不采用S/G(分散/聚集)模式的情况下,必须保证缓冲区是物理上连续的,linux内核有两个函数用来分配连续的内存:kmalloc()和get_free_pages()。这两个函数都有分配连续内存的最大值,kmalloc以分配字节为单位,最大约为64KB,get_free_pages()以分配页为单位,最大能分配2^order数目的页

使用DMA缓冲区的主要问题是:当大于一页时,它们必须占据连接的物理页,这是因为设备使用ISA或者PCI系统总线传输数据,而这两种方式使用的都是物理地址

linux块设备在处理io时会受到一些参数(设备的queue limits参数,以下简称limits参数)的影响,比如一个请求中允许的最大扇区数,最大segment数等。这些参数可以在/sys/block//queue/下查看,块设备在初始化时会设置默认值。这里主要分析max_segments和max_sectors_kb。

1.基本概念

1.1段的概念

首先就需要了解一下什么是段(segment)。
一个段就是一个内存页或者内存页的一部分,它们包含磁盘上物理相邻的数据块。
磁盘的每个io操作就是磁盘与一些RAM单元之间相互传送一些相邻扇区的内容。大多数情况下,磁盘控制器采用DMA方式传送数据,块设备驱动程序只要向磁盘控制器发送适当的命令就可以触发一次数据传送,一旦完成数据传送,磁盘控制器就会发出一个中断通知块设备驱动程序。
DMA方式传送的是磁盘上相邻的扇区数据,虽然也允许传送不相邻的扇区数据,但是这个比较低效,因为磁头移动慢。
老的磁盘控制器仅仅支持“简单”的DMA方式:磁盘必须与RAM中连续的内存单元传送数据。但是新的磁盘控制器支持分散聚集(scatter-gather)DMA方式,磁盘可以与一些非连续的内存区域相互传送数据。
为了支持分散聚集DMA方式,块设备驱动程序必须能够处理称为段的数据存储单元,一次分散聚集DMA可以传送几个段。
如果不同的段在RAM中相应的页框正好是连续的并且在磁盘上相应的数据也是相邻的,那么通用块层就可以进行合并,这种合并方式产生的更大的内存区域就称为物理段。

阅读全文 »

flashcachegroup浅析

发表于 2014-05-10 | 分类于 storage

简介

flashcachegroup能够使用一块或多块ssd来缓存一组hdd硬盘,硬盘组能够动态增加删除硬盘,ssd缓存能够整个硬盘组而不仅仅是一块硬盘。
其结构如下,参考官方说明https://github.com/lihuiba/flashcachegroup,这里借用介绍里的结构图.
fcg

1.安装使用flashcachegroup

1) 安装flashcache

首先需要安装flashcache,这里使用源码安装

1
2
#git clone https://github.com/facebook/flashcache.git
#cd flashcache

切换到稳定版stable_v3.1.1

1
#git checkout stable_v3.1.1

flashcache编译需要依赖KERNE_TREE

1
2
#make KERNEL_TREE=/usr/src/linux-headers-3.10.11-openstack-amd64/
#make install

加载flashcache模块

1
2
#modprobe flashcache
#lsmod | grep flashcache

阅读全文 »

systemtap分析软raid io拆分问题

发表于 2014-05-01 | 分类于 storage

使用linux 软raid1的时候遇到个奇怪的问题,就是当使用逻辑设备(比如device mapper设备)来创建软raid设备时,对该软raid的大块读写,都会被拆分为4k块大小的io;而使用裸设备(如sdb,sdc,vdb,vdc这种设备)来创建软raid设备时,对该软raid的大块读写就不会有io拆分问题。下面以例子说明这个现象(以raid1,写操作为例)。

情形一:使用裸设备创建软raid1

1
2
3
4
5
# mdadm –create /dev/md/md_test1 –run –force –metadata=0.9 –assume-clean –level=1 –raid-devices=2 /dev/vdb /dev/vdc
# cat /proc/mdstat
Personalities : [raid1]
md127 : active (auto-read-only) raid1 vdc[1] vdb[0]
20971456 blocks [2/2] [UU]

使用fio对该raid1进行随机写操作(顺序写也是一样的),块大小为64KB,fio的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
[global]
rw=randwrite
direct=1
numjobs=1
ioengine=sync
bsrange=64k-64k
rate_iops=60
time_based
runtime=120
group_reporting
[disk00]
filename=/dev/md127

fio写io过程中,使用iostat查看设备的io

1
#iostat -mx 2 md127 vdb vdc

con1-iostat
可以看到avgrq-sz为128,单位是扇区,也就是64KB,说明io并没有进行拆分。

阅读全文 »
1234
Wu Dong

Wu Dong

Diary Notebook

32 日志
6 分类
27 标签
RSS
© 2017 Wu Dong
由 Hexo 强力驱动
主题 - NexT.Mist