GaussDB关键技术原理:高性能(五)

GaussDB关键技术原理:高性能(四)从USTORE存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP并行执行等五方面对高性能关键技术进行解读,本篇将从LLVM动态查询编译执行、SQL-BYPASS执行优化、线程池化、多核处理器优化、日志无锁刷新与多级流水等方面继续介绍GaussDB高性能关键技术,并对高斯数据库性能优化进行总结。

3.11 LLVM动态查询编译执行

在传统经典执行器算子中基于遍历树的表达式计算框架,这种框架的好处是清晰明了,但是在性能上却不是最优的,主要有以下几个原因:

(1)表达式计算其框架的通用性决定了其执行模式要适配各种不同的操作符和数据类型,因此在运行时要根据其表达式遍历的具体结果来确定其执行的函数和类型,对这些类型的判断要引入非常多的分支判断。

(2)表达式计算在整体的执行过程中要进行多次的函数调用,其调用的深度取决于其树的深度,这一部分也有着非常大的开销。

这两个核心原因,分支判断和函数调用同样在执行算子中也是影响性能的关键因素,为了提升其执行速度,GaussDB引入了业界著名的开源编译框架LLVM(Low Level Virtual Machine)来提速的执行速度,LLVM是一个通用的编译框架,能够支持不同的计算平台。LLVM提升整体表达式计算的核心要点如下:

(1)GaussDB内置的LLVM编译框架通过为每一个计算单元(表达式或者执行算子里面的热点函数)生成一段独特的执行代码,由于在编译的时候提前知道了表达式涉及的操作和数据类型,为这个表达式生成的执行代码将所有的逻辑内联,完全去除函数调用。GaussDB内置的LLVM编译为这个表达式生成了一段特殊代码。里面已经没有任何其他的函数调用,所有的函数都已经被内联在一起,同时去掉了关于数据类型的分支判断。

(2)LLVM编译框架利用编译技术最大程度的让生成的代码将中间结果的数据存储在CPU寄存器里,让数据读取的速度加快。

LLVM通过消除条件逻辑冗余,降低虚函数调用次数,改善数据locality,可大大降低任务执行代价; LLVM生成的machine code为一次性成本,整个执行过程均可使用,数据量越大,所获取的收益将越大,因此对于一个可以实施LLVM动态编译优化的查询,其收益随着数据量的增多会逐步增加,对应的性能提升比例也会越来越大

3.12 SQL-BYPASS执行优化

在典型的OLTP场景中,简单查询占了很大一部分比例。这类查询本身大多数会走索引、分区剪支、只涉及单表和简单表达式的查询,这类查询的有效数据读取占比在这个查询解析、执行过程中并不大,即便使用计划缓存技术(PBE)把查询解析部分省下来以后,执行器初始化exec_init_*()仍然会有比较明显的开销,例如下面火焰图所profiling的场景,执行器初始化开销占比超过40%,并且每个同样的模板查询这部分的操作都是无效的重复开销,有效部分只有Operator::get_next(),占比只有15%左右。

因此为了加速这类查询,提出了SQL-BY-PASS框架,其核心思想是对执行路径inline处理优化,减少不必要的执行器函数迭代的开销,在parse层对这类查询做简单的模式判别后,进入到特殊的执行路径里,跳过经典的执行器执行框架,包括算子的初始化与执行、表达式与投影等经典框架,直接重写一套简洁的执行路径,并且直接调用存储接口,这样可以大大加快简单查询的执行速度。以分区表点差举例,通过SqlByPass技术将分区表的执行过程进行扁平化inline处理,将原来SQL执行引擎中很深的调用栈扁平化,性能提升30%。

3.13 线程池化

在OLTP领域中数据库通常需要处理大量的客户端连接。因此,高并发场景的处理能力是数据库的重要能力之一。对于外部连接最简单的处理模式是per-thread-per-connection模式,即来一个用户连接产生一个线程。这个模式好处是架构上处理简单,但是高并发下,由于线程太多,线程切换和数据库轻量级锁区域的冲突过大导致性能急剧下降,使得系统性能(吞吐量)严重下降,无法满足用户性能的SLA。归纳起来每当面对高并发业务(线程/CPU核数比大于10)场景时,系统通常面临以下几个方面挑战:

(1)资源耗尽,由于接入的会话数过多导致消耗过多的内存、连接数资源耗尽产生系统宕机、OOM等异常,造成系统可用性降低。

(2)过度争抢,由于并发数过多而具体CPU计算有限,增加了临界区锁、信号量等处理开销,大量资源并未产生客户实际吞吐量。

(3)相互影响,如果某一个会话请求占用过多的CPU、内存资源导致对其他会话资源的挤占,造成单个请求拖垮整个系统的严重问题。

因此,对于高并发性能稳定性从本质上分析,数据库系统需要从设计上解耦接入会话数与资源使用量&争抢之间的线性耦合关系,同时对极端“炸弹式”请求需要有有效的管控措施,将其影响控制在有限的范围内。GaussDB主要的解决方案过线程资源池化复用的技术来解决该问题。线程池技术的整体设计思想是线程资源池化,并且在不同连接之间复用。系统在启动之后会根据当前核数或者用户配置,启动固定一批数量的工作线程,一个工作线程会服务一到多个连接session,这样把session和thread进行了解耦。因为工作线程数是固定的,因此在高并发下不会导致线程的频繁切换,而由数据库层来进行session的调度管理。

高斯数据库线程池实现主要体现在以下3个方面:

(1)资源解耦:将接入会话&工作线程进行解耦隔离,确保高并发场景下系统资源不会持续增加而是保持稳定。

(2)多核优化:在多核场景下考虑到NUMA效应,线程池针对工作线程的调度范围根据NUMA node进行分配和限制,避免线程的调度跨numa,降低处理时延提升性能。

(3)资源管控:线程池化基础上实现以工作线程为粒度的过载管控,避免单一线程占用过多资源,提升系统可靠性。

通过线程池化改进后相比高并发场景下具有明显的性能稳定性,以下是数据库性能稳定性测试,通过标准OLTP负载模型(TPCC)的测试结果。

并发数

MySQL非线程池

GaussDB(线程池)

100

339,171.29

852,701.91

200

401,879.30

1,267,780.87

400

380,815.54

1,616,192.10

600

344,775.51

1,693,294.49

800

316,093.14

1,663,179.51

1600

250,559.43

1,632,902.63

2400

207,585.54

1,631,816.55

3200

181,735.22

1,615,253.23

总结:在线程池的帮助下数据库系统面对大并发场稳定性、性能两个方面都有明显提升。

(1)稳定性:随着并发数增加MySQL无线程模式的数据库性能在CPU资源满了以后并不会像GaussDB这样保持稳定。

(2)高性能:数据库线程池化考虑多核CPU NUMA亲和以后进一步提升性能,相比MySQL有明显优势。

3.14 多核处理器优化

鲲鹏ARM服务器多CPU-socket架构下跨NUMA内存访问延迟存在严重的不对称,远/近端内存访存时延有成倍数差异,同时相比x86内存访问时延高50%、并发控制原语代价高2-3倍,在数据库中会以进一步恶化OLTP瓶颈,尽管通常在架构下CPU物理核心数相比x86有了一定提升,但如果不合理设计和实现数据库内核关键数据结构、线程调度模型无法充分利用ARM多核的优势,如何优化NUMA带来的访问时延问题,如何充分利用众核CPU解决并发控制问题成为了鲲鹏上优化数据库OLTP负载性能的主要挑战。使用标准事务型负载TPMC benchmark测试结果96核x86 135w,128核ARM在NUMA优化前只有110w tpmC左右。

GaussDB Kernel根据ARM处理器的多核NUMA架构特点,进行针对性一系列NUMA架构相关优化,主要围绕三个方面进行:

(1)线程调度访存本地化:减少跨核内存访问的时延问题,让线程调度尽可能在单个NUMA节点内,同时针对高频热点数据结构通过适当的冗余保留在本地,减少跨NUMA远端内存访问。

(2)ARM多核算力优化:针对鲲鹏ARM体系下计算核心多的优势,对数据库查询处理、数据库缓冲区脏页处理、WAL日志等关键处理流程进行multi-thread多级流水线改造,将原有单线程处理流程下发给多个CPU-线程进行并行处理提升总体性能。

(3)ARM指令集优化:借助ARMv8.1引入的新的原子操作LSE,将大量的可转换为原子类型操作(plus、minus、CAS)的部分,替换为ARM硬件相关原语LSE指令集,从而提升多线程间同步性能,例如工作线程-WAL写入性能等。

3.15 日志无锁刷新与多级流水

在写事务型负载中日志落盘位于性能关键路径,为了确保数据可靠性在执行INSERT、DELETE、UPDATE等操作均需要记录。经过在多核环境上的性能测试,我们发现日志在Flush时存在大量的等待,其本质原因是当前在并发场景下日志落盘环节中很难在WalInsertLock数量和锁遍历开销中取得平衡最优解,导致成为瓶颈。

上图展示了常见的日志的实现方案,主要可以归纳成3个方面:

(1)数据库内核线程必须获取日志插入锁WALInsertLock才能进入第一个临界区,在临界区中,Backend线程首先会预留WAL的插入位置,然后将生成的WAL复制到WAL Buffer的对应预留位置中。由于是多个数据库后台线程进行的并发拷贝,每个Backend线程拷贝完成的时机并不一致。

(2)数据库后台线程需要遍历所有的WALInsertLock检查lsn是否已经下盘,当WALInsertLock的数目越多时,在执行WAL Flush之前等待其他Backend线程将日志拷贝完成的时间就越长。

(3)WALInsertLock的数目越少时,XLog插入锁的抢占就越激烈。所以不管WALInsertLock的数量如何变化,系统的性能都很难达到最优,这成为了目前日志落盘的瓶颈。

GaussDB针对WalInsertLock日志锁进行优化,利用LSN(Log Sequence Number)及LRC(LogRecord Count)记录了每个backend的拷贝进度,取消WalInsertLock机制。在backend将日志拷贝至WalBuffer时,不用对WalInsertLock进行争抢,可直接进行日志拷贝操作。并利用专用的WalWriter写日志线程,不需要backend线程自身来保证xLog的Flush。通过以上优化,取消WalInsertLock争抢及WalWriter专用磁盘写入线程,在保持原有xLog功能不变的基础上,可进一步提升系统性能。针对Ustore Inplace update WAL log写入,Ustore DML operation并行回放分发进行优化。通过利用prefix和suffix来减少update WAL log的写入。通过把回放线程分多个类型,解决Ustore DML WAL大多都是多页面回放问题。同时把Ustore的数据页面回放按照blkno去分发,更好的提高并行回放的并行程度。

Ustore存储引擎

4 高斯数据库性能优化总结

高斯数据库GaussDB华为公司过去10年打造的一款高性能OLTP交易型数据库产品,在迭代演进过程当中吸纳当今主流数据的技术与思路,确保架构和演进层面的领先性,在达到高性能的同时能够保证事务的强一致性,在国内泛金融领域、保险、等主要行业、公司内部ERP等有广泛的应用和成功落地实践。

首先,高斯数据库从架构层面需要保证处理能力可持续提升、可横向扩展,避免某一单点问题阻碍上限的提升,因此最初架构演进上就做过深入的考虑,因此在相同代码基础上同时具备分布式、集中式两种不同的部署形态,这里集中式部署形态决定了单节点(单分片)的性能上限,而分布式将多个数据分片结合到一起通过横向扩展提升总体上限。因此从产品架构维度上看,高斯数据库的高性能技术点可分成集中式、分布式两个优化维度。

(1)集中式性能维度,主要聚焦数据库进程内的算法实现,其目标在于将节点内有限计算资源有效最大化利用。首先,从查询执行算法的宏观维度,优化器通过查询重写、CBO/ABO代价模型确保查询整体执行步骤最优;其次,执行引擎将执行计划内的每个算子执行效率发挥出来,通过节点内SMP对称多线程并行处理技术将多核CPU资源加以利用实现处理任务时序在时间维度重叠达到提升,通过算子Vec向量化、CodeGen/LLVM化等技术实现局部编译器执行,确保了CPU指令集微观层的优化效果,此外集中式场景还考虑单节点大容量数据场景,执行层面提供了丰富可选数据分区策略(Range、List、Hash、Interval、二级组合分区)能够根据用户业务的定义对数据查询范围进行数量级的裁剪,通过ustore存储引擎确保读写混合负载长稳性能以及空间节省,同时为了保证数据的强一致性处理WAL日志落盘也进行了异步流水化改造提升单位时间内日志持久化落盘的速率,进而提升读写事务的性能。再次,在性能稳定性层面,同样做了线程池化、内存共享化改造能够确保并发线程在内存、CPU调度之间得到平衡,能够在极致并发场景下如5x(相对满负荷负载并发)并发性能不显著下降,十倍甚至百倍并发系统不崩溃,并已在公司MetaERP项目中得到过实战检验。

(2)分布式性能维度,主要聚焦多数据分片汇聚线性度确保性能可横向扩展,在高斯数据库里实现了CN轻量化技术、分布式单分片事务降低CN路由和本地事务处理开销能够在256大集群内线性度达0.85以上,对于分布式事务提供了轻量化全局事务GTM-lite技术能够让分布式事务开销进一步降低,在标准TP点查负载模型下32节点以内线性度达到0.9以上。分布式大数据量处理处理场景下,分布式优化器能够基于全据统计信息合理生成分布式查询计划确保在数据搬迁-本地计算量两个维度获得最优解,实现跑批处理的高效性,分布式执行框架串联多个分片计算单元在分片间实现并行计算,实现节点内-节点间的双重并行叠加最大化分布式系统的资源利用率,在数据分布层面同样提供HASH、LIST、RANGE分布策略供客户应用场景进行选择,实现了分布-集中式分区两个维度的数据分片能力叠加,极大提升了大数据量场景下的数据剪枝优化能力,并在CBG、邮储等核心业务系统中得到实战检验

其次,为了确保高斯数据库性能易用性,针对历史版本升级、异常场景下的逃生策略同样做了一些列性能辅助特性,例如SPM计划管理、SQL-PATCH能够在版本升级、系统迁移、统计信息突变场景下对已有optimal计划起到保护作用,避免计划跳变导致的性能劣化,基于线程调度抗过载逃生能有效控制慢查询等“性能炸弹”进行有效隔离,在企业应用的一些边界极端场景确保数据库性能SLA达成。

回顾过去,GaussDB在演进迭代过程中积极吸取了时下关系型数据库、分布式数据库的设计与优化方案,在短短的10年内走完了A国友商40年的演进历程,同时并未对分布式TP/AP系统的复杂性妥协,在确保单节点性能领先的前提下仍然可通过分布式提升整体的性能上限并具备0.85+不错线性扩展比。放眼未来,随着计算机软硬件、OS/编译器/网络协议等基础软件不断革新,高斯数据库性能优化也扎根到与之相结合的新高度,在近年出现的多核128/256多核CPU,鲲鹏/x86体系结构相关背景下基于多核NUMA的优化方案也在产品里落地商用,其中鲲鹏2/4路180w/230w tpmC、32节点1600w tpmC的优势更是在友商性能性能比拼测试中获胜,此外还进行编译器相结合的优化,基于毕昇编译器的PGO、LTO、BOLT、静态编译优化等手段已在局点实战比拼中提升已有上限的20-30%,进一步巩固领先优势并在可预见的将来落地商用版本。

欢迎小伙伴们交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/791583.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【文档+源码+调试讲解】冷冻仓储管理系统

摘 要 随着互联网时代的到来,同时计算机网络技术高速发展,网络管理运用也变得越来越广泛。因此,建立一个B/S结构的冷冻仓储管理系统,会使冷冻仓储管理系统工作系统化、规范化,也会提高冷冻仓储管理系统平台形象&#x…

若依搭建 帝可得 售货机 笔记

一、搭建项目 1.后端gitee链接: 启动项目时记得修改mysql和redis的相关信息;创建项目相关数据库,并导入初始化的SQL脚本 dkd-parent: 帝可得后台管理系统 (gitee.com) 2.前端gitee链接: 启动项目时记得安装依赖:np…

IPv4与IPv6的定义和主要区别

IPv4与IPv6的定义 IPv4,即互联网协议版本4(InternetProtocolversion4),是互联网使用最为广泛的协议之一。它采用32位地址,以点分十进制表示,如192.168.1.1。 IPv6,即互联网协议版本6&#xff…

自动驾驶革命:商汤科技突破性大模型UniAD震撼登场

自动驾驶革命:商汤科技突破性大模型UniAD震撼登场! 在人工智能的浪潮中,自动驾驶技术一直是科技巨头们竞相追逐的圣杯。而今,商汤科技联合上海人工智能实验室与武汉大学,以一篇名为"Planning-oriented Autonomou…

Shader每日一练(2)护盾

Shader "Custom/Shield" {Properties{_Size("Size", Range(0 , 10)) 1 // 控制噪声纹理缩放大小的参数_colorPow("colorPow", Float) 1 // 控制颜色强度的指数_colorMul("colorMul", Float) 1 // 控制颜色乘法因子_mainColor("…

政安晨:【Keras机器学习示例演绎】(五十四)—— 使用神经决策森林进行分类

目录 导言 数据集 设置 准备数据 定义数据集元数据 为训练和验证创建 tf_data.Dataset 对象 创建模型输入 输入特征编码 深度神经决策树 深度神经决策森林 实验 1:训练决策树模型 实验 2:训练森林模型 政安晨的个人主页:政安晨 欢…

【机器学习】独立成分分析(ICA):解锁信号的隐秘面纱

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 独立成分分析(ICA):解锁信号的隐秘面纱引言I…

人工智能算法工程师(中级)课程3-sklearn机器学习之数据处理与代码详解

大家好,我是微学AI,今天给大家分享一下人工智能算法工程师(中级)课程3-sklearn机器学习之数据处理与代码详解。 Sklearn(Scikit-learn)是一个基于Python的开源机器学习库,它提供了简单有效的数据挖掘和数据分析工具。Sklearn包含了…

webstorm问题解决:无法识别 @

问题解决tsconfig.json 问题 本地的 vite.config.ts 已经配置 路径 但是,我用webstorm 上识别不了 解决 新增文件tsconfig.json,添加 baseUrl 和 paths 的配置,以告诉 TypeScript 和 WebStorm 如何解析路径别名 tsconfig.json {&quo…

无需构建工具,快速上手Vue2 + ElementUI

无需构建工具,快速上手Vue2 ElementUI 在前端开发的世界中,Vue.js以其轻量级和易用性赢得了开发者的青睐。而Element UI,作为一个基于Vue 2.0的桌面端组件库,提供了丰富的界面组件,使得构建美观且功能丰富的应用变得…

禁止使用存储过程

优质博文:IT-BLOG-CN 灵感来源 什么是存储过程 存储过程Stored Procedure是指为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户可通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行。 …

AndroidStudio2023.3版本avd manager模拟器无法创建

创建到最后一步的时候提示WARN - #com.android.sdklib.internal.avd.AvdManager - com.android.prefs.AndroidLocationsException: Can’t locate Android SDK installation directory for the AVD .ini file. 前提: 1.sdk路径没问题 2.安装了下图内容 那是什么原因…

Linux /etc/profile 详解

概述 Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量&…

原生小程序生成二维码并保存到本地

需求:我要在一个页面中生成一个二维码,并且这个二维码可以长按保存到本地或者发送给好友; 我这里是将生成的canvas二维码转换成图片,利用长按图片进行保存或转发 效果图: 第一步先下载对应的包: npm instal…

C语言笔记31 •单链表经典算法OJ题-3.反转链表•

反转链表 1.问题 给你单链表的头节点 head&#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 2.代码实现&#xff1a; //3.反转链表 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <assert.h>typedef int …

LLM——langchain 与阿里 DashScop (通义千问大模型) 和 DashVector(向量数据库) 结合使用总结

文章目录 前言预览直接调用大模型使用 prompt template格式化输出使用上下文 RAG 增强检索 自定义 langchain AgentPromptTemplate 和 ChatPromptTemplate使用少量示例创建ChatPromptTemplate 前言 langchain 是一个面向大模型开发的框架&#xff0c;其中封装了很多核心组件&a…

设计模式之外观模式(Facade)

Facade设计模式&#xff0c;也称为外观模式&#xff0c;是一种结构型设计模式&#xff0c;它主要用于为子系统中的一组接口提供一个统一的高层接口&#xff0c;从而使得子系统更加容易使用。以下是关于Facade设计模式的详细介绍&#xff1a; 一、定义 Facade模式为多个复杂的…

期权专题12:期权保证金和期权盈亏

目录 1. 期权保证金 1.1 计算逻辑 1.2 代码复现 1.3 实际案例 2. 期权盈亏 2.1 价格走势 2.2 计算公式 2.2.1 卖出期权 2.2.2 买入期权 免责声明&#xff1a;本文由作者参考相关资料&#xff0c;并结合自身实践和思考独立完成&#xff0c;对全文内容的准确性、完整性或…

【Linux】管道命令

命令执行的时候有时会输出数据&#xff0c;有的命令输出的数据太繁杂了。 那么我们怎么去筛选这些信息来得到我们所想要的格式&#xff1f; 这就牵涉到管道命令的问题了&#xff08;pipe&#xff09;&#xff0c;管道命令使用的是【|】这个界定符号。另外&#xff0c;管道命令与…

Mongodb单字段索引详解

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第89篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…