在视频监控项目中,录像是必须且至关重要的一个基本功能,可以说录像质量及稳定性在很大程度上就反映了一个监控产品的好坏。
传统的文件系统在长时间大容量的录像并发生覆盖时往往存在以下三方面的问题:
1)文件碎片越来越多、录像效率逐渐下降,无法满足规划时的系统要求;
2)文件的删除效率极低,导致覆盖时的码流录像能力低于开始的规划要求从而出现录像异常停止或者码流数据的丢失;
3)文件系统复杂、庞大,系统异常情况下的问题查处相当困难,几乎束手无策。
基于以上考虑,特提出VBFS文件系统的设计实现;本文简单介绍VBFS文件系统构成、覆盖机制以及存在的短板。
1 VBFS文件系统中的关键字
VBFS: Video Block File System, 视频块文件系统
SBR: System Boot Record, 文件系统引导记录
RAT: Record Allocation Table, 录像记录分配表
RIA: Record Index Area, 记录索引区
2 VBFS文件系统简介
2.1 VBFS文件系统总体结构组织图
SBR | 备份SBR | RAT | 备份RAT | RIA | 备份RIA | 数据区 |
---|
在VBFS文件系统中,主要包括六个区域,SBR,RAT,备份RAT,RIA,备份RIA和数据区。
VBFS支持O_direct(无缓冲的输入、输出)的磁盘写方式,因此所有区域的起始位置都以磁盘扇区大小进行对齐;
除了数据区,其他五个区域的最小分配单元为磁盘的扇区大小,而磁盘的数据区则被划分为一块块大小固定的数据簇,因此数据簇成为数据区的最小分配单元。
2.2 SBR
SBR作为文件系统引导区,主要记录了一个分区的总体信息,帮助上层应用可以正确识别并访问该磁盘分区。主要内容包括:
字段 | 长度(字节) | 默认值 | 说明 |
---|---|---|---|
FS | 4 | VBFS | 文件系统标识,固定不变。 |
PV | 8 | KEDA 1.0 | 厂商及版本 |
UUID | 36 | 变量 | 分区唯一标识 |
Label | 16 | 变量 | 卷标,暂时未用 |
BPS | 4 | 变量 | 每个扇区字节数(Bytes per Sector),在磁盘格式化时根据实际磁盘扇区大小填写 |
SPC | 4 | 1024 * 1024 / BPS | 每个簇包含的扇区数(Sectors per Clustor)注:簇大小固定为1M字节 |
RSS | 4 | 63 | 保留扇区数(Reserved Sectors),整个SBR空间 |
SPT | 4 | 63 | 每个磁道扇区数(Setors per Track) |
TSS | 8 | 变量 | 磁盘分区总扇区数(Total Sectors) |
BBS | 4 | 6 | 备份SBR的起始扇区号(Backup boot Sector),固定不变 |
NORA | 4 | 2 | RAT个数(Number of RATs) |
NORI | 4 | 2 | RIA个数(Number of RIAs) |
SPR | 4 | 变量 | 每个RAT包含的扇区数(Setors per RAT) |
BPR | 4 | 512 | 每个记录索引占用的字节数(Bytes per record) |
SOR | 4 | MaxRecNum*BPR/BPS | 每个RIA占用扇区数(Setors of RIA)注: MaxRecNum的默认值为500000,可以在格式化时通过格式化参数进行调整 |
CRC | 4 | 变量 | SBR的CRC校验码 |
2.3 RAT
RAT为录像记录分配表,记录了每个录像文件占用的簇的信息。
RAT中的每一记录项使用4字节来保存簇号,簇号编号从数据区开始,第0簇和第1簇保留,
因此有效的簇号必然大于等于2。
RAT中的第0记录项保存的值固定为0x52415400,第1记录项保存当前可使用的簇号,即整
个磁盘分区的当前写位置。
也可以这么来形容RAT,RAT其实就是一个u32的数组,数组的容量就是数据区包含的簇总
数,而数组下标就是簇号,数组项保存的u32值就是一条录像记录所使用的下一个簇的编号或者其他有意义的值,其中数组项的可能值如下:
RAT记录项值 | 对应簇情况 |
---|---|
0 | 未分配 |
2~0xFFFFFFEF | 已分配簇,数值代表下一簇号 |
0xFFFFFFF0~ xFFFFFFF6 | 文件系统保留 |
0xFFFFFFF7 | 坏簇 |
0xFFFFFFF8~0xFFFFFFFF | 记录结束符 |
示例:
假设RAT保存的信息如下:
0x52415400 | 0x08 | 0x04 | 0x06 | 0x05 | 0x07 | 0xffffffff | 0xffffffff | 0 |
---|
这就表示当前簇为第8簇,其中第2,3,4,5簇数据有效,第6,7簇为结束簇,第8簇尚未分配。
根据RAT中记录项保存的值的意义,我们可以得到如下两条录像记录占用簇的情况:
第一条录像记录使用的簇为:2 à 4 à 5 à 7
第二条录像记录使用的簇为:3 à 6
2.4 RIA
RIA为录像记录索引区,每条记录索引对应一条录像记录,其记录的录像信息如下:
字段名 | 长度(字节) | 默认值 | 说明 |
---|---|---|---|
RN | 256 | 字符变量 | 录像记录名称,第一字节为0xE5则代表记录已删除 |
SS | 4 | U32 | 录像记录占用的起始簇号 |
ST | 4 | U32 | 录像开始时间 |
ET | 4 | U32 | 录像结束时间 |
CID | 36 | 字符变量 | 编码器通道ID,32位设备号+4位通道号(未使用) |
CNM | 32 | 字符变量 | 编码器通道别名(未使用) |
NI | 4 | U32 | 相同CID的下一条录像记录的索引项位置,从RIA区开始偏移的记录数(未使用) |
TBS | 8 | U64 | 录像数据的总字节数 |
PDT | 8 | 字符变量 | 编码器制造商信息 |
RFM | 4 | 字符变量 | 录像数据格式(MP4、H264) |
RSD | 148 | 字符变量 | 保留数据 |
CRC | 4 | U32 | 校验码,0为不校验 |
2.5 VBFS文件系统录像规则
1. 为了提高写的效率,在VBFS中写磁盘采用严格的顺序写,即从磁盘头顺序写到磁盘结束,然后再从磁盘头开始,因此从磁盘开始位置到当前写位置之间的某块被释放的磁盘空间,不会立即被使用,即如果第n簇及第n+6簇被占用,即使第n+1到n+5簇已经被释放,这时如果录像再需要分配磁盘空间,则会分配第n+7簇。
2. 数据区中的每一个数据簇只属于一个录像文件,即如果一个录像文件只用了一个簇的一部分,该簇的未使用部分也不能再分配给其他录像文件使用
2.6 VBFS文件覆盖
1. 由于VBFS采用严格顺序写的方式,因此VBFS的文件覆盖则是发生在录像文件占用的第一个簇被再次分配时。
2. 当录像文件被覆盖时,在VBFS中只是将该录像记录的录像索引中录像名的第一个字节置为0xE5,而不会真正的将该录像文件所占用的簇全部清空,因此这样也大大提高了录像记录的覆盖效率。
3. 由于VBFS采用严格顺序写的方式,因此在磁盘写到结束后,必然从磁盘头开始写,因此不管此时磁盘的中间位置是否有空闲的空间,都会将位于磁盘头的录像记录覆盖。
3 VBFS文件系统的短板
俗话说:有利必有弊,VBFS文件系统一方面给我们的产品带来了诸多好处的同时,比如录像效率稳定、覆盖效率高,解决定位问题容易,另一方面又存在着一些问题:
首先,由于VBFS执行的是严格顺序写盘,因此在覆盖时无法有选择的进行录像覆盖,而且不会跳过某条录像记录而使用后续已经被释放的空间,也就是磁盘空间利用率不高。
其次,由于VBFS在加载磁盘分区时,会将RAT及RIA中的有效索引全部加载到内存中,而RAT占用的大小又取决于磁盘分区的大小,因此如果磁盘分区大,则RAT加载到内存中占用的内存就多,而随着录像记录数的增加,索引也在增加,占用的内存也会越多,因此每个VBFS磁盘分区占用的内存大小就取决于该磁盘分区的大小及磁盘分区上录像记录数的多少,而整个NRU占用的内存则会受到所有VBFS磁盘分区占用的内存之和的影响,也就是说VBFS磁盘分区越多,NRU占用的内存也就会越多。