可视化存储智能解决方案之三“大话应用感知”


书接上文。


我们看到,目前的存储系统几乎是没有考虑任何应用层的事情的。有些存储进化了一些,可以在不同的Lun之间做QoS差异化处理,以及在缓存中同时支持不同尺寸的页面以适配不同类型应用发出的IO。但是这些都属于一种“盲”处理,也就是被动的布好一张网,等着上层的IO落入,能命中则已,不命中则没任何效果。相同的事情发生在自然界的每一处。比如蜘蛛网,有的很稀疏,那证明这位蜘蛛先生偏好大个头猎物,滤掉小个头的;有些则很密,那证明这蜘蛛老兄大小通吃。同时自然界也存在内圈密外圈疏的蛛网,有理由推测这是一种进化,产生了差异化,由各向同性进化为各向异性。

可视化存储智能解决方案之三“大话应用感知”

图2-0-1 各向同性及各向异性

SmartMotion 其实就是一种应用感知,它通过各种输入因素比如手动、定时、自动负载判断等来动态的改变每个逻辑卷的布局以充分最大化资源利用率。SmartMotion是坐落在IO路径最底层的两种优化思路之一,另外一个思路是所谓自动存储分级/分层。其实分级比分层范围大一些,分级是指在线、进线、离线这几个大级别之间横向的透明迁移以降低成本;而分层一般是指在一个小范围子系统内部通过将数据纵向的从机械盘提升到高速介质来提升性能。我们可以思考一下,自动存储分层/分级算不算是一种应用感知?某种程度上来讲也算,毕竟它能够自动统计判断冷热数据然后分层放置。

2.1 应用感知精细化自动存储分层

这里有必要说一下传统的自动分层是怎么做的。首先,需要将参与分层的所有存储空间分块,然后才能按照块的粒度来判断冷热及迁移。假设分为4KB大小的块,那么对于一个10TB的存储空间,会被分为约1.0×10 10 个块。由于需要对每个块做访问次数的统计,以及记录每个块的物理地址与逻辑地址的映射关系,我们保守的假设每个块需要100字节的元数据,算下来总共需要250GB的元数据,这简直不可忍受。现在的SATA盘基本都是2TB/4TB级别,这才10TB,就需要250GB了。所以必须增加分块大小,太小的分块虽然最终效果相对会好,但是元数据的庞大反而会降低最终体现的效果,因为每一笔IO都需要查表,表越大性能越差。假设我们提升到1MB分块,那么元数据就会被压缩250倍,也就是1GB,这个量其实也挺大的,但是至少是可以接受了。

值得一提的是,如果是对Raid2.0模式的的存储池启用分层的话,由于Raid2.0已经可以做到条带Segment级的拆分了,而且物理地址与逻辑地址的映射原生就已经存在,那么直接可以将访问频率统计元数据追加到已有元数据表每一个表项里即可。但是对于Raid1.0/1.5的池来讲,由于没有做块级拆分,所以必须从头设计元数据。当你对某个存储池启用了分层功能之后,这张元数据表就会在内存中生成并占用空间。

下一步是设置监控统计时段和迁移时段。系统需要不停的监控每个块的读写各自访问次数、IO属性等信息。但是某些特殊时段对这些块的访问是没必要算入统计结果的,比如备份时段,基本上所有数据都会被读一遍,每次IO都会增加一个额外的步骤就是更新对应块的访问计数,徒增了计算开销,所以有些产品允许用户配置那些不需要统计的时段。此外,需要配置迁移时段,为了不影响在线业务,多数产品需要让用户来自行设置在哪些时段将热数据迁移到高速介质中,比如每天凌晨4点到5点。在热数据迁移之前,系统会首先对统计元数据表做排序,然后比对高速介质区域的数据块访问次数排序结果以及低速介质区域数据块访问次数排序结果,如果发现低速区排在第一位的访问次数仍然不如高速区排在最后的访问次数多,那么本次迁移完成,其实就没有迁移;如果低速区排第一的次数高于高速区排最后的次数,则本次迁移的数据块就是这一段重叠的数据块,也就是将高速区这个重叠范围内的数据块迁移到低速区,同时低速区对应的数据块迁移到高速区,系统会把待迁移的数据块生成一个链表或者位图结构,然后启动迁移线程扫描链表或者位图完成数据迁移动作。

多久触发一次迁移可以灵活配置,但是一般不会连续滚动迁移,也就是这次迁移完后立即启动下一次迁移,因为这么做太过耗费资源,一个是需要不停的排序,另一个是需要不停的读出写入。

上面的过程看似没问题,但是最终的效果要么是基本无效,要么是效果甚微,只有特定条件下效果明显,也就是那些热点恒久远,一迁永流传的场景。但是随着上层应用的多样化和复杂化,热点恒久不变的场景越来越少,更多的场景其实是当你利用统计、排序之后判断出“热点”之后,迁移到高速介质之后,结果“热点”早已变凉了,或者说快吃吧凉菜都热了。

这种慢慢腾腾优哉游哉的热点判断方式,显然已经跟不上时代了。所以说目前的自动分层方案,毫无新意,不管你加多少层,比如有些厂商已经不局限在存储系统内部分层,而是可以上升到利用主机端的PCIE Flash卡存储最热的数据。甭管你用PCIE闪存卡,亦或甚至你直接用主机端RAM或者更疯狂你够牛能直接利用CPU L2 Cache来当热点缓存,在“判断不准”这个前提下,一砖撂倒,因为你所提升的,根本就不是真正的热点。粒度太粗,太过一刀切,不够精细化,是这些方案的弊病。举个例子来讲,如图2-1-1所示,如果遇到了图中所示的情况,传统自动分级这种“四肢发达头脑简单”的做法,就是搞不定的了。

可视化存储智能解决方案之三“大话应用感知”

图2-1-1 头脑简单的自动分层所做不到的

可以肯定的是,目前的方案是无法解决这个需求的:“甭管你的监控数据显示出多冷,我就想让某某数据或某某文件透明存放在高速介质,你能不能做到吧!?”类似场景数不胜数,比如一个视频,某大领道讲话,平时没人看,但是突然接到10分钟后该大领道要来突击视察,为了显示出高度的思想觉悟以及为国为民奋斗终身的决心,领道下令所有人电脑上播放此讲话,但是由于码流过大视频太长,缓存又太小,导致不能顺畅播放,本来大领道脸就大,屏幕上一卡壳,哎呦,甭提多尴尬了。领道震怒,下令在5分钟内 搞定。当然,这个场景比较夸张,咱们就说这个场景,靠周期统计的话,平时这个视频根本不会被作为热点,但是最近这几分钟内的访问又不会立即触发迁移,所以无解了。

解决这个问题的办法很简单,就是提供一种能够让用户有选择的、可以控制的、立即生效的数据透明分层。对于NAS存储系统,我们需要增加文件系统级别的分层,而不能只相信块层分层,这样就可以直接选择将哪个文件在什么时候,或者立即,迁移到哪种存储介质上去,同时还保证所有目录的文件视图无变化。

而对于SAN存储系统,做到这一点可就不是这么简单了。SAN存储系统是不理解一个逻辑卷上到底哪些区域是“我就要把某某数据立即迁移到高速介质”里的“某某”的,它更不了解哪些是临时工哪些是实习生哪些是正式工。要让它了解,有两个办法,第一个办法是直接让SAN存储系统识别到对应的文件系统格式,这基本上再往前走一步的话和做成个NAS无多大区别了,不可行;另一个办法是在主机客户端使用一个特殊的代理程序,将用户需要迁移的文件,底层所占用的块信息生成一个列表推送给SAN存储系统,SAN存储系统立即或者在设定的时间段将这些块迁移到高速介质,或者迁回。如图2-1-2所示。

可视化存储智能解决方案之三“大话应用感知”

图2-1-2 代理组件负责应用感知

第二个办法显然不错,实现起来也方便,主机端提取某个文件对应的底层块列表是没问题的,传送这些信息可能稍微复杂一些,可以通过管理口带外方式传送,也可以通过SCSI路径带内方式,比如针对一个虚拟Lun写入这些要传送的数据,都可以。其次是如果一个文件碎片太严重,那么这个列表就会很大,系统此时可以做判断,比如只把大块连续的地址传送即可,不要求整个文件精确到每个块地址都必须传送到,因为过多的碎片记录会增加阵列端额外的处理开销,毕竟这只是为了透明迁移,只要大块的数据被迁移了,零散的边角料不要也罢。另外,文件/目录可能随时发生变化,比如大小变化,甚至被删除,此时其对应的底层块也会随之变化,如果被删除那其对应的块便都成了垃圾块,阵列端应该及时获取到这些变化,从而做对应的更新或者作废操作,但是这种变化不会导致数据丢失或者不一致,如果不及时通知阵列则只会导致阵列加速了没必要加速的数据。此外,可以提供超时机制,比如一旦Agent端长期没启动或者故障退出,无法及时将最新的变化同步到阵列端,那么阵列端可以使用超时机制,在一定时间之后,作废对应的加速操作。

2.2 应用感知精细化SmartMotion

如果说精细化动态分层主打的是稳准狠短平快速战速决打一枪换一个地方的游击战,那么SmartMotion主打的是大部队大规模集团军作战。SmartMotion改变一次逻辑卷布局,相当于两万五长征,是为了将来更好的发展,是从大局着眼考虑的。那么这个技术是否也像自从分层一样,存在一些弊病?答案是肯定的。举个例子,同一个逻辑卷内,也很有可能存在差异化区域,有冰区、冷区、暖区、热区、烫人区、沸腾区、爆炸区,这是从访问热度角度去考虑;如果从其他角度考虑,比如还可以分为陆地区、沼泽区、雷区、烟雾区、炮弹区、狙击区等,如图2-2-1所示。比如数据库存放数据文件的区域,和存放在线日志的区域,其IO访问属性就非常不一样,虽然两者可能都属于烫人区,如果这两个区域同时分布在同一个Raid2.0池中,不加以区分对待的话,就是粗枝烂叶了,性能就不会好。

可视化存储智能解决方案之三“大话应用感知”

图2-2-1 全局数据气象图

如果可以仅仅对这些关键区域进行SmartMotion操作,而无需Motion整个逻辑卷,那么就是事半功倍。也就是说,不仅可以Mo(摸欧哞)逻辑卷,还可以Mo条带,因为Raid2.0模式下已经是以条带为单位的视角了。如果只是做到了这一点,还不能称其为应用感知,因为存储系统此时依然不知道这些冷区域是存储的哪些应用的数据,或者那些爆炸区是存储的哪些应用的数据。比如,要将某数据库DB1的数据文件DBFile1进行SmartMotion操作,这个动作对于SAN存储是无法理解的,因为SAN存储系统不知道到底什么是“DBFile1”,所以同样,也需要由主机端运行的代理组件来将这种信息推送给SAN存储系统。对细粒度精细化SmartMotion的展现详见下文。

2.3 应用感知精细化QoS

存储系统的QoS,源头其实是从主机端的IO Scheduler(Linux)开始的。对IO Scheduler的详细介绍请参照《大话存储2》,这里不再敖述。IO Scheduler的两大目的,一个是IO合并,这一点不少场景下会显著提升性能;另一个就是均衡多进程之间的IO抢占底层通道资源。以防止有进程出现IO饿死现象。但是IO Scheduler只在单机OS内部发生作用,多机之间是没有人来协调IO均衡处理的。比如如图2-3-1所示,2台主机连接到一台存储系统之上,虽然左侧主机的IO经过IO Scheduler整流之后可以做到均衡处理,但是出了主机之后就不是IO Scheduler的地盘了,假如右侧主机某线程发送大量的异步IO,如果阵列侧不加差异化的对待的话,则这两台主机的IO到了存储系统之后,谁数量多,谁就压死其他人。

可视化存储智能解决方案之三“大话应用感知”

图2-3-1 全局IO饿死

一个解决办法是将队列分开,比如存储系统为每主机设一个队列,每队列设1个线程处理IO请求,这样的话,如图2-3-2所示。假设CPU每20ms发生一次线程调度,这样的话每个队列轮流各执行20ms,总体上来讲,就可以达到这两台主机的IO是平均对等的被处理的。但是这样所带来的一个问题就是,整体性能会被拖慢。假设整个系统存在50个队列,但是只有队列1里排了很多IO请求,其他49个队列都很空闲。那么这样CPU依然要轮转50次才能再次转回到队列1 来处理积压的IO,虽然轮转到其他队列处理线程的时候,这些线程由于队列里几乎没有请求而立即就挂起了,但是怎么说也耗费了无谓的CPU资源,这样整个系统的性能就被拖慢了。所以为了全局着想,系统不得不根据队列里的IO多少来动态的增加或者减少队列的处理线程,比如如果图示队列2 里的IO积压的非常多,那么系统可能会临时创建额外的多个线程来处理这个队列的IO,这样对应该队列的线程数量比例增大,就会导致这个队列的IO在同样的轮转周期内更多的被处理,这样那些积压IO少的队列就较难得到机会被处理了。所以尴尬就此产生了,到底是更该顾及全局的吞吐量,还是保证公平呢?所以从这一点上看,在存储端实现QoS还是很有必要的,也就是将这种尴尬扔给用户去决策,因为只有用户最清楚他到底需要哪些业务的优先级高于其他业务。比如用户可以强行指定队列1的IO优先级永远高于其他队列,不管队列1里的IO是多么耍大牌,只要队列1有IO,就必须优先执行。图示例子是按照主机来映射队列,实际中还可以按照逻辑卷来映射队列,或者每(主机+逻辑卷)为单位。

SCSI 协议其实是有一定QoS定义的,比如可以指定将一个IO排到队列头部或者尾部,但是尴尬的是这只是Initiator-Target管用,如果是多台机器同时访问一个存储系统,两台机器如果都指定了排到队首,你是排还是不排?都要求优先等于没要求一样。

可视化存储智能解决方案之三“大话应用感知”

图2-3-2 全局IO公平处理

另外,存储系统保有较大容量的缓存,就是用来做预读和写缓存的,这里面就牵扯到一个预读力度的问题,以及写缓存高水位线低水位线的问题。预读力度到底多大?系统只能根据当前的IO属性来猜测,所以说算法在高深,它终究也离不开猜,只要是猜,都可以被定义为“不靠谱”。有没有办法不让存储系统时刻处于迷茫的猜测中?QoS此时就可以派上用场。比如在给存储系统发送IO的时候,顺便扔一句话:“亲我要频繁写呦~”,“亲我要频繁读呦~”,“亲后续有大块读呦~一波攻势马上就要来了呦~做好准备呦~”,“亲后续有大块写呦~”,“我这是同步读呦~”等诸如此类。

从这个角度上看进去,就可以看到QoS的另一面,也就是访问属性上的提前预告,以便让系统做最优的处理,避免浪费资源。比如某程序打开文件的时候,可以指定要求预读还是不预读,如果要求不预读,那么系统才不会费那个劲干出力不讨好的事情。这一点本地文件系统做得还可以,但不是非常到位。Windows下系统IO调用时有个参数成为FILE_FLAG_SEQUENTIAL_SCAN,指定了这个参数的话,那么文件系统会狠劲的给你预读。CIFS网络文件访问协议,由于大部分远程调用继承的是本地文件系统IO调用,所以也沿袭了不少类似参数,其中有个Access Mask段,里面每一位都规定了当前IO请求到底要干些什么,这样在NAS系统收到请求之后就可以有的放矢的做优化了,如图2-3-3所示。

可视化存储智能解决方案之三“大话应用感知”

图2-3-3 Access Mask

但是目前对于SAN存储系统来讲,的确需要一种前导性质的QoS方案。SCSI协议里的QoS不给力,我们就得自己设计交互协议。这里我不打算使用重量级协议,比如修改每个IO指令的格式之类,那个理论上没问题但是生态搞不定,除非以后就你一家用。打算另辟蹊径,在不修改任何IO指令格式和原本的协议交互方式的前提下,利用旁路向存储系统推送一些指示信息。比如,某某逻辑卷的某某到某某地址段给我狠劲预读,再比如某某逻辑卷的某某地址段给我按照3级优先处理(比如一共10级)。这种方式可以被称为“Hinted”方式,就是在旁路上提供参考信息。那么应该由谁来生成和发起这种Hint?可以由应用程序发起,但是这需要搞好生态建设,一般搞不定,比如你让Oracle、微软来一起参与定义一套API来传递Oracle的各种IO需求,基本行不通。应用和OS都保持透明,那么只能是由用户发起然后直接传递给存储系统执行了,存储提供一个工具或者界面,这都没问题,问题是用户怎么知道把哪个卷的哪段地址做什么样的QoS请求?用户肯定不知道,但是最起码用户知道要把哪些应用或者文件或者哪些用户的某些文件、邮箱之类做什么样的QoS处理。所以,这就同样需要一个代理组件,来负责将这些业务层的对象映射成底层的块信息,然后夹带上对应的QoS信息,传送给存储系统执行。这样就可以做到“凡是某某应用发出的IO,优先级设为某某”或者“凡是针对某某文件的访问IO,优先级设为某某”的效果。


本次分享先到这,下次分享一下整个这套解决方案的最终产品化实现。


本文转载请注明出自 大话存储 公众号。长按识别二维码关注 大话存储 获取业界最高逼格的存储知识。 看了好的请点赞/转发/红包,平时群里发红包装逼,不如把红包猛烈的砸向冬瓜哥吧!冬瓜哥后续会有更多高逼格的东西出炉。大话存储,只出精品。

可视化存储智能解决方案之三“大话应用感知”

长按图片发红包:

可视化存储智能解决方案之三“大话应用感知”

强赠冬瓜哥真容:

可视化存储智能解决方案之三“大话应用感知”