作者:吴香伟 发表于 2017/01/08
版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明


人们常常容易忽略一些不起眼但特别重要的事物。曾经跟同事聊Python,有人说一切皆对象,这也是一些OOP的广告词,但我始终觉得一切皆函数。至今为止,还尚未听过见过没有函数的编程语言(SQL算不算?)。

很多QoS算法都不提队列,但队列是这类算法中最重要的要素了。具体来说,QoS算法的目的就是定义一个优先级队列,定义队列元素出队列的先后顺序。

从预留说起

起初把Reservation翻译为下限,与上限(Limit)相对应,意为保证用户IO不低于某个值。下限两个字很容易误解,如果用户一段时间内不产生IO那实际IO为0又如何保证IO不低于某个值。它原本的含义是在系统繁忙的情况下,如果用户产生的IO高于该值,保证实际IO不低于该值;如果用户不产生IO或者产生的IO低于该值,那自然不用保证。

一次偶然机会看到有人将其翻译成预留,顿时觉得妙,至少在用户看来非常贴切。预留极易让人联想到生活中预订餐桌的情况,假如预订一个八人桌,那么餐馆的服务生就会在其中一张八人桌上放个已被预订的牌子以防止被其他顾客占用。预订张八人桌能够保证8个以内的人均有位置,但不保证第九个人也有位置,可能有也可能没有。回到存储,与预订餐桌略有区别的是,预留并不会让系统为用户腾出一部分IO处理能力而等着用户IO到来。

如何预留?
假设存储系统有两个用户,两个用户都预留了10个IOPS,并且系统IO能力超过了两个用户的预留之和。

为保证用户的预留,系统处理IO分两个阶段:第一阶段先满足每个用户的预留,第二阶段再将剩余能力分配给所有用户。第一阶段要解决的问题是如何判断预留已满足。对此,不同算法有不同的策略,最直观的当属令牌桶算法。算法每隔1/10秒就为两个用户各生成一张令牌,用户的请求只有拿到令牌后才允许出队列,当用户无令牌可用时就说明该用户已经达到预留,当所有用户都无令牌可用时代表第一阶段结束。令牌桶通过产生令牌的速度来模拟用户预留的IO平均处理速度。

mClock的策略是依据IOPS将请求映射到时间轴,确定每个请求应该被处理的时刻。请求出队列时只要将排在当前时刻前面的请求处理完就能够满足预留要求了

如何确定请求应该被处理的时刻?
依据IOPS的定义,每隔1/10秒处理一个请求,也就是说,时间轴上相邻两个请求的平均间隔为1/10秒。将系统接收到给定用户的第一个请求放到时间轴中接收到该请求的时刻所在的位置,后续请求从前个请求的位置开始向右偏移1/10秒。假设系统在t1时刻开始接收请求,t2时刻开始处理请求,t1、t2的间隔恰好1秒。如果这段时间内系统刚好接收到10个请求,那么t2时刻处理完这10个请求就刚好满足预留;如果这段时间内接收到的请求数目超过10个,那么超过的部分将排到t2后面,t2时刻只要处理掉它前面的请求就能够满足预留要求了。

所谓将请求摆到时间轴,具体到实现层面就是为请求添加一个Tag,Tag的内容为请求应该被处理的时刻。后文将预留的Tag,称为R Tag。

考虑这样一种应用场景,用户起初有部分IO(时间段I),空闲了10分钟(时间段II)后,又有了IO(时间段III)。根据上文描述的方法,时间段III中请求的R Tag将严重滞后当前时间。这将导致时间段III中的某个时刻解决掉所有排在它前面的请求后用户实际的IOPS超过预留。这对该用户来说是件好事,但对其它用户极不公平,甚至会因为无法分配到IO而饿死。

上面的公式就是解决这个问题的方法,空闲了段时间后的第1个新请求将重新被设置为接收到该请求的时刻。公式中i代表用户,r代表请求,R代表Tag的值。

前文的关注点主要在单用户如何保证预留,多用户情况最容易导致的问题是IO分配不公平。如果系统总IO能力低于两个用户的预留之和,会不会出现用户饿死的情况?因为两个用户的请求都映射到时间轴,出队列时按照时间从小到大的顺序执行,因此不会出现不公平的问题。

上限有何不同

没有。
预留过程可以分成两步,第一步请求入队列时为请求添加R Tag,第二步请求出队列时决定哪些请求应该出队列哪些请求不能出队列。简单来说,当前时刻前的请求出队列,当前时刻后的请求不能出队列。

上限也是如此两步,只是含义略有不同。出队列时,当前时刻前面的请求全部被处理掉代表此时IOPS已经达到用户的上限,所以不能继续处理当前时刻后面的请求,否则就超出上限了。

权重有何不同

有点。
上限和预留是针对给定用户的绝对值,权重是用户间的相对值。第二步只要根据P Tag从小到大的顺序依次出队列即可,即使P Tag超过了当前时间也可以继续出队列。

IOPS、带宽和延迟

IOPS比较简单,两个请求之间没有差别。带宽稍微复杂点,要考虑到每个请求的大小。

假设某用户的预留为10MB/s,可以理解为每秒钟处理10MB数据,也可以理解为每1/10秒处理1个请求,每个请求的大小为1MB。为什么这么理解呢?因为我们需要找个参照物,此例以1MB的请求为参考,两个相邻的1MB大小的请求在时间轴上的间隔为1/10秒。那么,一个大小为512k的新请求与前一个请求的间隔应该设置为1/20;一个大小为2MB的请求和前个请求的间隔应该设置为1/5。

为什么比参照物小的请求间隔小,比参照物大的请求间隔大?这要从带宽的定义来理解。

(待续)

突发IO

应用场景
大文件拷贝、虚拟机的启动和迁移、数据库批量更新、页缓存刷新等。

不同厂商的定义
SolidFire定义突发IOPS能够超过上限IOPS,只能持续一小段时间。HP 3PAR定义突发IO不能超过上限,只是通过抑制其它应用来提高突发应用的优先级。mClock对突发IO的定义和HP 3PAR相同,只是提高其比例不能越过上限。

(1)只在系统有余力的情况才允许突发IO;
(2)只调整P Tag,不影响预留和上限。

dmClock先检查给定的应用是否空闲,如果空闲就给予一定的突发能力。

读、写和读写

(待续)

调度和调度引发的危机

(待续)

扩展mClock到多服务器

(待续)

聊聊dmClock算法的更多相关文章

  1. Ceph QoS 初探(下)

    作者:吴香伟 发表于 2017/01/24 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 存储QoS是个可以做很大也可以做很小的特性.SolidFire认为将Q ...

  2. 聊聊缓存淘汰算法-LRU 实现原理

    前言 我们常用缓存提升数据查询速度,由于缓存容量有限,当缓存容量到达上限,就需要删除部分数据挪出空间,这样新数据才可以添加进来.缓存数据不能随机删除,一般情况下我们需要根据某种算法删除缓存数据.常用淘 ...

  3. JavaScript机器学习之KNN算法

    译者按: 机器学习原来很简单啊,不妨动手试试! 原文: Machine Learning with JavaScript : Part 2 译者: Fundebug 为了保证可读性,本文采用意译而非直 ...

  4. CEPH集群操作入门--配置

      参考文档:CEPH官网集群操作文档   概述 Ceph存储集群是所有Ceph部署的基础. 基于RADOS,Ceph存储集群由两种类型的守护进程组成:Ceph OSD守护进程(OSD)将数据作为对象 ...

  5. 【机器学习】粗糙集属性约简—Attribute Reduction

    介绍 RoughSets算法是一种比较新颖的算法,粗糙集理论对于数据的挖掘方面提供了一个新的概念和研究方法.本篇文章我不会去介绍令人厌烦的学术概念,就是简单的聊聊RoughSets算法的作用,直观上做 ...

  6. 转载:Databricks孟祥瑞:ALS 在 Spark MLlib 中的实现

    Databricks孟祥瑞:ALS 在 Spark MLlib 中的实现 发表于2015-05-07 21:58| 10255次阅读| 来源<程序员>电子刊| 9 条评论| 作者孟祥瑞 大 ...

  7. 机器学习 | SVD矩阵分解算法,对矩阵做拆分,然后呢?

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题第28篇文章,我们来聊聊SVD算法. SVD的英文全称是Singular Value Decomposition,翻译过来 ...

  8. Redis 中的原子操作(3)-使用Redis实现分布式锁

    Redis 中的分布式锁如何使用 分布式锁的使用场景 使用 Redis 来实现分布式锁 使用 set key value px milliseconds nx 实现 SETNX+Lua 实现 使用 R ...

  9. 聊聊找AI算法岗工作

    https://blog.csdn.net/weixin_42137700/article/details/81628028 首先,本文不是为了增加大家的焦虑感,而是站在一名学生的角度聊聊找AI算法岗 ...

随机推荐

  1. pip安装icu失败:Command "python setup.py egg_info" failed with error code 1 in

    问题 Mac 下通过 pip 安装 icu 失败. 解决办法及原因 问题的原因是因为icu库中的某一行代码找不到一个文件,获取不到ICU_VERSION的值. # Install icu brew i ...

  2. selenium IE 浏览器驱动下载地方

    download: http://selenium-release.storage.googleapis.com/index.html

  3. 已知从BUF开始存放了10个字类型有符号数据,编程求出这10个数中的最大数和最小数(将最大数存入MAX字单元、最小数存入MIN字单元),并将其以10进制数的形式在屏幕上显示出来。

    data segment            pmax db 0dh,0ah , 'MAX :   ','$'    pmin db 0dh,0ah , 'MIN :   ','$'    buf ...

  4. CodeSmith批量生成实体

    保存以下文件为ModelBatch.cst <%@ Register Name="Model" Template="D:\Q\web\LHWYVISIT\trunk ...

  5. [osg]osg显示中文信息

    转自:http://www.cnblogs.com/feixiang-peng/articles/3152754.html 写好了在osg中实时显示中文信息的效果.中间遇到两个问题,一个是中文显示,一 ...

  6. 报错:Can't bind to local 8647 for debugger

    修改8600为8601,并且勾上Use ADBHOST

  7. radiobutton设置样式

    单选题里会用到radiobutton,如果不想使用系统提供的圆圈样式,可以自定义样式,想要做成的效果就是, 使用自定义的图片替换圆圈,然后选择有4个选项的其中一个,图片上有个对勾标记, 然后如果正确选 ...

  8. 十二生肖&天干地支

    看相:http://baike.baidu.com/view/833122.htm?fr=aladdin 八字:http://baike.baidu.com/view/17127.htm?fr=ala ...

  9. 高斯RBF核函数中Sigma取值和SVM分离面的影响

    1:高斯RBF核函数的定义 k(x) = exp(-x^2/(2×sigma)) 在MATLAB中输入一下代码:ezsurf('exp(-x^2/(2*sigma^2))'); 在GOOGLE中输入“ ...

  10. PHP安全编程

    转自:http://www.nowamagic.net/librarys/veda/detail/2076   1.关闭register_globals,以提高安全性 2.在部署环境,不要让不相关的人 ...