CDN 的缓存数据是怎样实现分片的,怎样有效的实现各分片的存储及删除

泻药,首先如何实现分片:CDN的cache服务器一般都自己实现了一个文件系统,以一定大小分片为基本存储单位,而而当下游(也就是请求资源的用户)发起请求时,cache服务在向上游(就是提供资源的源站)拉取资源时,以一定的固定大小分片保存在自己文件系统的各个单位中,并有自己的索引方式可以找到各内容的各个分片和总体信息。题主第二个问题,关于效率,一般会采用LRU或LFU的算法把经常命中的内容存在内存内,以增加访问速度。此外linux系统自身vfs的缓存机制也有利于常用内容在内存中命中。同时因为分片存储必定伴随着分片淘汰,删除的高效方式是在删除的时候只删除对分片的索引,不删内容,且索引一般保存于内存,内容则在下次写入时直接覆盖。此外在随机淘汰之后,普通的文件系统会变得零散,而对于硬盘中零散的块,读写效率降低,怎样做到高效。目前比较先进的方案是采用随机读,顺序写的方式,也就是所谓COSS环形对象存储系统,这里不展开了具体实现参见ATS和squid的源码。PS话说没注意题主都加了squid 的标签,squid开源,你既然想知道细节就去读源码或者懒一点读分析的文章啊
■网友
没有看过 ngx_http_slice_module 但是设计实现过视频CDN的分片. 所以厚脸皮还是回答一下.
分片从应用角度来说, 可以分为几个层面: 存储, 分发, 服务
对于大文件来说, 分片肯定是非常有用的:
大文件的分片分发能够大大提高分发效率和缓存速度. 分片存储 可以将一个内容存在多个磁盘甚至多台机器上, 这可以提高存储设备的负载均衡, 容错, 性能可扩展性等很多方面的能力. 分片服务肯定是必需的, 你可以理解为类似HTTP Range的东西, 当然根据应用协议会有所不同, 假如一个视频不能拖动那怎么可以忍受? (其实最开始的土豆优酷就是除非已经客户端缓存否则无法拖动的)注意分片存储的话, 和分片分发和服务本身并没有什么必要的关系. 比如BT协议, 假如在本地就是一整个文件, 但是不妨碍你做逻辑的分片来P2P分发(只要应用里面做个逻辑分片索引即可). 比如RAID5可以认为是一个基于磁盘的分片, 但是在服务/分发上, 都可以视为整个文件来操作. 另一个方面, 即使存储分发服务都是分片的, 但是他们的分片之间可能没有什么联系, 分发和服务经常是以Bytes或者KB为单位, 但是存储分片为了效率和性能考虑, 常常是MB以上的单位.
对于分片存储, 其实提问者可以先了解FAT32和Ext2/3 , COSS之类的文件系统, 再根据 CDN缓存的设计难点去理解一些分片方式的设计要点. 主要还是缓存单位的大数量,碎片化和管理, 以及因为上面几个带来的性能方面的折中. 很多时候是要根据特定的应用和缓存场景来设计的, 比如做视频的, 很多视频用户就看个开头, 所以删除的时候, 一些不是很冷的片子可以保留开头的分片. 删除效率方面, 很多场景下面只要删除分片内容的索引即可, 实际分配的空间可以以后在合适条件下回收(大部分文件系统都是这么设计的).
不同场景的方案也有不同的考量, 还是得多了解一些实现, 看文档和代码, 然后考虑怎么规避他们的缺点. 比如一些文件系统, 将缓存单位ID hash化以后, 再来存储, 因为hash无法逆向, 所以这样的实现假如没有一些辅助措施, 很难实现比如删除某个目录下所有文件的操作或者删除URL匹配某个正则表达式的操作的.

■网友
缓存跟存储其实是分开的,缓存可以分片,存储并不要求分片,只需要支持范围读取即可。至于缓存更新,可以参考动态内容缓存方式。比如etag。存储我觉得没必要分片,缓存分片就可以了。
■网友
【CDN 的缓存数据是怎样实现分片的,怎样有效的实现各分片的存储及删除】 比较好奇在源站不支持 Range 的情况下,我们有没有什么方案可以在 CDN 上打开该功能


    推荐阅读