云时代, 本地部署的企业级软件在不扩容的情况下, 能做到短期内十倍的性能提升的确是一件令人侧目的成绩.
众所周知, x86 的性能已经被压榨到了极致, 带着种种疑问 SegmentFault 思否社区采访了云杉网络研发总监向阳. 访谈中, 向阳详细谈了在企业数据中心网络场景下各种时序数据库的表现, 并解释了云杉网络如何从工程的角度实现 x86 软件十倍性能的提升.
向阳: 云杉网络研发总监, 网络架构师. 负责云杉研发团队的管理和 DeepFlow 的架构设计和核心功能实现.
2013 年获清华大学计算机科学与技术博士学位, 师从吴建平教授并独立实现了世界上第一个基于关联分析的 BGP 劫持检测系统, 因此摘得 Internet Measurement Conference( IMC, 网络测量领域国际顶级会议)社区贡献奖. 2015 年获得清华大学博士后证书, 主要研究方向为云数据中心网络架构, 获得了多项网络安全, 云数据中心相关专利.
思否: 能否请您先介绍一下主要工作经历, 专注的技术研究方向, 以及目前所负责的工作.
向阳: 我的工作经历其实比较简单, 在加入云杉之前, 我在清华大学读博. 师从吴建平院士做一些包括域间路由的算法和结构, 域间路由的安全等等方面的工作. 毕业后, 我接触到 SDN 的领域, 也就顺理成章地加入云杉, 然后一直做 SDN 的研发工作直到现在. 现在我在公司是研发团队的负责人和 DeepFlow 产品线的负责人.
思否: 随着业务需求的提升以及云计算等相关技术的发展, 企业开始建立自己的云数据中心, 其中网络是云数据中心的重要组成部分之一. 您认为现代企业的云数据中心在网络架构的搭建上通常有哪些痛点? 企业应当如何应对这些挑战?
向阳: 我们能看到的企业在去做这一块的时候, 主要的一个挑战其实可以分为两个方面, 一个方面就是说怎么去建设, 另外一个方面, 其实还要去考虑到怎么样去维护它.
建设主要解决两个痛点: 一个是网络连通性的问题, 一个是网络服务化的问题.
为了支撑业务, 首先要把异构的资源, 混合云这些场景下做一个打通和互联; 然后在此之上提供丰富的网络服务, 包括像应用交付服务, 安全服务等等.
与上述问题平行展开的, 是复杂网络的运营维护问题. 因为现在网络会相当的复杂, 一般来讲 IT 基础设施会同时在公有云, 在私有云不同的资源池上, 此外还有虚拟化的一个容器资源池. 在这样一套 IT 基础设施上要打通一个统一的网络, 才能支撑业务的灵活需求.
比如说一个业务要想在容器的资源池里面去拿到几个 POD, 在虚拟机资源池里面拿到一些虚拟机, 在裸机资源池里面拿到几个物理机来实现一个业务需求, 这个时候实际上这些资源池是互相独立的, 但是从网络的视角看 (这个业务) 是一个整体, 要将上述资源池的这些网络打通, 做统一的编排, 这是一个挑战.
在此基础之上, 如果说我们把网络做了打通, 那么这个网络维护的难度也是非常高的, 不可能再由人工去做维护 -- 如果说这张网增加了 10 倍的复杂度, 那就意味着至少要投入 10 倍的人力, 这件事难以为继.
思否: 云杉网络为了帮助企业解决网络运维管理上的挑战, 早在 2016 年的时候就推出了云网分析产品 DeepFlow, 能否请您先介绍一下 DeepFlow 的核心组件, 功能特点以及应用场景?
向阳: 实际上我们把 DeepFlow 的一个解决方案划分成两个场景, 一个是采集分发, 另外一个是分析. 那也就对应着 DeepFlow 的整个产品中的三个核心的组件: 采集器, 分析器和控制器.
从组件的角度来讲, 控制器负责中央的管控和大规模 (采集器) 的管理, 因为我们的采集器会运行在很多异构的环境里面 -- KVM 虚拟化, VMware 虚拟化, 公有云的环境, 私有云的环境, 容器的环境, Linux 的环境以及 Windows 的环境 -- 这时采集器的特点是运行的环境异构, 另一个特点就是采集器的数量非常大.
控制器它需要做的就是一个集中的大规模的管控; 而采集器需要做的就是刚才对于这些异构环境的一个全网覆盖, 包括物理的, 虚拟的等等, 做一个全网的覆盖; 以及我们需要有一个高性能的策略匹配的算法.
因为如果对所有的流量数据全部做处理, 这个时候的资源开销将会非常大. 有的流量我们可能只是希望看一看, 有的流量我们希望把它的一些 counter 记录下来, 还有的流量会进入它的 pcap 文件, 进入它的一些详细的数据包, 以及把一些流量直接分发出去.
不同的流量需求, 我们就需要通过一个策略的体系去对它做一个相当于编排. 通过匹配, 把符合某意图的一些流量, 给到后端对应的消费工具里面. 这样的话我们在采集这一侧是需要有一个较强的策略匹配引擎, 再到后面我们的流量除了去分发给第三方的分析工具, 传统的 NMP,DPI 以外, 我们还能自己做一些分析, 这就是我们的分析器.
我们的分析器主要一个特点, 就是通过一个分布式的时序数据库, 来将网络中的所有的状态和统计数据存储下来. 这相当于对网络的全景视图做一个刻画. 客户再去做混合云场景下的一个网络排障的时候, 能把所有的这些关联点, 不同的网络, 不同的层面, 不同的 Overlay, 不同的 Underlay -- 比如说在容器的场景下可能是双层的 Overlay -- 把它们都联系起来.
再回到应用场景. 第一个是混合云上流量的采集和分发. 这种应用场景一般是针对于客户已经有了很多传统的分析设备, 比如说 DPI 的设备, NPM 设备等等, 但是他们苦于无法拿到虚拟网络, 容器网络里面的流量.
在虚拟网络的场景下, 网络的规模非常大, 现在一个服务器可以虚拟出来 10 个虚拟机, 一个虚拟机可能又有 10 个 POD, 这个数量是非常庞大. 因此在虚拟网络里你不能像传统物理网络那样通过分光, 镜像直接拿流量. 我们能做到全网覆盖, 按需的把流量拿出来给到后端的分析工具.
另一个场景就是混合云的网络诊断, 这实际上是网络分析的场景. 因为我们看到现在的云的网络是充分复杂的, 这里面有异构的资源池, 有不同层级的 Overlay, 我们怎样在这样一个复杂的网络环境下去做故障的诊断定位? 这需要我们有一个全网流量数据的分析能力, 即网络分析.
思否: DeepFlow 自 5.0 版本之后的每次更新都对性能进行了改善, 尤其是 5.5.6 版本后核心组件的性能再次大幅提升, 这是如何实现的? 是否与编程语言和数据库有关? 云杉为什么如此看重性能上的提升?
向阳: 首先来谈一谈这些性能的提升是如何实现的, 其实总的来讲包括几个方面. 采集这一侧, 我们是对于新技术有一些引入, 像 DPDK 以及像 Linux 内核高版本的 XDP 的技术, XDP 对于客户的环境的依赖是比 DPDK 要低, 并且流量的采集性能比我们上一代的技术能有 10 倍的提升.
另外补充说明一下我们对新技术的引入, 我们其实是走在了社区的前面, 2019 年发布的 CentOS 8 使用的内核版本对于 XDP 的支持其实并不好, 我们也从内核的层面对 XDP 的支持做了一些提升, 使得我们能在低版本的 Linux 环境里面将我们的采集器的性能提升上来.
另外一个方面是分析侧, 主要我们是基于数据结构和算法的一个优化. 我们整个 DeepFlow 平台, 绝大部分的组件都是基于 Golang, 稍后再讲我们为什么会去选择 Go. 我们对它原生的数据结构 -- 像 map 这样一些数据结构 -- 做了一些非常关键的算法和数据结构上的改变, 使得其性能都提升了 10 倍.
这里面我们有一些专利存在, 比如说我们对于 Go 的对象资源池, 内存池的一些改进, 对于 map 的一些改进, 这是在分析侧的优化.
然后就是在存储侧的优化, 我们是基于 InfluxDB 数据库, 对它的内核做了全新的开发, 实现了 10 倍读写性能的提升, 以及具有一个水平扩展的能力, 更重要的是使它更适合网络的场景.
回过头来说 Golang, 其实和语言的关系还不是太大, 如果说我们需要去追求一个极致的性能, 我们可能会去选择比如说像 C 这样的语言. 但这里还有另外一个问题, 就是我们的开发效率和适配性. 如果我们用 C 的话, 可能对于环境 (比如说 glibc 的版本) 的依赖会比较严重.
Go 其实是一个云时代的语言, 像 Docker 这样的技术, 就是构建在 Go 之上的, 其依赖是非常小. 我们选择 Go 能够在依赖性和开发效率上获得优势, 此外我们也会去克服它的缺点, 像它的 GC 带来的缺点, 它的数据结构带来的性能问题, 这些方面我们都做了提升.
最后说说我们为什么如此关注于软件的效率, 因为我们是一家软件公司. 硬件公司比如说做盒子的企业会更多地专注于做专用机之类的产品. 我们必须做一个云原生的平台软件, 这样它才可以运行在任何的地方 -- 在公有云里面, 私有云里面, 容器里面 -- 它不应该对于运行环境的操作系统以及物理的机器有任何的假设, 而且它还需要在不要求硬件环境的前提下给客户更大的效益.
也就是说硬件我们是没有办法改变的, 因此我们需要对软件的性能有一个极致的追求, 这样才能给客户带来价值.
思否: 云杉网络在产品研发过程中曾采用过开源时序数据库 InfluxDB, 那么 DeepFlow 进行数据库选型与开发的依据是什么? 在 DeepFlow 持续迭代的 3 年时间中, 在数据库选择方面是否有经历过变动?
向阳: 回到三年前, 我们最初在做这个产品的时候, 发现时序数据库的发展并不好. 当时时序数据库都是基于一些传统的数据库来做的, 它不是一个直接面向时序数据场景的数据库. 比如说 Elasticsearch, 它其实是一个搜索引擎, 但被当做时序数据库在用.
当时 InfluxDB 的版本是在 0.x 的时代. 我们最初同时在使用 Elasticsearch 和 InfluxDB. 一方面依赖于 Elasticsearch 的稳定性, 以及它的大规模的水平扩展能力; 另外一个方面我们当时其实也看到了, 时序数据是一种新的数据类型, 它不能够直接全部在现有的这些数据库里面去存储, 所以我们当时在小范围内选用了 InfluxDB.
后来我们有一个重要的版本调整, 因为 Elasticsearch 作为一个搜索引擎消耗的资源量实在太大了, 它不太适合于时序这个场景, 更不太适合在一个大规模网络监控数据的场景下做存储. 因此我们又全部切换到了 InfluxDB, 这相当于是我们数据库选型的第二阶段. 再往后其实就是第三阶段, InfluxDB 在开源的版本里曾经一度存在过集群的解决方案, 但是在某个版本之后被删掉了 -- 这个功能变成了商用的解决方案.
这是我们切换数据库的一部分原因, 其实另外一部分原因, 也是更重要的原因在于我们发现 InfluxDB 不太适合网络的场景. 我们用普通的时序数据库去监控 1 万台服务器, 这 1 万台服务器每个时间点比如说每秒它都会有一个 CPU 的值, 那么其数据量就是每秒 1 万的量级.
也就是说这些监控数据是和被监控服务器的数量强相关, 但是在虚拟网络场景下, 机器 (虚拟机) 的数量高出几个量级. 还是上面的场景, 这时如果有任意两个机器之间互访, 这个数据虽然到不了前面所说数据的平方量级, 但是仍能高出几个数量级以上, 而且这种访问的关系还能够去和其他的维度, 比如说协议类型(TCP/UDP), 端口号以及服务的数量直接相关. 这里面的数据是一个非常高维度的存储, 而且是一个相当于稀疏矩阵的存储, 它和经典的时序数据库的应用场景还是不太一样.
另外网络的场景下面也存在一些特定的一些需求, 比如说查询一个网段, 做一个网段的权重匹配, 尤其是网络流量基本都是通过负载均摊的方式给到不同的机器去处理. 在这样大的一个数据体量下, 这个时候我们如何去把不同机器处理的结果聚合之后存储下来, 这些场景 InfluxDB 都是不支持的. 所以我们基于 InfluxDB 核心的存储和查询引擎, 在此基础上做了性能的提升, 做了水平扩展的支持, 做了高可用的支持, 以及做了更多的网络数据的查询, 聚合, 过滤的支持. 这样最终形成我们现在使用的, 自研的网络时序数据库.
我们其实测过像 Prometheus 这样的很多后端的长期存储方案, 因为 Prometheus 适合短期的数据存储 -- 通常就存一到两天. 它有很多后端的存储, 像 S3DB (Simple Sloppy Semantic Database),VictoriaMetricsDB 等有很多这样的数据库. 从开源社区的时序数据库排行来看, InfluxDB 是排在第一位的, 但是其他的数据库会比它的性能测试数据要好看.
这个性能测试其实也是各家测的, 而且很重要的一点, 其它的数据库往往是局限在某个特定的场景下的测试数据比较好看, 或者它的使用量还没有达到广泛使用的程度. 所以我们在考量的时候, 也基于 InfluxDB 去做自己的时序数据存储.
另外一个层面, 现有的时序数据库都是基于相同的场景, 即对物理服务器进行固定频率的监控, 而网络监控的场景不是这样. 网络监控的对象是海量的一维 IP, 二维的 IP 对, 三维的 IP 端口号等等, 这显然不是固定频率的监控, 而是一个稀疏矩阵的监控. 这种差异性使得我们现在也在考虑, 例如所有现存的时序数据库都在使用 TSM 这种数据存储结构, 因此我们也在这种数据存储结构上进行下一代产品的研发, 使之支持稀疏矩阵的 TSM 特性, 以便更好的去存储和检索网络数据.
简单的说, 因为 InfluxDB 的使用范围更广, 更成熟, 更稳定, 而且其他的时序数据库在最底层的算法层面和 InfluxDB 实际上是一样的. 那么也就是说这个测试性能的差异, 可能是测试方法或者使用场景或者其他方面的差异, 我们认为这个 (测试性能) 差异其实是可以忽略的.
思否: 云杉网络在产品研发过程中采用了开源的数据库组件, 目前对开源有什么想法吗?
向阳: 我们目前还不是一家开源软件驱动公司, 未来我们可能会把一些组件反馈给社区. 我们也看到在 InfluxDB 社区版本把集群的能力拿掉了, 我们认为我们的集群功能做的还是相当好的, 它非常方便运维, 不依赖于像 zooKeeper 的 ZAB 或者 Raft 这样的集群协议, 是一个非常适合时序数据场景的高可用的集群方式. 如果我们把自研的集群实现以及水平扩展的查询能力贡献到社区, 这对于社区的运作可能会有冲击, 因为社区已经把一部分能力放到了商业化的版本里面.
思否: DeepFlow 开放了开发与数据的接口, 客户可以在 DeepFlow 上开发个性化的应用与工具, 那么 DeepFlow 目前支持哪些编程语言?
向阳: 对于客户自定义开发, 我们现在提供了两种方式, 一种方式是 API, 这个 API 因为它是 Restfull 的, 所有的语言都能够去调用.
另一种方式是基于 Python 的 SDK, 我们看到 Python 有很多方面的优势, 包括它的用户基数大, 使用门槛低以及拥有丰富的库, 它在数据处理和网络编排等方面有天然的优势.
思否: 未来还会在编程语言的支持上进行扩展吗, 比如 Java? 这些客户自行开发个性化的应用会影响 DeepFlow 的性能吗?
向阳: 目前我们在这一个方面的计划主要是客户驱动. 客户通过我们的 API 自行开发的应用对 DeepFlow 的性能不会产生什么影响. 在我们的产品模块里, InfluxDB 存储引擎之上还有一个分布式的查询引擎, 它主要做很多分布式的计算. 实际上 API 调用是把计算的任务交给了我们的分析器集群, 大量的工作是在分析器的集群里完成的. 因此 API 调用方的效率不会成为整个查询链条的瓶颈, 因为最终给到 API 调用方的数据是一个充分聚合后的数据结果, 它的体量和我们在平台里面存储的数据 (例如一个月的网络数据) 相比远不是一个量级. 不管客户选择什么语言进行自定义开发, DeepFlow 的性能都不会受影响.
思否: 当前环境下, 互联网公司在产品研发上大都会选择敏捷开发, 快速迭代的方式. 而 DeepFlow 则在 5.0 版本之后实现了软件架构的解耦, 那么是什么因素促使你们决定这样做的呢? 您又是如何看待软件架构稳定性与需求变化快速应对能力之间的平衡的?
向阳: 我们在 DeepFlow 研发的过程中, 版本迭代周期也在不断变化. 在三年前我们的迭代周期是 6 个月 -- 这对于一家 to B 的公司比较常见. 但是我们的产品是运行在云的环境下, 快速迭代的能力非常重要. 我们必须将产品快速交付给客户, 而客户的环境对我们来说不是一个可运营的系统, 也无法让我们的产品一天更新多少次. 我们需要在这种情况下做一个取舍, 确保我们的迭代周期要尽量低, 同时产品的稳定性要非常高.
在这样的背景下, 我们做了 DeepFlow 平台的解耦, 使得其迭代周期从三年前的 6 个月逐步降到 3 个月, 再逐步降到现在的 6 周, 满足了我们对客户需求的快速响应 -- 不是在项目中, 而是在标准化的产品版本中就能满足.
我们用产品化的思路应对不断增长的客户需求, 解耦后的产品分上下两层, 上面是应用层, 下面是平台层. 平台层追求的是高性能和稳定, 应用层追求的是灵活性和高效率. 在产品迭代过程中, 我们可以有选择的去安排上层和下层的迭代周期. 比如说在连续的几个版本里面, 底层的平台是不需要迭代的, 但与此同时, 每一个版本我们都可以对上层的应用做更新, 以满足客户的新需求.
思否: 除了实现解耦之外, DeepFlow 在软件架构上是否还进行了其他方面的调整? 原因是什么?
向阳: 我们在 DeepFlow 研发过程中有一个非常明显的变化, 最初我们在做这个产品的时候使用了大量的开源组件, 这其实也是很多同类产品的做法, 但这对产品的稳定性是一个非常大的考验. 因为开源组件更多的是面向运营, 需要有人去值守; 因为代码不是完全由我们自己掌控的, 一旦出了问题, 解决的速度也会比较慢.
后来我们慢慢的去切换到了另一种模式, 即自研大量的组件. 现在我们产品里完全属于开源组件的是 MySQL, 因为它实在太经典, 太稳定, 我们不需要对它做什么改动; 除此之外, 其他组件都是我们自研的. 我们从以前充分使用开源组件走到了自研加使用开源的库的道路上来. 因为开源组件比如 Elasticsearch 的核心其实很稳定, 但它的很多周边组件比如输入输出, 启停等操作往往容易发生问题.
我们现在会用一些非常成熟的库, 我们也会像替换 InfluxDB 一样逐步替换其他组件, 现在我们仅仅只是有 InfluxDB 核心的存储和查询引擎, 但这一部分我们也在慢慢替换, 因为 InfluxDB 基于经典的 TSM, 不太适用于网络的场景.
思否: 产品组件里 MySQL 跟 InfluxDB 主要承担的角色有什么不同吗?
向阳: MySQL 主要是存储一些 metadata, 我们叫做元数据, 就是一些业务层面的数据; 而 InfluxDB 存储的是时序数据, 即有许多资源对象, 它们每时每刻都在生成一些统计数据, 我们将这部分时间维度上的统计数据存在了 InfluxDB 里面.
思否: 元数据和时序数据存在不同的地方, 查询时的性能会不会有影响?
向阳: 这两种数据存在同一个地方并不太适合对数据进行维护. 比如对于业务数据或者关系型的数据, 例如对一个虚拟机关联的 Interface, 关联的 IP 怎么去做增, 删, 查, 改?
如果每个时间点都去存对应的信息, 一旦虚拟机本身产生了变化 (这种情况经常发生), 那么就需要对它的历史数据做相应的改变. 而时序数据则不同, 时序数据是面向特定的对象的固定时间点的统计数据, 基本不存在对于历史数据做修改的情况; 唯一需要做修改的场景是在做故障恢复时, 或者该对象有变动时. 举个容易理解的例子, 数序数据的存储场景有点就像对电商的产品页面做存储, 一个 SKU 的商品名, 图片, 介绍等属性(特定对象) 很少变动(除非下线), 但价格和库存的实时数据经常在变, 甚至一直在变.
思否: DeepFlow 自身的应用在调用平台层的时候跟客户开发个性化应用时的调用有什么不同?
向阳: 区别就是我们给客户加上一个权限认证的机制, 其他的没有大的区别. 系统原生的应用和客户自己开发的应用是完全平等的. 我们非常重视让客户加入整个产品链条中来, 包括客户开发一些应用, 以及客户在我们的产品里生成的数据.
思否: 云杉的客户主要都是集中在金融, 电信, 制造这些传统行业的企业, 我们对这些企业的印象一般都是慢. 这些客户的业务没有那么多的快速变化, 为什么云杉要在性能上, 在快速迭代上, 去做这些极致的提升?
向阳: 事实上现在客户的整体技术环境已经发生了变化, 尤其是 IT 的环境. 比如在金融银行的客户已经在生产环境大规模使用包括虚拟化, 容器, 微服务等应用. 实际上客户对新技术的引入是比较快的. 另外一个层面, 这些客户以前买的确实都是 "盒子", 现在在云的环境下要去买软件. 如果我们的软件去消耗了客户过多的硬件资源, 这时软件的价值其实很难体现出来.
思否: 那么下一阶段 DeepFlow 准备将在哪些方面为客户带来新的提升? 是否能透露 DeepFlow 接下来的研发重点?
向阳: 在前面一个阶段, 我们主要将 DeepFlow 数据的采集能力和一些数据统计的能力进行了产品化. 下一个阶段主要是提升数据的智能分析能力. 智能分析能力首先体现在诸如怎样去对于一个网元设备前后的流量做关联等, 例如一个防火墙, 一个负载均衡器前后的流量, 究竟哪些流量属于同一个会话? 一个客户访问负载均衡器, 负载均衡器又访问一个后端的主机, 这个访问链条该怎么绘制? 这些体现的都是智能分析能力.
另一个层面是对于不同网络层的关联, 像容器网络的数据和下一层虚拟化网络的数据和再下一层物理网络的数据该怎么做关联? 在混合云场景下的这种关联能给客户带来一个完整的, 端到端的逐跳诊断能力, 这是我们产品演进的一个重要方向. 我们现在已经采集了非常多的网络数据, 怎样基于这些网络数据做智能的基线告警, 做故障的告警处理, 以及做故障的预警, 这都是我们下一步要做的事.
从客户的使用层面, 我们会更多的去关注客户生成的数据. 刚才也提到 SDK 的方式是一种客户参与的手段, DeepFlow 主要还是做一个数据的平台, 我们不会限定客户怎么使用这个平台, 客户有自己解决问题的想法和思路. 我们让客户在这个平台之上去灵活地构建一些监控数据的视图, 能便捷地从这些视图中 DIY 自己的监控大屏, 这是我们对客户定制化能力的提升.
思否: DeepFlow 有针对行业做一些调整吗?
向阳: 我们主要是从解决方案的层面做调整. 我们会组合上下游的产品构建完整的解决方案去给到客户, 面向不同的场景, 解决不同的问题.
思否: 对于未来的云网络工程师来说, 您认为可能需要掌握哪些技能才会适应将来云时代的发展?
向阳: 以前对于一个网工来讲, 面向的是 CLI, 有时需要做一些自动化的工作, 比如写 Expect 脚本去抓一些 SNMP 数据, 但这个时代正在慢慢的成为过去. 现在的网工可能更多的是从两个方面提高自己, 说到这里我打个招聘广告, 欢迎对 SDN 有兴趣的同仁加入我们: https://www.liepin.com/company/8485026/
首先是自动化. 现在一个网工管理的设备数量级是以前管理的十倍, 自动化肯定是必须的. 刚才提到的 Python 其实是比较适合自动化的编程语言, 而且它的准入的门槛也不高.
其次是面向复杂系统的数据分析能力. 不同岗位的人对一个系统监控数据的需求不尽相同, 不能期待有一个产品级的东西点一下鼠标就能解决所有问题. 网络工程师需要具备, 基于采集到的数据稍加处理, 能够得到一个自己想要的结果的能力. 在网络数据之外可能还有一些系统的数据, 例如日志的数据, 怎样去做这些数据的关联和分析, 目前仍然需要人的创造力.
来源: https://segmentfault.com/a/1190000022427563