2011年6月13日

RAID 1

RAID 1就是镜像。也就是将相同的数据同时写到两个,甚至多个盘上。由于是完全的镜像,RAID1的可靠性十分高。但是RAID1的空间利用率很低。如果两个300G(总共600G)的硬盘组成RAID1, 实际用户可用空间也只有300G。

由于相同的数据分布在多个磁盘中,读取数据时,理论上可以从多个磁盘同时读取,所以RAID1是可以大大提高读取性能的。但是其前提是RAID控制器可以高效合理分配不同的读取请求到不同的磁盘。因此有些RAID1的实现并没有实现这样的并行读取,而是只从一个磁盘中读取数据。一些旧的RAID1控制器会从多个磁盘读取同样的数据并在提交给主机前比较这些数据以检测是否有错误发生。但是现代的磁盘自身的查错和纠错功能已经比较强,所以这类实现在现在来看不是很有必要了。

理论上,RAID1的写性能应该和单个磁盘的写性能差不多。

参考资料:

http://en.wikipedia.org/wiki/Standard_RAID_levels

posted @ 2011-06-13 15:23 Charlie_Wang 阅读(38) 评论(0) 编辑

2011年6月10日

JBOD & RAID0

摘要: RAID是独立磁盘冗余阵列(Redundant Array of Independent Disks)的简写,简称磁盘阵列。其基本思想就是把几个相对便宜的磁盘通过特定方式组合起来,使其在容量、可靠性等性能上达到甚至超过一个价格昂贵、容量巨大、可靠性高的磁盘。根据磁盘组合方式的不同可以分为RAID0 RAID1 RAID5 RAID6等。这里简单介绍一下常见的RAID类型中的JBOD和RAID0。JBODJBOD(Just a bunch of disk)严格上来说不是一种RAID,因为它只是简单将多个磁盘合并成一个大的逻辑盘,并没有任何的数据冗余。数据的存放机制就是从第一块磁盘开始依序向后存储阅读全文

posted @ 2011-06-10 13:28 Charlie_Wang 阅读(287) 评论(0) 编辑

2010年11月9日

Utilization Law 和 Little's Law

在学习磁盘相关的队列理论的时候学时常会提到两个定理Utilization Law和Little's Law:

 

Little's Law:

 

Number of request in the system = arrival rate * average response time

这一个定理可以被用来计算系统average response time,就是:

average response time = Number of request in the system/arrival rate

实际应用中可以用IO的并发线程数取代Number of request in the system, 用IOPS取代arrival rate来计算average response time。

 

Utilization Law

 

Utilization = throughtput X mean service time,

也就是:

系统的使用率 = 系统吞吐量 X 系统处理一个任务的平均时间

如果一个IO系统的吞吐量是 100 IOPS,其平均处理一个任务的时间是7ms,则该系统利用率就是 100 * 7/1000 = 70%.

 

之前一直不明白该公式是怎么来的,其实其推导很简单。

系统使用率  = 系统服务时间/总时间 = (完成任务数/总时间)* (系统服务时间/完成任务数) = 吞吐率 * 处理单个任务的平均时间。

posted @ 2010-11-09 23:02 Charlie_Wang 阅读(267) 评论(0) 编辑

Python: Input and Output

参考资料: http://en.wikibooks.org/wiki/Python_Programming/Input_and_output

 

Input

以下两个函数是用来直接从用户获取输入的:

input()

raw_input()

 

raw_input()

raw_input()要求用户输入字符串,并返回该字符串。

 

raw_input("what is your name?")

 

输出就是:

 

what is your name?<user input>

 

 

input()

input()会按照python的语法去分析输入,并返回相应的结果,如果用户输入:

 

[1,2,3]

input()返回的不是字符串“[1,2,3]”而是列表[1,2,3]。

 

由于input有可能允许用户通过输入python语句来执行程序,所以比较不安全。 建议使用类型转换和raw_input来获取输入。

 

x = None
while not x:
try:
        x = int(raw_input())
    except ValueError:
        print 'Invalid Number'

 

File Input

一般可以用for语句遍历一个文件。

 

f = open('test.txt', 'r')
for line in f:
    print line[0]
f.close()

也可以一次读取特定数目的字符。

 

 

c = f.read(1)

 

 

标准文件对象

 

import sys
for line in sys.stdin:
    print line,

 

除此之外,sys.argv数组保存python的命令行参数。

 

Output

一般用print输出。一般print输出一行,但是如果加上逗号,则多个print将在同一行输出。 以逗号隔开的参数中间会自动加入空格。

 

for i in range(10):
    print i,

的输出是:

 

 

0 1 2 3 4 5 6 7 8 9

 

 

如果不想print自动加入空格可以这样写:

 

print str(1)+str(2)+str(0xff)+str(0777)+str(10+5j)+str(-0.999)+str(map)+str(sys)

 

 

可以用如下方式用print输出到文件。

 

print >> f, 'Hello, world'

 

也可以用sys.stdout.write来输出。

 

import sys
write = sys.stdout.write
write('20')
write('05\n')

posted @ 2010-11-09 12:50 Charlie_Wang 阅读(196) 评论(0) 编辑

2010年11月8日

Singleton

之前去一个公司面试的时候被问到了Singleton模式,本以为Singleton是“最简单”的一个模式,于是便按照Gamma等人的《设计模式》一书写了个C++实现。结果被面试官当即指出这个实现不是现成安全的,好吧,原来是踩入陷阱里了。于是上网搜索,发现此设计模式还是很有讲究的。

实现0:全局变量和静态变量

有人会问,为啥要用这个设计模式呢?为啥不直接定义一个全局或静态变量呢,不就能保证只有一个实例的吗?对于这个问题,《设计模式》书中就有答案,书中给出了三个理由。

1. 无法保证,只有一个变量被定义。很有可能在不同的实现文件里定义了多个变量,这样就不是一个实例了。我的理解是,使用这种方式,实例的个数必须由开发人员自己掌握,如果哪个不长眼的, 比如分不清声明和定义的区别的,在维护代码的时候,一不小心多定义了一个实例,这样整个系统就会出问题了。

2. 可能没有足够的信息来初始化一个实例。如果有些类的初始化数据是在系统开始运行后才能得到的,显然无法在系统初始化的时候来初始化Singleton的实例了。

3.多个Singleton之间不能有依赖关系。这一点其实本人还不是很理解。大概的意思是如果有多个全局Singleton,而且他们互相有依赖关系,由于C++在这种情况下没有定义其初始化顺序,所以会引入错误。

4. 显而易见的就是,不管用没有,都生成了一个实例。

由于以上原因,我们不能简单的用静态或全局变量来是些Singleton的要求。

这种情况下有以下两种实现:

一种实现其实就是在类中定义一个该类的静态成员。

class Singleton

{

private:

    staitc Singleton _instance;

public:

    static Singleton &getInstance()

    {

        return _instance;

    }

};

另一种实现是使用静态方法的静态变量。

class Singleton

{

public:

    static Singleton &getInstance()

    {

        staitc Singleton instance;

        return instance;

    }

};

这种实现和第一中相比略有改进。实例只在getInstance被调用时初始化。但是在一般情况下它并非线程安全的,这和具体的C语言实现相关。

实现1: 典型实现

《设计模式》书中描述的实现是这样的。

class Singleton

{

private:

    staitc Singleton *_instance;

public:

    static Singleton &getInstance()

    {

        if(_instance == NULL)

            _instance = new Singleton();

        return _instance;

    }

};

Singleton * Singleton::_instance = NULL;

这也就是我在面试时写的代码,而这个代码的一个严重问题就是该代码不是线程安全的。如果多个线程同时进入了那个if判断,则他们会得到不同的实例。

实现2: 加锁

所以很显然的改进就是加锁:

Singleton* Singleton::instance()

{

    Lock lock; // acquire lock (params omitted for simplicity)

 if (_instance == NULL)

    {

        _instance = new Singleton;

    }

 return _instance;

} // release lock (via Lock destructor)

但是这样写对性能的影响又太大,由于竞争只在if里面发生,于是便会想要该进一下。

Singleton* Singleton::instance()

{

 if (_instance == NULL)

    {

       Lock lock; // acquire lock (params omitted for simplicity)

        _instance = new Singleton;

    }

 return _instance;

} // release lock (via Lock destructor)

然而这样是错误的,因为两个线程可能同时进入if,虽然在lock处会互斥,但是依然创建了两个实例。所以正确的做法是两次检查。

Singleton* Singleton::instance()

{

 if (_instance == NULL)

    {

       Lock lock; // acquire lock (params omitted for simplicity)

       if(_instance == NULL)

           _instance = new Singleton;

    }

 return _instance;

} // release lock (via Lock destructor)

第一次检查是为了提高性能,而第二次是为了确保不会创建两个实例。但是这个实现还有一个问题:

就是编译器优化后可能会变成如下顺序:

1. 分配地址给 _instance

2. 初始化Singleton

而一般的理解应该是先初始化Singleton再把地址赋予_instance。优化后的代码就会出现如下问题。当把一个地址分配给_instance却没有初始化Singleton时另一个线程可能返回_instance,而这个instance其实并没有被初始化,这样悲剧就发生了。

如何解决呢?请参考: http://c.chinaitlab.com/skill/798679_5.html

http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B

posted @ 2010-11-08 15:22 Charlie_Wang 阅读(79) 评论(0) 编辑

什么是IDE,ATA,SATA,SCSI和SAS硬盘

当谈到硬盘类型的时候,时常会出现IDE,ATA,SATA,SCSI和SAS这些术语。这些术语究竟是什么意思呢,这边做个简要的介绍。

 

IDE/ATA

 

IDE/ATA 是Integrated Device Electronics/Advanced Technology Attachment (IDE/ATA)的缩写。这是一种十分流行的计算机外设接口,它不但能用于连接硬盘,也广泛地用于连接CD-ROM,软盘驱动器等设备。其中IDE是指一种协议,它规定了主板上的控制器如何与连接的硬盘通信。ATA是指连接主板和外设的借口类型。

 

这种类型的接口的优点是廉价,兼容性好。缺点是速度相对较慢,比如Ultra DMA/133标准支持的带宽是133MB/s。而且缆线长度很短,一般只能用于机箱内的设备连接。

 

记得我2001年买的第一台电脑的硬盘就是IDE接口的。

 

 

 

SATA

 

SATA其实就是Serail ATA,串行的ATA。SATA设计的目的就是取代并行的ATA,第三版的SATA最高传输速度可以达到6Gb/s(大概等于715MB/s)。SATA是可热插拔的,它使用7针脚的窄连接线。

 

我2009年买的电脑就用SATA硬盘了。

 

SCSI

 

SCSI是Small Computer System Interface的缩写。是一种历史比较悠久但仍广泛使用的的外设连接标准。它除了被用于连接硬盘和磁带机以外还可以连接其它外设,如扫描仪和打印机之类的。SCSI包括了一系列标准,其使用的物理接口类型也都不尽相同。其中Ultra-640 SCSI支持640MB/s的带宽。

 

相对于IDE设备,SCSI设备一般比较贵一点,SCSI硬盘以往常常用于服务器级别的主机上。

 

SAS

 

Serial Attached SCSI。串行版本的SCSI,是SCSI的进化版本。而且SAS对SATA是兼容的,3 Gbit/s的SATA盘可以连接到SAS的接口,不过SAS的硬盘不能连接到SATA的接口上。

 

目前SAS硬盘被广泛地应用于服务器级别的主机上。

 

 

 

本文的图片来自维基百科。

posted @ 2010-11-08 15:21 Charlie_Wang 阅读(556) 评论(0) 编辑