当前位置: 首页 > 科技观察

网易数据通道系统NDC设计与应用

时间:2023-03-17 21:43:10 科技观察

NDC是网易在过去一年中新推出的结构化数据传输服务。它融合了网易以往在数据传输领域的各种工具和经验。OLAP系统和下游应用程序通过数据链接串在一起。NDC的设计除了保证高效的数据传输外,还遵循单元化、平台化的设计理念。本文将带大家深入了解NDC的设计思路和实现原理。NDC简介NDC的全称是NeteaseDataCanal,直译为NeteaseDataCanalSystem,是网易平台化的结构化数据库实时数据迁移、同步和订阅解决方案。在NDC之前,我们主要通过自研或者开源的软件工具来满足异构数据库实时迁移和同步的需求。易用性、易用性等多样化的功能提出了更多的要求和挑战,NDC平台解决方案应运而生。NDC的建设,快速整合了我们之前在结构化数据迁移领域的积累。项目于2016年8月正式立项,同年10月上线,为我司主要产品线提供在线数据迁移和同步服务。业界类似NDC的产品有阿里云的DTS、阿里巴巴的开源产品DataX、Canal、Twitter的Databus。传统领域有Oracle的GoldenGate和开源产品SymmetricDS。从产品功能和成熟度来看,NDC与阿里云DTS最相似,都具有简单、快速、全面三个特点:简单易用,具有平台化的web管理工具,以及配置过程简单易懂。快速、快速的数据同步、迁移订阅、高效执行,满足互联网产品快速迭代的需求。NDC功能齐全,支持多种常用的异构数据库,包括Oracle、MySQL、SQLServer、DB2、PostgreSQL、网易分布式数据库DDB。除了满足不同数据库之间的在线数据迁移和实时同步外,NDC还可以实现从数据库到各种OLAP系统的实时数据同步和ETL。目前同步目标支持的OLAP系统有Kudu和Greeplum。另外,NDC支持对数据库的数据订阅。通过将数据库的增量数据扔到消息队列中,应用可以自由消费数据库的实时增量数据,从而实现数据驱动业务和复杂业务调用的解耦。提炼场景和需求,是做好产品的第一步。本文首先通过三个典型的应用场景介绍了NDC的使用价值,然后从产品形态和系统架构两个方面阐述了NDC在产品交互、集群管理、资源调度、跨机房等方面的作用。部署的设计理念,最后介绍了NDC实现数据迁移、同步和订阅的一些原理和关键特性,可以为开发者在实现类似功能时提供思路和参考。应用场景以下三个真实案例说明了NDC在数据迁移和数据订阅方面的应用场景。DDB数据迁移分布式数据库DDB从2006年开始为网易旗下各大互联网产品提供透明的分库分表服务,在我们家喻户晓的互联网产品背后,几乎处处都可以看到DDB的身影,比如考拉、云音乐、云阅读、教育等。DDB是一个分库分表的结构化数据库。一张表的数据一般存储在多个数据节点中。每一张表都会选择一个或多个字段作为分区键来决定数据在数据节点上的分布。以用户表为例,用户ID作为主键,电话号码和邮箱地址作为唯一键。分区键一般选择这三个字段中的任意一个或组合。分区键的选择决定了数据分布是否均匀。随着业务数据量的增长,可能会发现之前选择的partitionkey区分度不够,需要更改partitionkey。partitionkey的修改涉及到数据的重新分布,修改过程必须和业务的线上服务同步进行,这就需要DDB提供线上数据迁移的解决方案。同样,在业务发展过程中,可能会遇到扩表或者机房迁移,需要DDB的在线数据迁移功能。以扩表为例,NDC解决DDB在线数据迁移如图1所示。图1NDC解决DDB数据迁移问题当DBA发起分区键修改或扩容请求时,管理工具统一解析将其转化为数据迁移命令,并向NDC服务发起相应的调度请求,NDC会根据调度规则选择一个组执行节点执行具体的迁移过程。每个源数据节点都会有对应的迁移过程拉取节点上的全量数据和增量数据,通过DDB分库分表驱动面将这些数据重新应用到目标中。当目标端和源端之间的数据延迟在毫秒以内时,通过在DDB管理工具上执行切换表操作完成最终迁移。应用缓存更新应用缓存更新是NDC数据订阅一个非常典型的应用场景。在不使用数据订阅进行缓存更新的应用环境中,缓存数据通常由应用服务器自己维护,但是由于缓存操作和数据库操作没有事务,但是简单的缓存操作可能会造成数据不一致,如图在图2中。图2缓存数据库不一致问题在图2的场景中,线程2更新缓存为最新数据后,线程1异步滞后更新为旧数据。由于线程1和线程2不共享任何状态,操作后缓存中的数据可能会被之前操作的数据覆盖,导致缓存和数据库数据不一致。如果发生这种情况,除非主动清除缓存,否则应用程序将始终读取脏数据。对于上述数据不一致的问题,业界也有基于CAS的解决方案,但至少会对缓存造成成倍的压力。通过NDC数据订阅可以完美解决以上问题。NDC数据订阅将数据库中的增量数据丢到消息队列中,应用程序读取消息队列的内容同步到缓存系统。在这个过程中,NDC执行节点和消息队列保证了高可用,而数据库增量数据是唯一的、顺序的,可以避免缓存和数据库状态不一致的情况。如果说使用数据订阅只是缓存更新的最优方案,那么NDC的数据订阅功能就是下面淘汰多机房缓存的必选方案。在图3中,应用部署有两个环境,主机房和备机房。这两个环境中的每一个都有一组应用程序服务、缓存和数据库。宿主机房数据库的只读从库,这种架构一般适用于读多写少的应用系统。图3NDC解决了多机房的缓存淘汰问题。当服务不申请数据订阅更新缓存时,从机房删除数据时,先删除主机房的数据,再删除从机房的缓存。从机房的数据库同步有一定的滞后期间,从机房应用服务可能会把从机房数据库中的脏数据重新加载到缓存中,这样从机房应用仍然可以看到删除的数据。为此,我们的解决方案是使用NDC订阅从机房数据库的删除操作,保证从机房数据库和缓存在删除操作上是一致的。OLAP系统集成/ETL业务数据库与OLAP系统的数据集成是互联网产品架构中非常重要的一环。更传统的应用程序通常会定期将OLTP数据库中的所有数据导入到OLAP系统中。比如每天凌晨1点通过Sqoop将线上MySQL中的所有数据导入到Hive中。这种方式有很大的局限性:首先,ETL的时间是完全不可控的,这对于时间敏感的数据尤为重要;其次,ETL过程中源数据库的负载压力非常大,尤其是对于数据量大的应用,控制ETL对源负载的影响意味着ETL时间更加不可控。在NDC这样的系统出现之后,架构师有了更明智的选择:通过NDC实现结构化数据的增量ETL。首先,ETL的延迟从几小时减少到几秒,其次,NDC的增量数据抓取对源头的影响很小。对于直接支持数据更新的OLAP系统,可以直接通过NDC实现ETL,比如Kudu、HBase。对于Hive等不支持数据更新的系统,可以通过NDC的数据订阅功能,将数据库的增量数据发布到消息队列中,然后周期性的从消息队列中获取增量数据,合并到通过MR的股票数据。当然,这里的计时比原来的全计时间隔要小很多,比如每小时或者每15分钟——这样就实现了准实时的ETL。图4通过NDC实现OLAP系统集成和ETL产品形态在产品形态上,NDC具有平台化、可插拔和单元化三个特点。平台化要追溯到几年前,各种PaaS和SaaS服务并不像现在这样无处不在。运维伙伴更习惯于通过部署软件的方式为业务方提供各种服务。比如在NDC之前,我们有一个软件包Hamal来支持DDB的各种数据迁移任务。DBA在实现DDB扩容时需要经过以下步骤:准备一定数量的物理机或云主机来运行迁移任务;在这些节点上部署Hamal进程,并配置source端Target端、并发度等参数;通过Hamal日志或监控程序实时查看迁移进度;数据迁移赶上线上数据增长后,完成切表或切库操作;回收Hamal进程,释放相关资源。随着负责的产品越来越多,规模越来越大,管理员在不同产品的机器和配置之间疲于奔命。经历漫长的采购周期。对于DBA等运维人员来说,迫切需要一套平台化的管理工具,帮助他们解决采购、部署、调度、任务完成后的资源回收等一系列运维工作。这是国家数据中心。NDC提供基于跨IDC平台的Web管理界面和类似云计算的租户管理理念。使用NDC时,产品管理员可以在产品相关租户下创建、修改和删除特定的数据迁移、同步和订阅任务。NDC调度中心向相关执行节点调度任务。此外,还配备了专门的平台管理员,负责规划整个NDC平台的容量。NDC管理界面如图5所示。从图5NDC管理界面可以看出,NDC除了提供基本的任务管理外,还为管理员提供了大量的运行时监控统计信息,帮助管理员更好的控制任务进度和状态.可插拔NDC除了直接为产品管理员和开发者提供服务外,还是DDB数据迁移和Mammoth(网易大数据系统)数据同步的依赖组件,如图6所示。图6NDC平台的可插拔特性WhenDBA使用DDBAdmin进行扩容缩表、更改分区字段等操作,DDBAdmin会将请求解析为多个数据迁移任务提交给NDC。同样,未来NDC也可能支持其他具有自身认证功能的平台系统,比如公有云。为此,NDC需要能够轻松地从其他平台插入和拔出。NDC的平台可插拔特性本质上是支持不同租户认证的可插拔,因为其他大部分依赖NDC的平台都有自己的租户认证功能,要求NDC支持这些不同的认证方式是不现实的,我们的方法是“认证服务”》,具体的租户鉴权由上层平台自行完成。同时,我们可以根据上层平台的租户名称对任务进行物理隔离,划分任务视图。租户可插拔的另一个关键点是需要在API服务中实现NDC自带的租户认证。从NDC调度中心的角度来看,API服务与其他平台是同一架构层的不同接入平台。NDCpluggable的另一个含义是“功能上可插拔”。自立项以来,NDC先后支持了6个关系型数据库和3个OLAP系统。通过实现统一的Extractor和Applier接口支持每个源和目标,我们对JAR包进行了合理的拆解。点,以便可以独立推出一些功能修改。通过实现接口和添加新的JAR包,还可以在不重新启动任何进程的情况下扩展对新源和目标的未来支持。单元化可以通过NDC实现跨机房的数据同步解决方案,特别是比较大的应用,比如网易考拉、云音乐等,一般需要同城甚至异地机房之间的业务冗余、扩容和容灾。相应的,这些应用所依赖的底层服务也需要具备多机房冗余和扩展功能,如图7所示。图7NDC跨机房单元方案在一个机房的系统架构中,应用服务是无状态、缓存和大数据。这些有状态系统的数据来自于数据库的数据同步和订阅,而数据库的数据除了本地机房应用产生的数据外,还可以与数据进行同步来自NDC的其他机房。从这个架构可以看出,NDC同步机房的数据库数据,再由NDC同步数据库的变化到大数据、缓存、消息队列,从而带动机房业务的无缝扩展和冗余。电脑室。在图7中,每个机房都有一套完整的从应用服务到数据库的数据链路。机房内的网络、IT资源及相关调度具有高度自主性。机房内的耦合模块只能通过NDC共享数据库数据进行连接。目前业界将这种服务链路完整、自治度高的跨机房解决方案称为“单元化”。NDC单元化需要在每个机房部署独立的调度中心和执行节点组,需要注意的是,unitization不包括NDCAPI服务。API服务具有无状态、离散请求的特点,不需要独立部署。同时,跨单元的API可以提供平台化的管理服务。值得一提的是,所谓“单元”是一个逻辑概念。单元具有物理隔离和高度自治的特点。我们也可以在一个机房部署多个NDC单元,以区分和隔离不同的业务线。比如我们可以为DDB和Mammoth部署一套独立的单元来支持他们的平台依赖,但是一个单元基本不会跨机房部署。系统架构一个单元的NDC系统架构如图8所示。图8NDC架构图顶部的无状态API服务是一个平台化的直接面向用户的Web管理工具。API节点通过RPC向调度中心Center发起请求。除API节点外,中心还将接受来自DDB管理工具的请求。、MammothManagementTool等平台的RPC调用请求。该中心是NDC的大脑。所有的管理、调度、监控、报警等工作都需要通过中心进行。目前,中心为单位单点服务,通过高可用组件进行冷备份。由于元数据统一存储在NDC系统的数据库中,主备Center之间不需要进行数据同步。Center定期收集单元内所有Engine节点的负载状态、任务执行状态等信息,实现任务均衡调度,任务失败时自动重试或重新调度,保证任务执行的高可用。Engine是NDC系统中数据迁移、同步、订阅的任务执行者。它接收来自Center的调度请求,并维护一组实际的任务执行进程Executo。在任务执行过程中,Engine负责收集每个执行过程的任务状态和进度信息,并实时上报给Center。Center不知道任何Executor的存在,任务执行过程完全由Engine管理,由Engine全程监控。“Unit”是NDC物理资源隔离的最大单位。除了基于单元的隔离,NDC还提供了租户级别的物理隔离。管理员可以为租户分配专属的任务执行节点。如果在配置任务属性时选择“独占”任务,则任务只会被调度到属于用户的资源池中,保证任务执行有节点级隔离,而普通共享任务只有进程级隔离。实现简介NDC是针对结构化数据库的数据迁移、同步和订阅的解决方案,数据同步可以看作是“永无止境”的数据迁移。接下来,我们将讨论NDC在数据迁移、数据订阅和一些关键特性的实现上的简单介绍。NDC的订阅和迁移都是基于表的。如无特殊说明,以下迁移对象均指待迁移的表。数据迁移不同于通常的“迁移”概念。NDC的“数据迁移”并不是将源端的数据迁移到目标端,而是“复制”源端的数据,同时保证对源端数据的影响尽可能小。”或“同步”到目标。例如在线数据库到数据仓库的ETL,需要在不影响在线服务质量的前提下,将数据实时同步到数据仓库。再比如DDB的在线扩容,同样需要在扩容过程中不影响原有的数据节点。当用户通过web工具启动数据迁移任务时,NDC调度服务会根据任务类型、调度算法、节点负载情况,在相关Engine资源池中选择一个或多个节点进行任务下发。一项迁移任务对应一个源端数据库实例。数据迁移引擎中的任务执行流程如图9所示。图9NDC数据迁移执行流程从图中可以看出,整个数据迁移流程包括以下四个步骤:Pre-check:检查资源、网络可用性、架构兼容性、用户权限等;全量迁移:源库、表存量数据的迁移过程;增量迁移:在迁移过程中,源库和表的增量数据迁移过程;数据校验:对源端和目标端的同步数据进行采样校验。在预检阶段,NDC会检查源端和目标端的网络连通性、免费资源的可用性、用于迁移的源端和目标端用户对相关数据库表的权限、白名单、schema是否为被迁移兼容等。NDC不要求迁移对象的Schema在源端和目标端严格一致,但要求目标端与源端兼容。例如,源中的字段类型int可以是目标中的bigint。否则,预检查会报错。源和目标的索引结构允许变化。预检完成后,NDC任务执行流程会立即启动增量数据拉取模块,拉取增量数据后开始全量迁移流程。顾名思义,全量迁移就是将迁移对象的现有数据同步到目标端。NDC的全量数据迁移采用“快照读取”,判断迁移对象中哪些数据是存量数据哪些是增量数据的依据是在启动全量迁移时获取迁移表的最小主键和最大主键。的最小主键和最大主键之间的所有数据都被认为是存量数据,其余的被视为增量数据。之所以没有像MySQLDump这样使用大事务划分存量数据的迁移工具,是为了避免大事务造成的源回滚段不断累积的影响(这是针对MySQL,针对不同类型的源数据库,大事务会造成一定的不良影响),并且使用快照读会在全量迁移过程中引入一些增量数据,但这部分增量“脏数据”最终会被增量迁移修正,不会影响数据性的最终一致性。以表为单位进行全量迁移,不同表之间可以并发迁移。增量迁移以源实例为单位执行(想想MySQL的binlog)。因此,在一个迁移任务中,当所有的迁移对象全部迁移完毕后,才会进入增量迁移阶段。增量迁移至少由两个线程组成,第一个是增量数据拉取线程,在全量迁移开始之前启动,负责将所有(相关的)源头增量数据缓存到本地磁盘上;另一个是增量播放线程,在增强迁移过程开始时启动,其作用是不断读取本地缓存中的增量数据,并按时间顺序播放回目标端。由于全量迁移是在增量拉取开始后进行的,NDC可以保证全量迁移过程中引入的增量数据最终会在目标端回放。在全量迁移和增量迁移的过程中,会重复导入一些增量数据,NDC会保证增量数据导入是幂等的。随着增量迁移的进行,目标端增量数据与源端增量数据之间的时间延迟会逐渐缩短。最后,在延迟控制在1秒以内后,我们将这个迁移任务定义为同步状态。对于同步状态下的迁移任务,管理员可以选择进行数据校验。一般建议在源端使用5‰到100‰的随机数据来验证源端和目标端的数据一致性。NDC数据迁移中的全量迁移、增量迁移、数据校验都是可选流程,但NDC要求管理员至少勾选全量迁移和增量迁移中的一项。迁移任务进入同步状态后进行数据校验。可选操作在提交任务时不选择,可以重复执行。在实践中,当数据迁移任务进入同步状态时,一般会先进行一次数据校验,然后再进行相关的切库切表操作。对于数据同步场景,一般会定期进行全量数据校验。数据订阅数据订阅是从数据库中实时拉取数据变化,交付给下游应用程序执行相应业务逻辑的过程。与数据迁移相比,数据订阅的逻辑相对简单——相当于数据迁移中的增量过程。在应用场景上,数据订阅可以满足更多样化的业务需求,例如:通过数据订阅维护全文索引图10通过数据订阅对复杂业务进行异步解耦,展示了一个更复杂的ETL数据订阅的执行逻辑。图10数据订阅执行流程数据订阅任务由NDC调度服务选择执行相应的订阅引擎节点。与数据迁移的增量过程不同,数据订阅引擎不会将增量变化数据缓存在本地,而是直接丢弃。进入消息队列(使用我们的消息队列服务),SDK通过消费消息队列中的数据实现增量数据播放。之所以使用消息队列而不是本地磁盘,是因为SDK的数据播放过程完全由应用端控制,速度不可控。如果业务逻辑处理过慢,或者下游节点意外宕机,可能会积累大量的增量数据。这里是message队列,可以作为一个足够大容量的消息缓存,让SDK端的异步消息播放更加优雅。数据订阅时,Engine必须严格按照增量数据的时间顺序串行发布消息,无法实现类似数据迁移增量过程的并发复制。这是因为订阅任务Engine无法感知到应用端SDK的消费数据,并发发布消息。势必会导致SDK消费数据乱序执行。在实践中,需要特别注意消息队列发布消息的瓶颈和订阅任务引擎对消息队列的网络开销。KeyFeatures对于NDC的实现,我想和大家分享三个关键特性:并发迁移断点续传多源适配对于数据迁移和同步,速度是生命线:如果迁移速度不够快,任务就会永远不要进入同步状态。迁移和同步也是不可能的。NDC的全流程和增量流程都支持并发迁移,保证迁移任务能够尽快进入同步状态。并发全量迁移比较简单。首先,可以对不同的表进行并发迁移。其次,向目标端导入数据的过程也可以并发执行。selectdata和insertdata线程的解耦,在实践中可以大大缩短迁移时间。此外,全量NDCMigration可以配置一次导入操作的数据批次数,减少迁移过程与源端和目标端的交互次数。增量并发播放是NDC最重要的核心实现之一。NDC增量播放线程会根据增量数据之间的冲突关系构造一张或多张有向无环图,图中所有入度为0的数据所有节点都允许并发播放,增量数据将从图中删除导入到目标后,从而解锁其他冲突数据。理论上,该算法可以最大限度地发挥并发播放的优势。在实际性能测试中,NDC的增量并发播放效率远高于MySQL5.7基于GroupCommit的并行复制。断点续传是NDC任务漂移和高可用实现的基础。表示迁移或订阅任务异常退出,或者进程或节点崩溃后,可以就近重启任务。断点续传的实现有两个前提条件:首先,要求系统定期持久化任务的位置点信息,必要时可以从持久化的位置点继续执行任务。NDC方式是Engine定时上报位置点信息ForCenter,后者会持久化到系统库中;其次,迁移和订阅任务中的所有数据导入操作(全量和增量)都要求是幂等的,为此我们可以使用带有replace语义的SQL来实现导入操作,对于不支持replace语法的目标,可以使用结合delete+insert的SQL来实现相似的语义。在实践中,保证幂等操作绝对是一种省时省力省心的做法。多源适配的问题主要在于如何为不同的源数据库拉取增量数据最实用、最高效。目前主要有三种方式:基于日志:MySQLbinlog、Oracleredolog;基于CDC:Oracle、DB2、SQLServer;trigger-based:适用于所有支持触发器的数据库。这三种方法各有优缺点。trigger的使用比较简单,对用户权限的要求也比较明确,但是性能较差,尤其是源码线上压力比较大的时候,可能会出现大量的锁超时,所以不最佳选择;CDC的全称是ChangeDataCapture,是一些数据库特有的功能。它可以将数据库产生的增量数据同步到一些视图或表中。迁移或订阅过程通过这些表和视图获取增量数据。可以看出,CDC在使用上和触发器非常相似,不同的是CDC是一些数据库特有的功能,可以在性能上进行优化。以Oracle为例,通过解析redolog可以生成增量数据,相比通过触发器生成增量数据,对源头的影响要小很多。CDC的缺点是不同数据库没有统一标准,方言严重,权限要求比较苛刻。总的来说,我们将第一种基于日志的增量数据拉取方案列为最佳方案。以MySQL为例,MySQL内置的binlog功能可以直接将日志同步到远端,对用户权限和源端数据库性能的影响也在可控范围内。综上所述,工欲善其事,必先利其器。顾名思义,NDC希望为企业打造一条“数据通道”,可以容纳来自各种结构化数据库的实时数据,并通过通道将数据传输到不同的目的地。应用只需要在管理页面简单配置几个参数,就可以很方便地将数据库的内容集成到其他数据或应用系统中。NDC的快速建设很大程度上得益于我们团队在分布式中间件和数据迁移工具领域的成绩和积累。如果开发者想设计和实现类似的系统,建议多使用开源资源。例如,调度模块可以考虑集成或使用ApacheAzkaban的实现。任务执行模块也有很多开源的工具和代码可以参考。此外,在设计数据迁移和订阅平台时,需要考虑以下问题:与其他平台的集成,NDC具有平台可插拔的特性,可以方便地与网易其他平台服务集成。任务执行应该很快,对源的影响尽可能小。NDC有一个非常高效的全量数据迁移和增量数据回放模块。在实现增量数据拉取模块时,尽量选择同步日志的方式,对源端影响较小。需要考虑断点续传的问题。任务执行过程中,可能会出现网络抖动、分区、节点故障等各种异常情况。这首先需要我们的任务具备从某个时间点或地点重新开始执行的能力,其次需要调度中心能够快速发现异常。并使用合理的算法实现任务漂移。考虑灰度发布。由于NDC的平台化设计,随着系统功能越来越多,平台全面升级的成本越来越高。为此,我们需要通过灰度升级,确保功能在全面上线前得到充分验证。此外,通过功能“可插拔”特性,确保在线任务对在线任务的影响尽可能小。到目前为止,NDC已经上线半年多,承接了40+个应用,以及拥有10000+迁移、同步、订阅实践案例,可以预见,在网易未来的云计算、大数据布局等各种数据驱动的应用场景中,NDC将发挥举足轻重的作用。