全部博文(356)
分类: LINUX
2018-06-29 09:41:34
原文地址:Prefetch,一个神奇的功能 作者:hanwei_1049
Prefetch是一个ATS代码里有,管理文档里没有说,也没有其他任何官方说明的功能。当然,这是一个非常强大的隐藏的功能,不然我们也不去管它了。这里我将会介绍这个功能的主要设计思想,以及如何使用,并且介绍后续的开发与优化路线图,希望可以帮助大家理解ATS的强大与系统化设计思想,帮助大家掌握ATS的使用、二次开发,创造更大的价值。
我们假设有这么个网络环境,这个网络环境的延迟很大很大,比如比中美之间的延迟还大,并且网络的效率也不高,还会有丢包,并且带宽成本还很高,你希望优化用户的感受,并且极致的压缩带宽开销,你可以用ATS做什么样的工作呢?
ATS的开发者在这个场景下,首先想到了是如何改善网络延迟带来的不爽:
首先,网络上的延迟在应用层面已经是无解的了,ATS并没有做到tcp协议优化层面来,而是独辟蹊径,在服务器端通过解析用户请求的html内容,提前预知用户可能请求的资源文件的方式,来预取后续用户端可能需要的资源,这样等用户端解析完html内容,对ATS发起请求的时候,ATS已经开始预取了很多内容,并且甚至已经递归到了后面好几层的网页资源了。用户端浏览器多数请求的资源都会已经缓存在cache里或者正在回源取的过程里了,如果正在回源的内容,又可以配合rww的回源合并功能避免重复回源,从而获得良好的用户端感受。
然后,聪明的开发者又想到了如何压缩传输中的数据以减少数据传输量,提高传输效率。ATS在这种情况下,一般会在网络的两端分别部署,这样的话,中间网络就是一个管道,管道上传输的资源可以进一步压缩,甚至在进入管道前,可以对资源做更进一步的压缩,可能的方向包括但不限于:
是啊,我们的资源既然已经先于用户开始从源服务器下载了,抢先出来的时间,自然可以干点什么更有意义的事情啦,比如这里比较耗时的压缩、再压缩等。哎,你永远也不知道还有多少空间可以压榨的,干脆交给用户来搞吧,于是有了Prefetch相关的一堆API。
Prefetch的原理很单纯,简单的原理就是,接收到了客户请求的返回html后,分析其中的页面元素、下层链接,提取出来后,逐个从本机发起一个对本机代理端口的一个请求,形成一个ATS抢跑客户端请求预先加载的结果,为了控制,这个功能里可以配置谁来触发这个功能、以及要分析提取的tag等等。
我们在前面已经把Prefetch的前因后果交代出来了,现在来看看如何启用Prefetch功能。
Prefetch可以说是一个实现在核心中的业务功能,是基于Scheduled Update功能核心模块做出来的,作为核心一部分就会使用核心的配置管理方法:
records.config:
records.config中的配置项不多,关键的也就是前三个,其中需要改的,也就是第一个prefetch_enabled这个选项,buffer相关的就是得根据业务情况来调整了。
proxy.config.prefetch.prefetch_enabled 控制是否启用Prefetch功能
proxy.config.prefetch.child_port 指定Prefetch的发起端口用哪个
proxy.config.prefetch.config_file
proxy.config.prefetch.url_buffer_size
proxy.config.prefetch.url_buffer_timeout
proxy.config.prefetch.keepalive_timeout
proxy.config.prefetch.push_cached_objects
proxy.config.prefetch.default_url_proto
proxy.config.prefetch.default_data_proto
proxy.config.prefetch.max_object_size
proxy.config.prefetch.max_recursion
proxy.config.prefetch.redirection
prefetch.config:
Prefetch.config是一个简单的配置文件,主要控制对那些客户端启用Prefetch功能,对哪些html标签如何提取资源URL两个方面:
如何控制对哪些客户端启用Prefetch功能,目前采用的是一个简单模式,定一个IP地址段,如果客户端IP地址在这个范围内,我们就会对它启用Preftch功能:
prefetch_children 10.0.0.0 - 10.255.255.255, 216.1.2.3
对哪些html标签如何提取资源URL?这里的格式比较复杂,又分为简单格式和复杂格式
简单格式为:
html_tag tag attr,例子:html_tag img src定义了取<img height=10 width=10 src="http://www.example.com/images/1.gif"/>中的src里的URL为需要递归的资源。
复杂格式:
html_tag tag attr filter_attr filter_value,例子:html_tag link href rel stylesheet定义了取<link rel="stylesheet" type="text/css" href="example.css"/>中的css属性的链接URL为需要递归的资源。
默认的配置中,已经包含了常用的html标签定义,如果你自己定义的话,就会覆盖掉这些默认的定义:
html_tag img src
html_tag body background
html_tag frame src
html_tag fig src
html_tag applet code
html_tag script src
html_tag embed src
html_tag td background
html_tag base href
html_tag meta content
html_tag input src
html_tag link href rel stylesheet
实践用法之缓存灌数据
大家都知道缓存的数据从0到满,需要很长时间,尤其是现在的大容量缓存,那都需要几周甚至月的。如果我们能够把数据从一个已在线的节点把数据复制到新节点,是不是会很高效?或者利用已在线的节点的访问纪录来主动跑一遍这些url?当然,如果你已经拿到这些url后,就可以用http_load等工具来对缓存做取的动作,然后就可以做到灌数据的效果了。
如果我们使用Prefetch,只需要这样做:
<img src="URL"/>
1.html
traffic_line -s proxy.config.prefetch.prefetch_enabled -v 1
本人实测,用这个模式刷缓存,加载速度远超对外服务能力,可能是由于ATS的顺序写磁盘优化在sata传统盘上的效果比较好的缘故吧。
实践例子:
测试代码里的那个test-hns-plugin.c的,极有可能是为 satellite company Hughes Network Systems做过啥特别的插件,请参考:
~bakos/classes/cdn.pdf 请有兴趣的同学自己挖掘吧。
Prefetch也不是没有问题:
但是,基于移动互联网以及业务Edge化的考虑,类似Prefetch这种优化,将是非常非常有意思的一些领域,前途无量啊。
So,问题是你觉得呢?我觉得吧,好功能也得靠用户捧,玩社区就是要参与,要是你觉得好,去社区里voice出来啊,它的未来靠你了。