缓存服务器设计与实现(七)

本文讲缓存中的内容管理–目录的删除

基本原理

目录刷新,在很多地方也叫目录删除,这个功能是要求CDN的cache系统,删除特定目录下的所有文件(有些变态的需求,是让删除目录下符合特定规则的文件)。这里只是提供一些思路和简单的实现方案,供不了解这块的朋友参考。

因为缓存服务器的文件组织结构一般不同于普通的web服务器。在web服务器里,文件一般是按照url的路径在本地文件系统里存放的,例如:
web服务器的docroot为/var/web/doc,请求的url为http://xxx.com/file/2015/index.html,那么在磁盘的/var/web/doc/file/2015/目录下,就存放着index.html这个文件,所以如果你需要删除该目录下的所有文件,只需要简单的rm这个目录就可以了。但是对于cache来说,目录往往不是按照url的层级来存放的,原因参见前面的系列文章。所以很难去确定一个文件在磁盘上的具体位置,更别提哪些文件属于哪个目录了。虽然也能通过二次开发,去做到这点,但是比较复杂,也很丑陋。

业界通用的解决方案是先登记一下要删除的目录信息,然后GET请求的url过来时,检查是否匹配某个目录。匹配的方法,最简单的就是基于前缀的比较,因为属于某个目录的文件,url的前缀(目录部分)是相同的,当然匹配的细节是比较棘手的,有两种方案,一种是使用整个url作为key,这样的话hash表会比较大,严重的问题是当请求过来时,你用哪部分url(或者说哪段目录)来算key去查hash表呢?必须得依次尝试不同层级的目录来算key查hash表。如果只把host作为key放到hash表里,那么hash占用的内存就变少了,但是目录部分就需要直接比较字符串来做匹配了。这块有很多优化的空间,大家多研究下。我们以后者为例来讲解下。

上面提到需要删除的目录应该预先登记在系统里,这往往是常驻内存的。凡是大规模存储数据的结构都要考虑资源的占用问题,过多的目录信息登记可能要配合LRU来做淘汰,以保存一定的内存占用率。有个比较好的策略就是针对每个域名限制可以同时产生的目录刷新请求的最大个数。

域名可以放到一个hash表里,一个域名对应的节点信息里有该域名下所有需要进行删除的目录的集合,数据结构可以用队列,也可以用tree之类的。队列有个好处就是,它可以自然维持一个lru状态,例如最近访问的在队列头,少访问的在队列尾。这样到达数量上限时可以比较方便做lru处理(从队尾删除节点)。而用tree之类的,就麻烦一些。当然刚开始的时候集合是空的。那么这些目录刷新的请求哪里来,如何登记在cache里?一般cdn都会自己定义一个内部的HTTP方法,跟GET,HEAD等价。这里我们用DEL来讨论。通常,cdn的客户会把需要删除的目录通过一定的接口报告给CDN的任务系统,CDN的任务系统会周期性或者触发式的,获取相应的任务,然后转化成一个DEL请求,请求格式跟普通的HTTP请求类似,例如:

DEL /file/2015/ HTTP/1.1
Host: xxxcdn.com
Connection: close

注意,这个DEL方法的请求,在cdn的cache中只会起到登记的作用。这里有点要注意,一个登记以后的待删除目录,需要有一定的过期时间管理。这是cache的特点,在cache里几乎所有的资源都是有保鲜时间的,原因很简单。cache服务的对象是热点,长时间没有用到的内容,就需要淘汰掉,腾出资源给别的内容。cache是个系统资源的吸血鬼!

登记完之后,一个正常的GET请求过来的时候,如果匹配了目录,就将该文件删除,当然这里的删除都是异步的,只需要打个标记,让该文件内容不可用即可。这样请求原本应该hit,现在转向了miss流程,也就起到了文件删除,并回源更新的目的。现在问题来了,那再来同样的GET请求,文件还是会被删掉,由于登记了DEL目录,那么属于这个目录的文件都无法再hit了。所以在登记的过程中,有个很关键的步骤就是要在登记的目录相关的数据结构里,保存一个时间戳(当前时间)。有了这个时间戳,凡是文件缓存时间在这个时间戳之后的,都认为是新创建的。而在这之前的,都认为是旧的文件。这样就可以把旧的文件删除,又不会影响新创建的。这个时间戳,也是会被刷新(再次被更新成当时时间)的,时机就在下次同样的DEL请求到来的时候。

配置热重载与持久化

当配置重新加载的时候,需要注意一点,例如原来有n个域名,现在注释了一个(n-1)或者新加了一个(n+1),原来登记域名的hash表就需要修改。所以一般要在重载配置的逻辑里要添加相应的逻辑。还有一点,目录的注册信息有过期时间,而定时器在系统里都使用一定的数据结构(使用的是非持久内存)来实现,如果你的配置热加载机制像类似nginx那样子,需要子进程退出来,那么你就需要在新进程起来之后,把之前的定时器给重新校对,保证不要因为重新加载了配置文件,而导致过时时间被无谓的延长了。持久化的问题方案很多,基本可以参考普通文件的缓存思路,就不细讲了。

总的来说,目录刷新的功能用到的技术点,基本上涵盖了一个缓存系统里一些最基本,也是最常用的一些处理手段,麻雀虽小,五脏俱全啊。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值