云计算的挑战
云计算把计算、存储、网络资源进行池化,这样多个租户就可以同时使用这些资源,那么如何保证所有的租户可以公平的使用这些资源,互不影响?如何保证整个云平台不会过载呢?
最好的办法是能够限制租户对各种资源的使用,保护资源池(性能和容量)不被耗尽。
云硬盘的Throttling
在UnitedStack的UOS公有云中,我们提供了两种云硬盘:性能型和容量型。每种云硬盘的侧重点不同,性能型云硬盘适合于高IOPS高吞吐的场景,比如数据库应用等;容量型云硬盘适合于大文件和备份的场景。
在 性能型云硬盘中,IOPS和吞吐率是随着硬盘容量的增长而线性增长的,最高IOPS是6,000,最高吞吐率是170MB/s,这是我们承诺的SLA。其 实,在没有任何限制的情况下,每个云硬盘的最高IOPS可达50,000以上,最高吞吐率可达 1000MB/s。那么为什么我们要对每个云硬盘的IOPS和吞吐率进行限制呢?
这是因为每个分布式块存储集群的总IOPS和总吞吐是确定的,由集群的规模和硬件决定。当集群的负载快达到峰值时,每个I/O请求的延迟会显著上升。当有部分云硬盘无限制的进行读写操作,这会导致其他云硬盘的I/O延迟上升,降低其他云硬盘的IOPS和吞吐率。
为了保护存储集群,也为了保证每个租户可以公平的使用云硬盘,我们需要对云硬盘的IOPS和吞吐率进行限制,这就用到了Throttling技术。Throttling是为了在最坏的情况下保护存储系统的可用性。
目前UnitedStack的分布式块存储系统中,可以对云硬盘的限制项有:
- 总IOPS
- 读IOPS
- 写IOPS
- 总吞吐
- 读吞吐
- 写吞吐
目前,我们采用简单的策略,只对总IOPS和总吞吐进行限制。
I/O风暴问题
在存储系统中,我们经常遇到I/O风暴的问题。一般关系型数据库所产生的 IOPS 峰值都是很尖的凸起,数据库加载和表扫描需要的就是一个峰值形态的数据吞吐操作。在启动虚拟机时,也会产生I/O风暴。如何解决I/O风暴和Throttling之间的矛盾呢?
我们可以观察到:
- 在短时间内,只有少量云硬盘会产生I/O风暴。
- I/O风暴并不是持续很长时间。
- 在大部分情况下,整个存储集群的负载不是很高。
那我们是否可以提供一种方案,满足下面的需求:
- 短时间内,每个云硬盘的IOPS可以超过SLA的限制,以便应付I/O风暴。
- 长时间来看,每个云硬盘的平均IOPS和平均吞吐率还是被限制住。
答案是可以的,UnitedStack即将使用Burst技术满足这些需求,帮用户轻松应付业务尖峰。
AWS EBS的Burst
AWS Elastic Block Storage在08年夏天就发布了Magnetic类型的云硬盘,满足用户数据持久化的需求。在2012年EBS又推出了Provisioned IOPS(SSD)类型的云硬盘,满足持续超高负载的需求,这种类型是针对IOPS的级别收费的。
- Magnetic云硬盘:AWS最廉价的云硬盘,容量成本很低,IOPS和吞吐率也很低,没有SLA保证。
- Provisioned IOPS(SSD)云硬盘:可 用于I/O密集型的负载,比如交易系统或者是大型关系型数据库或NoSQL数据库。这种类型的云硬盘可以获得一致的性能,有SLA的保证。每个云硬盘最大 可以获得4,000 IOPS,可以用多个云硬盘组成RAID,获得总共48,000 IOPS的性能。但是你需要给IOPS的级别付费。
在半年前,AWS Elastic Block Storage推出新的云硬盘类型:General Purpose(SSD)。推出这种类型的云硬盘的目的是打算在成本和性能之间做个平衡,比Magnetic云硬盘的IOPS要高10倍,延迟只是以前的十分之一。这种云硬盘的付费跟容量大小成正比关系,得到的IOPS数也与容量大小成正比(跟UnitedStack的性能型云硬盘一样)。
General Purpose(SSD)云 硬盘有Burst(突发)特性,可以提供3,000 IOPS的Burst性能(不管云硬盘容量的大小,IOPS的峰值可以达到3,000)。当然,持续可靠的IOPS性能是跟云硬盘容量有关系的,每GB的 容量可以得到 3 IOPS, 500GB的云硬盘可以得到持续可靠的 1,500 IOPS(SLA保证)。AWS分析了大量的应用负载,并设计了General Purpose(SSD)类型云硬盘去满足这些应用的I/O风暴。
General Purpose(SSD)云硬盘底层技术使用的是Token Bucket模型:
- 每个token代表一个”I/O credit”,用于支付一个I/O读写请求。
- 每个General Purpose(SSD)云硬盘跟一个bucket关联,每个bucket最大能够装满540万个token。
- 在bucket中token的累积速度是 3 每GB每秒,直到bucket被装满。
- 每个bucket的token消费速度最大可以达到3,000,也就是说每个云硬盘的最大IOPS是3,000。
- 每个云硬盘的持续可靠IOPS跟token的的累计速度有关,也就是跟容量有关。
- 在短时间看,token的消费速度可以 大于或等于 token的累积速度(在bucket中有多余token的情况下)。
- 在长时间看,token的平均消费速度 小于或等于 token的累积速度。
当bucket中没有token时,云硬盘就会阻塞中,把I/O请求放到调度队列中,不去执行I/O请求,直到bucket又积累了足够多的token。因此token消费完是I/O请求被阻塞的触发条件。
UOS云硬盘的Burst
目 前UOS云平台上云硬盘的Burst功能开发已经完成,已经进入测试阶段,即将在北京一区和广东一区上线。所有的性能型和容量型云硬盘都会Burst功 能,突发最大IOPS仅受限于虚拟机的配置(多核产生的负载和单核产生的负载是不一样的),持续可靠IOPS和原来SLA一样。
可以带来的好处是:
- 小容量高性能:10GB的性能型云硬盘也可以有高达10,000~50,000的突发IOPS。
- 低成本高吞吐:容量型云硬盘也可以有480MB/s的突发吞吐率。
突发IOPS可以达到10,000
突发吞吐率可以达到 1000MB/s
UOS云硬盘的Burst功能使用了Leaky Bucket模型:
Leaky Bucket模型的核心抽象就是一个会漏水的桶,桶本身会按照一定速率(bucket.avg)往下漏水,而桶上方会时快时慢地流水进桶里。当桶没有满 时,上方的水可以没有限制的流入,一旦水满了,上方的水就无法加入了。桶是有一定容量(bucket.max)的,桶在某个时刻是有水位线 (bucket.level)的,当桶满时(bucket.level >= bucket.max),就会触发异常,阻塞上方的水加入桶中,直到桶的水位线下降之后。
- 每个桶跟一个云硬盘关联。
- 桶上方的水就是云硬盘发出的I/O请求(这个是与Token Bucket的不同点)。
- 在短时间看,水流入速度可以 大于等于 水流出的速度(在bucket不满的情况下)。
- 在长时间看,水流入平均速度 小于等于 水流出速度。
- bucket.avg就是云硬盘的持续可靠IOPS(SLA保证)。
- bucket.max就是桶的容量,桶容量越大,Burst的最大IOPS越大,持续时间越长。
AWS与UOS的对比
在云硬盘中,UOS对比AWS的性能优势是:
- UOS的1TB性能型云硬盘的持续可靠IOPS是6,000,是AWS General Purpose(SSD)云硬盘的2倍。
- UOS单个云硬盘的突发(Burst)最大IOPS可达到10,000 ~ 50,000,这个值跟虚拟机的配置有关系。而AWS General Purpose(SSD)云硬盘的突发最大IOPS只有3,000。
机制与策略
在UOS使用了Leaky Bucket模型去实现云硬盘的Burst特性,可以通bucket.avg和bucket.max去灵活配置SLA和Burst最大IOPS和最大吞吐率。但是配置什么参数就是一个策略问题。
目前在我们的分布式块存储系统中,单节点上存储网络带宽是 1000MB/s,性能盘资源池中,总读IOPS性能是总写IOPS性能的13倍,总读吞吐率是总写吞吐率的6倍。在容量盘资源池中,总读IOPS总性能是总写IOPS性能的6倍,总读吞吐率是总写吞吐率的6倍。
因此我们设置burst策略的原则就是:
- burst策略应该发挥我们分布式块存储系统的特性,保护我们的存储系统。
- 系统盘和云硬盘的策略应该有区分,系统盘的性能不能超过云硬盘的性能,使用burst给虚拟机启动加速。
- 性能型云硬盘和容量型云硬盘的策略应该有区分。
- 对于读IOPS和写IOPS的策略应该有区分。
- 突发吞吐率不能太大,避免存储网络被阻塞,影响I/O延迟。