• [DevKit] 【Hyper Tuner调优实践 11】基于系统性能分析工具的Python拼接字符串的性能调优实践
    【Hyper Tuner调优实践 】基于系统性能分析工具的python字符串拼接优化调优介绍Hyper Tuner是一款鲲鹏性能调优工具,本实践中使用Hyper Tuner工具对业务中使用python进行字符串拼接接口执行系统全景分析分析,应用热点函数分析,找到性能瓶颈点,并根据分析结果进行优化修改,从而实现使用python进行字符串拼接性能增强。组网环境说明:本实践以TaiShan 200服务器(型号2280)+ CentOS 7.6组网举例,Hyper Tuner在其他鲲鹏平台和操作系统上的操作类似。表格1 调优环境项目说明服务器TaiShan 200 服务器(型号2280)CPUKunpeng 920 4826OSCentOS 7.6应用python3调优工具Hyper Tuner 2.3.T10 操作步骤      1、python3执行如下demo,该接口中使用“+”在for循环中拼接字符串,该demo耗时约11s      2、进行全景分析操作,按照如下参数创建任务3、全景分析任务结果分析总览页面显示CPU利用率高查看Top数据,内存使用率也较其他进程高 接下来跑应用的热点函数分析任务来观察哪些相关的C API有被调用到。4、创建应用的热点函数分析任务由于python3不在工具默认的路径中,首先配置python3的目录到应用程序路径配置项中返回到工程管理页面,按照下图方式创建性能分析任务5、热点函数任务结果分析查看总览页面的Top热点函数,其中memcpy实现内存中复制,__libc_realloc即malloc函数,用来实现内存的申请及分配,它们消耗了较多的cpu资源性能瓶颈分析综合以上的分析,python中的string是不可变对象,循环中使用+进行大量字符串拼接时,会频繁的进行内存的申请、分配以及字符串的复制,导致性能低下。性能瓶颈优化将代码进行修改,使用join拼接字符串,重复以上操作步骤,查看分析结果注意运行参数修改为string_join系统全景分析任务显示,内存平均使用率降低,持续时间缩短应用热点函数分析任务显示,运行时长降低到之前一半,__libc_realloc不再是TOP热点函数总结字符串拼接方式运行时长%MEM(平均)+拼接11.50s15.59%join拼接5.43s15.52%  
  • [其他] 分享数仓性能调优必读:从系统级到SQL级,带你进阶为性能调优高手
    数仓性能调优是数据库应用开发和迁移过程中的关键步骤,在整个项目实施过程中占据很大的份量。它没有明确的衡量标准和对错之分,考验的是资深一线技术人员的隐式技能。如果想成为一个性能调优的高手,除了对应用程序的逻辑做到游刃有余外,还需要了解应用的数据库的基本实现原理,更甚者,需要对操作系统、网络等基础知识有所涉猎,同时还要具备性能诊断和分析技巧。介于此,华为云社区推出了“GaussDB(DWS)性能调优”系列专题,该技术专题由华为云数据库内核技术专家、一线系统工程师撰写,从业务实战经验出发,为开发者介绍数据库级别的性能调优思路和总体策略,包括系统级和语句级调优。本系列文章共分为三部分,前面的基础篇和实战篇聚焦于数仓调优,最后为大家简单介绍数仓产品的最新动态。各位开发者可以通过基础篇文章了解数据库的基本原理,然后结合调优思路,对实战篇的各个调优技巧进行深入的学习。性能调优是一个不断积累的过程,大家不用考虑一步到位,唯有进行实践的积累,才能在广阔的调优战场所向披靡。Part 1: 数仓调优基础篇基础篇介绍性能调优最基本的数据库命令analyze和explain,同时,基于分布式数据库GaussDB(DWS)中产生的分布式计划多种多样的特点,补充对现有分布式计划种类及其性能优劣的详细介绍。⇔  GaussDB(DWS)性能调优系列基础篇一:万物之始analyze统计信息介绍analyze命令,依次解读什么是统计信息,为什么要收集统计信息、怎么收集统计信息以及什么时候应该收集统计信息。⇔  GaussDB(DWS)性能调优系列基础篇二:大道至简explain分布式计划详细解读explain展示的数据库执行计划,介绍如何通过执行计划了解数据库的执行过程、识别性能瓶颈,针对性调优。⇔  GaussDB(DWS)性能调优系列基础篇三:衍化至繁之分布式计划详解基于分布式数据库GaussDB(DWS)中产生的分布式计划多种多样的特点,补充对现有分布式计划种类及其性能优劣的详细介绍。Part 2: 数仓调优实战篇从数据建模、表定义的设计,到数据库硬件、集群部署的选择,再到数据库系统级调优、数据表结构设计,以及单个SQL语句的编写及调优,都要考虑对性能的影响。系统级调优也好,SQL级调优也罢,掌握这十八般武艺,你也能成为一个性能调优高手。⇔  GaussDB(DWS)性能调优系列实战篇一:十八般武艺之总体调优策略介绍数据库级别的性能调优思路和总体策略,包括系统级和语句级调优,本篇主要重点放在系统级调优。⇔  GaussDB(DWS)性能调优系列实战篇二:十八般武艺之坏味道SQL识别发现SQL中的坏味道(导致执行效率低下的SQL语句及其执行方式)是性能调优的前提,本文简要介绍如何通过自诊断视图识别和发现业务中存在的 “坏味道”SQL,以便针对性调优。⇔  GaussDB(DWS)性能调优系列实战篇三:十八般武艺之好味道表定义如何根据数据库特征和产品业务特征,设计合理的表定义,以达到性能提升的目的。⇔  GaussDB(DWS)性能调优系列实战篇四:十八般武艺之SQL改写通过SQL改写提升执行性能,同时改写方法也是数据应用开发过程应该遵循的好SQL的书写习惯。⇔  GaussDB(DWS)性能调优系列实战篇五:十八般武艺之路径干预路径干预方法介绍,路径生成是表关联方式确定的主要阶段,本文讨论几个影响路径生成的要素:cost_param、 scan方式、join方式、stream方式,并从原理上分析如何干预路径的生成。⇔  GaussDB(DWS)性能调优系列实战篇六:十八般武艺Plan hint运用计划干预方法介绍,执行计划数据库执行方式的外在展示,本文讨论如何通过plan hint提示优化器采用更高效的计划,可以使查询执行的性能获得大幅的提升,成为性能调优的一件有利的工具。Part 3: 数仓GaussDB(DWS)产品动态新一代华为云数仓GaussDB(DWS)已广泛应用于金融、政府、运营商、交通、物流、互联网等领域,服务于全球1000+客户,为各行业提供极具竞争力的数据仓库解决方案。⇔  华为云GaussDB(DWS)数据仓库以2048大规模节点通过信通院评测认证⇔  五大关键能力,华为云原生数据仓库GaussDB(DWS)深度技术解读⇔  华为GaussDB(DWS)数据仓库,助力招行“人人用数,创新前行”⇔  数智金融 使能创新,“2020华为数智金融论坛”在溪村成功举办⇔ 华为认证GaussDB OLAP数仓高级工程师 HCIP-GaussDB-OLAP V1.5(中文版)发布通知数仓GaussDB(DWS)开发者论坛:https://bbs.huaweicloud.com/forum/forum-598-1.html数仓GaussDB(DWS)产品主页:https://www.huaweicloud.com/product/dws.html转自,【技术补给站】第2期:数仓性能调优必读:从系统级到SQL级,带你进阶为性能调优高手-云社区-华为云 (huaweicloud.com)
  • [问题求助] Flink作业如何进行性能调优?
    你好,我的Flink作业反压严重,请问如何判断瓶颈点在哪?如何确定是资源不足还是其他问题?
  • [性能调优] GaussDB A 使用roach备份恢复性能调优,roach 命令 buffer-block-size 应如何使用呢?
    问题描述:roach 备份恢复命令,使用roach的备份和恢复命令 发现 备份速度可以通过调节参数buffer-block-size 来调优,设置4M 比较优(4M速度比起2M,快了近3分之一),但是过了一段时间,换一个比较大的数据2T测试性能,又发现2M和4M速度基本没有区别,都达到了以前比较快的速度(环境是千兆网,GaussDB A版本是8.0.0,没有其他干扰程序运行)问题:请问一下,1 为什么会出现这个情况?2 什么情况 需要调这个参数?3 如何配置这个参数,可以达到速度最优?
  • [新手课堂] 微认证之路 鲲鹏软件性能调优实践
    ### 名称及链接 [鲲鹏软件性能调优实践](https://edu.huaweicloud.com/certifications/76a8b58fa7d6425c95a3c38bcea5c439)   ### 课程章节 1. 鲲鹏性能调优思路及方法 2. MariaDB性能调优案例 3. 重点工具与求助渠道   ### 证书 ![wrz-kp-zj-xnty.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202105/17/193933e0aigl2murlremqn.png)   ### 笔记 1. 基于硬件特性的性能调优 2. 从冯诺依曼架构看性能优化的四个方向 1. 网卡 2. 应用 3. 磁盘 4. CPU/内存 3. 编译器性能优化 1. 指令布局优化 2. 内存布局优化 3. 循环优化 4. JDK性能优化 1. JIT编译优化、GC内存回收管理优化提升内存管理性能 2. JVM循环、向量化、序列化技术,提升程序执行性能 5. SMP(对称多处理器架构):核数的扩展受到内存总线的限制 6. NUMA(非统一内存访问架构) 1. 内存在物理上是分布式的,不同的核访问不同内存的时间不同 2. NUMA-Aware 亲和性资源规划,让内存访问最短路径 7. 三种NUMA绑核配置方法 1. 使用系统工具numactl设置 2. 在代码中调用亲和性设置参数 3. 多数开源软件中提供了配置接口 8. 加速库 1. 基础加速 1. glibc 2. hyperscan 2. 压缩加速 1. gzip/zlib 2. ZSTD 3. snappy 3. 加解密加速 1. openssl 4. 多媒体加速 1. X265 2. ffmpeg 3. HMPP 9. 加速使能 1. 业务&基础软件库加速使能 2. 内核态硬加速器件使能 10. PCle加速卡(QAT卡) 11. 鲲鹏RSA加密加速引擎 12. 磁盘 1. 文件系统决定了磁盘加载到内存过程的快慢 2. 磁盘预取可以充分利用磁盘带宽 13. 网卡 1. 中断产生的频率高,会消耗大量的CPU时间片 2. 中断产生的频率低,会影响应用收到数据的时延 3. 调整网卡中断聚合,在低时延和高吞吐取平衡点 14. 应用 1. 软件调优的本质是充分发挥硬件性能 2. 减少资源抢占,提升并行度,发挥多核性能优势 3. 锁 4. cache 15. MySQL5.7.12内存对齐硬编码,导致伪共享 16. 性能调优十板斧 1. CPU/内存 1. 调整内存页大小 2. CPU预取 3. 修改线程调度策略 2. 磁盘 1. 脏数据刷新 2. 异步文件操作 3. 文件系统参数 3. 网卡 1. 网卡多队列 2. 开启网卡TSO 3. 开启网卡CSUM 4. 应用 1. 优化编译选项 2. 文件缓存机制 3. 缓存执行结果 4. NEON指令加速 17. 性能优化三步法 1. 监控 1. CPU:top dstat 2. 内存:numastat free 3. 磁盘:iostat blktrace 4. 网卡:sar ethtool 2. 分析 1. CPU:us hi si 2. 内存:numa_hit mem 3. 磁盘:iowait util% 4. 网卡:txkB/s tx-usecs 3. 优化 1. CPU:提高并发、线程绑核 2. 内存:减少跨numa访问、大页内存 3. 磁盘:I/O调度策略、异步I/O 4. 网卡:中断聚合、网卡中断绑核 18. 鲲鹏社区:在线资源整合平台 1. 鲲鹏文档 2. 鲲鹏软件 3. 鲲鹏论坛 4. 认证查询 19. 鲲鹏小智 1. 兼容软件查询 2. 镜像包查询 3. 汇编指令查询 4. 经验文档检索 20. dependecy advisor 1. 分析移植软件包依赖库,评估可移植性 2. 分析移植软件代码文件 21. porting advisor:分析软件源文件,提供代码移植指导报告 22. tuning kit:分析待移植软件源码文件,给出代码移植指导报告   ### 备注 1. 感谢老师的教学与课件 2. 欢迎各位同学一起来交流学习心得^_^ 3. 在线课程、沙箱实验、博客和直播,其中包含了许多优质的内容,推荐了解与学习。
  • [技术干货] 微认证之路 基于BoostKit的大数据性能调优实践
    ### 名称及链接 [基于BoostKit的大数据性能调优实践](https://edu.huaweicloud.com/certifications/73ec4d971bc44c028558598f90218b87)   ### 课程章节 1. 大数据特点及调优原因 2. 大数据性能调优思路 3. 性能调优案例分享 4. 性能调优实践流程   ### 证书 ![wrz-kp-zj-boostkit-bigdata.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/202105/14/151012olzlkuyrxeovvb4s.png)   ### 笔记 1. 大数据介绍及组件关系分布 1. zookeeper 分布式协作服务 2. hbase 列存数据库 3. hive 数据仓库 4. ES elastic 全文检索 5. redis 内存数据库 6. mapreduce 分布式批处理 7. spark 分布式内存计算 8. storm 分布式流处理 9. yarn 集群资源管理系统 10. hdfs 分布式文件系统 11. kafka 分布式缓存队列 2. 大数据并行计算特点天然匹配鲲鹏多核架构 1. mapreduce模型 1. 源数据 2. 拆分 3. map 映射 4. sort 排序 5. merge 合并 6. reduce 汇总 3. 调优原因 1. 组件参数默认值保守 2. 合理配置上下游组件的资源分配 3. 性能瓶颈因硬件配置而异 4. 常见调优思路 1. 保障测试压力 2. 分配物理资源 3. 监控资源使用情况 4. 确定性能瓶颈 5. 实施优化 5. 大数据常见调优问题 1. 应用层面 1. CPU占用率低 2. 内存消耗尽但CPU等资源还有富余 3. GC频繁 4. CPU占用率高 2. 硬件层面 1. 磁盘IO占用率高,CPU iowait高 2. 网络IO占用率高 3. 内存占用多 3. 客户端 1. 组件参数已确保较优,但性能不好 6. Hadoop调优 1. HDFS 分布式存储 1. nameNode 2. DataNode 2. Yarn 资源分配和管理 1. resourceManager 2. applicationMaster 3. nodeManager 4. container 3. Mapreduce 分布式计算 1. map阶段 2. reduce阶段 7. 大数据组件:Hadoop常见调优参数 1. hdfs 2. yarn 3. MapReduce 4. 磁盘 5. 网络 8. 大数据组件:HBase 1. 框架 1. hmaster 2. hregionserver 3. hregion 4. store 5. hlog 2. 读写流程 1. 写入流程 1. 优先写入memstore内存区域,加速写入速度,hlog保障数据可靠 2. 读取流程 1. 依次从memstore和blockcache查找数据,若未命中,再从磁盘查找 3. 常见调优参数 1. hbase 2. 磁盘 3. 网络 9. 性能定位: 1. 问题定位流程 2. 资源监控工具 1. nmon 2. perf 3. dstat 4. top 5. iostat 6. sar 7. jstat 8. java visualVM 3. web监控界面,显示基本配置和运行状态 10. 性能调优案例 1. Hbase bulkload 性能优化 2. hbase 1.x版本执行读测试时,资源利用率低   ### 备注 1. 感谢老师的教学与课件 2. 欢迎各位同学一起来交流学习心得^_^ 3. 在线课程、沙箱实验、博客和直播,其中包含了许多优质的内容,推荐了解与学习。
  • [迁移系列] Gauss 子查询性能调优
    子查询SQL语句中子查询的使用非常灵活,但过于复杂的子查询会造成性能问题。先对常见的子查询类别及性能问题判断方法进行介绍。子查询从大类上来看,分为相关性子查询的非相关性子查询。非相关性子查询: 子查询的执行,不依赖于外层父查询的任何属性值。这样子查询具有独立性,可独自求解,形成一个子查询计划先于外层的查询求解.例如:select first_name, last_name from emp where department_id in (select department_id from dept);        上述语句中,子查询select department_id from dept的计算不依赖于外层父查询的任何属性,可以独立求解。因此,非相关性子查询没有性能问题,不需关注。 相关性子查询: 子查询的执行依赖于外层父查询的一些属性值。子查询因依赖于父查询的参数,当父查询的参数改变时,子查询需要根据新参数值重新执行(查询优化器对相关子查询进行优化有一定意义)。例如:select first_name, last_name from emp where department_id in (select department_id from dept where manager_id = emp.employee_id); 上述语句中在,子查询select department_id from dept where manager_id = emp.employee_id依赖于父查询emp表中的employee_id字段,因此是一个相关性子查询。对于相关性子查询,按照场景举例如下,分别进行说明。exists/not exists等值相关子查询select first_name, last_name from emp where not exists (select 1 from dept where manager_id =emp.employee_id and department_id > emp. department_id);select first_name, last_name from emp where exists (select 1 from dept where manager_id =emp.employee_id and department_id > emp. department_id); 上述两个语句为exists/not exists子查询,子查询依赖于外层表emp,因此是相关子查询,针对exists/not exists子查询,如果join条件中有等值条件,则不存在问题。注:如果join条件没有等值条件,则有性能问题。在这种场景下,子查询内只能是单一查询,如存在union/union all/intersect/minus等操作,则存在性能问题,需要将集合操作拆开。带聚集操作的等值相关子查询select first_name, last_name from emp where department_id =  (select max(department_id) from dept where manager_id =emp.employee_id and department_id = emp. department_id);select first_name, last_name from emp where department_id >  (select max(department_id) from dept where manager_id =emp.employee_id and department_id = emp. department_id); 注:如果子查询中join条件有任何一个非等值条件,则存在问题可以是父查询中的某一列等于、大于、小于、大于等于、小于等于、不等于子查询。其他类型相关子查询其他类型相关子查询,如果数据量大(一般为>10万条),则存在性能问题,需要根据具体场景改写为非相关子查询或上述两类相关子查询。
  • [技术干货] 基于鲲鹏平台Ceph深度性能调优
    基于鲲鹏平台Ceph深度性能调优随着 IOT、大数据、移动互联等应用的暴涨,产生的数据也越来越多,整个存储市场总量也逐年增长,预计到 2021 年分布式存储会占到整个存储市场的 50%,到 2027 年,分布式存储会占到整个市场的 70%。Ceph 则是典型的分布式存储软件的代表。杉岩数据作为一家软件定义存储商,软件的发展与硬件的结合密必不可分,与华为共建 ARM 生态是杉岩发展的关键着力点。目前,杉岩数据的对象存储 MOS 和块存储 USP 已完成在鲲鹏平台的适配工作,且可进行商用。以下是杉岩数据云存储高级研发工程师刘亮奇在华为开发者大会中关于 Ceph 开发和应用方面的经验分享。Ceph 是什么?在用户层面,Ceph 对外提供的三个服务:1、Block storage 即(RDB 块存储接口):如同一个没有格式化的 U 盘,在第一次接入个人 PC 时,windows 操作系统会弹出一个格式化的请求界面供用户选择参数,如比较重要的文件系统选项,有 NTFS、exFAT 等文件系统以供选择,格式化完成后的 U 盘才能进行创建目录、拷贝文件等操作;形象一点的概括:整个块设备可以看成一栋大楼的框架,在进入大楼工作生活前,需要对这栋大楼进行装修,即格式化。而大楼不可能只有一个人,所以需要物业进行管理,物业可以比作一个文件系统。2、Object storage 即(RADOS GW 对象存储):对象存储在大家的生活中也是接触较多的,例如我们平常使用的云盘;或者我们使用的智能手机都有云备份功能,都是基于对象存储的一种业务表现。所以对象存储是为了解决信息化时代海量不规则文件的存储问题。就如世界上没有两片相同的叶子,每个人都会产生不同的信息,如何解决这些独一无二数据的存储,对象存储就是提供了一种解决方法。3、Flie system 文件系统:把 Ceph 提供文件系统服务,类比成购买个人电脑的过程,DIY 用户可能会买各种硬件、零件组装起来装上操作系统之后才能使用,而电脑商家还会提供一个已经预装好 windows 系统的整机供用户选择,用户购买之后接通电源开机后可直接使用。Ceph 提供的文件系统服务也就类似于这样的一个整机,用户只需将对应的目录挂载到本地即可进行工作。RGW:对象存储接口,使用这个接口服务需要配合一些客户端软件;当然了,手机上的云备份功能是因为手机操作系统已经内置了 APP 进行支撑,所以不需要再额外安装软件。RBD:块存储接口,如果使用的是 Linux 系统,可以使用内核模块 krbd 直接在本地直接生成一个块设备供用户使用。针对 Windows 系统,则可以通过 iSCSI 协议,虚拟一块硬盘来供用户使用。RADOS:再往下是整个 Ceph 集群的统一抽象层 RADOS,即抽象的对象存储集群。它是上面的所有接口数据经过处理后都会以对象的形式保存在集群当中。同时 RADOS 还确保这些接口数据在整个集群中的一致性,而 LIBRADOS,主要是访问 RADOS 层的接口库。接下来是 Ceph 集群中一些比较重要的组件,如 mgr,mirror 等,这些组分布在集群中的各个服务器上,未在上图中体现。下面简略说明各个组件的职能:MON:即 monitor,可以认为是集群的大脑,负责集群状态的维护和元数据的管理。MDS:元数据服务,它是为 Ceph FS 接口服务提供文件层次结构检索和元数据管理的,如果不需要 Ceph FS 服务,可以选择不部署该组件。OSD:对象存储设备,这是整个集群中用户数据主要承载的终端设备,用户所有的数据读写请求基本上最终由 OSD 来负责执行。所以 OSD 的性能决定了整个上层业务的表现。OSD 一般会绑定一个较大的存储空间,例如一块硬盘或一个硬盘分区;而 OSD 管理存储空间的本地存储接口主要有 File Store 和 Blue Store。当然 File Store 还需要借助本地文件系统(比如 XFS)来管理存储空间。而 Blue Store 则可以直接接管裸设备,这样就可以减少它的 IO 路径,以提高性能。总体来看,Ceph 是一个统一的分布式存储系统。它的设计目标是较好的性能,可靠性和可扩展性。这是因为从 Ceph 的架构来看,没有专门的缓存层,所以在性能表现并不是很理想。社区也针对这个问题一直在推动分级缓存(tier)功能,但这个功能还没有达到可生产的阶段;所以目前比较通用的做法就是在操作系统层面来缓存 Ceph 数据;如内核的通用块层使用 dm-cache、bcache、enhanceIO 等开源软件,在操作系统层面将数据缓存在一个较高速的设备(如 SSD),以此提高 Ceph 的性能。Ceph 现有架构与业务存在哪些问题?1、Ceph 数据与内核缓存的割裂问题。以 BlueStore 为例,它将 OSD 的元数据保存在 RockDB 中,RockDB 又是运行在一个简化的文件系统(Blue FS)之上的,此时可以认为 Blue FS 的 IO 就是 OSD 的元数据,但对于内核缓存来说,它是无法感知 OSD 下发的数据是有元数据和业务数据之分的。2、内核缓存无法区分 OSD 业务的热点数据和冷数据,比如用户配置比较典型的三副本存储策略,此时只有主副本数据才会为客户端提供读写服务,而从副本则直接不用缓存即可,但是内核层缓存是没法区分这种差异的。如果使用的是 DM Cache,还会在内存中分配一个空间来缓存部分数据,这无还疑会浪费内存资源。总体来说,内核缓存存在浪费 Cache 空间,还有 Cache 命中率不高,频繁刷新缓存导致缓存设备寿命缩短等缺陷。有何解决方案?在 BlueStore 下发 IO 的地方增加一个适配层,用来标记下发 IO 的类型,在内核缓存入口处增加一个适配层,用来捕捉 OSD 的 IO 类型,最后在内核缓存处理时,根据 IO 类型进行不同的写回、淘汰策略。例如将三副本中的两个从副本用 NOCACHE 标签经过适配层随 IO 请求一起带到内核缓存里去,这样内核缓存就可以不缓存,直接写后备盘。同时可以将 Blue FS 的 IO 标记成元数据类型,让其在内核缓存更长时间的驻留。或根据用户业务需求,将用户有比较重要的,且读写频繁的数据,标为高等级,其他不重要的数据标成中或低等级,然后在内核缓存针对高等级数据采用和元数据一样的处理策略;这样就可以根据用户需求来执行不同的淘汰和回写策略。BlueStore 使用的是 Libaio API 接口来下发 IO 请求,此时需要一个 IOCB 结构体作为下发请求的 IO 参数,可以通过 io_prep_pwrite 函数生成 iocb 结构体之后,把 io flag 设置到 IOCB 的 Flag 结构体当中,作为 io_submit 的参数,一起提交至内核层;内核在 VFS 层时捕捉到 Direct io 时,将 flag 转换到通用块设备层的 BIO 结构体里面,比如 BIO 的 bi_rw 结构体里面,此时位于通用块层的内核缓存即可捕捉到上层业务标签。内核缓存可根据不同的标签执行不同的回写、分配策略,比如让元数据更久的驻留在缓存当中,或者让高等级的用户数据和元数据执行相同的缓存策略。Ceph 在 ARM 架构上面临的问题与挑战华为鲲鹏处理器与 Intel Xeon 主要存在如下六个方面的差异:1、ARM 的跨片访问:主要反映在内存方面,(数据是估测值,非实测数据,不做测评)。ARM 相对 X86 来说不占优势,所以后面的优化手段中有规避跨片 numa 的操作。2、矢量运算:这方面未获取到鲲鹏的具体参数,以 ARM 的 A76 作为参考,从目前来看, ARM 也是不占优势的。3、物理核数:ARM 先天就有物理核数上面的优势。4、协处理器:即加速器,在加速器方面鲲鹏 920 有 EC/RSA/zlib 等外围协处理器,相对通用的 X86 6148 来说是较为丰富,这是鲲鹏 920 的优势。5、内存操作:ARM 采用的是 load-store 的微架构,简单地理解为:ARM 在内存到内存之间的拷贝是需要 CPU 参与的,X86 则可以直接做到不用 CPU 参与内存到内存间的拷贝。这是 ARM 微架构决定的。6、功耗比:单论总体的功耗不太准确,毕竟功耗还跟启用的物理核数有关系。当然先进的工艺在可以降低功耗。如果论单个物理核的功耗比,ARM 确实相对 X86 是有优势的。基于鲲鹏平台的 Ceph 调优针对鲲鹏平台的 Ceph,目前有以下几种主流的优化方案:1、针对跨片 NUMA 操作场景,限定进程运行在片内 NUMA 针对跨片 NUMA 操作场景,采用将进程限定在片内 NUMA 上面,以 Ceph 为例,Ceph M 及以后的版本提供一个 OSD_numa_node 参数,该参数可以限定整个 OSD 进程所运行的 numa。如果使用的是其他版本的 ceph,可以借助 numactl 和 taskset 这两个工具来实现限定进程运行在指定 numa 的功能。numactl 需要在进程启动时进行设置,主要的参数有绑分配内存 NUMA(–membind)、绑进程运行的 NUMA(–cpunodebind),以及更细的,绑进程运行的物理核(–physcpubind)。Taskset 较为灵活,可以在进程运行时进行设置。限定了 NUMA 之前,对应的硬件都尽量分配在片内的总线下面,比如网卡、内存、SSD 等都尽量分配在对应片内总线下面,以避免跨片访问。2、矢量运算短板借助协处理器补齐 矢量运算方面可以借助鲲鹏 920 的平台的加速器,华为有提供一些基础设施的接口文档,可以根据这些文档进行相应的适配;比如这里的纠删码运算(EC),华为提供的接口文档有详细的设置和参数配置,需要在代码层面上进行适配,此时需要投入工作量,进行稳定性方面的测试。3、增加进/线程数以及内存操作利用鲲鹏在物理核上的优势,可以增加相应处理业务的进程或线程,针对业务繁忙的线程,可以把线程拆分成两个,分配到不同物理核上去。内存操作方面,除了减少内存操作,华为还针对 ARM 微架构出了一个补丁,该补丁主要优化了内存方面的接口,可以去华为的基础设施网站上下载 patch 来提升性能。此外,还有其他优化手段:绑定网卡/SSD 中断:必须先把 irqbalace 服务关闭,否则 irqbalace 服务会将绑定给重新均衡掉。cgroup 隔离业务:针对对繁忙的线程或者进程来说是比较有效的,主要是基于 CPU cache 考虑,如果 CPU 被切换到不相关的进程和线程的时候,会导致 CPU cache 刷新,致使命中率下降,CPU cache 预读也会浪费内存带宽。同时进程 CPU 一旦被切出,就会导致整个流水线被清空/排空的,此时并发的指令数也会减少,所以对性能还是有影响的。主要还是在业务比较繁忙的时候对性能的改善比较大。第三方库:主要是优化内存的分配和回收效率,有 Tcmalloc 和 jemalloc 可选,可以去 Tcmalloc 和 jemalloc 的网站去下载相关文件进行阅读。接下来,为大家介绍三种 Ceph 性能观测工具,如下图所示:Ceph 的 OSD perf/perf daemon:这是 Ceph 自带的工具,其中 OSD perf 主要记录 IO 读写的时延,可以初步判断到底的瓶颈是否在我们的硬盘上面,如果是,可以采取相应的优化手段。perf daemon 主要是记录整个 IO 请求在 Ceph 内部的一些状态的处理流程,这些处理流程耗时多少,都会通过这个命令导出,可以进行初步的诊断。操作系统——Perf 工具:比较常用的 perf top,显现当前整个系统的运行情况,如上图的右上脚,OSD 进程显然是耗费了大量的 CPU,可以进行层级下剥,查找到热点函数位置,再针对性地去优化热点函数。而 perf stat 主要是采集进程在一段时间内的总体的情况。还可以使用 perf record,记录数据,后续可以结合 FlamGraph 生成一个火焰图,这种火焰图相对来说比较直观。主要关注一些平头的函数调用(图),因为这里耗费的 cpu 时间比重比较大,是优化的目标。Systemtap:主要在 Redhat 系统用得比较多。通过采集内核函数、系统调用、用户函数的运行信息、函数出入口数据等,根据这些采集的数据,进行函数级别的分析。如基于 openresty-systemtap-toolkit 工具,进行二次开发。通过工具就可以去分析整个系统或者是程序在哪里有瓶颈点,然后再针对瓶颈点进行性能优化。优化后的 Ceph 存储系统性能如何?兼容性方面:从开始到结束整个过程没有遇到比较大的阻塞点,依赖库和部分技术问题在华为的基础设施网站上能够找到解决方法,将 Ceph 移植到鲲鹏平台上的整个流程较为顺利。优化的性能:基于现有服务器配置进行的优化前后对比,这里的测试并未鲲鹏 CPU 的极限,主要的瓶颈点是在硬盘上。主要是展示经过上面介绍的优化方法、手段进行优化后的成果。如表所示,可以看到优化后的性能是有改善的。低功耗:主要体现在 ARM 的单物理核的功耗确实比 X86 要低的,所以在后期运营成本上具备优势。下面介绍一下我们的块存储产品运行在鲲鹏平台上的状况,主界面显示的是整个块存储产品集群的状态,节点信息部分,上面部署了 monitor 和 OSD 等组件,这里的服务器信息可以看出是华为的 TaiShan 服务器,TaiShan 200(型号 2280)的服务器使用的就鲲鹏 920 的处理器。其他管理功能,例如卷管理,Linux 系统可以通过内核的 krbd 模块实现本地挂载,,也可以走 iSCSI 协议挂载到 windows 系统上供用户使用(图)。当了还有其他的功能,这就不展开了。未来的展望和计划首先是基于 TaiShan 服务器的一个长远计划,例如发布一个基于全闪存场景的产品,这种场景下所有的硬盘性能都比较高,而传统以太网网络将是一个瓶颈,现在 TaiShan 服务器刚好支持 RDMA 功能,为全闪存场景的部署铺平了道路,无需额外适配、调优网络端口了。seastar 对于 ARM 架构来说,多核竞争中跨片访问时,性能处于劣势,此时采用无共享编程的 seastar 框架,有利于规避 ARM 跨片访问的劣势;seastar 架构的改造社区也在积极投入,我们也会持续跟进。最后是安全存储产品对数据加解密和解压缩的处理较为重要,而鲲鹏外围加速器 zlib/rsa/md5/sm3 能够提供高效的数据安全处理流程。关于强耦合的内核缓存改造后是否需要重新编译操作系统?不需要,在 VFS 层时是通过 kernel hacking 的方式处理 I/O 的,不需要改动内核原有的逻辑,只需将修改后的 KO 加载到操作系统就可以处理我们定制的 IO 了。为什么不考虑将缓存做到 blue Store 里面?Blue Store 在社区当时设计的目标是面向未来全闪存场景的,是没有考虑过混合场景的;而且混合场景只是一个过渡阶段,并不长远,所以社区在设计时就没有考虑过加缓存;如果将缓存做到 Blue Store 的话,是与社区设计理念相悖,同时导致整个 Blue Store 处理异常复杂;无论是以后跟进社区还是向社区推送改动都比较麻烦。文章来源 如下链接  如需删帖 请联系版主  感谢。  https://mp.weixin.qq.com/s/o9HH-8TF0DbMqHrvsFh1NA目前我也在学习 这方面的内容  发帖为收藏 方便学习  感谢理解。
  • [性能调优] Spark CarbonData性能调优创建二级索引问题
    【功能模块】Spark CarbonData性能能调优创建二级索引【操作步骤&问题现象】1、Spark CarbonData性能能调优创建二级索引,如果创建二级索引的字段是字符串类型或者字符类型可以成功创建,但是字段如果是int或者Bigint创建就会报下面的错误2、创建索引语句:create index catalogreturns_index_crreturnedtimesk on table catalog_returns (cr_returned_time_sk) as 'carbondata' PROPERTIES ('table_blocksize'='128');【截图信息】表结构报错信息【日志信息】(可选,上传日志内容或者附件)
  • [SQL] GaussDB(DWS)性能调优系列实战篇五:十八般武艺之路径干预
    【摘要】 路径生成是表关联方式确定的主要阶段,本文介绍了几个影响路径生成的要素:cost_param, scan方式,join方式,stream方式,并从原理上分析如何干预路径的生成。从另外一个角度看,即路径生成,是从这些底层的选择开始,从行数的估算、到scan的选择、再到join方式以及stream的选择,构成一条简单路径,然后多条路径根据代价选择,再逐层关联更多的表,最终形成一个完整的执行路径。一、cost模型选择顾名思义,cost_param是控制cost相关的一个参数。在了解cost_param之前,先回顾一下选择率的概念,GaussDB优化器中的选择率是指,当一个表有一个过滤或关联条件时,通过该条件能被选中的行数占总行数的比例,是介于0~1之间的一个实数。选择率在优化器中是一个重要的概念,主要应用于行数和distinct值的估算,行数和distinct值是计划生成中的基本要素。首先,我们来看带有过滤条件的基表行数如何估算。如果一个表只有一个过滤条件,那么以选择率乘以表的行数,即可得到过滤完的行数;如果有多个过滤条件,那么就需要算出一个综合的选择率,如何计算?方式有二:一是通过多列统计信息直接计算,二是通过组合单列的选择率。那么组合的方式就由参数cost_param决定了,具体地,取值描述适用场景cost_param = 0选择率按乘积方式组合完全不相关场景cost_param & 2 != 0取最小的选择率作为综合选择率完全相关场景举一个例子,TPC-H 1x的part表,过滤条件是:p_brand = 'Brand#45' and p_container = 'WRAP CASE',查看不同cost_param下的过滤后行数。(1)cost_param=0(2)cost_param=2从估算出的行数(E-rows)和实际的行数(A-rows)对比可以看出,cost_param=0的不相关模型适合part表的p_brand和p_container列。其次,Join的行数怎么估算的呢?原理跟过滤条件的行数估算是类似的,如果没有多列统计信息可以使用,则也需要单独计算每个条件的选择率,然后计算出综合选择率,得出行数。例如 TPC-H 1x lineitem和orders关联,关联条件是:l_orderkey = o_orderkey and o_custkey = l_suppkey,不同cost_param的执行情况如下:(1)cost_param=0(2)cost_param=2此例中,Join的列之间也适合完全相关模型,这与l_orderkey和l_suppkey的分布是吻合的。由于TPC-H的模型接近完全不相关模型,因此cost_param=0模型可以较好的描述场景,实际应用中,用户可以根据具体业务场景来调整模型,行数估算的准确性是计划生成的重要保证,在调优中检查估算的最直接的地方。GaussDB会在后续版本中新增更多的模型供业务需求选择。二、Scan方式的选择GaussDB中扫描方式主要分顺序扫描和索引扫描,每种扫描方式都对应若干扫描算子,顺序扫描在行列存中对应的扫描算子分别是Seq Scan和CStore Scan算子(下面我们讨论中不加区分)。这些扫描算子大部分都可以通过开关来进行调控,例如Seq Scan,如果设置enable_seqscan=off,则表示不会优先选择Seq Scan,而不是一定不会选。扫描方式的选择,很大程度上决定了获取基表数据的路径。我们以如下的例子来说明:select l_orderkey, o_custkey from lineitem, orders where l_orderkey = o_orderkey;lineitem分布键是l_orderkey,并且在l_orderkey上有index,orders分布键是o_orderkey。默认情况下,Scan的方式如下:两个表都是顺序扫描的路径,关联方式选择了Hash Join。如果把Seq Scan关掉(enable_seqscan=off),计划如下:lineitem的扫描变成了Index Only Scan(因为l_orderkey的类型是int),而在orders表上仍然选择Seq Scan(因为没有其他路径),同时关联方式也变为了Nest Loop,因为Hash Join需要全表扫描数据(lineitem的Seq Scan已经被关掉了)。优化器的选择方式我们从代价(E-costs)一栏中也可以看出。再把Index Only Scan关掉,看看计划如何变化:扫描路径都变为了Seq Scan,而且Seq Scan的代价都很大。此时既然都走了Seq Scan,为什么不选Hash Join呢,把Nest Loop关掉,看看Hash Join计划的代价:从代价上看出Hash Join的总代价比Nest Loop的小,但优化器没有选择Hash Join,这是因为优化器比较路径代价时,会比较Startup和Total代价,即启动代价和总代价,综合考虑,E-costs栏中显示的是总代价。把explain_perf_mode设置为normal,查看原Nest Loop的启动代价:红框中的两个cost,分别是启动代价和总代价,在看Hash Join的cost,明显Hash Join的启动代价比Nest Loop的大很多(启动代价代表了输出第一条数据的代价),优化器在比较路径时,综合了这两个代价,最终推荐了Nest Loop的路径。从上面的例子可以看出,扫描路径的调控,可以改变路径生成,合理的搭配是生成最优计划的前提,默认情况下,GaussDB优化器可以根据现有的路径选择(如上面的lineitem有两条扫描路径,orders只有一条扫描路径),最后确定出最优的一条。两条路径代价比较时,总代价不是唯一要素,但总代价越小,一般也会越容易被选中。三、关联方式的选择GaussDB优化器中表关联的主要方式有:Nest Loop,Hash Join和Merge Join,分别可以通过enable_nestloop、enable_hashjoin、enable_mergejoin进行控制,这种控制也不是绝对的,可以理解为是否优先选择。大部分场景下,三种路径的代价关系:Hash Join < Merge Join < Nest Loop。我们以一个简单的关联示例说明,store_returns和store_sales是TPC-DS 1x中两个表,SQL如下:select count(*) from store_returns, store_sales where sr_customer_sk = ss_customer_sk;默认情况下,优化器推荐Hash Join路径,计划如下:如果把Hash Join关掉,则优化器选择了Merge Join路径:如果再把Merge Join路径关掉,可能就会选择Nest Loop路径。关联方式的控制开关一般用于调优或规避问题,但具体是否能够起作用要看具体的语句,除了当前关联方式,还有没有其他方式。实际场景中,一个语句中关联的算子较多,一般很难用参数enable_hashjoin或enable_nestloop或enable_mergejoin来控制某两个表的Join方式,GaussDB中更细致的语句级别的调优手段是Plan Hint,感兴趣的读者可以参考产品手册。四、Stream方式的选择Stream算子是GaussDB分布式执行的关键算子之一,主要起到网络传输的作用,概要介绍可以参考:GaussDB(DWS)性能调优系列实战篇一:十八般武艺之总体调优策略。Stream算子由参数enable_stream_operator控制,如果关掉Stream算子,则可能导致生成不下推的计划,例如:因为lineitem表关联的键l_partkey不是lineitem的分布键,需要添加Stream算子,但Stream功能被禁,于是只能生成不下推计划。GaussDB计划中常见的主要Stream算子包括Redistribute、Broadcast和Gather。Gather一般是分布式计划中,CN用于收集DN的数据进行最后的处理,除非最后收集的行数非常多,这个算子涉及性能问题一般较少。Redistribute和Broadcast一是对“互补”的算子,前者用于重分布,后者用于广播,生成计划时,优化器会根据代价大小来选择。当Join Key没有包含表的分布键的时候,一般会添加Redistribute路径,能选择Redistribute路径理论上也可选择Broadcast路径,最终选择哪条路径要看优化器估算的代价是多少。这两个算子可以通过参数enable_redistribute和enable_broadcast进行控制。在SMP开启的情况下,当并行度(dop)大于1时,一般还会有Local Redistribute、Split Redistribute、Local Broadcast和Split Broadcast;当倾斜优化开启时,还有PART REDISTRIBUTE PART ROUNDROBIN、PART_REDISTRIBUTE_PART_BROADCAST、PART_REDISTERIBUTE_PART_LOCAL等等,这些也是Stream算子,主要就是重分布、广播、RoundRobin的一些扩展形式,这里我们不一一介绍了,感兴趣的读者可以参考GaussDB DWS 产品手册。我们考虑两个表的简单关联,store_sales和sr_tbl,它们的分布键分别是ss_item_sk 和sr_returned_date_sk,Join 条件是store_sales.ss_customer_sk =sr_tbl. sr_customer_sk,执行结果如下:由于两个表的分布键都不是Join Key,因此走Hash Join路径的话需要有一个表做Broadcast或者两个表都做Redistribute,但是store_sales表比较大(E-rows显示28.7亿行),而sr_tbl表行数估算比较少(E-rows显示100行),优化器认为适合做Broadcast。于是最终选择了一边Broadcast的计划。对于这个计划,由于sr_tbl表统计信息不准确(如果是中间结果集,则表示中间结果集估算不准),一种调优的方法是,将sr_tbl的表统计信息重新收集准确一些(如果sr_tbl是中间结果集,则无法收集),另一种方法是让sr_tbl走Redistribute路径,而后者我们又有两种方式来实现,一是用Plan Hint,即在生成计划时,告诉优化器走Redistribute路径,二是把Broadcast关掉。禁用Broadcast后,执行计划如下:本列中,开启了SMP自适应,即优化器会根据系统资源和当前Active SQL数量来自行决定并行度(dop),如果Redistribute和Broadcast选择不当,则可能导致(1)Broadcast计划会出现下盘(2)两个计划的并行度不一样,最终执行时间可能会差异比较大。对于Stream方式的控制,一般的调优方式有Plan Hint、GUC参数、改善统计信息或估算信息。Plan Hint的详细介绍可以参考产品手册或者:GaussDB(DWS)性能调优系列实战篇六:十八般武艺Plan hint运用。五、结束语本文介绍的cost_param属于cost底层参数,建议对数据特征和使用场景比较熟悉的DBA慎重使用。Scan、Join、Stream调控的基本依据也是代价,代价一般体现在执行耗时上,调优时可从Performance中识别出性能的瓶颈点,分析选择的算子是否与代价匹配。另外,除了本文介绍的Session级别的控制参数外,还有基表、中间结果的行数,也可以通过Plan Hint进行语句级别的调控,感兴趣读者可通过GaussDB DWS产品文档进一步了解。原文链接:https://bbs.huaweicloud.com/blogs/212459【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [SQL] GaussDB(DWS)性能调优系列实战篇二:十八般武艺之坏味道SQL识别
    【摘要】 GaussDB在执行SQL语句时,会对其性能表现进行分析和记录,通过视图和函数等手段呈现给用户。本文将简要介绍如何利用GaussDB提供的这些“第一手”数据,分析和定位SQL语句中存在的性能问题,识别和消除SQL中的“坏味道”。SQL语言是关系型数据库(RDB)的标准语言,其作用是将使用者的意图翻译成数据库能够理解的语言来执行。人类之间进行交流时,同样的意思用不同的措辞会产生不同的效果。类似地,人类与数据库交流信息时,同样的操作用不同的SQL语句来表达,也会导致不同的效率。而有时同样的SQL语句,数据库采用不同的方式来执行,效率也会不同。那些会导致执行效率低下的SQL语句及其执行方式,我们称之为SQL中的“坏味道”。         下面这个简单的例子,可以说明什么是SQL中的坏味道。图1-a 用union合并集合         在上面的查询语句中,由于使用了union来合并两个结果集,在合并后需要排序和去重,增加了开销。实际上符合dept_id = 1和dept_id > 2的结果间不会有重叠,所以完全可以用union all来合并,如下图所示。图1-b 用union all合并集合         而更高效的做法是用or条件,在扫描的时候直接过滤出所需的结果,不但节省了运算,也节省了保存中间结果所需的内存开销,如下图所示。图1-c 用or条件来过滤结果         可见完成同样的操作,用不同的SQL语句,效率却大相径庭。前两条SQL语句都不同程度地存在着“坏味道”。         对于这种简单的例子,用户可以很容易发现问题并选出最佳方案。但对于一些复杂的SQL语句,其性能缺陷可能很隐蔽,需要深入分析才有可能挖掘出来。这对数据库的使用者提出了很高的要求。即便是资深的数据库专家,有时也很难找出性能劣化的原因。         GaussDB在执行SQL语句时,会对其性能表现进行分析和记录,通过视图和函数等手段呈现给用户。本文将简要介绍如何利用GaussDB提供的这些“第一手”数据,分析和定位SQL语句中存在的性能问题,识别和消除SQL中的“坏味道”。◆ 识别SQL坏味道之自诊断视图         GaussDB在执行SQL时,会对执行计划以及执行过程中的资源消耗进行记录和分析,如果发现异常情况还会记录告警信息,用于对原因进行“自诊断”。用户可以通过下面的视图查询这些信息:•       gs_wlm_session_info•       pgxc_wlm_session_info•       gs_wlm_session_history•       pgxc_wlm_session_history         其中gs_wlm_session_info是基本表,其余3个都是视图。gs_开头的用于查看当前CN节点上收集的信息,pgxc_开头的则包含集群中所有CN收集的信息。各表格和视图的定义基本相同,如下表所示。表1 自诊断表格&函数字段定义名称类型描述datidoid连接后端的数据库OID。dbnametext连接后端的数据库名称。schemanametext模式的名字。nodenametext语句执行的CN名称。usernametext连接到后端的用户名。application_nametext连接到后端的应用名。client_addrinet连接到后端的客户端的IP地址。 如果此字段是null,它表明通过服务器机器上UNIX套接字连接客户端或者这是内部进程,如autovacuum。client_hostnametext客户端的主机名,这个字段是通过client_addr的反向DNS查找得到。这个字段只有在启动log_hostname且使用IP连接时才非空。client_portinteger客户端用于与后端通讯的TCP端口号,如果使用Unix套接字,则为-1。query_bandtext用于标示作业类型,可通过GUC参数query_band进行设置,默认为空字符串。block_timebigint语句执行前的阻塞时间,包含语句解析和优化时间,单位ms。start_timetimestamp with time zone语句执行的开始时间。finish_timetimestamp with time zone语句执行的结束时间。durationbigint语句实际执行的时间,单位ms。estimate_total_timebigint语句预估执行时间,单位ms。statustext语句执行结束状态:正常为finished,异常为aborted。abort_infotext语句执行结束状态为aborted时显示异常信息。resource_pooltext用户使用的资源池。control_grouptext语句所使用的Cgroup。min_peak_memoryinteger语句在所有DN上的最小内存峰值,单位MB。max_peak_memoryinteger语句在所有DN上的最大内存峰值,单位MB。average_peak_memoryinteger语句执行过程中的内存使用平均值,单位MB。memory_skew_percentinteger语句各DN间的内存使用倾斜率。spill_infotext语句在所有DN上的下盘信息:None:所有DN均未下盘。All: 所有DN均下盘。[a:b]: 数量为b个DN中有a个DN下盘。min_spill_sizeinteger若发生下盘,所有DN上下盘的最小数据量,单位MB,默认为0。max_spill_sizeinteger若发生下盘,所有DN上下盘的最大数据量,单位MB,默认为0。average_spill_sizeinteger若发生下盘,所有DN上下盘的平均数据量,单位MB,默认为0。spill_skew_percentinteger若发生下盘,DN间下盘倾斜率。min_dn_timebigint语句在所有DN上的最小执行时间,单位ms。max_dn_timebigint语句在所有DN上的最大执行时间,单位ms。average_dn_timebigint语句在所有DN上的平均执行时间,单位ms。dntime_skew_percentinteger语句在各DN间的执行时间倾斜率。min_cpu_timebigint语句在所有DN上的最小CPU时间,单位ms。max_cpu_timebigint语句在所有DN上的最大CPU时间,单位ms。total_cpu_timebigint语句在所有DN上的CPU总时间,单位ms。cpu_skew_percentinteger语句在DN间的CPU时间倾斜率。min_peak_iopsinteger语句在所有DN上的每秒最小IO峰值(列存单位是次/s,行存单位是万次/s)。max_peak_iopsinteger语句在所有DN上的每秒最大IO峰值(列存单位是次/s,行存单位是万次/s)。average_peak_iopsinteger语句在所有DN上的每秒平均IO峰值(列存单位是次/s,行存单位是万次/s)。iops_skew_percentinteger语句在DN间的IO倾斜率。warningtext显示告警信息。queryidbigint语句执行使用的内部query   id。querytext执行的语句。query_plantext语句的执行计划。node_grouptext语句所属用户对应的逻辑集群。         其中的query字段就是执行的SQL语句。通过分析每个query对应的各字段,例如执行时间,内存,IO,下盘量和倾斜率等等,可以发现疑似有问题的SQL语句,然后结合query_plan(执行计划)字段,进一步地加以分析。特别地,对于一些在执行过程中发现的异常情况,warning字段还会以human-readable的形式给出告警信息。目前能够提供的自诊断信息如下:◇多列/单列统计信息未收集         优化器依赖于表的统计信息来生成合理的执行计划。如果没有及时对表中各列收集统计信息,可能会影响优化器的判断,从而生成较差的执行计划。如果生成计划时发现某个表的单列或多列统计信息未收集,warning字段会给出如下告警信息:Statistic Not Collect:schemaname.tablename(column name list)         此外,如果表格的统计信息已收集过(执行过analyze),但是距离上次analyze时间较远,表格内容发生了很大变化,可能使优化器依赖的统计信息不准,无法生成最优的查询计划。针对这种情况,可以用pg_total_autovac_tuples系统函数查询表格中自从上次分析以来发生变化的元组的数量。如果数量较大,最好执行一下analyze以使优化器获得最新的统计信息。◇SQL未下推         执行计划中的算子,如果能下推到DN节点执行,则只能在CN上执行。因为CN的数量远小于DN,大量操作堆积在CN上执行,会影响整体性能。如果遇到不能下推的函数或语法,warning字段会给出如下告警信息:SQL is not plan-shipping, reason : %s◇Hash连接大表做内表         如果发现在进行Hash连接时使用了大表作为内表,会给出如下告警信息:PlanNode[%d] Large Table is INNER in HashJoin \"%s\"目前“大表”的标准是平均每个DN上的行数大于100,000,并且内表行数是外表行数的10倍以上。◇大表等值连接使用NestLoop         如果发现对大表做等值连接时使用了NestLoop方式,会给出如下告警信息:PlanNode[%d] Large Table with Equal-Condition use Nestloop\"%s\"目前大表等值连接的判断标准是内表和外表中行数最大者大于DN的数量乘以100,000。◇数据倾斜         数据在DN之间分布不均匀,可导致数据较多的节点成为性能瓶颈。如果发现数据倾斜严重,会给出如下告警信息:PlanNode[%d] DataSkew:\"%s\", min_dn_tuples:%.0f, max_dn_tuples:%.0f目前数据倾斜的判断标准是DN中行数最多者是最少者的10倍以上,且最多者大于100,000。◇代价估算不准确         GaussDB在执行SQL语句过程中会统计实际付出的代价,并与之前估计的代价比较。如果优化器对代价的估算与实际的偏差很大,则很可能生成一个非最优化的计划。如果发现代价估计不准确,会给出如下告警信息:"PlanNode[%d] Inaccurate Estimation-Rows: \"%s\" A-Rows:%.0f, E-Rows:%.0f目前的代价由计划节点返回行数来衡量,如果平均每个DN上实际/估计返回行数大于100,000,并且二者相差10倍以上,则认定为代价估算不准。◇Broadcast量过大         Broadcast主要适合小表。对于大表来说,通常采用Hash+重分布(Redistribute)的方式效率更高。如果发现计划中有大表被广播的环节,会给出如下告警信息:PlanNode[%d] Large Table in Broadcast \"%s\"目前对大表广播的认定标准为平均广播到每个DN上的数据行数大于100,000。◇索引设置不合理  如果对索引的使用不合理,比如应该采用索引扫描的地方却采用了顺序扫描,或者应该采用顺序扫描的地方却采用了索引扫描,可能会导致性能低下。索引扫描的价值在于减少数据读取量,因此认为索引扫描过滤掉的行数越多越好。如果采用索引扫描,但输出行数/扫描总行数>1/1000,并且输出行数>10000(对于行存表)或>100(对于列存表),则会给出如下告警信息:PlanNode[%d] Indexscan is not properly used:\"%s\", output:%.0f, filtered:%.0f, rate:%.5f顺序扫描适用于过滤的行数占总行数比例不大的情形。如果采用顺序扫描,但输出行数/扫描总行数<=1/1000,并且输出行数<=10000(对于行存表)或<=100(对于列存表),则会给出如下告警信息:PlanNode[%d] Indexscan is ought to be used:\"%s\", output:%.0f, filtered:%.0f, rate:%.5f◇下盘量过大或过早下盘         SQL语句执行过程中,因为内存不足等原因,可能需要将中间结果的全部或一部分转储的磁盘上。下盘可能导致性能低下,应该尽量避免。如果监测到下盘量过大或过早下盘等情况,会给出如下告警信息:•       Spill file size large than 256MB•       Broadcast size large than 100MB•       Early spill•       Spill times is greater than 3•       Spill on memory adaptive•       Hash table conflict         下盘可能是因为缓冲区设置得过小,也可能是因为表的连接顺序或连接方式不合理等原因,要结合具体的SQL进行分析。可以通过改写SQL语句,或者HINT指定连接方式等手段来解决。         使用自诊断视图功能,需要将以下变量设成合适的值:▲ use_workload_manager(设成on,默认为on)▲ enable_resource_check(设成on,默认为on)▲ resource_track_level(如果设成query,则收集query级别的信息,如果设成operator,则收集所有信息,如果设成none,则以用户默认的log级别为准)▲ resource_track_cost(设成合适的正整数。为了不影响性能,只有执行代价大于resource_track_cost语句才会被收集。该值越大,收集的语句越少,对性能影响越小;反之越小,收集的语句越多,对性能的影响越大。)         执行完一条代价大于resource_track_cost后,诊断信息会存放在内存hash表中,可通过pgxc_wlm_session_history或gs_wlm_session_history视图查看。         视图中记录的有效期是3分钟,过期的记录会被系统清理。如果设置enable_resource_record=on,视图中的记录每隔3分钟会被转储到gs_wlm_session_info表中,因此3分钟之前的历史记录可以通过gs_wlm_session_info表或pgxc_wlm_session_info视图查看。◆ 发现正在运行的SQL的坏味道         上一节提到的自诊断视图可以显示已完成SQL的信息。如果要查看正在运行的SQL的情况,可以使用下面的视图:•       gs_wlm_session_statistics•       pgxc_wlm_session_statistics         类似地,gs_开头的用于查看当前CN节点上收集的信息,pgxc_开头的则包含集群中所有CN收集的信息。两个视图的定义与上一节的自诊断视图基本相同,使用方法也基本一致。 通过观察其中的字段,可以发现正在运行的SQL中存在的性能问题。         例如,通过“select queryid, duration from gs_wlm_session_statistics order by duration desc limit 10;”可以查询当前运行的SQL中,已经执行时间最长的10个SQL。如果时间过长,可能有必要分析一下原因。图2-a 通过gs_wlm_session_statistics视图发现可能hang住SQL         查到queryid后,可以通过query_plan字段查看该SQL的执行计划,分析其中可能存在的性能瓶颈和异常点。图2-b 通过gs_wlm_session_statistics视图查看当前SQL的执行计划         再下一步,可以结合等待视图等其他手段定位性能劣化的原因。图2-c 通过gs_wlm_session_statistics视图结合等待视图定位性能问题         另外,活动视图pg_stat_activity也能提供一些当前执行SQL的信息。◆ Top SQL——利用统计信息发现SQL坏味道         除了针对逐条SQL进行分析,还可以利用统计信息发现SQL中的坏味道。另一篇文章“Unique SQL特性原理与应用”中提到的Unique SQL特性,能够针对执行计划相同的一类SQL进行了性能统计。与自诊断视图不同的是,如果同一个SQL被多次执行,或者多个SQL语句的结构相同,只有条件中的常量值不同。这些SQL在Unique SQL视图中会合并为一条记录。因此使用Unique SQL视图能更容易看出那些类型的SQL语句存在性能问题。         利用这一特性,可以找出某一指标或者某一资源占用量最高/最差的那些SQL类型。这样的SQL被称为“Top SQL”。         例如,查找占用CPU时间最长的SQL语句,可以用如下SQL:select unique_sql_id,query,cpu_time from pgxc_instr_unique_sql order by cpu_time desc limit 10。         Unique SQL的使用方式详见https://bbs.huaweicloud.com/blogs/197299。◆ 结论         发现SQL中的坏味道是性能调优的前提。GaussDB对数据库的运行状况进行了SQL级别的监控和记录。这些打点记录的数据可以帮助用户发现可能存在的异常情况,“嗅”出潜在的坏味道。从这些数据和提示信息出发,结合其他视图和工具,可以定位出坏味道的来源,进而有针对性地进行优化。原文链接:https://bbs.huaweicloud.com/blogs/197413【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [SQL] GaussDB(DWS)性能调优:列存表scan性能优化
    1.问题背景某局点出现如下业务场景:从存量清单表中,根据条码,合同号等条件,查询明细数据,表总数据量有3亿。一次业务请求包含10个并发的查询语句,需要1秒内返回结果集。但是多次优化之后并发性能依旧长达4s左右。2.   硬件配置硬件配置信息:集群 6个数据节点:每个节点都是RH5885服务器,配置1T内存、 144个CPU core、SSD 存储空间3.   历史优化对于这个业务场景需求,客户做了多种性能优化尝试,优化动作主要分为如下三个阶段l  第一版本:调试分布键分析业务数据特性,并测试验证选择最合适的分布键,既能保障数据不倾斜,又能利用分布键做为条件过滤数据调整后单个查询响应从平均9秒降到4~5秒l  第二版本:添加PCK&限制结果集接口上线后,发现业务中会有几个高频条件字段,同时有些查询返回结果集过大,有几十万记录,不符合前端查询响应要求,所以添加了限制,单次最大只能返回1万条记录;同时对合同号添加了PCK调整后单个查询响应从平均5秒降到2秒l  第三版本:使用SMP,以资源换性能从系统监控发现资源使用率低,建议使用SMP,通过提高CPU资源使用率的方式提升查询性能。根据现网CPU配置推荐设置query_dop=8调整后单个查询响应从2秒降到了400MS版本上线后,生产使用发现查询性能劣化到3~4秒,但是把SQL提取之后单独运行时性能达到400ms。分析平台日志发现下日志中会每10个请求发起时间点很接近,然后再找到下游调用方了解,才确认是会每此业务请求包含10个类似SQL语句的并发调用。后续测试确认并发查询时性能下降,导致性能不达标。4.   优化分析4.1. SQL语句分析业务SQL是如下简单的单表查询语句,SQL语句未发现明显的不下推、不能提升子查询等明显低效性能点。需要进一步获取performance信息分析性能瓶颈。4.2. 性能瓶颈分析执行并发查询,获取performance信息,典型信息如下,详细信息见附件 发现耗时主要有两个1)  数据收集(GATHER和LOCAL GATHER),这个算子主要是从相关线程收集数据,这个算子耗时一般分为两个场景 数据量大,导致数据收集耗时特别长CN申请线程,DN上创建STREAM线程等计算相关线程初始化耗时长2)   数据扫描(Scan)耗时长分析Scan算子,发现顺序扫描(Cstore Scan)时,RoughCheck(根据稀疏索引排除查询不相关的数据)时排除掉的元组为0,即稀疏索引没有预过滤掉任何CU根据上述分析可以看到当前查询性能主要损耗在计算相关线程初始化上,但是如果把SMP去掉(设置query_dop为1),底层数据扫描耗时会变长,同样导致性能不达标。和相关维护和业务人员也确认了这点4.3. 性能优化4.3.1. 优化思路找到性能瓶颈点之后就可以针对性进行性能优化,我们把优化的重点放在Scan性能的提升上,期待在不设置SMP时通过Scan性能的大幅提升来优化性能。根据表扫描信息分析,我们发现,表扫描的filter条件可以过滤掉376029639条记录,输出149条记录,可以过滤掉99.99996037%的元组,效果非常明显。 分析表的扫描条件,通过测试验证发现过滤效果最明显的条件为POSITION(','||a.ItemNo||',' in ','||'0835TXWY'||',') > 0,过滤效果在99.99%以上,其它表达式基本没有起到过滤效果进一步分析RoughCheck,发现RoughCheck排除掉的元组为0,稀疏索引没有任何过滤效果 通常来讲,这类过滤效果非常明显的filter是典型的构建PCK和索引场景,但是这个filter条件为函数表达式,导致此filter条件即没有办法构建PCK又没办法构建索引。因此我们尝试跟业务人员沟通,看能够改写POSITION约束,使其支持索引和PCK4.3.2. 业务分析跟客户业务人员进一步沟通position函数的业务含义,发现1.  position函数的第二个参数如果个合同号通过’,’连接起来的子串2.  函数功能是查询能跟匹配到第二个参数中任一合同号的记录第二个参数通过如下的方式从客户端输入这样写的原因是从在客户界面上操作的方便性以及常规的操作习惯上来讲,在外部输入时不会在合同号上引号,在SQL拼接时不能把此约束条件写成itemno in ('0AFR2C', ‘0A672C’, ’0A902C', '0AY72C'')这类索引支持的表达式4.3.3. 最终优化方案在了解这些原因之后,我们和业务人员沟通,采取以下优化手段1)   在业务层在接受客户界面输入的合同号之后,内部在拼接SQL之前,进行数据预处理,把函数的逻辑转化为itemno in ('0AFR2C', ‘0A672C’, ’0A902C', '0AY72C'')式的in约束2)  在itemno上建PCK以及索引,通过PCK和索引的双重优化来提升性能采取这两个措施之后,标准并发测试场景下,SQL查询性能提升到90ms,端到端的性能从4s提升到300ms5.   优化总结5.1.       关于列存点查性能通常场景下,列存表的点差性能比行存表的点查性能要差,但是在如下场景下列存表的索引查询性能也非常好1)宽表的少量列查询列存是按照列存储的,宽表的少量列查询时,列存表只需要读取少量查询相关列即可,这可能会导致列存表扫描的数据量小于行存表的数据量,体现列存表扫描的性能优势2)索引列上局部聚簇通过在索引列上做PCK,通过PCK的聚簇效果减小扫描的CU个数,导致列存表扫描的数据量小于行存表的数据量。注:行存表有全局聚簇的手段,详见产品文档的CLUSTER命令5.2.       关于优化思路SQL语句优一些建议:1)  梳理性能问题业务,找出执行性能差的SQL语句2)  分析业务流程,确认SQL全生命周期的耗时分布,如果数据库执行时间长,那么进入下一步3)  分析是否存在不下推场景。如果存在,通过改写SQL消除不下推因素,如果SQL语句可以下推,进入下一步4)  通过performance找性能瓶颈点:根据performance显示的算子耗时,查询耗时最长的算子,这个算子就是导致执行耗时时间比较长的最基本因素5)  针对性能瓶颈点,给出优化思路和方案优化不要局限在SQL语句本身,要和具体硬件配置和业务背景相结合。名词解释1. 【CU】列存的基本存储单元,同时也是列存表扫描时基本的读取单元。列存表读取数据时会把全部CU的数据读上来,而不能读取CU中的一部分数据。2. 【PCK】Partial Cluster Key(局部聚簇)的简称,是列存表的一种局部聚簇技术,该技术可以在批量数据导入时,把数据按照PCK指定的列(单列或多列)进行局部排序,实现不同值区间的数据存储到不同的CU上。这种局部聚簇结合列存表CU的内置min/max稀疏索引,可以大幅提升表在PCK列上简单filter的过滤效果使用PCK需要注意的几点1)  只有列存表支持PCK2)  一个表只能定义一个PCK3)  PCK列上的fliter要满足以下约束 简单的<、>、≤、≥、=表达式 一侧是PCK列,而不能是列相关表达式、函数另一侧是常量表达式计算时,PCK列不需要进行隐士类型转换4)  上个步骤的filter条件要可以过滤掉较多的元组,减轻Scan以及相关投影计算量5)  表数据是批量数据入库,且单次入库数据不小于DN的个数*6w * 5条记录;如果单次入库记录数不满足上述约束,建议把表建成分区表,定期对增强数据所在分区进行VACUUM FULL操作增强聚簇效果6)  通过ALTER语法增加PCK时,只有后续新增数据才会有局部聚簇效果。可以通过VACUUM FULL全表让已有数据恢复聚簇3. 【SMP】SMP特性通过算子并行(可以理解为把一个线程的任务拆分为多个线程并行执行)来提升性能,本质上是一种以资源换取时间的方式,在合适的场景以及资源充足的情况下,能够起到较好的性能提升效果;但是如果在不合适的场景下,或者资源不足的情况下,反而可能引起性能的劣化。GaussDB A中可以通过参数query_dop设置算子并行度4. 【RoughCheck】粗过滤检查,列存表扫描的特殊的优化手段。在列存表简单filter条件(单列 op 常量, op为>、<、=、≤、≥)过滤时,通过判断CU的内置min/max跟filter条件进行快速比较,如果此CU内是不满足filter条件,那么直接跳过此CU的扫描。GaussDB A的列存表通过PCK +RoughCheck+Latter Read(先读取filter条件列进行过滤、再读取非filter条件列数据) 组合技术,可以典型场景下节省大量的数据扫描,提升查询性能原文链接:https://bbs.huaweicloud.com/blogs/175458【推荐阅读】【最新活动汇总】DWS活动火热进行中,互动好礼送不停(持续更新中)  HOT  【博文汇总】GaussDB(DWS)博文汇总1,欢迎大家交流探讨~(持续更新中)【维护宝典汇总】GaussDB(DWS)维护宝典汇总贴1,欢迎大家交流探讨(持续更新中)【项目实践汇总】GaussDB(DWS)项目实践汇总贴,欢迎大家交流探讨(持续更新中)【DevRun直播汇总】GaussDB(DWS)黑科技直播汇总,欢迎大家交流学习(持续更新中)【培训视频汇总】GaussDB(DWS) 培训视频汇总,欢迎大家交流学习(持续更新中)扫码关注我哦,我在这里↓↓↓
  • [新手课堂] Perf -Linux下的系统性能调优工具
    使用 perf record, 解读 report使用 top 和 stat 之后,您可能已经大致有数了。要进一步分析,便需要一些粒度更细的信息。比如说您已经断定目标程序计算量较大,也许是因为有些代码写的不够精简。那么面对长长的代码文件,究竟哪几行代码需要进一步修改呢?这便需要使用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果。您的调优应该将注意力集中到百分比高的热点代码片段上,假如一段代码只占用整个程序运行时间的 0.1%,即使您将其优化到仅剩一条机器指令,恐怕也只能将整体的程序性能提高 0.1%。俗话说,好钢用在刀刃上,不必我多说了。仍以 t1 为例。12perf record – e cpu-clock ./t1 perf report结果如下图所示:图 2. perf report 示例不出所料,hot spot 是 longa( ) 函数。但,代码是非常复杂难说的,t1 程序中的 foo1() 也是一个潜在的调优对象,为什么要调用 100 次那个无聊的 longa() 函数呢?但我们在上图中无法发现 foo1 和 foo2,更无法了解他们的区别了。我曾发现自己写的一个程序居然有近一半的时间花费在 string 类的几个方法上,string 是 C++ 标准,我绝不可能写出比 STL 更好的代码了。因此我只有找到自己程序中过多使用 string 的地方。因此我很需要按照调用关系进行显示的统计信息。使用 perf 的 -g 选项便可以得到需要的信息:12perf record – e cpu-clock – g ./t1 perf report结果如下图所示:图 3. perf – g report 示例通过对 calling graph 的分析,能很方便地看到 91% 的时间都花费在 foo1() 函数中,因为它调用了 100 次 longa() 函数,因此假如 longa() 是个无法优化的函数,那么程序员就应该考虑优化 foo1,减少对 longa() 的调用次数。使用 PMU 的例子例子 t1 和 t2 都较简单。所谓魔高一尺,道才能高一丈。要想演示 perf 更加强大的能力,我也必须想出一个高明的影响性能的例子,我自己想不出,只好借助于他人。下面这个例子 t3 参考了文章“Branch and Loop Reorganization to Prevent Mispredicts”[6]该例子考察程序对奔腾处理器分支预测的利用率,如前所述,分支预测能够显著提高处理器的性能,而分支预测失败则显著降低处理器的性能。首先给出一个存在 BTB 失效的例子:清单 3. 存在 BTB 失效的例子程序1234567891011121314151617//test.c #include <stdio.h> #include <stdlib.h>  void foo() {  int i,j;  for(i=0; i< 10; i++)  j+=2; } int main(void) {  int i;  for(i = 0; i< 100000000; i++)  foo();  return 0; }用 gcc 编译生成测试程序 t3:1gcc – o t3 – O0 test.c用 perf stat 考察分支预测的使用情况:12345678910111213141516[lm@ovispoly perf]$ ./perf stat ./t3   Performance counter stats for './t3':  6240.758394 task-clock-msecs # 0.995 CPUs 126 context-switches # 0.000 M/sec 12 CPU-migrations # 0.000 M/sec 80 page-faults # 0.000 M/sec 17683221 cycles # 2.834 M/sec (scaled from 99.78%) 10218147 instructions # 0.578 IPC (scaled from 99.83%) 2491317951 branches # 399.201 M/sec (scaled from 99.88%) 636140932 branch-misses # 25.534 % (scaled from 99.63%) 126383570 cache-references # 20.251 M/sec (scaled from 99.68%) 942937348 cache-misses # 151.093 M/sec (scaled from 99.58%)   6.271917679 seconds time elapsed可以看到 branche-misses 的情况比较严重,25% 左右。我测试使用的机器的处理器为 Pentium4,其 BTB 的大小为 16。而 test.c 中的循环迭代为 20 次,BTB 溢出,所以处理器的分支预测将不准确。对于上面这句话我将简要说明一下,但关于 BTB 的细节,请阅读参考文献 [6]。for 循环编译成为 IA 汇编后如下:清单 4. 循环的汇编123456789101112131415// C code  for ( i=0; i < 20; i++ )  { … }   //Assembly code;  mov    esi, data  mov    ecx, 0  ForLoop:  cmp    ecx, 20  jge     EndForLoop … add    ecx, 1  jmp    ForLoop  EndForLoop:可以看到,每次循环迭代中都有一个分支语句 jge,因此在运行过程中将有 20 次分支判断。每次分支判断都将写入 BTB,但 BTB 是一个 ring buffer,16 个 slot 写满后便开始覆盖。假如迭代次数正好为 16,或者小于 16,则完整的循环将全部写入 BTB,比如循环迭代次数为 4 次,则 BTB 应该如下图所示:图 4. BTB buffer这个 buffer 完全精确地描述了整个循环迭代的分支判定情况,因此下次运行同一个循环时,处理器便可以做出完全正确的预测。但假如迭代次数为 20,则该 BTB 随着时间推移而不能完全准确地描述该循环的分支预测执行情况,处理器将做出错误的判断。我们将测试程序进行少许的修改,将迭代次数从 20 减少到 10,为了让逻辑不变,j++ 变成了 j+=2;清单 5. 没有 BTB 失效的代码12345678910111213141516#include <stdio.h> #include <stdlib.h>  void foo() {  int i,j;  for(i=0; i< 10; i++)  j+=2; } int main(void) {  int i;  for(i = 0; i< 100000000; i++)  foo();  return 0; }此时再次用 perf stat 采样得到如下结果:12345678910111213141516[lm@ovispoly perf]$ ./perf stat ./t3   Performance counter stats for './t3:  2784.004851 task-clock-msecs # 0.927 CPUs 90 context-switches # 0.000 M/sec 8 CPU-migrations # 0.000 M/sec 81 page-faults # 0.000 M/sec 33632545 cycles # 12.081 M/sec (scaled from 99.63%) 42996 instructions # 0.001 IPC (scaled from 99.71%) 1474321780 branches # 529.569 M/sec (scaled from 99.78%) 49733 branch-misses # 0.003 % (scaled from 99.35%) 7073107 cache-references # 2.541 M/sec (scaled from 99.42%) 47958540 cache-misses # 17.226 M/sec (scaled from 99.33%)   3.002673524 seconds time elapsedBranch-misses 减少了。本例只是为了演示 perf 对 PMU 的使用,本身并无意义,关于充分利用 processor 进行调优可以参考 Intel 公司出品的调优手册,其他的处理器可能有不同的方法,还希望读者明鉴。
  • [技术干货] Perf -Linux下的系统性能调优工具
    perf 的基本使用说明一个工具的最佳途径是列举一个例子。考查下面这个例子程序。其中函数 longa() 是个很长的循环,比较浪费时间。函数 foo1 和 foo2 将分别调用该函数 10 次,以及 100 次。清单 1. 测试程序 t1123456789101112131415161718192021222324252627//test.c void longa() {   int i,j;   for(i = 0; i < 1000000; i++)   j=i; //am I silly or crazy? I feel boring and desperate. }  void foo2() {   int i;   for(i=0 ; i < 10; i++)        longa(); }  void foo1() {   int i;   for(i = 0; i< 100; i++)      longa(); }  int main(void) {   foo1();   foo2(); }找到这个程序的性能瓶颈无需任何工具,肉眼的阅读便可以完成。Longa() 是这个程序的关键,只要提高它的速度,就可以极大地提高整个程序的运行效率。但,因为其简单,却正好可以用来演示 perf 的基本使用。假如 perf 告诉您这个程序的瓶颈在别处,您就不必再浪费宝贵时间阅读本文了。准备使用 perf安装 perf 非常简单,只要您有 2.6.31 以上的内核源代码,那么进入 tools/perf 目录然后敲入下面两个命令即可:12make make install性能调优工具如 perf,Oprofile 等的基本原理都是对被监测对象进行采样,最简单的情形是根据 tick 中断进行采样,即在 tick 中断内触发采样点,在采样点里判断程序当时的上下文。假如一个程序 90% 的时间都花费在函数 foo() 上,那么 90% 的采样点都应该落在函数 foo() 的上下文中。运气不可捉摸,但我想只要采样频率足够高,采样时间足够长,那么以上推论就比较可靠。因此,通过 tick 触发采样,我们便可以了解程序中哪些地方最耗时间,从而重点分析。稍微扩展一下思路,就可以发现改变采样的触发条件使得我们可以获得不同的统计数据:以时间点 ( 如 tick) 作为事件触发采样便可以获知程序运行时间的分布。以 cache miss 事件触发采样便可以知道 cache miss 的分布,即 cache 失效经常发生在哪些程序代码中。如此等等。因此让我们先来了解一下 perf 中能够触发采样的事件有哪些。Perf list,perf 事件使用 perf list 命令可以列出所有能够触发 perf 采样点的事件。比如12345678910111213141516$ perf list  List of pre-defined events (to be used in -e):  cpu-cycles OR cycles [Hardware event]  instructions [Hardware event] … cpu-clock [Software event]  task-clock [Software event]  context-switches OR cs [Software event] … ext4:ext4_allocate_inode [Tracepoint event]  kmem:kmalloc [Tracepoint event]  module:module_load [Tracepoint event]  workqueue:workqueue_execution [Tracepoint event]  sched:sched_{wakeup,switch} [Tracepoint event]  syscalls:sys_{enter,exit}_epoll_wait [Tracepoint event] …不同的系统会列出不同的结果,在 2.6.35 版本的内核中,该列表已经相当的长,但无论有多少,我们可以将它们划分为三类:Hardware Event 是由 PMU 硬件产生的事件,比如 cache 命中,当您需要了解程序对硬件特性的使用情况时,便需要对这些事件进行采样;Software Event 是内核软件产生的事件,比如进程切换,tick 数等 ;Tracepoint event 是内核中的静态 tracepoint 所触发的事件,这些 tracepoint 用来判断程序运行期间内核的行为细节,比如 slab 分配器的分配次数等。上述每一个事件都可以用于采样,并生成一项统计数据,时至今日,尚没有文档对每一个 event 的含义进行详细解释。我希望能和大家一起努力,以弄明白更多的 event 为目标。。。Perf stat做任何事都最好有条有理。老手往往能够做到不慌不忙,循序渐进,而新手则往往东一下,西一下,不知所措。面对一个问题程序,最好采用自顶向下的策略。先整体看看该程序运行时各种统计事件的大概,再针对某些方向深入细节。而不要一下子扎进琐碎细节,会一叶障目的。有些程序慢是因为计算量太大,其多数时间都应该在使用 CPU 进行计算,这叫做 CPU bound 型;有些程序慢是因为过多的 IO,这种时候其 CPU 利用率应该不高,这叫做 IO bound 型;对于 CPU bound 程序的调优和 IO bound 的调优是不同的。如果您认同这些说法的话,Perf stat 应该是您最先使用的一个工具。它通过概括精简的方式提供被调试程序运行的整体情况和汇总数据。还记得我们前面准备的那个例子程序么?现在将它编译为可执行文件 t11gcc – o t1 – g test.c下面演示了 perf stat 针对程序 t1 的输出:1234567891011121314151617$perf stat ./t1  Performance counter stats for './t1':   262.738415 task-clock-msecs # 0.991 CPUs  2 context-switches # 0.000 M/sec  1 CPU-migrations # 0.000 M/sec  81 page-faults # 0.000 M/sec  9478851 cycles # 36.077 M/sec (scaled from 98.24%)  6771 instructions # 0.001 IPC (scaled from 98.99%)  111114049 branches # 422.908 M/sec (scaled from 99.37%)  8495 branch-misses # 0.008 % (scaled from 95.91%)  12152161 cache-references # 46.252 M/sec (scaled from 96.16%)  7245338 cache-misses # 27.576 M/sec (scaled from 95.49%)    0.265238069 seconds time elapsed  上面告诉我们,程序 t1 是一个 CPU bound 型,因为 task-clock-msecs 接近 1。对 t1 进行调优应该要找到热点 ( 即最耗时的代码片段 ),再看看是否能够提高热点代码的效率。缺省情况下,除了 task-clock-msecs 之外,perf stat 还给出了其他几个最常用的统计信息:Task-clock-msecs:CPU 利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO。Context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的。Cache-misses:程序运行过程中总体的 cache 利用情况,如果该值过高,说明程序的 cache 利用不好CPU-migrations:表示进程 t1 运行过程中发生了多少次 CPU 迁移,即被调度器从一个 CPU 转移到另外一个 CPU 上运行。Cycles:处理器时钟,一条机器指令可能需要多个 cycles,Instructions: 机器指令数目。IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。Cache-references: cache 命中的次数Cache-misses: cache 失效的次数。通过指定 -e 选项,您可以改变 perf stat 的缺省事件 ( 关于事件,在上一小节已经说明,可以通过 perf list 来查看 )。假如您已经有很多的调优经验,可能会使用 -e 选项来查看您所感兴趣的特殊的事件。perf Top使用 perf stat 的时候,往往您已经有一个调优的目标。比如我刚才写的那个无聊程序 t1。也有些时候,您只是发现系统性能无端下降,并不清楚究竟哪个进程成为了贪吃的 hog。此时需要一个类似 top 的命令,列出所有值得怀疑的进程,从中找到需要进一步审查的家伙。类似法制节目中办案民警常常做的那样,通过查看监控录像从茫茫人海中找到行为古怪的那些人,而不是到大街上抓住每一个人来审问。Perf top 用于实时显示当前系统的性能统计信息。该命令主要用来观察整个系统当前的状态,比如可以通过查看该命令的输出来查看当前系统最耗时的内核函数或某个用户进程。让我们再设计一个例子来演示吧。不知道您怎么想,反正我觉得做一件有益的事情很难,但做点儿坏事儿却非常容易。我很快就想到了如代码清单 2 所示的一个程序:清单 2. 一个死循环1while (1) i++;我叫他 t2。启动 t2,然后用 perf top 来观察:下面是 perf top 的可能输出:123456789101112131415161718PerfTop: 705 irqs/sec kernel:60.4% [1000Hz cycles] -------------------------------------------------- sampl pcnt function DSO 1503.00 49.2% t2 72.00 2.2% pthread_mutex_lock /lib/libpthread-2.12.so 68.00 2.1% delay_tsc [kernel.kallsyms] 55.00 1.7% aes_dec_blk [aes_i586] 55.00 1.7% drm_clflush_pages [drm] 52.00 1.6% system_call [kernel.kallsyms] 49.00 1.5% __memcpy_ssse3 /lib/libc-2.12.so 48.00 1.4% __strstr_ia32 /lib/libc-2.12.so 46.00 1.4% unix_poll [kernel.kallsyms] 42.00 1.3% __ieee754_pow /lib/libm-2.12.so 41.00 1.2% do_select [kernel.kallsyms] 40.00 1.2% pixman_rasterize_edges libpixman-1.so.0.18.0 37.00 1.1% _raw_spin_lock_irqsave [kernel.kallsyms] 36.00 1.1% _int_malloc /lib/libc-2.12.so ^C很容易便发现 t2 是需要关注的可疑程序。不过其作案手法太简单:肆无忌惮地浪费着 CPU。所以我们不用再做什么其他的事情便可以找到问题所在。但现实生活中,影响性能的程序一般都不会如此愚蠢,所以我们往往还需要使用其他的 perf 工具进一步分析。通过添加 -e 选项,您可以列出造成其他事件的 TopN 个进程 / 函数。比如 -e cache-miss,用来看看谁造成的 cache miss 最多。
  • [业务动态] 关于《鲲鹏软件性能调优实践》微认证下线优化的通知
    尊敬的微认证客户:您好!为保证您获得最佳的学习与实验体验,华为云学院将于2021年2月25日对《鲲鹏软件性能调优实践》微认证的课程及实验进行下线优化,预计将于2020年3月19日重新上线,届时请您关注相关通知。为此,我们将采取以下措施:1.对于已购买该微认证并通过考试领取证书的客户,原证书在证书有效期内仍有效,并与课程优化后的证书拥有同等效力;2.对于已购买该微认证但未通过考试且仍有考试机会的客户,可在重新上线后进行新课程学习、实验,参加考试并领取证书;3.对于已购买该微认证但未完成实验操作的客户,请您关注华为云学院资讯专栏-业务动态的上线通知,待实验优化重新上线后再前往沙箱开展实验。如您有任何问题,可随时通过工单或者服务热线(+86-4000-955-988 )与我们联系。感谢您对华为云微认证的支持! 发布日期:2021年2月24日
总条数:82 到第
上滑加载中