面向磁盘设计的存储软件不需要考虑竞争锁带来的性能影响。磁盘存储软件的性能瓶颈点在于磁盘,磁盘抖动会引入极大的性能损耗。因此,传统存储软件的设计不会特别在意处理器的使用效率。曾经对一个存储虚拟化软件进行性能调优,在锁竞争方面做了大量优化,最后也没有达到性能提升的效果,原因就在于存储虚拟化的性能瓶颈点在于磁盘,而不在于处理器的使用效率。正因为如此,在面向磁盘设计的软件中,很多都采用单线程、单队列处理的方式,一定程度上还可以避免由于并发所引入的磁盘抖动问题。

在面向NVMe SSD设计的存储软件中,这一切正发生着变化。和传统磁盘相比,NVMe SSD具有极高的IO读写性能,不存在传统磁盘所具有的访问寻道、抖动问题。为了发挥NVMe SSD的性能,无论在软件还是在硬件上都需要采用多队列技术,通过多队列方式充分发挥NVMe SSD的性能。通常NVMe SSD控制器可以提供128个IO提交和结束队列,NVMe驱动会根据处理器的核数利用SSD控制器提供的硬件能力,实现IO的并发处理。在驱动层面,可以绑定处理器与IO队列,达到IO并发处理的效果。在这种情况下,业务线程一定要多线程并发利用处理器,才可以将NVMe SSD的多队列真正用起来。在很多情况下,业务的软件模型往往会分为计算单元和存储单元两部分。计算单元往往是多线程并发处理的模式;存储单元在传统磁盘上是单线程模式,在NVMe SSD上会变成多线程并发处理的方式。这种软件处理模型可以描述如下:

在上述软件模型中,如果Compute和IO单元通过合理的资源切分划分在一起,Compute和IO单元在同一个执行上下文中,那么整个软件的效率将会变得非常高。但是在很多情况下,计算和存储可以是两个软件模块,或者计算和存储资源无法有效的进行划分,那么在这种情况下,计算和存储线程之间需要通过消息队列进行通信。这种消息通信可以抽象成生产者-消费者模型。Compute单元是生产者;IO单元是消费者。

生产者-消费者在实现过程中需要进行同步操作。如果采用传统的锁机制实现“生产者-消费者”队列,那么存储系统的性能瓶颈将会转移到锁竞争点。锁竞争一方面使得处理器处于长时间等待或者睡眠调度的状态;另一方面由于大量的缓存无效操作使得CPU的访存效率大大降低。总的来说,锁竞争将会导致CPU使用效率的降低,从而可以看到处理器的IPC指标变得很低。

那么在上述软件模型中,如何提升处理器效率,充分发挥NVMe SSD的性能呢?这就需要考虑采用无锁设计。在多线程并发处理的场景下,难免需要在线程之间进行数据交互,为了提高CPU的效率,这种大量的线程交互可以采用无锁的方式进行同步。无锁设计需要采用特殊的算法与处理器提供的特殊指令,常用的无锁算法有采用CAS指令实现的无锁队列,该种类型的算法需要一个Dummy节点,因此存在动态分配内存的问题。为了避免动态内存分配,可以采用固定长度的无锁队列Lock-free Ring,但是会存在队列深度固定的问题。在存储系统设计中,关键路径上最好需要避免内存资源的频繁分配,另外还需要实现队列深度的可变与IO数量的流控。因此,需要根据存储系统的特征,需要设计符合自身特点的无锁算法。在最近一个存储项目中,我们创造了一种无锁生产者-消费者及无锁流控算法,采用这种算法之后,我们可以发现IO的性能可以随着CPU核数线性变化。当CPU核数越多,IO性能越高。下图是实际测试的性能与IO线程数量之间的关系图:

上图我们可以看出当IO线程数量增加到28之后,随机读性能变化不明显,并且出现了一定的性能下降。在该测试平台上,一共具备28个CPU硬核,通过超线程的方式,达到56个CPU核。从上面的实验结果来看,超线程对IO性能贡献不大。随机读性能在IO Thread数量达到8个之后,性能达到峰值。这是由于后端NVMe SSD盘性能达到了峰值。

NVMe存储系统设计面临CPU性能瓶颈的问题,如何提高CPU的IO处理效率是高性能存储系统设计必须要考虑的问题。无锁设计是提高CPU效率的一种有效手段,一个好的无锁设计需要与系统软件的设计整体考虑。

谈谈存储软件的无锁设计相关推荐

  1. Linux 多线程 ”一写多读” 模式下的无锁设计

    缘起 双buffer "无锁" 设计 指针的切换 ptr 竞争条件的解决 指针访问丢失 延伸 结语 缘起 在linux多线程环境下对同一变量进行读写时,经常会遇到读写的原子性问题, ...

  2. UNIX(多线程):28---双buffer “无锁” 设计

    在linux多线程环境下对同一变量进行读写时,经常会遇到读写的原子性问题,即会出现竞争条件.为了解决多个线程对同一变量访问时的竞争条件问题,操作系统层面提供了锁.信号量.条件变量等几种线程同步机制.如 ...

  3. 每秒钟承载600万订单级别的无锁并行计算框架 Disruptor学习

    1.来源 Disruptor是英国外汇交易公司LMAX开发的一个高性能队列,研发的初衷是解决内部的内存队列的延迟问题,而不是分布式队列.基于Disruptor开发的系统单线程能支撑每秒600万订单,2 ...

  4. 无锁编程(Lock Free)框架 系列文章

    无锁编程(Lock Free)框架 系列文章: 1 前置知识:伪共享 原理 & 实战 2 disruptor 使用和原理 图解 3 akka 使用和原理 图解 4 camel 使用和 原理 图 ...

  5. java 无锁框架_高性能无锁并发框架 Disruptor,太强了!

    Java技术栈 www.javastack.cn 关注优质文章 Disruptor是一个开源框架,研发的初衷是为了解决高并发下队列锁的问题,最早由LMAX提出并使用,能够在无锁的情况下实现队列的并发操 ...

  6. java 无锁缓存_如何在高并发环境下设计出无锁的数据库操作(Java版本)

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

  7. 如何在高并发环境下设计出无锁的数据库操作(Java版本) 转载

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

  8. Atitit。Cas机制 软件开发 编程语言 无锁机制 java c# php

    Atitit.Cas机制 软件开发 编程语言 无锁机制 java c# php 1. 为什么需要无锁操作1 2. 硬件支持 cas  atomic2 3. 无锁编程(Lock-Free)就是在某些应用 ...

  9. 【共享内存】基于共享内存的无锁消息队列设计

    上交所技术服务 2018-09-05 https://mp.weixin.qq.com/s/RqHsX3NIZ4_BS8O30KWYhQ 目录 一.背景 二.消息队列的应用需求 (一)  通信架构的升 ...

最新文章

  1. 实现简书个人中心UI效果
  2. 使用聚类算法进行标签传播学习(Clustering for Semi-Supervised Learning)
  3. 悠然乱弹:聊聊模块化
  4. webstorm 使用svn
  5. python计算结果传给spark_将Python函数作为对象传递给Spark
  6. VMWare Linux虚拟机设置固定IP上网方法(靠谱)
  7. 转:在RHEL5系统中搭建iSCSI存储服务器
  8. Linux debian安装PyCharm教程
  9. 敏捷开发一千零一问系列之六:业务人员怎样参与开发?
  10. 国产数据库年终大盘点!
  11. 图像融合(三)-- 拉普拉斯金字塔
  12. 高质量程序设计指南C/C++语言——C++/C程序设计入门
  13. windows 驱动开发 DDK与WDK WDM的区别
  14. 基于STM32制作万能遥控器---1
  15. Drain基于固定深度解析树
  16. php短链接api,PHP实现短网址还原API接口
  17. js获取非行间样式(兼容ie和标准浏览器)
  18. 计算机数值分析-插值法-差商-04
  19. Android 6.0新特性
  20. 帧同步与状态同步:方案比较

热门文章

  1. uml 时序图_UML学习-14种UML图
  2. GraphViz :1 安装和简单使用
  3. 点击列表高亮_HTML5 标签列表
  4. 【Java】Java 语言的初步认识及工作应用范围
  5. 数组去重(包括es6)
  6. webpack4.x Loaders
  7. linux中的定时,linux中的定时任务
  8. An overview of gradient descent optimization algorithms
  9. 机器学习系列(5)_从白富美相亲名单看特征选择与预处理(上)
  10. SVM学习(三):线性分类器的求解