大神来,求问分块操作文件的问题

sl51314240 2012-11-07 08:45:49
有一个大文件(TB计算),把该文件分为若干等大小的块,因为内部逻辑,导致我修改多个块为一个原子操作,例如,我要修改第0、200、5000、8000块为一个原子操作,如何保证原子操作的完整性,要么这几个块一起修改,要么这几个块全部修改。

现在的方法是:
1.创建新文件,并且标记文件不可用
2.将更改的几块写到新文件里面
3.标记该文件可用
4.将该文件的内容合并到那个大文件中
5.删除该文件

现在的问题是:
1.每次原子操作都会有大量的磁盘IO
2.因为磁盘IO造成的性能问题
3.原子操作大锁造成的性能问题

大神们,求好的解决方法啊~~~
...全文
198 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
sl51314240 2012-11-12
  • 打赏
  • 举报
回复
木有好心人么……
sl51314240 2012-11-08
  • 打赏
  • 举报
回复
引用 6 楼 gogdizzy 的回复:
我感觉改进的余地不大。那个临时文件应该类似于一个记录,如果在合并到大文件时断电,重启后,第一步就是先处理那个临时文件(合并),当然这个合并操作必须是可重复的。 要保持一致性,中间操作用磁盘这种不怕断电的介质保存可能是必需的。 blockSize目前是1M,不知道是不是已经调整到最优了,如果每次修改内容不多可以调小点,可能可以减少写入量。
目前就是 1.创建临时,标记临时文件无效 2.写临时文件,标记临时文件有效 3.合并临时文件到大文件 4.删除临时文件 若断电: 1.检查是否存在临时文件 2.查看临时文件是否有效 3.无效则删除临时文件 4.有效则再次执行合并操作 我想问一下有没有什么系统函数或者第三方库,能直接进行这样的操作 初始化,逆初始化,读,写,刷新(合并) 大概就是事务的修改,提交模式
  • 打赏
  • 举报
回复
我感觉改进的余地不大。那个临时文件应该类似于一个记录,如果在合并到大文件时断电,重启后,第一步就是先处理那个临时文件(合并),当然这个合并操作必须是可重复的。 要保持一致性,中间操作用磁盘这种不怕断电的介质保存可能是必需的。 blockSize目前是1M,不知道是不是已经调整到最优了,如果每次修改内容不多可以调小点,可能可以减少写入量。
wood87654321 2012-11-08
  • 打赏
  • 举报
回复
即便新文件操作完全没有问题,海量数据的所谓原子操作,又怎能保证写回原文件到一半时就不断电?
sl51314240 2012-11-07
  • 打赏
  • 举报
回复
弄点结构题看吧

//BlockId - 块号,以块大小

#define BLOCK_SIZE ((__int64)1024*1024)

union Header
{
    struct
    {
        BYTE    Flag[32];           //头标识
        ...
        __int64 BlockIdleList;      //记录空闲块链表,初始为0,若0,表示没有空闲链表,则扩大文件
    }
    BYTE Reserve[BLOCK_SIZE];
}

union Block
{
    __int64 BlockNext;          //未使用时记录下一个空闲块偏移
    BYTE    Data[BLOCK_SIZE];   //被使用的时候存储数据
}

//假设有这些操作
__int64 BlockAlloc  (void);
bool    BlockFree   (__int64 vBlockId);

bool    BlockRead   (__int64 vBlockId, Block* vBlock);
bool    BlockWrite  (__int64 vBlockId, Block* vBlock);
sl51314240 2012-11-07
  • 打赏
  • 举报
回复
引用 2 楼 wood87654321 的回复:
如果你的一个原子操作数据量很大,则磁盘IO是不可避免的,理想的情况是减少块大小或一个原子操作的块数量使得原子操作能够在内存中完成,如此即便原子操作总数增加很多效率也远高于磁盘IO 另外不明白你为什么锁定临时文件而不是大文件,事务处理担心的是对原文件的并发操作,难道你自创的临时文件还担心别人会并发操作?
不是锁定临时文件,是锁整个操作,如果修改原文件的话可能出现这样的错误: 1.我要修改第0、200、5000、8000块...假设需要10次IO 2.其中第0块是文件头,200、5000、8000等这样的块都是链式操作 3.有大量的重新生成磁盘链表,修改块的指向(大文件变长) 4.如果写了第0块、第200块的时候突然断电了…… 5.那么整个链式结构被打乱,造成文件不可用,问题就大条了
wood87654321 2012-11-07
  • 打赏
  • 举报
回复
如果你的一个原子操作数据量很大,则磁盘IO是不可避免的,理想的情况是减少块大小或一个原子操作的块数量使得原子操作能够在内存中完成,如此即便原子操作总数增加很多效率也远高于磁盘IO 另外不明白你为什么锁定临时文件而不是大文件,事务处理担心的是对原文件的并发操作,难道你自创的临时文件还担心别人会并发操作?
sl51314240 2012-11-07
  • 打赏
  • 举报
回复
如果有更好的方法实现这个功能就更好了

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧