centos 随机偏移二进制原始磁盘写入,无任何缓存

vngu2lb8  于 2022-11-07  发布在  其他
关注(0)|答案(1)|浏览(83)

对于我的应用程序,我正在尝试确定数据备份系统是否丢失了任何写入操作。我通过向1GB虚拟磁盘写入一个递增整数计数器来完成此操作,为了确保没有丢失任何写入操作,我可以查看恢复的快照,看看是否存在任何间隙(例如,如果我看到1、2、3、0、0、6、7,我就知道备份没有正确获得写入4和5)。这都是在CentOS 7虚拟机上进行的,主要使用Python 2.7脚本进行写入/读取(速度不是主要问题)
我的大部分问题都与缓存有关:因为我模拟的是随机I/O,所以写操作通常会从缓存中刷新并无序地写入磁盘。这使得每次测试都显示为误报,因为看起来好像在快照时丢失了一些数据。同样,我并不真正关心效率,所以我不介意写操作非常慢。读操作可以使用缓存,这不是问题,但也没什么关系
以下是我为尝试禁用缓存所做的工作:
1.使用sudo hdparm -W 0 /dev/sdb禁用磁盘写高速缓存,其中/dev/sdb
1.写入到没有文件系统的原始磁盘,因此没有文件系统缓存
1.将Python脚本中with open上的缓冲标志设置为0(无Python写缓存)
要确保我的写操作按顺序放到磁盘上,基本上是一项不可能完成的任务吗?我所需要的只是write #(n)发生在write #(n+1)之前,#(n+1)发生在#(n+2)之前,等等。
这是我用来写入磁盘的Python脚本(SIZE和PRIME根据磁盘的大小和随机种子而变化):

from struct import pack, unpack
import sys
SIZE,PRIME = [x],[x]

# random I/O traversal iterator

def rand_index_generator(a,b):
    ctr=0
    while True:
        yield (ctr%b)
        ctr+=a

with open('/dev/sdb', 'rb+', buffering=0) as f:
    index_gen = rand_index_generator(PRIME, SIZE)
    # random traversal using iterator above, write counter to file
    for counter in xrange(1, SIZE-16):
        f.seek(index_gen.next()*4)
        f.write(pack('>I', counter))

然后,为了进行验证,我以相同的顺序遍历,并观察未写入数据的间隙。这是在将虚拟机恢复到快照之后进行的。我知道所有遍历和写入操作都可以正常工作,因为在恢复之前,验证将顺利进行,不会出现未写入的情况,但我认为一些“已写入”的数据会在RAM中死亡,而不会进入磁盘
将采取任何建议,以保证写顺序,我需要这个应用程序

lg40wkob

lg40wkob1#

找到了这个问题的答案。我误解了写入到原始磁盘的效果,它没有消除操作系统缓存,因为我仍然在调用操作系统写入到我的原始磁盘。哎呀
要绕过操作系统缓存,您应该使用os.open并传递os.O_DIRECTos.O_SYNC标志,以确保写入以正确的顺序(more info on those flags)发生,并且不会卡在易失性内存中。
页面大小因操作系统而异。对于Linux,页面大小为4096
代码的顶部部分保持不变,但下面是write循环:

PAGESIZE = 4096
filedesc = os.open('/dev/sdb', os.O_DIRECT|os.O_SYNC|os.O_RDWR)
for counter in xrange(1, SIZE-16):
    write_loc = index_gen.next()*4
    page_dist = (write_loc%PAGESIZE)
    offset = write_loc - page_dist
    bytemap = mmap.mmap(filedesc, PAGESIZE, offset=offset)
    bytemap[page_dist:(page_dist+4)] = pack('>I', counter)
    bytemap.flush()
    bytemap.close()

相关问题