BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

ContainerDNS性能优化之路 17W到1000W QPS超高性能DNS技术实践

| 作者 京东商城基础架构部 关注 0 他的粉丝 发布于 2018年3月23日. 估计阅读时间: 16 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

一、 引入

随着TIG阿基米德平台全面应用。组成京东容器生态技术栈的分布式域名解析服务ContainerDNS(go版https://github.com/tiglabs/containerdns )全量生产环境应用,承载着每天百亿的访问量,单实例峰值每秒请求达到15W QPS,已经接近ContainerDNS的性能极限(17W QPS)。为了更好的提高系统的并发服务,对ContainerDNS 的优化也势在必行。

本文对ContainerDNS性能优化思考和技术实践历程,希望对业内在容器领域和域名解析方向技术实践一些启迪。

ContainerDNS 的DNS Server 代码用Go 语言实现,我们在后期的优化中,通过各种尝试,并通过pprof 采集数据分析,发现性能损耗最大的是收发包的地方。同时我们对bind9 进行了压测、采集分析发现同样是收发包函数最为耗时。

数据平面开发套件DPDK(Data Plane Development Kit)可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。灵感来自TIG容器生态技术栈另外一个重要的服务高性能负载均衡服务Jupiter (https://github.com/tiglabs/jupiter )实现单实例200万QPS的高性能。因此TIG团队工程师想到用DPDK 来实现DNS数据报文的收发是一个有挑战和前景的尝试。

二、系统概述

让我们先来回顾下ContainerDNS设计之初的愿景和初心。ContainerDNS作为京东商城新一代软件定义数据中心的关键基础服务之一,具有以下特点:

  • 分布式设计 多数据中心数据同步复制 避免维护多个域名解析元数据副本
  • 支持自动发现服务域名 支持容器Service
  • 支持后端探活
  • 易于维护、易于动态扩展

图一 ContainerDNS 架构图

ContainerDNS 包括四大组件 DNS server、service to DNS 、user API 、IP status check。这四个组件通过etcd 数据库集群结合在一起,彼此独立,降低了耦合性,每个模块可以单独部署。DNS server 用于提供DNS 查询服务的主体。service to DNS 组件是k8s 集群与DNS server的中间环节,会实时监控k8s集群的服务的创建,将服务转化为域名信息,存入etcd 数据库中。user API 组件提供restful api,用户可以创建自己的域名信息,数据同样保持到etcd数据库中。IP status check 模块用于对系统中域名所对应的ip做探活处理,数据状态也会存入到etcd数据库中。如果某一个域名对应的某一个ip地址不能对外提供服务,DNS server 会在查询这个域名的时候,将这个不能提供服务的ip地址自动过滤掉。

KDNS(DPDK DNS 简称) 不是ContainerDNS 的否定而是其延续,我们只是替换了DNS server模块,采用C语言,并且是基于DPDK全新实现。ContainerDNS探活模块、API 模块、k8s监控模块都是可以复用的,对于工程来说具有很好的延续性。如上图所示KDNS Server进程部署物理机上,同时部署quagga 进程,对外发布一个VIP。这样可以实现KDNS Server的多活,同时Client 端经过路由器访问DNS Server 的VIP,路由器对BGP 协议的支持,不同的访问可能会访问到不同的KDNS Server 上,可以实现一定的负载均衡。这样设计方便后期的升级扩展,关闭quagga 程序数据就不会打到对应的KDNS Server,然后版本升级,开启quagga发布VIP,新的Server 对外提供服务。可以很方便在服务不中断的条件下进行KDNS Server版本的动态回滚、升级。同时可以方便的监控KDNS,如果不能提供服务可以将此物理机上的quagga杀死,这样这台服务器就不对外提供服务。这种设计方式的实现可以很方便的实现热升级、高可用。下面将主要介绍DNS server 基于DPDK的实现。

三、 KDNS系统设计与实现

DNS server 是提供DNS的主体模块实现架构如下图:

如上图所示,系统中用到的CPU核有两种角色:主核和从核。主核相当于控制通道,域名数据、交给协议栈的数据都是主核处理。从核主要处理数据通道的数据,通过DPDK网口收包,报文解析处理,解析结果发包给用户。

Data Plane Development Kit(DPDK):是运行在Linux用户态,实现X86通用平台网络报文快速处理的库和驱动的集合,其主要特点:

  • 多核编程框架及CPU亲和性
  • 巨页(HugePage),减少页表项数目,降低TLB miss
  • 无锁队列
  • UIO支持,用户态驱动,减少报文copy
  • poll-mode网卡模式,无中断轮询收包

为了充分利用DPDK的特性,我们根据功能将KDNS 划分为:数据收发模块、协议解析处理模块、转发报文处理模块、域名信息数据处理模块、ARP/BGP协议报文处理模块等。数据收包、协议解析都是跑在从核中,转发报文处理模块、域名信息数据处理模块为单独的处理线程处理,ARP/BGP协议等协议的支持由主核通过DPDK的KNI 接口发送给内核协议栈,发送数据由主核发出。每个包数据、域名数据在各个模块中的交互,通过DPDK的无锁队列实现。并且对外提供RESTful  API 接口,用户可以对域名数据的更新。为了结合ContainerDNS其他组件的使用,我们这里开发了DNS-agent 进程,此进程go 语言实现会监控etcd的数据变化,实时将域名信息通过RESTful  API 接口更新到KDNS Server 中。当然KDNS完全可以脱离ContainerDNS的生态环境运行,只要通过RESTful  API 接口就可以更新域名数据,这样KDNS 就可以正常工作起来。

下面是主核的处理流程:

首先创建和Restful API 数据交互的domain-msg-ring,域名变更处理线程检测到域名变更数据,会将数据放入domain-msg-ring中,主核后面会进入一个死循环,首选处理域名变更,并将变更的数据分发到所有的从核,从核同样在循环处理的时候回首先更新域名数据到本地缓存中。然后主核会检测是否有从核发过来的数据(例如ARP 请求),主核将数据转给DPDK 的KNI 接口交由Linux协议栈处理。然后主核调用接口从KNI收取数据,如果有协议栈发过来的数据,调用DPDK的发包函数rte_eth_tx_burst 将数据发送出去。然后主核判断是否有转发域名数据,如果有同样调用rte_eth_tx_burst 将转发域名请求的结果发送出去。这里主核只负责发包,转发查询上级DNS Server 全部由后台的转发处理线程处理,不会影响主核的处理速度。

从核的处理逻辑较为简单,首先调用处理主核发过来的域名数据,从而及时改变自己的域名数据缓存信息。然后调用DPDK收包函数rte_eth_rx_burst 收取报文,如果有数据则进行数据包解析处理,参考下面的协议解析处理模块。如果是本地zone 的域名查询,将查询的结果直接发送给客户端。如果是ARP请求,则将数据包放入kni-pkt-ring 中交由主核处理。如果是转发域名,则交由转发报文处理线程处理。

数据收发模块:采用DPDK的收发包接口,开DPDK启RSS (Receive Side Scaling,多 CPU之间高效分发的网卡驱动技术),由于DNS 访问基本是UDP包端口是53,RSS采用了对IP和端口进行Hash的方式,当客户端很多的时候可以有效地实现多核的均衡。为了更好地提高性能,系统中每一个从核只处理一个收包队列上面的数据。发包也是只发送对应队列上的数据。所以收发包数据间,所有的核都是独立的,没有任何耦合不需要任何锁机制,更加快速。

协议解析处理模块:每一个从核通过DPDK 接口收到数据包,进行数据包解析。并将结果返回给客户端。流程图如下:

转发报文处理模块:系统所有的域名数据都是基于某一个或者多个zone进行的,如果域名不在本地支持的zone内就要将请求发送给上级的DNS Server,比如我们的DNS Server 支持本地的zone是 tst.local,也就是说所有访问*.tst.local的域名本地的DNS Server 都会查询解析,如果用户访问的不是*.tst.local的域名就得转发给上级的DNS 进行解析,这个转发的处理流程较慢,我们采用了一组后台的线程进行处理,这些线程不会绑定到CPU上,完全与主核、从核的功能分离开来,这样主、从核都不会处理这样的慢速数据请求。

首先数据处理从核收到数据包,发现如果请求的域名不是本地的zone配置的域名后缀,走慢速流程即转发流程。从核会将本请求入放在和转发处理线程共享的数据队列中,这样做的好处是把从核解放出来,只处理快速的查询请求,不会block住,从而能全速的处理本地数据。转发报文处理线程是一个死循环,首先从队列中读取数据,没有数据则休眠。如果有数据则将预处理数据并调用转发接口转发给上级DNS Server,并将上级DNS Server的回包处理后放入与主核共享的rte_mbuf无锁队列中。主核会及时的出队转发报文处理线程放入的数据,调用DPDK的网卡发送接口,将数据从主核的发送队列发送出去。需要说明的是这期间数据都是公用一个rte_mbuf 内存,没有任何的数据复制的过程,从而更好地提高性能。

域名信息数据处理模块: 这个是一个后台的线程提供Restful API,可以和agent进行数据交互,从而获取系统的域名数据。

首先注册支持url和方法,目前支持GET、POST、DELETE分别对应着域名的查询、增加、删除三个接口。同时提供状态的查询接口,目前只有两种状态Init和Runing,当agent 检测到进程是刚启动(Init 状态)时,会将所有的域名信息下发到DPDK DNS Server,之后将DPDK DNS Server的状态设置为Runing状态。后面如果有域名信息变更,agent 会调用POST或者DELETE 接口将域名数据同步到DNS Server。为了提高数据的安全性,DNS Server的API支持ssl证书,这样可以有效的防止域名数据被恶意的窃取、修改。同时域名数据插入删除操作的时候,采用了Hash 表的设计,每一个域名先计算出Hash值,如果发生冲突先比较Hash值,如果相同再进行字符串匹配。由于Hash值远远大于Hash桶的长度,当发生Hash冲突的时候先匹配Hash值会增加大大提高匹配的效率。

ARP/BGP报文处理:这模块较为简单,从核解析数据包如果发现是ARP协议报文,将数据传送给主核,主核在将数据通过DPDK的KNI将数据报文发给Linux 协议栈,主核后面再通过KNI 读取Linux协议栈处理的结果,然后调用DPDK的发送接口,将数据发送出去。BGP 协议的处理模式类似,也是交与Linux 内核协议栈处理。

四、性能优化及测试

  1. 恰当地使用rte_prefetch0(),可以减少cache-miss次数
  2. likely()和unlikely()的使用,可以减少分支预测失败的次数
  3. 数据处理全程无锁,交互部分利用无锁队列实现
  4. 整个处理过程无包copy,发送包复用收包的mbuf内存,减少mbuf的申请

性能测试:

1)测试环境

CPU:Intel(R) Xeon(R) CPU E5-2698 v4 @ 2.20GHz
NIC:intel 82599ES 10-Gigabit SFI/SFP+ Network Connection

2)测试配置

KDNS(八个数据核一个控制核),bind9 (16个核,版本bind-9.10.6-P1)

3)测试结果

bind9 五分钟单域名测试结果(47W QPS):

上图是bind9 稳定运行5分钟的数据采集结果,平均47W QPS。

KDNS 20分钟单个域名测试结果(1000W QPS):

如上图所示,优化后的KDNS性能达到1000万QPS,而且二十分钟运行很平稳,并发性能是bind9 20多倍、ContainerDNS(go版)的50倍。

KDNS 多个域名测试结果,其中系统域名记录大概20亿条。

相同网络环境下响应时间对比(queryperf 测试):

Queryperf数量

最慢响应us(bind9/ KDNS)

最块响应us(bind9/ KDNS)

平均响应us(bind9/ KDNS)

1

1140/226

15/16

102/68

3

1138/654

18/17

172/83

如上图所示,可以看到在相同的测试服务器、客户端主机、网络的环境下测试,利用DPDK收发包实现的DNS,对于访问的响应更加优秀和稳定,最慢响应由bind9的1140微妙提高到226微妙,平均响应时间也提高了一倍。

五、总结

本文主要介绍了KDNS,一种基于Intel DPDK平台开发的DNS Server。其接近网卡线速处理能力,灵活的部署,多样的监控以及可靠的稳定性,同时兼顾ContainerDNS的所有的分布式模块功能。作为TIG阿基米德平台京东数据中心操作系统(JDOS)的一个重要的组成部分,在京东数据中心发挥至关重要的作用。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT