聊聊dmClock算法
作者:吴香伟 发表于 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算法的更多相关文章
- Ceph QoS 初探(下)
作者:吴香伟 发表于 2017/01/24 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 存储QoS是个可以做很大也可以做很小的特性.SolidFire认为将Q ...
- 聊聊缓存淘汰算法-LRU 实现原理
前言 我们常用缓存提升数据查询速度,由于缓存容量有限,当缓存容量到达上限,就需要删除部分数据挪出空间,这样新数据才可以添加进来.缓存数据不能随机删除,一般情况下我们需要根据某种算法删除缓存数据.常用淘 ...
- JavaScript机器学习之KNN算法
译者按: 机器学习原来很简单啊,不妨动手试试! 原文: Machine Learning with JavaScript : Part 2 译者: Fundebug 为了保证可读性,本文采用意译而非直 ...
- CEPH集群操作入门--配置
参考文档:CEPH官网集群操作文档 概述 Ceph存储集群是所有Ceph部署的基础. 基于RADOS,Ceph存储集群由两种类型的守护进程组成:Ceph OSD守护进程(OSD)将数据作为对象 ...
- 【机器学习】粗糙集属性约简—Attribute Reduction
介绍 RoughSets算法是一种比较新颖的算法,粗糙集理论对于数据的挖掘方面提供了一个新的概念和研究方法.本篇文章我不会去介绍令人厌烦的学术概念,就是简单的聊聊RoughSets算法的作用,直观上做 ...
- 转载:Databricks孟祥瑞:ALS 在 Spark MLlib 中的实现
Databricks孟祥瑞:ALS 在 Spark MLlib 中的实现 发表于2015-05-07 21:58| 10255次阅读| 来源<程序员>电子刊| 9 条评论| 作者孟祥瑞 大 ...
- 机器学习 | SVD矩阵分解算法,对矩阵做拆分,然后呢?
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题第28篇文章,我们来聊聊SVD算法. SVD的英文全称是Singular Value Decomposition,翻译过来 ...
- Redis 中的原子操作(3)-使用Redis实现分布式锁
Redis 中的分布式锁如何使用 分布式锁的使用场景 使用 Redis 来实现分布式锁 使用 set key value px milliseconds nx 实现 SETNX+Lua 实现 使用 R ...
- 聊聊找AI算法岗工作
https://blog.csdn.net/weixin_42137700/article/details/81628028 首先,本文不是为了增加大家的焦虑感,而是站在一名学生的角度聊聊找AI算法岗 ...
随机推荐
- php字符串压缩
在PHP中偶尔遇到字符串的压缩,比如一个长字符串,数据库开始设计的字段存不下,但是又不想改数据库字段存储长度,就可以用压缩的方式降低数据字段字符串的长度数量级,把几百个字符的字符串压缩到几十个字符.总 ...
- JS利用短路原理简写if语句
看GoogleDoodle-Dance的源代码,学习到一个小知识——简写if语句. 几乎所有语言中||和&&都遵循“短路”原理,如&&中第一个表达式为假就不会去处理第二 ...
- 360路由器设置网段ip
路由器设置->高级设置->修改路由器地址
- leetcode--003 LRU cache
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABHAAAACmCAIAAAA9PO+sAAAgAElEQVR4nO3du3HbytvH8X8zqoB12A ...
- IOS开发-UI学习-NSMutableAttributedString(带属性的字符串)的使用
带属性的字符串: NSString *aa = @"hellochinaIloveYou!"; NSMutableAttributedString *mas = [[NSMutab ...
- Nodejs之编辑器ueditor
ueditor编辑器的使用说明. 最近在找nodejs前台界面可以编辑文字发表文章的工具,后来找到了ueditor,感觉还不错,就拿来使用了一下,使用过程如下. 1.下载及准备 下载ueditor,官 ...
- bzoj 2286 [Sdoi2011]消耗战 虚树+dp
题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...
- JS 响应式编程
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script ...
- Selenium2(java)TestNG的使用 七
TestNG,即Testing Next Generation,下一代测试技术,是一套根据JUnit和NUnit思想而构建的利用注释来强化测试功能的一个测试框架,即可以用来做单元测试,也可以用来做 ...
- ZOJ-2343-Robbers
题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1398 题意: 输入t 有t个测试用例每个测试用例第一行输入三个数n, ...