• [技术干货] 浅析PostgreSQL并行查询代价估算
    并行查询特性最早是在PostgreSQL 9.6中引入。自那时起,社区一直在扩展该功能。在PostgreSQL 11和PostgreSQL 12中,社区开发人员向数据库引擎添加了更多的相关功能。本文就PostgreSQL查询优化器对并行执行代价估算的工作原理进行阐述,不足之处希望大家多多指正。串行顺序扫描执行代价估算       为了方便解释,用一个简单的例子来说明问题。首先通过代码片段1创建一个表包含两列。    1.  //代码片段1     2.  mydb=# CREATE TABLE people (id int PRIMARY KEY NOT NULL, age int NOT NULL);      3.  CREATE TABLE为了演示并行查询带来的益处,利用代码片段2往表people**一千万条数据,其中age字段是0-100之间的随机数。    1.  //代码片段2     2.  mydb=# INSERT INTO people        3.         SELECT id, (random()*100)::integer AS age        4.         FROM generate_series(1,10000000) AS id;       5.  INSERT 0 10000000默认情况下PostgreSQL是打开并行执行的。我们首先关闭并行执行开关,检查串行查询执行的耗时。通过将配置参数max_parallel_workers_per_gather设置为0可以关闭并行执行特性。从查询执行计划可以看到,顺序扫描的执行代价为144.248ms(Pg的执行计划显示的时间由两部分组成,‘..’前面的称之为start_up_cost,后面部分叫做run_cost)。总的查询执行代价为169.248ms。Pg如何计算得到这些数字的? 1.  //代码片段3  2.  mydb=# SET max_parallel_workers_per_gather TO 0;    3.  SET    4.  mydb=# explain analyze select count(*) from people;    5.                                 QUERY PLAN    6.  --------------------------------------------------------------------------------  7.   Aggregate  (cost=169248.60..169248.61 rows=1 width=8) (actual time=1375.237..1375.237 rows=1 loops=1)    8.      -> Seq Scan on people(cost=0.00..144248.48 rows=10000048 width=0)    9.   (4 rows)Pg查询执行时间total_cost = start_up_cost + run_cost,具体来说pg的运行时的代价由以下的式子计算得到:                total_cost = cpu_run_cost + disk_run_cost                                   = (cpu_tuple_cost + cpu_operator_cost) × Ntuple + seq_page_cost×Npage (1)        其中cpu_tuple_cost是CPU传输该记录的代价;cpu_operator_cost指函数运算或其他操作符的开销。有了上述计算规则以后,可以通过Pg的元数据表pg_class查询表people相关统计信息,见代码片段4。可以得到Npage=44248,Ntuple = 10000048.Pg源代码的cost.h头文件定义了公式(1)相关的计算代价,见代码片段5:    1.  //代码片段4     2.  mydb=# SELECT relpages, reltuples FROM pg_class WHERE relname = 'people';       3.   relpages |   reltuples       4.   ----------+---------------       5.     44248 | 1.0000048e+07       6.  (1 row)计算代价如下:    1.  //代码片段5     2.  /* defaults for costsize.c's Cost parameters */       3.  /* NB: cost-estimation code should use the variables, not these constants! */       4.  /* If you change these, update backend/utils/misc/postgresql.sample.conf */       5.  #define DEFAULT_SEQ_PAGE_COST  1.0       6.  #define DEFAULT_RANDOM_PAGE_COST  4.0       7.  #define DEFAULT_CPU_TUPLE_COST  0.01       8.  #define DEFAULT_CPU_INDEX_TUPLE_COST 0.005       9.  #define DEFAULT_CPU_OPERATOR_COST  0.0025       10. #define DEFAULT_PARALLEL_TUPLE_COST 0.1       11. #define DEFAULT_PARALLEL_SETUP_COST  1000.0将代码片段5的计算代价,放入公式(1),我们可以得到顺序扫描的代价:                              total_cost = (cpu_tuple_cost)×Ntuple + seq_page_cost×Npage                        = 0.01×1.0000048e+07 + 1×44248                                 = 144248.48这就是代码片段3第8行的顺序执行代价。而总的执行代价,需要对每条元组进行count函数操作,因此需要加上cpu_operator_cost,因此聚集函数count的查询执行start_up_cost为:                              Start_up_cost = cpu_run_cost + disk_run_cost                               = (cpu_tuple_cost + cpu_operator_cost)×Ntuple + seq_page_cost×Npage (1)                       = (0.01 + 0.0025) ×1.0000048e+07 + 1×44248                               = 169248.6 (代码片段3第7行所示)最后,系统只需要对这条元组传输即可,因此总的查询执行代价为:                            total_cost = (cpu_tuple_cost)×Ntuple + start_up_cost                                       =  0.01 + 169248.6                                       =  169248.61(代码片段3第7行所示)并行顺序扫描执行代价估算现在我们将并行执行的特性打开令max_parallel_workers_per_gather=2,相应的执行计划如下:1.  //代码片段6 2.  mydb=# set max_parallel_workers_per_gather = 2;   3.  SET   4.  mydb=# explain analyze select count(*) from people;   5.                           QUERY PLAN   6.  ------------------------------------------------------------------------------------------------------------ 7.   Finalize Aggregate  (cost=97331.80..97331.81 rows=1 width=8) (actual time=524.896..524.896 rows=1 loops=1)   8.     ->  Gather  (cost=97331.58..97331.79 rows=2 width=8) (actual time=524.828..526.162 rows=3 loops=1)   9.           Workers Planned: 2   10.          Workers Launched: 2   11.          -> Partial Aggregate  (cost=96331.58..96331.59 rows=1 width=8)   12.                -> Parallel Seq Scan on people  (cost=0.00..85914.87 rows=4166687 width=0)   13.  Planning Time: 0.307 ms   14.  Execution Time: 526.209 ms   15. (8 rows)为了解释并行查询执行代价,我们首先看看不同进程(为什么用进程是历史原因)之间工作量的分配。当并发进程只有两个的时候,主进程需要将大部分时间花费在执行工作,当并行进程的增加,主进程逐渐将工作转向聚合部分结果。Pg的进程工作量分配正是建立在这个基础之上。具体的分配算法见代码片段7第22行-27行。并行执行的框架如图1所示。1.  //代码片段7 2.  static double   3.  get_parallel_divisor(Path *path)   4.  {   5.      double      parallel_divisor = path->parallel_workers;   6.     7.       /*  8.        * Early experience with parallel query suggests that when there is only 9.        * one worker, the leader often makes a very substantial contribution to 10.       * executing the parallel portion of the plan, but as more workers are  11.       * added, it does less and less, because it's busy reading tuples from the  12.       * workers and doing whatever non-parallel post-processing is needed.  By  13.       * the time we reach 4 workers, the leader no longer makes a meaningful  14.       * contribution.  Thus, for now, estimate that the leader spends 30% of  15.       * its time servicing each worker, and the remainder executing the  16.       * parallel plan.  17.       */   18.     if (parallel_leader_participation)   19.     {   20.         double      leader_contribution;   21.    22.         leader_contribution = 1.0 - (0.3 * path->parallel_workers);   23.         if (leader_contribution > 0)   24.             parallel_divisor += leader_contribution;   25.     }   26.    27.   return parallel_divisor;  28.  }                                                                                    图1.并行执行框架因此当并行执行的worker为2的时候,每个工作进程所分配得到的工作量为:10000048.0 / (2 + (1 – 0.3 * 2)) = 4166686.66 rows.这就是代码片段6第13行得到每个worker处理的元组(rows)数目。这里需要注意的是虽然是并行扫描但是IO代价仍然是按照全表扫描的代价计算。这主要是因为每个并发进程在同一份数据上按照block-by-block的方式顺序推进全局next指针,这等价于全表扫描。总结PostgreSQL的口号是开源数据库中最强大的关系型数据库系统。其实业界也一直将其称为开源数据库的oracle。此言不虚,因为很多企业客户在去“O”问题上选择用PostgreSQL替代Oracle。PostgreSQL不仅在语法上高度兼容Oracle而且在性能上也向Oracle靠拢,例如并行查询特性就是PostgreSQL引以为豪的特性之一。PostgreSQL实现了并行scan,merge-join,hash-join,以及partition-join等。这篇文章对PostgreSQL的并行查询进行了初步的分析,探讨了并行工作进程之间的工作量分配,查询执行代价的计算,以及并行查询的总体框架。后续我们计划对PostgreSQL的并行join算法进行深入探讨以更好地了解PostgreSQL的并行查询功能。
  • [调优工具] 【tuning kit】进程ID CPU信息,出现了线程信息
    1. Tuning-Kit-release-2.1.T5.zip版本2. centos 7.63. 进程分析任务->进程/线程性能分析4.  问题:选择进程ID,且只能选择进程ID,但图出现了线程曲线。
  • [调优工具] 【tuning kit】线程CPU信息不正确
    1. Tuning-Kit-release-2.1.T5.zip版本2. centos 7.63. 进程分析任务->进程/线程性能分析4.  问题:   1. TID与PID不应该相同   2. 所有TID CPU都是0,实际后面附的截图不为0进程CPU:线程CPU:
  • [技术干货] 漫谈Lite OS-物联网操作系统介绍
    漫谈Lite OS-物联网操作系统介绍1简介提到操作系统,可能首先想到的就是苹果操作系统,windows,Linux,Unix,Android,IOS等,显然目前比较为人熟知的操作系统基本都是一些手机或者电脑端的操作系统。而随着互联网技术的不断发展,硬件的体积越来越小,物联网技术也迎来了爆棚式的发展。物理网不同于 互联网的不同在于后者更关注的是人与人的互联,而前者是更加强调人与物,物与物的连接,从而实现万物互联(IOT)。显然传统的嵌入式操作系统已然无法满足如今飞速发展的物联网的需求,因此针对物理网应用的操作系统也就应运而生。据统计全球物联网系统至少有几十种,甚至上百种。2 什么是物联网操作系统物联网大致可分为终端应用层、网络层(进一步分为网络接入层和核心层)、设备管理层、后台应用层等四个层次。其中最能体现物联网特征的,就是物联网的终端应用层。终端应用层由各种各样的传感器、协议转换网关、通信网关、智能终端、POS机、智能卡等终端设备组成。这些终端大部分都是具备计算能力的微型计算机。物联网操作系统,就是运行在这些终端上,对终端进行控制和管理,并提供统一编程接口的操作系统软件。其实简单来讲物理网操作系统就是一种满足物联网需求的服务软件平台。3 物联网操作系统的主要特点3.1 内核尺寸伸缩性强以及整体架构的可扩展性物联网操作系统的内核,应该设计成一个框架,这个框架定义了一些接口和规范,只要遵循这些接口和规范,就可以很容易的在操作系统内核上增加新的功能的新的硬件支持。简单来讲就是随着物联网应用功能需求的增多或减少,操作系统可以根据不同场景下的技术要求在原有简单内核基础之上进行扩展同时增加内核尺寸以实现对于上述需求的满足。3.2 实时性实时性要求系统能对外部事件在规定时间内进行处理,因为很多的关键性动作,必须在有限的时间内完成,否则将失去意义。如中断响应的实时性,一旦外部中断发生,操作系统必须在足够短的时间内响应中断并做出处理。其次线程或任务调度的实时性,一旦任务或线程所需的资源或进一步运行的条件准备就绪,必须能够马上得到调度。即任务调度需要支持抢占式优先级调度。3.3安全性和可靠性安全性和可靠性是一个系统的基本需求,首先物联网应用环境具备自动化程度高、人为干预少的特点,这要求内核必须足够可靠,以支撑长时间的独立运行。其次操作系统的安全性和稳定性与物联网设备的安全性和稳定性密切相关。3.4低功耗物联网设备本身具有体积小,独立性强等特点,因此电源的供电至关重要,因此需要系统实现低功耗节能省电,以支持足够的电源续航能力。如系统采用加入休眠模式实现节能。4 几种常见的物联网操作系统4.1 Huawei LiteOS4.1.1简介LiteOS是华为在2015年发布的一款面向IoT领域,遵循BSD-3开源许可协议、构建的的开源的轻量级的物联网操作系统,其大小为10KB。具备零配置、自发现和自组网能力,让使用 LiteOS 的物联终端能够自动接入支持的网络。目前LiteOS可广泛应用于智能家居、个人穿戴、车联网、城市公共服务、制造业等领域,开发门槛低上手快、设备布置以及维护成本低、开发周期短使得硬件开发更为简单。4.1.2 LiteOS内核的特点(1)超小内核。(2)高实时性,高稳定性。(3)低功耗。(4)支持功能静态裁剪。(5)支持动态加载、分散加载。与正常的操作系统内核一样,包括任务管理、内存管理、时间管理、通信机制、中断管理、队列管理、事件管理、定时器等操作系统基础组件,可以单独运行,内核部分可以参考。https://github.com/LiteOS/LiteOS/blob/master/doc/Huawei_LiteOS_Developer_Guide_zh.md。4.1.3 LiteOS SDKLiteOS SDK 是 Huawei LiteOS 软件开发工具包(Software Development Kit),包括端云互通组件,FOTA,JS引擎、传感器框架等内容。4.2 RT-Thread4.2.1 简介RT-Thread 是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务,允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。4.2.2 特点 C 语言编写,浅显易懂,方便移植。它把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。RT-Thread 体积小,成本低,功耗低、启动快速,除此以外 RT-Thread 还具有实时性高、占用资源小等特点,非常适用于各种资源受限(如成本、功耗限制等)的场合。架构图如下。4.3 FreeRTOS4.3.1 简介FreeRTOS创始人是Richard Barry,它是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。4.3.2 特点用户可配置内核功能、多平台的支持、目标代码小,简单易用强大的执行跟踪功能、堆栈溢出检测、没有限制的任务数量和任务优先级,多个任务可以分配相同的优先权、队列,二进制信号量,计数信号灯和递归通信和同步的任务、优先级继承。5总结目前常用的操作系统有很多,每一款操作系统都具有各自的特点,但是大体功能较为相似,需要用户根据自己的需求进行选择。
  • [问题求助] liteos线程无法正常退出,状态变为invalid
    如下图所示,线程创建后进行校时,校时成功后就会主动退出,但是去查看后台线程发现线程还在,只是状态变成了 invalid,不知道这是怎么回事
  • [Atlas500] 您好!我想询问一下同一个engine中的thread_num=5时,该5个线程间共享静态全局变量吗?
    我想询问一下同一个engine中的thread_num=5时,该5个线程间共享静态全局变量吗?比如我在 taskengine.cpp 中创建: static   uint32_t  task_job; static  pthread_mutext_t task_lock;在engine 中设置线程数目thread_num=5时,多线程访问和修改 task_job的值是否与我们外部创建任务线程访问一致?
  • [Java] 鲲鹏aarch64系统下java线程并行同步出现问题,请问是否有人了解原因?
    在鲲鹏aarch64平台上,多线程并行使用okhttp进行文件上传,发现出现了空指针,下标越界等异常。而同样的代码在x86平台运行无异常情况。遂对调用okhttp的代码进行抽取并将问题缩小范围,得到如下的一段问题重现代码,仅包含简单的原生java代码,不涉及任何第三方包的引用。package test2; import java.util.ArrayList; import java.util.LinkedList; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class RequestTest { public static void main(String[] args) { outter: for (int i = 0; i > -1; i++) { ExecutorService exs = Executors.newCachedThreadPool(); ArrayList<Future<String>> lst = new ArrayList<>(); ArrayList<HttpCall> calls = new ArrayList<HttpCall>(); for (int j = 0; j < 100; j++) { HttpCall call = new HttpCall(); calls.add(call); } for (HttpCall httpCall : calls) { Future<String> future = exs.submit(httpCall); lst.add(future); } for (Future<String> future : lst) { try { String result = future.get(); if (!"".equals(result)) { exs.shutdown(); break outter; } } catch (Exception e) { e.printStackTrace(); } } exs.shutdown(); System.out.println("No." + i + " done!"); } } } class HttpCall implements Callable<String> { public static LinkedList<Object> lst = new LinkedList<Object>(); @Override public String call() throws Exception { try { for (int i = 0; i < 200; i++) { synchronized (HttpCall.class) { if (!lst.isEmpty()) { lst.remove(0); } } Thread.sleep(1); synchronized (HttpCall.class) { if (lst.size() < 8) { lst.add(new Object()); } } } } catch (Exception e) { e.printStackTrace(); return "-"; } return ""; } }以上代码x86平台运行无异常,但是拿到鲲鹏aarch64平台下却会有小概率抛出空指针异常:系统信息和jdk版本如下:
  • [技术干货] SendData方法是怎么实现的?
    请问Engine间的SendData方法是怎么工作的?如果我同时往下一个引擎SendData 多次,框架是会在资源允许下创建多个线程去执行IMPL_ENGINE_PROCESS么?还是要排队。 我如果自己写多线程的话,与其往其他engine发送数据,在同一个引擎里写多个线程,不发送数据,效率会更高么?
  • [HPC] QUANTUM ESPRESSO 6.4.1 移植指南(CentOS 7.6)
    文档位置已迁移至如下链接:https://support.huaweicloud.com/prtg-kunpenghpcs/kunpenghpcs_prtg_0020.html
  • [HPC] IOR测试指导书
    文档位置已迁移至如下链接:https://support.huaweicloud.com/tstg-kunpenghpcs/kunpenghpcs_tstg_0002.html
  • KUNPENG平台apr1.7.0移植自动安装脚本
    1 apr简介APR为上层的应用程序提供一个可以跨越多操作系统平台使用的底层支持接口库。使得平台细节的处理进行下移。对于应用程序而言,它们根本就不需要考虑具体的平台,不管是Unix、Linux还是Window,应用程序执行的接口基本都是统一一致的。因此对于APR而言,可移植性和统一的上层接口是其考虑的一个重点。而APR最早的目的并不是如此,它最早只是希望将Apache中用到的所有代码合并为一个通用的代码库,然而这不是一个正确的策略,因此后来APR改变了其目标。有的时候使用公共代码并不是一件好事,比如如何将一个请求映射到线程或者进程是平台相关的,因此仅仅一个公共的代码库并不能完成这种区分。 2 环境信息2.1 环境信息类别子项版本获取地址OSCentOS7.5 Aarch64href="https://www.centos.org/download/" https://www.centos.org/download/服务器配置16U16GB40GB软件apr1.7.0http://mirror.bit.edu.cn/apache//apr/apr-1.7.0.tar.gz3 软件移植3.1 环境准备OS安装类型:CentOS-7.5-aarch64-1804。 注:操作系统安装使用最小简化版安装(如上图),其余步骤安装一般安装操作系统步骤即可。 3.1.1 相关软件下载上传1、 上传CentOS 7.5系统ISO镜像文件至服务器2、 上传apr源码包至服务器目录下,如/opt, 下载地址如下:http://mirror.bit.edu.cn/apache//apr/apr-1.7.0.tar.gz3.2 安装apr    1、 安装apr    上传以下脚本至要安装apr的服务器上的任意目录,如/opt。    (apr_install.sh)    添加执行权限:    chmod +x /opt/apr_install.sh    执行脚本    sh /opt/apr_install.sh    2、 提示apr install success表示安装成功。  3.3 验证执行1.执行cat /usr/local/apr/lib/pkgconfig/apr-1.pc命令,简单使用apr是否正常,看到以下内容则表示apr已经安装成功。 4 参考信息https://www.huaweicloud.com/kunpeng/software.html
  • KUNPENG平台JMeter5.1.1移植自动安装脚本
    1 JMeter简介JMeter是Apache组织基于Java的压力测试工具。用于对软件做压力测试,能够对HTTP和FTP服务器进行压力和性能测试,也可以对任何数据进行同样的测试(通过JDBC)。安全的可移植性和100%纯java。完全Swing和轻量组件支持(预编译的JAR使用javax.swing.*)。完全多线程框架允许通过多个线程并发取样和通过单独的线程组对不通的功能同时取样。精心的GUI设计允许快速操作和更精确的计时。缓存和离线分析、回访测试结果。 2 环境信息2.1 环境信息类别子项版本获取地址OSCentOS7.5 Aarch64href="https://www.centos.org/download/" https://www.centos.org/download/服务器配置16U16GB50GB软件JMeter5.1.1 https://mirrors.bit.edu.cn/apache//jmeter/binaries/apache-jmeter-5.1.1.zip3 软件移植3.1 环境准备OS安装类型:CentOS-7.5-aarch64-1804。 注:操作系统安装使用最小简化版安装,但推荐安装时选择GUI选项。 3.1.1 相关软件下载上传1、 上传CentOS 7.5系统ISO镜像文件至服务器2、 上传apache-jmeter-5.1.1.zip软件包至服务器目录下下载地址:https://mirrors.bit.edu.cn/apache//jmeter/binaries/apache-jmeter-5.1.1.zip  3.2 安装JMeter    1、 如果当前服务器不能访问外网,请先配置本地yum源。        a. 上传以下脚本至要安装ActiveMQ的服务器上的任意目录,如/opt。        (local_yum_install.sh)        b. 执行如下命令添加执行权限:        chmod +x /opt/local_yum_install.sh        c. 执行如下命令安装配置本地yum源        sh /opt/local_yum_install.sh         2、 上传JMeter软件包,apache-jmeter-5.1.1.zip至服务器,如/opt目录下    3、 下载安装解压工具        yum install unzip –y    4、 解压安装包        unzip /opt/apache-jmeter-5.1.1.zip4 软件运行4.1 验证执行    1.进入到JMeter安装目录/bin目录执行jmeter.sh文件        /opt/jmeter.sh    2.加载以下图片表示安装成功   5 参考信息https://developer.arm.com/tools-and-software/server-and-hpc/arm-architecture-tools/resources/porting-and-tuning/building-blast-with-arm-compiler/single-page
  • [交流分享] DVPP日志ERROR日志存在关键词 Signal Interrupted, engine id报错,怎么定位
    错误日志此情况是deivce侧进程先退出,DVPP底层收到了进程退出信号 中断(Signal Interrupted),然后处理的图片需要终止,所以才报后面的DVPP  KLERNAL的ERROR日志。 这个问题需要开发者排查程序为什么退出,这个日志不是关注重心。
  • [Atlas300] 关于device侧调度的问题
    您好,以下几个问题请教一下:device侧1个graph对应1个进程吗?device侧的arm有几个核?最高并发线程数是多少?模型推理过程中,device侧os是否可以调度其它graph或者同一graph的其它engine处理非推理事务(比如DVPP解码、H2D copy、D2H copy等)
  • [问题求助] 系统load average高问题
    系统启动后,不做任何操作,top 命令,发现 load average 高,如下:6.10 6.07 6.091分钟、5分钟、15分钟的待执行进程都是6个,这样系统的负载偏高。百度了一下,执行如下脚本,发现系统开机启动的6个进程每秒被调用阻塞频度很高,这6个进程可以 kill 掉,降低系统 load average 吗?bbox_main、bbox_hdc、bbox_ts_main、bbox_lpm3_main、dvpp_ddr_power_、drvlog_kthread_#!/bin/bashLANG=CPATH=/sbin:/usr/sbin:/bin:/usr/bininterval=1length=86400for i in $(seq 1 $(expr ${length} / ${interval}));dodateLANG=C ps -eTo stat,pid,tid,ppid,comm  --no-header | sed -e 's/^ \*//' | perl -nE 'chomp;say if (m!^\S*[RD]+\s*!)'datecat /proc/loadavgecho -e "\n"sleep ${interval}done
总条数:756 到第
上滑加载中