前程无忧

客户推荐语录

在去O上云项目过程中,阿里云项目组与我司密切合作,帮助我们理清技术架构并定制了一套完整的去O迁移方案,在双方近半年的不懈努力下,我们共同解决了迁移评估、驱动适配、业务改造等众多复杂问题,于202445日和525日圆满完成了两次关键的数据库迁移割接任务,实现了从线下IDC自建Oracle成功迁移至阿里云PolarDB PostgreSQL版(兼容Oracle)

这种团队紧密协作的方式对于此次迁移割接任务起到了至关重要的作用。目前PolarDB作为核心数据库支撑了我司C端前程无忧、B端网才等核心业务。我们真诚地感谢阿里云团队在此次项目中所作的巨大贡献,并期待在未来的工作中继续保持这种密切的合作伙伴关系,共同推进我们业务的持续发展。

前程无忧-技术研发中心-业务研发部-许益平

客户背景

关于客户

image.png

前程无忧成立于1998年,在全国数十个城市设有分支服务机构,是中国领先的人力资源服务商之一。2019年,进入“2019年中国互联网企业100强”。2020年,被第十届中国公益节评选为“2020社会责任行业典范奖”。2023年,被HRoot评为“2023人力资源服务机构100强”。前程无忧为企业洞悉人才招聘、培养和保留以及员工关系等多元、个性化新需求,提供涵盖招聘平台和人才搜寻,领导力培训和人才发展计划以及人力资源事务性外包等一揽子产品和服务。同时,为让人们找到喜欢的工作和雇主而努力。前程无忧51job及应届生求职两个求职平台分别为“职场人”及“学生”提供细分、精准的求职服务。通过前程无忧卓有影响的产品和服务,无论是丰富的岗位信息,还是个人测评、学习课程和薪酬调查数据等,致力为个人从工作到技能发展的路径中提供切实的资源和支持。

业务场景

前程无忧的网才和51job业务是其两大核心业务。其中51job企业版-网才面向企业用户,企业客户在此平台发布职位招聘信息,该平台帮助企业高效筛选人才、管理面试,提供一站式专业人力资源服务,提高招聘效率,节约招聘成本。 51job主要面向C端的个人用户,提供职位推荐、简历投递、求职辅导、职业培训等业务。在前程无忧的老架构中,大量核心数据存储于线下IDCOracle集群中,承载网才和51job等核心业务的大规模流量请求。

业务挑战

客户基于成本和技术升级角度,需要替换核心的Oracle数据库,但由于多年来在业务上的高速发展和不同团队的融合,系统中集成Java系列的MyBatis框架和.NET系列的ORM框架Entity Framework。业务结构中还深度依赖Tuxedo服务,并在其上运行OCI以及Pro*C程序。

综上所述,由于历史原因,客户的技术架构极具多样性,几乎兼容大多数主流开发语言。这种多技术栈的混合性,对于任何试图替换Oracle的行动形成了一项巨大的挑战。前程无忧研发团队为更好地支撑业务,降本增效,对核心Oracle数据库的替换问题迎难而上,与阿里云携手合作,共同推进此项工作。从技术层面来看,双方需要面对的挑战在于:新的数据库架构不仅需要解决语言和框架层面的兼容问题,还必须确保数据库层面所有操作的平滑过渡,以维持业务连续性和系统的稳定性。

解决方案

端到端产品化、标准化、规模化的去O解决方案

基于阿里巴巴集团去IOE的实践经验以及阿里云服务万千企业客户的技术沉淀,阿里云传承并发展去O能力,积累大量去O方法论和配套产品,如ADAM、DTS、PolarDB PostgreSQL版(兼容Oracle),形成一套端到端的产品化、标准化、规模化的去O解决方案,帮助企业更加平滑地迁移改造,降低“去IOE”风险。

image

调研与评估:客户梳理业务范围,并分析上下游之间的相互依赖关系,同时运用ADAM评估SQL/对象的兼容性及整体迁移改造方案。异构数据库迁移ADAM(Advanced Database & Application Migration)提供数据库平滑迁云解决方案,全面评估上云可行性、成本和云存储选型,内置实施协助、数据迁移、应用迁移等工具,覆盖数据库迁移的全生命周期,帮助企业降低数据库和应用迁移的风险、技术难度和实施周期,助力企业源数据库迁移上云。使用ADAM包括数据库采集、数据库画像、目标库选型建议、数据库评估分析几个过程,其中数据库采集方式可选在线/离线采集,满足客户不同的采集场景需求。

分析与设计:按照ADAM迁移评估报告进行迁移可行性/兼容性分析、改造成本预估、数据库架构设计、改造方案设计以及测试方案设计。

进行改造:对数据库SQL/对象兼容性业务进行改造,以及驱动适配性改造。

数据库测试:对PolarDB PostgreSQL版(兼容Oracle)进行开发功能测试、运维功能测试、可靠性测试、压力测试、迁移测试。功能测试覆盖细致且全面。

数据库迁移:确认网络环境符合要求,使用阿里云数据传输服务DTS,针对生产库搭建迁移任务,配置结构迁移、全量迁移、增量迁移,进行DTS全量校验+增量校验,保障数据迁移稳定性以及数据一致性。数据传输服务DTS(Data Transmission Service)是阿里云提供的实时数据流服务,支持关系型数据库(RDBMS)、非关系型的数据库(NoSQL)、数据多维分析(OLAP)等数据源间的数据交互,集数据同步、迁移、订阅、集成、加工于一体。

割接上线:制定详细的分钟级割接计划安排表,保障迁移割接按照计划无遗漏执行。进行业务停写、源库检查、同步追平,反向回流,切换业务,上线保障工作。

数据库兼容性PolarDB PostgreSQLOracle生态高度兼容,全面拥抱Oracle数据库的基础架构,确保对所有基本数据类型的支持。同时,PolarDB还关注到数据库结构的细节,全面兼容Oracle4605个内置函数,包括从日常数据处理到高级分析的各类函数,对于22DBMS内部包和318个系统视图,也实现准确的对应和支持,这为客户的数据库运用提供更多灵活性和便捷性。

语法兼容性:PolarDB的深度兼容性体现在对Oracle特有语法特性的复现上,如ConnectBy用于实现层次化查询,RowNum用于数据分页,以及同义词的灵活运用,这些都使得从OraclePolarDB的过渡十分顺畅。此外,PolarDB在支持分区表、事务处理、PL/SQL等核心功能的同时,也充分考虑到企业级应用的需求,提供用户自定义包以促进代码重用,实现复杂逻辑封装,以及异构连接能力,确保多源数据整合的顺畅无阻。PolarDB还引入了诸如闪回表、全局临时表、全局索引等高级特性,显著提升了数据管理和恢复的效率,而透明数据加密(TDE)则为数据安全加上了一把坚实的锁,确保信息资产的安全。

多模态驱动适配复杂业务

驱动概述

Oracle数据库向PolarDB平台的迁移过程中,客户体验到云迁移的多项优势。在此过程中虽然遇到一些兼容性和驱动相关的问题,但PolarDB团队积极响应客户需求,对关键业务组件进行细致的优化和调整,通过升级和适配各个应用程序接口,成功实现业务系统的平滑过渡。接下来我们将详细介绍驱动更换的具体方案。

image

OCI驱动适配

在采用Polar OCI替代Oracle OCI的架构转型项目中,我们规划两大核心阶段:初始化配置与应用适配,以确保迁移过程的平稳且高效。

image.png

初始化阶段
  1. 代码适配与驱动整合:首先,我们深度参与客户的代码调整工作,确保其能够顺利集成Polar OCI驱动。这一过程涉及将原有业务逻辑和数据库交互代码(包括连接管理、CRUD操作)与Polar OCI库的接口(如OCIInitialize, OCIEnvInit, OCIHandleAlloc等)紧密对接,为后续的无缝迁移奠定基础。

  2. 库替换与连接重构:然后,协助客户逐步将Oracle OCI库替换成Polar OCI库。通过一系列步骤,如设定服务器连接(OCIServerAttach)、会话初始化(OCISessionBegin)等,顺利完成数据库目标从OraclePolarDB的转变,确保底层通信协议的兼容与高效。

  3. 编译与服务启动:利用Tuxedo的编译工具链,对已完成适配的C代码实施编译与链接,生成服务端程序。此外,我们还优化Tuxedo的标准初始化接口,通过执行命令顺利部署服务,实现与PolarDB的稳定连接。

  4. 环境验证与启动:最后,我们确保所有初始化步骤正确执行,通过Tuxedo环境成功启动服务。这标志着数据库连接与基础功能验证均达到预期,为应用层的深入适配铺平道路。

应用阶段
  1. 模块级功能适配:深入到应用层面,我们配合客户逐一完成数据查询、更新模块以及特定业务逻辑函数的适配工作。通过精确调用Tuxedo服务,确保客户端能够无缝执行数据库操作。这一过程中,C代码逻辑与Polar OCI接口的融合是关键,确保业务连续性和性能稳定性。

  2. 深度集成Libpq驱动:Polar OCI驱动内置对Libpq驱动库的高级封装,为客户端提供直接通过Libpq接口与PolarDB交互的能力,这一设计进一步简化开发者的接入难度,提升整体系统的兼容性和灵活性。

总结

通过上述两阶段的适配操作,我们在代码级别上完成从连接到业务逻辑的全面适配。特别是在面对Tuxedo环境下OCI业务模块的复杂迁移挑战时,通过Polar OCI的深度整合与优化,有效解决连接性、操作性及语法兼容性等问题,保障业务在迁移过程中的不间断运行。这一迁移策略不仅满足客户ToBToC业务的多元化需求,还为未来云原生架构的扩展奠定坚实基础。

Pro*C驱动适配

在采用Polar ECPG替代Oracle Pro*C的迁移架构设计中,同样规划初始化配置阶段与应用适配阶段。

image.png

初始化阶段
  1. 代码适配与ECPG集成:首先,我们的专家团队深入客户的代码基础,着手将原有业务逻辑与数据库操作代码(即含嵌入式SQLPC代码)适配至ECPG驱动。这一阶段在保持业务逻辑不变的同时,确保ECPG的有效集成。

  2. 编译工具链升级:然后,我们将客户的编译环境从Oracle Pro*C转向ECPG编译器,这一转换要求对Makefile和依赖文件进行相应调整,以确保ECPG能够准确识别并处理嵌入式SQL代码,将其转化为调用ECPG接口的纯C代码。

  3. 编译与服务配置:我们指导修改后的Makefile的编译过程,将ECPG处理后的C代码与Tuxedo的编译模块相结合,编译链接成Server程序。随后,通过执行tmboot命令,借助Tuxedo的标准化接口tpsvrinit成功启动服务,实现与PolarDB的初次握手。

应用阶段
  1. 模块全面适配:进入应用层面,我们携手客户逐一完成数据操作关键模块(如查询、更新、校验、会员管理、任务调度及网页生成)的ECPG适配。确保各模块接口函数无缝对接ECPG库,保障业务逻辑的执行与数据库操作通过ECPG接口紧密相连,维持业务流程的连续性和稳定性。

  2. 深化Libpq集成:在ECPG驱动之下,我们充分利用其对Libpq驱动库的高级封装,为客户端与PolarDB之间搭建起高效、可靠的通信桥梁。这一策略确保客户端能够通过Libpq接口函数,实现对数据库的流畅交互。

总结

通过以上策略,我们不仅在代码与逻辑层面成功适配Polar ECPG驱动,还在技术栈转型上取得实质进展,有效帮助客户将数十项服务从Oracle Pro*C平稳迁移到Polar ECPG。这一过程不仅解决数据库目标变更带来的连接、操作及语法兼容性等系列挑战,还保障业务在从OraclePolarDB转换期间的正常运行。

MyBatis框架的适配(JDBC)

MyBatis在处理时间类型数据时遇到与JDBC驱动的适配问题。这里我们将介绍JDBC处理数据类型的问题和对应解决方案。

imageJDBC处理数据类型流程
  1. 预处理语句(Prepared Statement):参数绑定,涉及将Java中的值映射到PostgreSQL的数据类型。

  2. 设置参数和绑定处理(Parameter Setting & Binding)

    • 使用setXXX()方法,JDBC驱动将记录在对应参数索引位置绑定的Java类型及值。

    • 针对每个参数,生成对应的格式化值,比如将其转换为字符串或二进制表达。JDBC驱动会根据之前调用的setXXX()方法来确定参数的PostgreSQL数据类型,并将这些信息以及参数的实际值发送到服务器。

  3. 类型推断(Type Inference):服务器接收到参数和类型信息后,将其与预先创建的查询计划结合,进行类型匹配和推断。

  4. 结果返回(Result Return):数据库处理结果后,通过结果集返回MyBatis框架的ResultSetHandler,从而上传处理结果。

JDBC处理数据类型过程存在的问题:在使用setXXX()方法时,JDBC驱动会丢失TIMESTAMPOID。这是由于社区版本PostgreSQLJDBC在处理TIMESTAMP类型时的保守策略引起的,从而导致数据库无法正确接收TIMESTAMP类型的时间数据。

解决方案

升级JDBC驱动,使其能够正确传递TIMESTAMP类型的OID。从而让数据库正确处理TIMESTAMP类型的数据。目前,PolarDBJDBC系列与MyBatis框架实现完全兼容,确保时间类型数据的准确处理。通过这次更新,我们解决MyBatis在交互时间类型数据时的适配难题,为使用者提供更加稳定可靠的开发体验。PolarDB JDBC驱动的详细介绍请参考JDBC

ODBC驱动的适配

ODBC问题简介

关于ODBC的具体问题在于,Oracle数据库中的DATE类型采用64位表示,格式为年、月、日、时、分、秒。然而,迁移至PostgreSQL协议后,PostgreSQL中的DATE类型为32位,表示年、月、日。为在PostgreSQL协议中实现与Oracle相同表述能力的64DATE类型,驱动类型的适配和改造成为必要。

解决方案

image.png

解决方案涵盖以下关键步骤:

  1. 从数据库中提取64位的SYS.DATE数据类型。

  2. 通过ODBC驱动,我们成功识别这种独特的64位日期类型,并在copy_and_convert_field函数中进行单独处理。此过程包括将其格式化为类似于时间戳的格式进行解析。

  3. 结果是,返回至应用层的日期类型数据现在包含完整的年、月、日以及时、分、秒信息。

通过这套方案,我们有效解决PostgreSQL协议在DATE类型支持方面存在的局限性。此项创新确保数据类型的完整兼容,从而实现在客户数据库中无损的时间类型适配。PolarDB ODBC驱动的详细介绍请参考ODBC

.NET&EntityFramwork驱动的适配

多版本适配

为满足客户对不同.NET框架版本的需求,PolarDB采取全面兼容的策略,实现从.NET Framework 2.0至的.NET Framework 7.0的全兼容,以及跨平台的.NET Core和跨库兼容的.NET Standard版本的适配。这项技术成就确保客户能够在各种.NET环境中无缝完成驱动的替换,全面保障了业务的持续性和技术的前沿性。PolarDB .NET驱动的详细介绍请参考.NET

数据类型适配

image.png

在基于ORM模型的Entity Framework框架内部,业务系统在时间类型适配方面遇到难题。这一点同ODBC类似,具体见ODBC问题简介

解决方案包括以下三个步骤:

  1. 实体层(Entity Layer):在实体定义中,用户指定TypeNameDATE,声明表结构中的时间字段应映射为数据库的抽象DATE类型。

  2. 上下文层(DbContext Layer):在DbContext中,为DATE类型定义一个内存中的表示。为适应不同的数据库驱动,这个类型需要有针对性的实现。对于PolarDB的.NET驱动,必要的工作是将实体的DATE类型映射为数据库中的64DATE类型。

  3. 数据库层(Database Layer):在数据库端,PolarDB提供DATE类型的完整的64位实现,确保数据表中的时间字段和Oracle中的时间字段保持相同的精度。

通过这样的梯次化适配,业务用户对DATE类型的使用变得透明无感,无论后端数据库是Oracle还是PolarDB。这种无缝适配策略最大程度地减少迁移和适配过程中对现有业务的影响,确保数据类型表示的一致性和准确性。

DTS保障数据实时迁移和一致性

数据迁移、校验流程

image
  • 结构迁移

    O结构的迁移可以利用DTS结构迁移包装的ADAM能力来实现结构对象的迁移。

  • 全量迁移

    结构迁移结束后开始存量数据迁移。

  • 增量日志解析和数据回放

    在全量迁移开始前启动增量日志解析,并缓存增量数据。在全量迁移结束后开始进行增量数据回放,包含全量迁移期间的增量数据和原库实时产生的增量数据,提供秒级实时同步能力。

  • 全量数据校验

    在增量回放第一次追平之后启动全量数据校验,校验该过程存量数据实时一致性。

  • 增量数据校验

    在增量回放第一次追平之后启动增量数据校验,校验增量数据实时一致性。

  • 反向回流和增量校验

    在应用停写后、应用割接切流前建立反向回流链路,启动增量数据反向回流,提供割接失败之后回切到Oracle数据库的能力。

数据迁移

采样切片保障全量迁移性能和稳定性

采样切片仅进行一次查询,使用数据库的sample函数进行采样,以确保切片效率和大表迁移稳定性。同时,解决Oracle临时表空间膨胀的问题,提供表内并发写入能力,提升全量迁移的效率。原理如下:

image
实现multi-verison-meta日志解析能力

根据Oracle提供系统基表(USER$OBJ$COL$IND$ICOL$CDF$CCOL$TABPART$TABSUBPART$TABCOMPART$)的存量和变更信息构建任意时间点表、列、索引、分区等信息,实现任意历史时间点启动、回溯、解析增量数据。

image

其中Meta snapshot为全量结构信息快照。DDL log为增量基表变更数据,使用SCN作为checkpoint位点标识。在增量日志解析过程中,可以构建实时表结构信息,保障增量日志解析的稳定性和准确性。

校验

DTS提供丰富的数据校验能力,其中全量提供切片并发、自适应复检能高效保障存量数据一致性,同时DTS提供增量校验能实现源库低流量、低扰动来校验增量数据一致性,具体核心实现能力如下:

image

一主多读架构高效承载流量压力

为应对日益增长的客户流量需求,PolarDB采取一种高度优化且策略性的一写一读部署架构,遵循读写分离的原则,从而实现资源利用的最大化与服务性能的显著提升。

image.png

主从数据库读写分离

主数据库作为整个架构的核心,专注于处理高并发的在线交易事务,例如订单处理等即时操作。通过先进的锁机制与事务管理策略,确保数据的一致性以及事务的ACID特性(原子性、一致性、隔离性、持久性),即使在面对高峰流量时也能保持极低的延迟响应。主从数据库的配置为系统的分析处理能力提供了强有力的支持。通过对主库数据的实时复制,从库拥有几乎完整的数据副本,能够独立承担报表生成、大数据分析、业务趋势预测等分析型工作负载。该架构设计不仅充分发挥了数据库的读取扩展性,还通过智能调度算法,根据查询类型和资源占用情况自动分配任务,从而实现查询效率与资源利用的最优化。

image.png

主数据库的单日流量图(示例)

image.png

从数据库的单日流量图(示例)

从上图中的监控示例可以看出,主从数据库同时负载主要的流量,读写分离有效地分摊业务的压力。

资源调度优化

image.png

主数据库上的等待事件(示例)

image.png

从数据库上的等待事件(示例)

通过观察等待时间,可以发现主数据库主要存在DDL行锁等待事件和数据库的IO等待事件,从数据库仅存在数据库的IO等待事件。该设计尽可能确保数据库行锁等待仅发生在主数据库,同时充分发挥两个节点的IO能力,以并发方式处理业务数据。通过精细的负载均衡策略,PolarDB的部署模式确保集群内资源的高效配置。

全方位的自动化监控

概述

PolarDB PostgreSQL版(兼容Oracle)还支持使用全局自动负载信息库(Global Automatic Workload Repository,简称GAWR)对数据库进行全方位多维度的监控。如下图所示,监控指标涵盖CPU、内存、I/O、文件系统、TPS、连接数、缓存命中率、延迟、慢SQL等多个维度,基于这些指标可以对数据库系统问题进行详细分析。

image.png

说明

此监控数据仅作为演示,非真实集群监控数据。

读写IO情况

image.png

I/O读写延迟通常反映当前磁盘带宽和延迟的实际表现,它是评估PolarDB在基于PSL4PSL5磁盘架构下对负载响应的关键指标。通过对比这两者,能够衡量不同硬件配置下的读写延迟影响,详细介绍请参见计算节点规格

对于当前的示例监控数据,有90%的读写操作延迟保持在200微秒(us)以下,进一步观察可发现超过99.8%的寻址(seek)和打开(open)操作的延迟同样低于200微秒。这些数据指标不仅展示该集群所使用存储设备的卓越性能,还表明其在I/O处理方面没有明显的瓶颈。简而言之,存储设备的性能表现优异,确保了数据处理的高效性与稳定性。

TOP 锁阻塞情况

image.png

锁阻塞状况是诊断数据库事务瓶颈的关键指标,为数据库管理员(DBA)提供洞察当前事务处理性能并采取针对性解决措施的依据。正如所示图表中,该数据库目前存在多个类型的锁,这暗示着事务之间发生因行锁引起的冲突(如并发场景下多个事务尝试更新同一行数据)。

基于这些观察结果,可以为DBA提供有价值的建议,即在未来的版本迭代中调整和优化数据更新逻辑,从而减少锁等待时间,提高事务效率。通过这样的策略性优化,DBA能够提升数据库整体的并发处理能力,降低竞态条件及其造成的性能瓶颈。

总结

受益于阿里云全面而成熟的产品和标准化的去Oracle解决方案,辅以阿里云数据库专家团队的技术力量和细致指导,前程无忧成功迈出数据库架构优化与升级的重要一步。在这项具有里程碑意义的项目中,阿里云的工程师和前程无忧的开发人员密切合作,数月时间里携手奋战,贯穿项目从适配、开发、测试到割接转移的各个关键阶段。在这一过程中,不仅彰显前程无忧对于项目的重视和资源的投入,同样显现出阿里云提供的全面支持和专业技术能力。

DTS作为成熟、可靠的去O搬站工具,提供了完备去O迁移方案。其中结构迁移、全量迁移以及增量迁移支持客户数据实时迁移搬站,满足业务割接宕机时间要求,全量、增量数据校验能力坚守数据一致性底线,为数据库迁移上云保驾护航。

PolarDB的稳定性和先进性支撑着前程无忧的核心业务。不仅带给客户前所未有的性能提升和卓越的使用体验,还有效地推动成本效益与运营效率的双重提升。项目的圆满完成,在上海地区的互联网去Oracle实践中树立了标杆,并标识着PolarDB在全方位支持Oracle生态方面的成熟和可靠。