深入浅出腾讯云 CDN:缓存篇

作者介绍:吴锐,开源爱好者。曾在阿里巴巴搬砖,目前就职于腾讯担任高级工程师,专注于创造高效代码。

1. 引言

互联网的发展为CDN的发展带来了巨大的机遇。不论是视频点播,直播或者VR技术都需要CDN做为传输内容的载体。老牌CDN服务商网宿2016年上半年CDN业务的营收比上年同期增长达到76.04%。

但是CDN作为云基础服务中关键的一环,一直是各个云服务器提供商的必争之地。腾讯云如果需要在竞争中取得一席之地,就需要能够从容应对云上这些复杂的内容进行处理。原有CDN服务器的存储引擎在处理视频文件,以及复杂的HTTP协议内容上出现了瓶颈,改造迫在眉睫。

2. 问题

对于视频这种大文件,原有SSD盘的存储容量无法保证热点文件存储在缓存中,因此SATA盘这种大容量磁盘被应用到了CDN边缘节点中用来缓存视频大文件,以保证CDN边缘节点的命中率。

但是原有CDN服务器存储引擎在SATA盘上的表现并不理想,如下图所示,在TS6上只能跑600Mbps流量,并且IO也处于比较高的水位,这限制CDN节点的服务能力。

图1 DiskTank在TS6上的处理能力

另外,在某些业务场景下服务器会导致CPU毛刺的出现,定位发现是原有存储引擎的一些限制以及处理流程的问题导致的。不能挡在业务前进的路上,存储引擎的改造势在必行。老的存储引擎为DiskTank,新改造的存储引擎因为历史原因命名为DiskTank3。下文就将老存储引擎成为DiskTank,新引擎成为DiskTank3。

图2 DiskTank的CPU毛刺

3. 硬件层

首先我们考虑是否完全充分利用了磁盘的性能,什么读写方式才能将磁盘的性能最大化。在调研了磁盘相关的构造后发现,经过对齐之后的写操作能够带来巨大的性能优化。

不管SSD盘或者SATA盘都有最小的操作单位,可能是512B,4KB,8KB。如果读写过程中不进行对齐,底层的硬件或者驱动就需要替应用层来做对齐操作,并将一次读写操作分裂为多次读写操作。

如下图是在同一台TS8服务器上进行测试的结果。每次操作块大小为130K的吞吐能力仅为128K的21.65%。每次操作的块大小变大了,性能反而出现了明显的下降。

这是十分反直觉的,并且也说明了对齐的重要性。因此DiskTank3的第一个优化就是将写入的数据都进行Page对齐。目前不论SSD盘或者SATA盘的Page都为4KB的倍数,因此DiskTank3写入数据时按照4KB进行对齐。当然,这个参数是可调,方便后续调整。

图3 128KB块大小吞吐量测试

图4 130KB块大小吞吐量测试

4. 系统层

接下从系统层开始考虑从系统层面开始优化。

第一,在运营过程中发现在内存吃紧时,即使Page Cache中还有空闲内存时,内核会使用Swap的内存,或者是回收内存带来额外的CPU开销等问题;

第二,文件系统的元数据也会有IO的开销。而CDN的存储引擎自己进行缓存数据的管理,完全可以使用裸盘进行读写。消灭文件系统的开销。如下图所示,DiskTank3中支持越过文件系统直接使用裸盘读写,来完全解放磁盘IO性能。

图5 IO处理流程

直接使用裸盘带来的另一个好处是可以使用内核提供的异步IO功能。异步IO可以解放CPU,进一步提高服务器的处理能力。目前DiskTank3已经支持异步IO。但是异步IO在IO没有完成之前,写入缓存会占用内存空间。需要对这部分内存进行限制,防止消耗过多内存影响服务器正常处理。

5. 应用层

最后再来考虑从应用层面优化。主要优化点有:

5.1 文件分片存储

DiskTank存储文件时候使用连续的存储空间。当需要淘汰老文件,挪出空间来存储新文件时,就需要将整个老文件从缓存中删除。对小文件这并没有什么问题。但是如果为了存储一个4KB的小文件而将一个1GB的文件从缓存中删除,这明显得不偿失的。

因此,在DiskTank3中,所有大文件都会被分成一个个1M的数据分片进行存储。这样在淘汰时也只需要淘汰一个1M的数据分片,在需要时也只需要拉取一个1M的数据分片即可。这解决了DiskTank在淘汰大文件时引起大量回源流量的问题。

同时,分片存储也带来了另外一个好处,就是CDN的缓存可以支持变长文件。这在客户源站只支持HTTP中的分块传输(Chunked transfer encoding),这种不知道文件大小长度的情况下就十分有用。

DiskTank由于在存储之前需要知道文件的确切大小,因此之前的做法是先在内存中接受并缓存数据,等到接受完毕确定文件大小后,再存储到缓存中。DiskTank3可以将数据直接写到缓存中,降低了内存和CPU开销。

图6 DiskTank存储与淘汰方式

图7 DiskTank3存储与淘汰方式

5.2 元数据与文件数据隔离

另外在运营中发现,在某些场景下,元数据频繁的被读写。导致元数据的读写IO开销变得十分明显。而元数据与正常文件数据是存放在同一块磁盘中,这影响了正常文件数据的存取。

因此,在DiskTank3中可以将元数据与文件数据分开存储。元数据可以存储在IO能力较强的SSD盘中,而文件数据则单独存储在数据盘中。在小文件场景下,甚至可以将元数据存放在内存文件系统tmpfs中,完全规避元数据的IO开销。

5.3 小文件忽略缓存头部

第三个优化点在于提高小文件的存储效率。CDN在缓存文件的同时会将和文件相关的一些信息,如HTTP头部,Mtime和Host等信息,作为头部存储在缓存文件的开头。这部分数据大小为几KB。在小文件业务,大量文件的长度也就为几KB,缓存头部就占据了将近一半的存储空间。部分业务并不需要这些缓存信息,因此可以将这部分缓存头部省略,进一步提高存储利用率。

5.4 单盘容灾

最后,运营海量服务器的场景下,坏盘变得频繁。

如果运维收到告警后,人肉处理就需要比较长的响应时间,甚至影响服务器上业务的运行。新版本的DiskTank3支持将坏盘自动从缓存中剔除坏盘,坏盘问题不会中断业务的正常运行。坏盘在被剔除之后,缓存会在剩余的其他磁盘上重新Hash分布,不影响正常文件存取。

6. 总结

在进行优化之后,将老版本的DiskTank与新版本的DiskTank3在同机房选择了两台机器,使用相同业务进行压测对比。流量提升40%,负载降低13%,消耗降低31% 。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

吴锐的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏kevin-blog

解决在/etc/porfile下设置环境变量以后zsh没有起效的问题

今天在添加java的环境变量的时候,我在/etc/profile添加了环境变量,因为我使用的是zsh,在source /etc/profile以后,zsh的主题...

2261
来自专栏风中追风

分布式进阶__动物园园长 zookeeper

数据的发布/订阅(配置中心:disconf) 、 负载均衡(dubbo利用了zookeeper机制实现负载均衡) 、

42317
来自专栏腾讯移动品质中心TMQ的专栏

【 测试左移专栏 】PiTest 测试左移 :谈手机管家测试左移实践

说起“测试左移”相信对于大家来说已经不再陌生,左移的也手段非常多,无论是使用NLP来做需求分析,还是使用ACC来做测试建模,目的都是希望将隐藏的缺陷提早暴露。今...

5570
来自专栏Java开发者杂谈

CentOS探索之路2---使用rpm安装JDK

1493
来自专栏技术博文

linux 设置中文版man手册

作为CentOS 新手,看懂英文man固然重要,不过配置好中文man也可以让自己更快速地学习! 1. 下载中文man包 源码的网址:https://src.fe...

2965
来自专栏开源优测

性能测试必备监控技能windows篇13

前言 在手头没有专门的第三方监控时,该怎么监控服务指标呢?本篇就windows下监控进行分享,也是我们在进行性能测试时,必须掌握的。下面我们就windows下常...

3695
来自专栏CaiRui

Mysql-15-mysql分布式应用

1.分布式应用的概念和优势   分布式数据库是指利用高速网络将物理上分散的多个数据存储单元连接起来组成一个逻辑上统一的数据库。分布式数据库的基本思想是将原来集中...

2108
来自专栏猿天地

内网穿透工具-ittun

相信大家在工作和学习都避免不了快速外网调试。比如微信支付、支付宝支付,消息推送,短信发送,邮件发送等等。都需外网能访问你本地服务器进行调试。 软件下载地址:h...

4598
来自专栏用户2442861的专栏

CMake与Make

但如果源文件太多,一个一个编译时就会特别麻烦,于是人们想到,为什么不设计一种类似批处理的程序,来批处理编译源文件呢,于是就有了make工具,它是一个自动化编译...

801
来自专栏架构师之路

php使用tcp长连接的一种优化思路

一、面向人群 如果站点架构满足以下几点,那么本文的优化方案会非常适合: 1)使用php等脚本语言作为开发语言 2)需要连接后端服务,例如RPC服务、memcac...

3006

扫码关注云+社区