公司网站上传图片大小,wordpress 筛选 文章,ico加网站,做注册任务网站源码本文整理自虎牙中间件团队在 Nacos Meetup 的现场分享#xff0c;阿里巴巴中间件受权发布。
这次分享的是全球 DNS 秒级生效在虎牙的实践#xff0c;以及由此产生的一些思考#xff0c;整体上#xff0c;分为以下5各部分#xff1a;
背景介绍#xff1b;方案设计和对比…本文整理自虎牙中间件团队在 Nacos Meetup 的现场分享阿里巴巴中间件受权发布。
这次分享的是全球 DNS 秒级生效在虎牙的实践以及由此产生的一些思考整体上分为以下5各部分
背景介绍方案设计和对比高可用具体实践和落地规划
背景介绍
虎牙用到的基础技术很多DNS 是其中比较重要的一个环节。 DNS 的解析过程很关键例如上图中的 DNS 解析器通过一个定位解析追踪到我们的 DNS再到本地域名服务器迭代解析经过根域再到.com名最后到huya.com的根域名获取最终的解析结果。
在这个过程中 DNS解析是天然的分布式架构每一层都会有缓存上一层出现问题挂掉下一层都会有缓存进行容灾。另外整个 DNS 协议支持面广包括手机和 PC我们用的编程框架里也有 DNS 解析器服务器也会配 DNS 解析引擎因此DNS 在虎牙的基础设施中是很重要的部分。
虎牙的 DNS 的应用现状
虎牙当前主要是依赖于公共的 DNS相信在座的小伙伴们或多或少都会遇到过下面这些问题
依赖公共 localDNS解析不稳定延迟大。记录变更生效时间长无法及时屏蔽线路和节点异常对业务的影响。例如权威 DNS 全球各节点数据同步时间不可控全局生效时间超过10分钟localDNS 缓存过期时间不可控部分 localDNS 不遵循TTL时间缓存时间超过48小时。内部 DNS 功能缺失无法解决内部服务调用面临挑战。例如时延大、解析不准、支持多种调度策略。无法满足国外业务的快速发展虽然一些海外云厂商提供了基于 DNS 的快速扩容方案以及基于 DNS 的数据库切换方案。
方案设计和对比
基于以上的问题我们开始重新规划 DNS 的设计。
名字服务架构 整个规划会分三个方面核心是我们做了「名字服务」的中心点基于此可以满足我们的需求。
一方面通过 Nacos Sync将现有多个注册中心的服务 同步到「名字服务」中 通过 DNS 实现不同框架之间的 Rest 服务方式的调用 实现例如 EurekaConsulTaf等框架之间的服务调用。
另一方面在全球负载均衡的场景下由于虎牙是以音视频业务为主而音视频业务对节点的延迟是非常敏感的所以我们希望一旦出现节点延迟的情况能立马做切换。
第三个是传统 DNS 的场景 可以满足容器和物理机的 DNS 需求 提供本机 Agent 和集群两种方案 通过缓存和 prefect 大大提高 DNS 解析的可用性和加快生效时间。 对于名字服务的总体设计主要分3部分接入层需要提供 API消息通知和 DNS 接入的能力。核心功能需要能在基于现有网络数据CMDB 和 IP 库的数据基础上提供灵活的负载均衡能力全球数据的秒级同步多个数据源的同步能对全网服务的健康状态进行监控及时感知到大范围的节点异常并且能够及时将节点的屏蔽的信息推送到端上。
最终我们选择 Nacos 作为名字服务的核心提供统一的 API 包括名字注册、变化推送、负载均衡等Nacos Sync 作为全球集群间数据同步的组件DNS - F是客户端组件用于拦截 DNS 请求实现基于 DNS 的名字服务。
改造前后 DNS 变更生效流程的不同
接下来我们通过对比看下改造前后 DNS 变更生效流程的差异。 原有 DNS 变更生效流程中对 DNS 生效时间有影响的是
Auth DNS
跨区域、跨国数据同步慢不稳定。
bind 在数据量比较大的时候同步比较慢。
Local DNS
根据 TTL 缓存过期后才会刷新数据。
部分厂商不遵循 TTL 时间缓存超过24小时的缓存时间。
服务器
服务器开启 nscd 做 DNS 缓存。
业务进程
应用的 DNS 缓存比如 Java 虚拟机、框架层的 DNS 缓存。
以上四种情况会比较影响 DNS 的变更生效流程下图是我们现有的 DNS 变更生效流程 整体上相对简单只要业务进程这边将自己内部的 DNS 缓存关掉 通过 DNS-F 进行查询的时候 会直接到最近的 Nacos 集群拉取最新的服务节点信息 而且后续节点的变化也会推送到 DNS-F 中 后续可以直接在缓存中获取最新信息。
国内 Nacos 集群
集群内通过 raft 协议同步数据毫秒级别完成同步。
Nacos Sync
Nacos 推送变化到 Nacos Sync跨区域、跨国网络差的情况下可能会导致推送结果丢失或者延迟加大。
Nacos Sync 会主动拉取实例变更拉取周期和监听的服务数量会影响到变更时效。
DNS - F
Nacos 会将变更推送到 DNS - F网络差的情况可能会导致推送结果丢失或者延迟加大。
DNS - F 会主动拉取实例变更拉取周期和监听的服务数量会影响到变更时效。
业务进程
通过应用禁用 DNS 缓存来解决。
核心设计 Nacos
Nacos 有两套推送机制。 一种是通过客户端来选择一个可获节点比如它第一次拉取的是一个正常节点这个正常节点就会跟它维护一个订阅关系后面有变化就会有一个相应的实地变化推送给我。如果当前节点挂掉 他会通过重连 在节点列表上连上一个正常的节点。这时候会有新的 DNS 关系出现。
另一种是通过 SDK 的方式在服务端寻找可获节点。服务端每个节点之间 会进行一个可活的探测 选择其中一个可活节点用户维护这个订阅关系。 当这个节点出现问题 连接断开后 SDK 重新发送订阅请求服务端会再次选择另外一个可活的节点来维护这个订阅关系。这就保证整了推送过程不会因为某个节点挂掉而没有推送。
推送的效率方面主要是用 UDP 的方式这个效率不像 TCP 消耗那么高。
以上两个方案都比较适合我们目前的场景。
核心组件设计 Nacos Sync
我们选择 Nacos Sync 作为多集群数据同步的组件主要是从以下4方面进行考虑的。
同步粒度
Nacos Sync 同步数据的时候是以服务为维度 比较容易做最终一致性处理 同时可以提供保活的机制满足节点维持的场景。 数据库通过 Binlog 同步的方式只能局限于事务粒度 而文件同步只能通过单个文件的粒度 在服务同步这个维度并不是很合适。
可用性方面
Nacos Sync 作为一个中间件是以集群方式进行的传统的数据库和文件方式基本是单进程进行的可用性方面可能不太满足要求。
同步方式方面
Nacos Sync 通过在服务粒度的全量写入满足服务注册和 DNS 这两种场景 不需要额外的事务消耗 能保证最终一致即可。
环形同步
我们国内有多个可获的节点希望它们之间的数据可以进行环形同步每个节点之间是相互备份的这时候用 Nacos Sync 的话是支持的。虽然数据库方面比较经典的是主主同步但如果同时对一个主件进行更新的话每一个点进行协助是会有问题的而且文件方面是不支持的。
Nacos Sync 和开源版本的不同
我们对 Nacos Sync 开源方案上做了几处修改以更好的适用于现在的场景
第一通过配置方式对任务进行分拆。因为在实际应用场景里面因为 Nacos Sync 的任务达一两万单机很容易到达瓶颈所以我们通过配置的方式将这些分片到多台 Nacos Sync 机器上。
第二通过事件合并和队列控制的方式控制 Nacos 集群的写入量以保证后端的稳定性。虽然下发事件一秒钟只有一个但在很多场景中例如需要 K8s 或者 Taf 进行数据同步的时候变化的频率是非常高的这时候通过事件合并每个服务单独进行一个写入进程。这样通过队列控制的方式可以控制整个 Nacos 集群的写入量。
第三添加了能支持从K8s 和 Taf 同步数据的功能。后期我们会将这个特性提交给 Nacos让更多的开发者使用。
核心组件设计 DNS - F
DNS - F是基于 CoreDNS 上开发的我们扩展了以下 4 个组件
Nacos 插件查询 Nacos 服务信息监听 Nacos 服务变化并将服务转化为域名实现以 DNS 协议为基础的服务发现
Cache 插件提供域名缓存服务;
Log 插件将 DNS 解析日志上报到日志服务
Proxy 插件代理解析外部域名
DNS - F 和开源版本的不同
第一在日志组件里面将日志上传到自己的日志服务。
第二对缓存功能做了一个增强。一般的缓存功能可能根据 TTL 时间会过期我们把这个过期时间给去掉了直接令到缓存永远不会过期然后通过异步将这个缓存进行刷新。比如 TTL 可能快到到时间了我们就会主动做一个查询或者推送查询这样服务端或者公共 DNS 出现问题的时候就不会影响到整体服务。
第三增强了高可用的保障能力。包括进程监控、内部运营和外部运营的探测。另外原来的开源版本用的是本机部署的方式我们做成了集群化的部署解决了服务推送、服务负载均衡方面的问题。
高可用
接下来由我们团队的李志鹏分享一下虎牙在高可用方面的实践。
周健同学跟大家介绍了项目的背景跟方案设计我来和大家介绍一下具体的实践和落地实践过程中的主要关注点是高可用。
全球化部署方案 这是虎牙的一个全球化的部署方案我们在全球部署了两个大区分别是国内和国外。这两个大区是指定服务同步的走的是专线这样可以保障同步的稳定性。在一个大区内我们又部署了多个接入点例如在国内大区我们部署了深圳和无锡两个接入点这两个节点的数据是互相同步、互为备份保证在一个集群挂掉下可以切换到另外一个集群。
多个接入点的情况下我们通过 HttpDNS 实现客户端的就近接入。客户端定期请求 HttpDNSHttpDNS 能根据地域寻找就近接入点。如果接入点出现故障我们就直接在HttpDNS 把这个节点给摘除这样客户端就能快速地切换到另外一个接入点。
接下来讲一下单个集群下的部署方案。 单个集群部署了多个 Nacos 节点并通过7层负载均衡的方式暴露给外面使用并且提供了多个 VIP满足不同线路和区域的接入要求。同时Nacos Sync 做了分片处理将同步压力分散到各个分片上一个分片下我们又部署了多个 Nacos Sync 的节点以保障多活和高可用。
线上演练
演练的场景是模拟一个单个集群挂了和两个集群都挂了。 从图中可以看到把深圳的流量切走之后无锡的流量就涨上去了然后再把无锡的流量切走再关闭服务这样就可以看到两边的流量已经没了。之后再去恢复两个集群的流量看一下整个切换过程中对服务的影响。 首先看一下对写入的影响在单个集群挂了的情况下是没有任何影响的。如果是两个集群都挂了写入就会失败。可以看到这个图有一个波峰这个波峰就是我们两个集群都挂了的情况下写入失败延迟加大。
但是切换的整个过程对 DNS-F 是没有任何影响的延迟保持平稳。此外在集群重新上线前我们需要做数据校验保证集群之间元数据和实例数据的最终一致。
可用性级别方面我们可以保障
单集群挂掉后不会有影响双集群挂掉后只会影响域名变更不影响域名解析
线上演练数据校验机制
运行过程中我们也要保证集群间数据的一致性。我们通过全量校验和增量校验两种手段去保证全量校验方式如下
大区内部做10分钟的全量校验保证大区内各个集群数据的一致大区之间做2分钟做一次全量校验保证大区之间被同步的服务的数据一致性。
增量校验方式如下
从其他数据源同步的数据通过数据源的时间戳做增量校验基于API的写入日志定期校验写入的内容是否已经全部同步。
DNF - S 高可用
关于 DNS - F 的高可用我们主要做了以下5个点
Agent 的健康状态监测包括进程存活和是否能正常解析缓存内部域名并做持久化处理保证 Nacos 集群出现问题时不会影响内部域名的解析提供备用节点保证在 DNS-F 挂了或者是 DNS-F 需要升级的情况下也不会影响到内部域名解析resolv.conf 配置检查发现127.0.0.1不在配置中会自动添加限制 Agent 的 CPU 的使用避免对业务进程造成影响。
具体的实践和落地
实践一数据库域名改造
之前的数据库是用 IP 方式接入的在数据库切换的时候需要通知每个业务方修改配置重启服务这样就带来一个问题整个过程是不可控的取决于业务方的响应速度生效时间通常超过十分钟。 提升数据库切换的关键点第一个就是切换时不需要业务方参与能在业务方无感知的情况下进行切换第二个是实例变化能秒级推送到我们的应用将应用快速切换到一个新的实例上。 大家可以看一下这个图这是我们现在做的一个改造图中的 DMX 是虎牙内部的一个数据库管理系统思路就是把 DMX 和名字服务打通。DMX 会把数据库实例信息以服务的形式注册到名字服务服务名就是域名。
实际应用过程中通过这个域名去访问数据库应用在访问前首先会经过 DNS - F 去做域名的解析解析的时候是从名字服务查询实例信息然后把实例的IP返回给应用。这样应用就能通过 IP 和我们的数据库实例进行连接。
切换的时候在 DMX 平台修改域名对应的实例信息并把变更推送到名字服务名字服务再推送给 DNS-F应用在下一次解析的时候就能拿到新的实例 IP达到切换数据库实例的目的。
这套方案落地后虎牙的数据库切换基本上在10秒钟之内能够完成。
实践二内部调用使用内部域名
虎牙部分内部系统之间调用是通过7层负载均衡但是由于没有内部 DNS需要通过的公共的 LocalDNS 来解析这就带来一些问题
问题一扩缩容的时候要去修改 DNS 记录整个过程生效时间可能会超过10分钟故障的节点会影响业务较长的时间。
问题二公共的 LocalDNS 智能解析不准确比如无锡的机器可能会解析到深圳的一个接入点影响接入质量。
问题三不支持定制化的负载均衡策略例如同机房、同大区优先的策略通过公共 LocalDNS 是实现不了的。
如果想要提升内部服务调用质量一是 DNS 记录变更绕过 LocalDNS把 DNS 的记录变更直接推到 DNS-F。二是与内部系统打通从 CMDB 等内部系统获取机器信息支持多种负载均衡策略。 大家可以看一下上面的图这个改造和数据库域名的改造思路是一样的最右上角有一个7层负载管理系统我们把这个系统和名字服务打通7层负载管理系统会把域名信息以服务形式注册到名字服务变更域名记录时直接从7层负载管理系统推送到名字服务名字服务再推送到 DNS-F达到快速切换的目的。
如果域名配置了负载均衡策略名字服务会从 CMDB 获取机器、机房等信息打标到域名的实例信息。然后DNS-F 查询名字服务时会携带 ClientIp名字服务根据 ClientIp 的CMDB 信息过滤实例列表返回同机房的实例给 DNS-F达到同机房优先的目的。
由此带来的效果是
第一服务扩缩容能够秒级完成减少了故障时间。
第二扩展了 DNS 的负载均衡策略例如有些业务是需要在不同区域有不同的接入点的而且不能跨区域调用之前的 DNS 负载均衡策略是不能满足这个需求的但在改造之后我们能根据 CMDB 信息去做同区域调度的负载均衡策略。
第三业务在接入内部域名之后延迟会有明显的下降。上图显示的就是某个服务在接入到内部域名之后延迟出现明显的下降。
另一个落地的效果就是我们对主机上的域名解析的优化。因为我们的 DNS - F 是部署在每台主机上的然后提供一个缓存的功能。带来的效果就是
平均解析延迟会从之前的200毫秒下降到现在的1毫秒 缓存命中率会从之前的90%上升到99.8%90%是用 CoreDNS 原生的那个 Cache99.8%是在这个 Cache 的组件下做了优化之后的效果解析失败率是从之前的0.1%下降到0%
这里再总结一下项目落地的技术价值
第一提供了基于 DNS 服务发现的能力消除异构系统之间互相调用的障碍。
第二填补了没有内部域名解析能力的空白。
第三解决我们上面说的内部服务调用面临的挑战延时大、解析不准、不支持多种负载均衡策略、故障牵引慢。
第四优化外部域名的解析屏蔽 LocalDNS 的故障。
落地规模是DNS - F 覆盖率100%完成 Taf 和 Eureka 注册中心的数据同步。
后续规划
LocalDNS
解决公共 DNS 节点位置影响域名解析准确性的问题
解决内部使用公共 DNS 不稳定的问题
优化内外网解析
精准调度
解决全球 DNS 节点生效慢的问题。
原文链接 本文为云栖社区原创内容未经允许不得转载。