Page 90 - 《软件学报》2021年第5期
P. 90

1314                                     Journal of Software  软件学报 Vol.32, No.5,  May 2021

                      LogView←decompress(data)        //解压缩
                      return LogView
                    end function
                    索引查询的过程如下.
                    (1)  首先,根据 LogView 的 id 值解析出 ip 地址,再根据日志上报的路由信息、{hour}数据和应用名信息定
                        位到该日志存在哪台机器上哪个文件目录下,以及对应的索引文件和数据文件.此外,根据 id 获取到
                        index 值,并拼接 ip 与 index/4K 的值为 A.
                    (2)  遍历一级索引中所有的 Entry,找到与 A 值相等的一级 Entry 值,即可定位到对应的二级 Segment 索引.
                    (3)  根据 index%4K 的值定位到二级索引中的 Entry 位置,获取对应 Entry 中的数据,即可分析得到该
                        LogView 存放的内存块的首地址以及块内偏移量.
                    (4)  根据内存块首地址(headAddress)获取首部 4 个字节的数据,得到内存块具体的字节大小(blockSize),将
                        指定字节量大小的块加载到内存中,再根据偏移量位置(offset)及后续 4 字节的长度信息(logSize),获取
                        指定的长度字节数据后经过解压缩即可得到对应 LogView 的原日志数据.
                 3.4   磁盘空间管理

                    在索引文件存储的时候,一级索引的空间会全部创建,而二级索引只会在新建一级索引 Entry 值时才会创
                 建.如图 8 所示,以 ip1,index(0~8K−1)为例,对应会创建两个一级索引 Entry 值,即“ip1,0”与“ip1,1”.一级索引中条
                 目 Entry 值为“ip1,0”对应的 index 范围为(0~4K−1),根据 index%4K 的值,刚好与对应的二级索引 Entry 值一一对
                 应,刚好占据 4K 个 Entry 值.“ip1,1”对应所有 LogView 的 index 范围为(4K~8K−1),而每个 LogView 根据
                 index%4K 的值刚好与图中第 2 个 Segment 索引中 4K 个 Entry 一一对应.以 ip2,index(0~3K−1)为例,占据了一级
                 索引的第 4 个 Entry,且对应的二级索引中实际只占据了 3K 个 Entry 的空间.














                                            Fig.8    Memory usage of two-level indexing
                                                 图 8   两级索引的内存占用

                    总的来说,上述例子中来自 ip1 与 ip2 所有的日志数据在索引文件中仅占据了 128KB(4K×8+4K×8×3)的大
                 小.二级索引的 Entry 值是按顺序存放的,顺序写数据的性能很高;此外,二级索引中不存在空洞空间,即不存在内
                 存碎片,并且二级索引空间是在需要的时候才开辟,这些都可以有效的节省磁盘空间.
                 3.5   特殊情况处理
                    前面说明了正常情况下的日志数据存储与查询流程,下面对几种特殊情况发生后的处理方式作出说明.
                    (1)  读写冲突
                    在内存块写入数据文件时,如果此时有日志查询的请求到来,并且该条请求日志也正好在这部分内存块中,
                 此时同时写和读数据文件时,理论上存储冲突.所以日志存储与查询的流程设计如下.
                    •   首先查询内存空间,如果存在,则直接从内存中返回日志数据;
                    •   如果不存在,则到磁盘文件中查找.
   85   86   87   88   89   90   91   92   93   94   95