古黑币3 个
成长值6451 点
金币157 个
精华贴3 个
今生相逢便是缘分,何苦去怨恨,何苦去仇视。
我是一个非常精密的存储介质,虽然具有坚固冰冷的外表,让人有种冷酷到底的感觉,但是你们却不知道我的内心是非常脆弱的~
* J$ m+ k. H; B# ?+ }( q
" F* C: h' ]5 o; Y9 z& G& z( Q 我知道CPU和内存是计算机的核心,毕竟所有的运算最后都得通过他们俩来完成,CPU从内存里要取一条指令,做计算,然后再写回内存,如此周而复始。
9 A& U' `2 ]3 e& f
# j# c+ l! W) ] 但是这俩货却瞧不起我,说这是什么年代了,还在用机械式操作,读写数据的时候,还得一个磁头在多个盘片上滑来滑去,找来找去,速度慢的要死。, z" E# G3 O# e3 j9 p7 J6 D) V5 d
$ B7 {) R- g& [. ~# ?1 {% x+ h# i" Z5 v" F( q( h) a
内存说:“CPU比我快100倍,比你快100万倍,整个系统的速度都被你给拖慢了。”#j318:
1 g3 Y) Q- m7 y; D O* `9 `* r/ n# t" W1 D
他俩还嘲笑我很娇气,得真空、密闭、不能有浮尘、运行时不能震动,一动就坏了。但这俩二货总是会忘记他俩的最大问题,所以我只用一句就把他们俩给噎死:你们俩断电了怎么办?, ^% d+ c% s/ R' T9 J9 X
" Y) ] ]1 ^- p( [ 还有我的容量都是按TB,甚至PB来算的,就你们俩那点容量,还笑我?还有,没有我来存储程序,你们从哪儿得到程序,难道要像牵牛星(如下图)一样,手工拨动一排开关来输入程序吗?
" n0 N; t+ j( f0 |1 E+ o# R- `" f) T' ]
. t5 [# Z& Q( r. L, ?' [ 其实我也很纳闷,为什么你们人类造不出来一个能够断电存储的,大容量的,访问速度快的,当然还要便宜的硬盘来,你们不都上天了吗?要登陆火星了吗?这些基础的材料怎么还无法突破?#j331:
" i4 y D7 }. { R, }- Z- a
; T8 Z0 c. X4 K! d- V 我憧憬着这么一天的来临,如果能制造出来了,CPU就可以直接访问硬盘了,内存就一边凉快去吧。
5 \3 g% y+ w+ v. |% _
! G k& a* U9 C2 H3 j6 M4 r4 n 在制造出来之前,你们必须得容忍CPU-内存-硬盘之间的速度不匹配,并且想出办法来解决这种速度的不匹配,比如用缓存、直接内存访问、多进程/线程切换等等方法。
- w3 i1 Y$ C, ~2 k1 U
3 Y" e2 I, V4 v* |$ Z我 的 内 部 结 构
% A7 _& ~0 f; T' l/ e8 o9 I# Y5 x8 z5 ?7 s$ Q, [% y: R0 N5 C" ]* G
5 T4 J) x \! k9 N
看到没有,我有很多个盘片像串糖葫芦一样被串在一个主轴上,主轴带着他们疯狂的旋转。
1 r2 p, ^' T* K+ _
3 Q0 ?) V6 A; l( |0 V: C 每个盘片都有很多一圈一圈的磁道,每个磁道又分为一个一个的扇区。
6 k( ~$ U8 z- E+ i3 R' H* M- ~) ^, g y. o* S
多个盘片上的同一位置的磁道组成了一个柱面(需要发挥一下你的想象力)! _( z; F# P$ Z7 o% p; ? u
8 q0 A$ S) r m0 i 最后每个盘片上都有可以读写数据的磁头。. _9 e/ _ ^$ k; p
( n Z4 ^+ f3 p& y6 F. q
所以,如果你想访问我的数据,可以说:把0柱面,0磁头,1扇区的数据给我拿来。( L, G. n: `$ r4 s6 J h
- F# a- R5 ~9 ]+ f( b6 R 我就把磁头挪到您指定的柱面,对每个磁盘来讲其实就是指定的磁道,所以这叫“寻道时间”
( d7 A2 E2 R1 _5 ~7 v" H4 i
+ C- k: j% q: H& i: J2 O 然后再旋转磁盘,让磁头指向您指定的扇区,这才能开始读取数据,这叫“旋转时间”,转速快的硬盘能更快的旋转到特定扇区,所以性能会更好些。( O" @: s1 R, e
5 w7 P* Q/ h1 c( f6 N' f5 X什 么 是 文 件
. O! c) W0 V7 e5 E
2 Y* \0 P) B& u [& t6 Z& Q; D 当然,对于绝大部分人来说,都不想去了解什么柱面,磁头,扇区这些非人的术语,所以我为懒人们专门提供了一个叫做逻辑块的方式,你看到磁盘就是有一个个“块”组成的,编号为1,2,3,..n。( ^# e3 w( U1 `0 v
/ J& V* {$ P0 H' r6 i5 H 想取哪一块就取哪一块,比如你说:把第1024号的“块"的数据给我取过来,我在内部就把1024转化成柱面,磁头,扇区,按照上面说的方法寻道,旋转,读取数据。 Z, |! g) w/ `, \
5 v9 L/ e0 t4 t8 _% G 但是这还远远不够,比方说你想写个文档,输入了很多字和图片,最后想存到我这个硬盘上,你该怎么操作?#j321:( r5 V( E0 n- d; _6 G5 }# c* G
" R0 S! e; }' i0 M1 J" {
一种方法是这样的:
; S3 q& f2 S/ C* Z9 d 7 u# N3 q6 S3 f* T
你:硬盘,给我找20个空闲的磁盘块,我想存我的文档。
2 R' l8 v. Y# ^
; c( Y7 t z# a& U" \! I 我:空闲的磁盘块编号是1024,2048,2049,3000,......
; y& ]( D7 [: g1 h+ R; K6 W
+ @' @" u, O V. I; h 你:把这些文字和图片存到这些磁盘块上。
1 F* d* _2 r- |9 A+ z3 i6 Z) ^7 j7 v5 R( x5 q; Z; v$ U
我:好的,存完了,你得记住这些块啊,这样下次才能读取。' ?) ^4 S& ~% T c F* N7 h- R9 H
- x5 D5 e0 ]3 }. ~2 {
你:拿一支笔把这些磁盘块编号都记到本子上。, Y4 B g O: D
- Q7 w5 |; w \% W9 K
过了几天......
- x* @ c. v' a# O( x+ U7 [( V% j9 o" [& }5 e* v" Q* w
你:硬盘,把1024,2048,2049,3000这些数据给我取出来,我要编辑。
4 g- R; f5 ?" q8 l8 U6 d1 o7 B+ L) A1 J6 @- c
我:好的,这是你的数据。: g8 w! g" z& Q2 m/ t4 O; k/ f0 X
Y; z4 F: V2 r$ \* y
没有人喜欢这种方式,太折磨人了!. ` v, D8 \7 I
所以你们更喜欢这么做:" ~9 ?, m3 q+ z% M2 {
& {6 y1 x* x: a2 P$ _9 {7 O 打开word->新建一个文件->输入文字和图片->保存到:D盘\我的文档 目录下。4 Y% y- A; q3 r8 j+ i
' U$ m( X& q2 v3 U' v8 b2 E9 R 这个所谓的“文件”和“目录”就是我的杰作啊,你再也不需要和烦人的磁盘块打交道,只需要记住你的文件名和路径,一切工作交由我和操作系统老大来搞定。
3 V" P( \; S- q! y6 H# v0 v* B( y, C* R2 C7 y
我和老大商量好了,文件对人类来说是最小存储单位,你想存任何东西,无论多么小,非得建个文件不可。
" |; d4 Y) L* y( I) k0 ^* v9 L6 Y2 j, {1 |/ G9 c3 G* m! a
此外为了让这个世界整洁有序,多个文件可以放到一个目录(其实也是个特殊的文件)里,目录之上还可以有目录,形成一个树的结构。
0 B+ P0 c3 n- }/ K" c, A6 ]8 v( ?# w- B9 |4 L
文件这个东西是个伟大的发明,我估计你们还得再用100年。#j346:9 I( @' ~9 K) E2 n4 H: b n
6 A& f4 i4 {" j5 x7 K' m M* D文 件 的 存 放
# d, d9 Y+ Y y% s
# B; B) N0 S4 U) \9 x6 \ 我日常的主要工作就是对目录和文件做操作,当然需要操作系统老大的配合,好吧,其实是老大在主导。
" r- W% c4 F4 J. }: o7 \; L) m8 }0 n+ f& ~- b+ P: z
这其中最重要的一个问题怎么去记录各个文件都用到哪些磁盘块?8 V9 n. k0 g9 t j
% ~3 w: v. c# [7 _& A; v; m! M9 k5 I' B
内存给我支了一招:你可以采用连续记录的方式啊,就像这样。
+ a H: I" j4 G7 m) X
0 Y" g, w! {2 J! w
! k4 H- w5 [1 ?+ Q
" S% Z7 b M4 p3 Q! W 文件1占据磁盘块1-3- f g+ |+ T$ x6 E5 l/ c! F8 {
文件2占据磁盘块8-123 a( Z0 ]- c3 z1 D
文件3占据磁盘块15-20
5 i, u: L1 E- B* Q9 s
f' ?2 R4 p- T 内存说:这种方法在随机访问文件是效率极好,因为你只要知道了开头和长度,就像数组一样可以随便访问,就像CPU访问我一样,只要给出地址,立刻就能定位到指定的位置。' t: Y; @, e. i4 @+ ^+ l
0 \2 t& u, e. N3 ]& V1 w& u+ f 我仔细想了想,内存出的是一个损招,比如说内存磁盘块4-7,以及13-14怎么没用?
' ?) |4 T$ _8 @9 {7 F6 I- |* g2 B$ K% j: J
那是因为之前那里也有文件,后来被删除了,留下了空洞,如果之后没有大小合适的文件过来,他们就永远空在那里了。9 @" U K8 r- J: d2 J
4 X& p1 y. V. T4 i2 s: _ 对我来说这是严重的浪费,这是我不能容忍的。2 f$ U! G' T* t' D9 L& Q
* c: G6 w; d7 V# |1 W7 m+ G% A! `
我说:“小样你以为我看不出来啊,你不就是嫉妒我容量大,让我浪费一点嘛”!$ F* y# ]) y+ { D
8 Y( M0 l1 N6 y! N! c1 {
内存坏笑了一下又说:不喜欢也没关系嘛,试试采用链式啊:
% T, w! {5 f( }# }/ H2 d- H! _. }: F" p1 \7 W, i
0 \$ T- q& i% h# s% D: e# `: f
$ m2 |$ h& o+ @! D; ^, i6 N; a
这个文件从第一块磁盘开始,形成一个链1->9->18->8->3,每一块空闲的磁盘都会得到充分的利用,效率非常高。
" I+ H. u$ r& M4 m; ] `6 T( x O/ V, {" K$ i5 @
我心想:这些码农说的数据结构和算法还真是有用啊,这里也用上链表了。可是这种方式随机的访问效果太差,每次都得从第一块开始,沿着绳子往后找,太痛苦了。
+ i5 I# D2 j2 V9 e8 m0 \# n- W) }
现在内存已经嘲笑我慢了,用这种很慢的办法,还不得笑死我?操作系统老大说:“别听内存在那里BB了,用索引式!”
8 G1 X8 c( q& O# ~% p" i7 n! n! q5 F& O4 W8 w& V$ \0 t
8 L1 K- d z3 n/ s
; c B7 R' g4 f2 }
例如第16号磁盘块专门用来存放文件属性以及该文件所使用的磁盘块。* o0 A# X! V, @$ K, C7 @+ N: \1 `9 x
: s$ d) Z7 X5 n8 m
老大把这个磁盘块叫做inode,通过它可以轻松的找到这个文件所使用的所有磁盘块,无论是顺序访问还是随机访问都很快。, k) [# p7 b0 c C, Z
; b4 S4 ^2 U1 S5 r# \% N
唯一的缺点是得用额外的磁盘块单独存放inode。
- H/ ?. @& {0 t3 q& Q* b! p' B) K9 c2 |0 i0 e+ B
我觉得挺好,没有十全十美的东西,折中达到平衡最重要!就是它了!#j325:2 c! z: f% v( w6 U, h6 w1 j" c
; x* ^+ N; ~% h1 [
我问老大:每个文件都需要有个inode来描述,每个目录是不是也需要一个?+ y5 q4 H; r5 M( `
9 C$ Z0 j& H+ h3 G1 v5 } ”这是自然,和文件一样,每个目录也是一个inode,其中有目录的属性,还有存放这个目录内容的磁盘块号,在磁盘块中才真正的存放着目录下的内容“。 S; O8 n$ Q9 G( K
, H4 X3 n% |5 C: t) k: I& C- p) m$ u8 U: Z1 c, @! ~
0 c% s( v- i8 w# b “举个例子来说吧:有人要读取/tmp/test.log这个文件,查找次序是这样的:根目录inode->根目录磁盘块->tmp目录inode->tmp目录磁盘块->test.log的inode->读取磁盘块”
( d0 E" P, m2 p6 F: [1 @" n/ Y) R1 Z. R- ?1 t, A# f6 D) g
; j( A+ {8 |! Z! c) t& V0 K( K
7 Y8 ~7 r( [5 W; o6 T5 V1 ] 内存说:“卧槽!这也太绕了吧,比CPU访问我的数据麻烦多了,硬盘,你要小心点,这要是操作不当的很容易出乱子的。”#j340:
7 z) U7 }/ S6 C
5 Q9 }: j+ c, z1 J; c 我心想内存这次没坑我,他提醒的对,这操作确实有点复杂,读数据的时候还行,如果是修改,尤其是删除就很容易出事,例如想删除上面的文件/tmp/test.log,需要这些步骤:& b6 E5 e" w& H$ g2 }
. S% U5 f7 `, j0 c
(1)在目录中删除文件
, t( P- K& u, b2 u8 T7 @9 d6 d1 | (2)释放inode到空闲的节点池,这样可以复用- v# k Y( x4 [# P4 x
(3)将磁盘块释放到空闲的磁盘块池
" [2 x! n8 L/ Q+ S' a. \; x
0 k# K( b/ [6 N 在操作某一步的时候出现系统崩溃,那我这些个目录和文件就凌乱了,可能会出现空间无法释放的情况。
' ^" S! b0 W7 o; g# s5 a
8 |& u/ h6 t3 l9 _/ T 系统老大说:“这确实比较烦,不过也能解决,听说过数据库是怎么办的吗:记录日志!”
2 O1 j7 ?0 g0 n- J% S4 @0 y3 _ U" e. w K
”就是把要做的事记录下来?“ B# d% b7 ?( D0 r$ B1 ~" c0 C$ D
! }$ L' M9 r" \3 p6 \) F
“是的,在做操作之前,记录要做的事情,形成日志,把他们成功写入磁盘以后再正式动手操作,等到所有步骤都搞完,才可以擦除日志项。你想想,如果执行到某一步崩溃,系统重启时检查日志项,就知道哪些没做,哪些已经做了,对于没做的日志,重新来一遍就是了”。4 p1 a9 B& T, u2 }2 t( @$ m5 k
- E! m2 Z! x, L$ u% K
其实说的很轻松,实施起来还是挺难的,重新执行就意味着那些操作一定是可以重复执行,并且不会带来破坏才行。
* T( Y. w" ], G3 {
2 i& r; Q, Q& X0 {8 A0 h$ t管 理 空 闲 块 9 N+ b- {" W8 m
9 G' E: i- m' F7 {, `; V% c% q2 Z 目录和文件的存储问题解决了,接下来我需要一个大管家,把那些没有使用的、空白的、数量上亿的磁盘块给管理起来,只有这样,新的文件来的时候,才能分配空间存储。0 W: z* l" L) r
* N+ [' L H! X- |4 B" C
操作系统老大给我推荐了两位,第一位主张是链式大法好,无非就是把空闲磁盘块组成一个链表(又是链表!),但是我心里盘算了一下:如果磁盘块号是32位的,每个块都得花费我32位的空间,如果我有5亿个空闲块,那仅仅为了记录他们就要占用接近2G的磁盘空间!这浪费可是有点大啊。
* c0 r) b" y" ?7 d0 c. \0 x7 D/ |. d% E
还有一位主张位图法,这个方法更简单,对每个磁盘块,如果已经被使用,那就标记为1,没被使用就是0。这样整个磁盘块就形成了一个由0和1组成的一个大位图。
! G" W# E. ^- y9 {; R
# q0 z& \% v1 i* J) W6 q
% o. R3 F5 g, I3 T. F. S4 g' W6 K6 D
由于每个磁盘块只用一个位来表示,非常节省空间,这个方案我喜欢!#j327:
% N k4 e9 n9 R X3 u! C+ y
! N# ^' l2 y3 d; K; e: k i: }文 件 系 统
# ^. i$ |2 ?: ?! X& e3 a7 `. J- a n5 B8 g9 u
扯了这么多,是时候看一看全局了,在你们程序员的眼中,其实我是长这个样子的(拿Linux ext2为例):
, Q. A8 m3 ^# I, F2 w
+ A5 T; z* V! R$ m6 V- R4 Q! A
# Y# u, r; M4 J' Y
我这个硬盘主要由MBR(Master Boot Record)和各个磁盘分区组成。
% C- e2 l% `+ C% K: }( K( ^7 i
% a. x0 y" Y8 B6 a MBR中的有引导代码和磁盘分区表,分区表中记录了每个分区的起始位置,以及哪个磁盘分区是活动分区,这样系统就会找到它,然后装载这个分区中的引导块,并执行之。' X% _- C3 o+ \9 {$ ] ?5 X0 l4 c0 h
( V* v7 P. c3 u( _4 _
引导块将会装载存存储在本分区的操作系统。需要注意的是,每个分区都有一个引导块,不管这个分区有没有操作系统,这是各大厂商的约定,是一种标准。& I* a0 c% w7 \) _4 V* `0 r1 ` _
( U, h+ R7 j6 u' l/ f 每个分区除了必须的引导块之外,又被分成多个块组。! J# V$ i3 i) |9 M6 Q) y! r
# u) h' M. f; k# e. i& {8 N4 G
在每个块组中你能看到熟悉的磁盘块位图和inode位图,不用解释估计你也知道是干嘛的。还有inode表(当然是存放文件和目录的inode了)和真正的数据块。* O' V3 M* l3 F# V9 P
, g( l$ w$ M: b+ k/ @ 对了,我的磁盘分区表只有64个字节,而每个分区项占用16个字节,所以只能容纳4个分区。如果你想用多于4个分区,你就需要把其中一个设为扩展分区,然后在其中继续划分成逻辑分区,想划几个就划分几个。9 f3 u" ` x+ {8 L6 f9 a+ X2 K
+ N2 u; z1 L( N8 p; m; a
一般情况下,大家都喜欢把我划分成一个主分区+一个扩展分区,在扩展分区中再需要划分。
7 t2 o( u8 X2 h/ E+ G! M
2 R. y/ L7 G6 h |
|