云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

_阿里云创始人王坚_免费领

小七 141 0

服务器排名_关于_中移动物联网公司

通过在ILUMOS上减少OpenCoS弧内锁争用,服务器和云主机,提高了8K块缓存随机读取性能225%。介绍弧的真实问题表演前删除列表?解决方案:使用更多锁!性能:之后提交详细信息附录1介绍锁是一种痛苦。更糟糕的是,一个锁序列化文件系统的所有页面缓存访问。虽然这不是OpenZFS ARC今年早些时候的情况,但已经相当接近了。对于那些不熟悉的人来说,OpenZFS文件系统是基于Nimrod Megiddo和Dharmendra S.Modha撰写的论文"ARC:A Self-Tuning,Low-overloadreplacement cache"构建在自己的页面缓存之上。虽然这篇文章提供了一个很好的基础,从中可以编写实际的代码来实现它的概念,但是它没有解决一些现实世界中的问题。在本文中,我们将研究其中一个问题:并发性。2弧的真实问题本文描述了一个全局数据结构,所有的页面访问都是从这个结构中执行的;问题是,它没有描述一种在高并发环境中安全地执行此操作的机制。由于任何现代文件系统显然都需要支持多线程并发操作,因此必须添加锁来保护用于管理和实现ARC的全局数据。你怎么能这样做?一种方法是用一个互斥锁包装所有修改全局结构的操作。这满足了从多个线程并发执行的所有访问都是安全的,同时也非常容易理解和实现。令我惊讶的是,在过去的十年里,OpenZFS的架构就是这样的三。性能:之前正如人们所料,这种简单化方法的主要缺点是性能。虽然安全,但在具有许多cpu的系统上,这种方法会导致多线程缓存工作负载的锁争用。为了突出这个性能问题,我使用FIO使用32个线程执行缓存的随机读取工作负载。每个线程都会使用自己独特的文件,从它的文件中随机读取8K个块(对齐偏移量为8K)[附录1]。在改变分配给虚拟机的虚拟CPU数量的同时测量聚合带宽,结果如下:请参阅[附录2]了解更详细的性能指标,可以看到,当系统中CPU数量增加时,性能会急剧增加。CPU越多,性能就越差,CPU越多,性能就越差!显然,这是一个不好的情况;尤其是随着CPU数量越来越大的系统变得越来越普遍。查看lockstat分析数据片段,可以清楚地看出是哪些锁造成的(以下内容摘自在一个拥有32个CPU的系统上运行的代码):导致瓶颈的两个锁用于保护ARC的内部列表。这些列表包含驻留在缓存中的所有ARC缓冲区,这些缓冲区不是由ARC的使用者主动使用的(即,引用计数为零的缓冲区)。每次在这些列表中添加或删除缓冲区时,必须保持列表的锁。这意味着必须为以下所有操作获取列表的锁:从磁盘读取、ARC缓存命中、逐出缓冲区时、弄脏缓冲区时、当使用者释放对缓冲区的所有引用时等等。4删除列表?在深入研究所采用的解决方案之前,我应该首先说明为什么需要这些列表。对于最近访问的缓冲区,允许最近访问的缓冲区列表进行迭代,反之亦然。进行此迭代的能力对于实现本文所述的ARC至关重要。它允许在逐出过程中以恒定的时间选择最近访问过的缓冲区[附录3]。5解决方案:使用更多锁!为了缓解这个问题,我们确实需要一种方法来执行这个迭代,而不会给性能关键的代码路径造成太多的锁开销(例如在ARC缓存命中期间)。我们决定的解决方案是将ARC的每个内部列表拆分为数量可变的子列表,每个子列表都有自己的锁并在其内部保持时间顺序(即,每个子列表中的缓冲区根据访问时间排序,但不同子列表之间没有缓冲区的顺序)。因此,创建了一个新的数据结构来封装这些语义,即"多列表"[附录4]。从表面上看,这似乎是一个非常小的变化,但有一个关键的方面使它的实现比人们预期的要复杂。由于子列表之间没有保持严格的顺序,选择最近访问最少(或最多)的缓冲区不再是一个固定的时间操作。一般来说,它变成了一个线性时间操作,因为每个子列表都必须迭代,大数据啥意思,比较每个子列表中的元素。对最近访问最少的缓冲区进行线性时间查找是不够的,因此使用了一种聪明的特定于域的解决方法来允许这种查找保持其恒定的时间复杂性。在逐出期间,不是选择最近访问的绝对最少的缓冲区,而是选择"足够旧"的缓冲区;这种选择是在固定时间内进行的。我们通过在每个子列表中均匀地插入缓冲区来做到这一点,然后在逐出过程中,选择一个随机选择的子列表。选择并逐出此子列表中最近访问次数最少的缓冲区。这个过程将根据缓冲区均匀地插入每个子列表的事实来选择一个"足够旧"的缓冲区,因此每个子列表的最近最少访问的缓冲区的访问时间将与所有其他子列表的最近最少访问的缓冲区成比例[附录5]。6性能:之后与任何与绩效相关的变化一样,实证结果对于赋予变革任何可信度都是必要的。因此,以前用来说明问题的工作量[附录1]再次用于确保实现预期的性能提升。下表包含了固定后的聚合带宽数("带宽后"列),以及不带固定值的聚合带宽数("带宽前"列,与前面显示的结果相同):正如预期的那样,随着系统中添加更多的CPU,性能会更好地扩展,使用32个CPU时,总体性能提高了225%(这是我可以测试的最大CPU数量)。此外,使用少量CPU时,性能差异可以忽略不计。再次使用了Lockstat,争用显然比以前少了很多(与以前一样,这个片段是从一个有32个CPU的系统上运行的):成功!7提交详细信息对于感兴趣的客户,此修复于2015年1月12日通过以下方式提交给illumos:它还在被移植和合并到Linux上的FreeBSD和OpenZFS中(至少,在撰写本文时是这样)。8附录用于运行性能基准测试的FIO脚本如下所示。请记住,这个脚本在收集性能数据之前运行了很多次,因为我专门针对完全缓存的工作负载,需要确保文件缓存在ARC中。除了用于收集聚合带宽数的运行之外,FIO脚本还运行了几次,以收集更多有用的调试和性能指标。具体地说,物联网展,它是在启用lockstat profiling的情况下运行的,它被用来精确定位导致伸缩性差的锁。以及另一个使用flame graph profiling的迭代,它可以精确定位感兴趣的特定函数(另外,还可以提供支持lockstat数据的确凿证据)。不幸的是,看起来我无法上传SVG或TAR文件;因此,如果有人对完整的lockstat输出或火焰图感兴趣,返利商城,请给我发一封电子邮件,我们就可以解决一些问题(可能只是直接通过电子邮件将TAR归档文件发送出去,因为它只压缩了227K)。列表也可以从最近访问的缓冲区迭代到最近访问最少的缓冲区。在缓存被"预热"之前填充L2ARC设备时使用此迭代方向。这个概念对我来说不是原创的,因为FreeBSD已经在他们的平台中包含了一个类似于ARC的修复。FreeBSD对这个概念的使用实际上给了我信心,让我相信它会在实践中得到解决,而不是真正有一个可行的解决方案。我意识到"足够老"是模糊的,但本质上我们要做的是使用一个启发式来确定哪个缓冲区是从缓存中移出的最佳候选。所以,我们修改了以前的启发式方法,从总是选择绝对最旧的缓冲区,大数据分析方法,变成从一组"旧"缓冲区中随机选择的缓冲区。由所有子列表的尾部组成的一组旧缓冲区。