我们正在开发一种 ssd 类型的存储硬件设备,它可以一次处理大于 4KB 的大块大小(即使是 MB 大小)的读/写请求。 我的理解是 linux 及其文件系统会将文件“切碎”为 4KB 的 block 大小,这些 block 大小将被传递给 block 设备驱动程序,这将需要用来自设备的数据物理填充 block (例如,用于写入)
我也知道内核页面大小在这个限制中起作用,因为它被设置为 4KB。
对于实验,我想看看是否有办法真正增加这个 block 大小,这样我们就可以节省一些时间(我们可以用更大的 block 大小来完成,而不是多次写入 4KB)。
是否有任何 FS 或任何现有项目可供我查看? 如果没有,做这个实验需要什么——linux 的哪些部分需要修改? 试图找出困难程度和所需资源。或者,如果甚至不可能这样做和/或我们甚至不需要这样做的任何原因。任何意见表示赞赏。
谢谢。
最佳答案
4k 的限制是由于页面缓存。主要问题是如果你有一个 4k 页面大小,但是一个 32k block 大小,如果文件只有 2000 字节长会发生什么,所以你只分配一个 4k 页面来覆盖 block 的前 4k。现在有人试图偏移 20000,并写入一个字节。现在假设系统内存压力很大,前 2000 字节的 4k 页面是干净的,被推出内存。您如何跟踪 32k block 的哪些部分包含有效数据,以及当系统需要写出偏移量 20000 处的脏页时会发生什么?
此外,假设系统内存压力很大,我们需要写出最后一页;如果没有足够的可用内存来实例化 32k block 中的其他 28k,那么我们可以执行读取-修改-写入循环只是为了更新偏移量 20000 处的那个脏 4k 页面?
这些问题都可以解决,但是需要在VM层做大量的手术。 VM 层需要知道对于这个文件系统,页面需要一次以 8 个页面的 block 的形式实例化,如果存在推出特定页面的内存压力,则需要写出所有 8 个页面同时如果它是脏的,然后同时从页面缓存中删除所有 8 个页面。所有这些都意味着您想要跟踪页面使用情况和脏页,而不是在 4k 页面级别,而是在复合 32k 页面/“ block ”级别。它基本上将涉及对 VM 子系统的几乎每个部分的更改,从页面清理器到页面错误处理程序、页面扫描器、写回算法等等。
还要考虑,即使您确实聘请了 Linux VM 专家来完成这项工作(HDD 供应商会非常喜欢您,因为他们也希望能够部署具有 32k 或 64k 物理扇区大小的 HDD) ,这种经过修改的 VM 层将在 Red Hat Enterprise Linux 内核或 SuSE 或 Ubuntu 的等效企业或 LTS 内核中出现还需要 5-7 年的时间。因此,如果您在一家希望将您的 SSD 产品销售到企业市场的初创公司工作——您现在最好放弃这种方法。在您的钱用完之前,它是行不通的。
现在,如果您碰巧在一家制造自己硬件的大型云公司(如 Facebook、亚马逊、谷歌等)工作,也许您可以走这条路,因为他们不使用企业内核以缓慢的速度添加新功能——但出于这个原因,他们希望相对靠近上游内核以最大限度地降低维护成本。
如果您确实为这些大型云公司之一工作,我强烈建议您联系同一领域的其他公司,也许您可以与他们合作,看看是否可以一起进行这种开发一起工作,努力让这种改变上游。这真的,真的不是一个微不足道的变化,虽然 --- 特别是因为上游 linux 内核开发人员会要求这不会对常见情况下的性能产生负面影响,而这不会 在不久的将来随时涉及 > 4k block 设备。如果你在 Facebook、谷歌、亚马逊等公司工作,这不是你想要作为对内核的私有(private)更改来维护的那种更改,而是你希望获得上游的东西,因为其他明智的将是一个如此巨大的、侵入性的变化,以至于支持它作为一个树外补丁将是非常令人头疼的。
关于linux - 绕过 block 层/设备上的 4KB block 大小限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30585565/
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我没有理解以下行为(另请参阅inthisSOthread):defdef_testputs'def_test.in'yieldifblock_given?puts'def_test.out'enddef_testdoputs'def_testok'endblock_test=procdo|&block|puts'block_test.in'block.callifblockputs'block_test.out'endblock_test.calldoputs'block_test'endproc_test=procdoputs'proc_test.in'yieldifblock_gi
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
我需要尝试一些AES片段。我有一些密文c和一个keyk。密文已使用AES-CBC加密,并在前面加上IV。不存在填充,纯文本的长度是16的倍数。所以我这样做:aes=OpenSSL::Cipher::Cipher.new("AES-128-CCB")aes.decryptaes.key=kaes.iv=c[0..15]aes.update(c[16..63])+aes.final它工作得很好。现在我需要手动执行CBC模式,所以我需要单个block的“普通”AES解密。我正在尝试这个:aes=OpenSSL::Cipher::Cipher.new("AES-128-ECB")aes.dec
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile