开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,可以解决你的问题。加群请联系 liuaustin3 ,(共2550人左右 1 + 2 + 3 + 4 +5 + 6 + 7)(1 2 3 4 5 6 群均已爆满,,新人进7群,开8群)
使用PolarDB-M(PolarDB for MySQL)已经有3年的时间了,作为PolarDB 非官方专业的技术传播渠道也有一段时间。替换MySQL到PolarDB-M,从当初的架构师,开发对这个云原生数据库的质疑,到现在一百多套的MySQL都消失了,拔地而起的一百多套的PolarDB-M,过程重要,结果也重要,其实都重要,如果没有结果,那么过程的目的又是什么。
今天我们就来说说深度使用PolarDB-M的用户,对于PolarDB-M拿手的技能,“并行”的一些使用经验和问题。(这也仅仅是第一期)
一、为什么要并行这个问题与两个事情有关
1 硬件的发展与数据库处理query之间的矛盾:硬件在发展的过程中,CPU的处理能力与CPU的核心数成关联性,数据库在处理数据查询的过程中,无法利用更先进的硬件。导致再多的CPU给付了数据库系统,也无法再一个SQL中发挥作用,单个SQL的处理速度并未因为CPU更多,而有更快的速度。
2 OLAP数据在传统数据库的处理 传统数据库在数据处理中,逐渐呈现多元化的发展道路,在数据处理中OLAP在线分析的工作在传统数据库中进行了延伸。更多的数据需要更多的CPU处理的需求逐渐被放大。
所以后续的数据库产生了并行处理SQL语句的功能,但并行查询并非是一个万全其美的好事,而是有利有弊的事情。
二、并行处理到底哪里并行
这个问题还的从一个SQL处理中哪个部分慢来说明,基于硬件的限制,每次IO的耗时是处理SQL中的一个难点,虽然后续有了SSD等磁盘系统,但如果有更多的线程来处理一个SQL中的数据,将是解决当前单个SQL数据处理中的一个解决方案,这也就是我们经常提起的并行读取。
三、如何并行
在进行并行处理的过程中,需要考虑的问题有很多
1 一个SQL我到底要不要进行并行
2 一个SQL我到底要怎么拆分
3 我怎么分配我的CPU资源去处理这些拆分的数据
4 我在处理了这些数据后,我们怎么合并这些数据,组成一个最终的结果
在这些问题提出后,我们必须去解决这些问题,其中解决这些问题的关键,cost 代价,代价是评价一个SQL到底值不值得进行拆分的关键,同时随着语句的复杂,多个表进行JOIN的情况下,则并行处理SQL将变得更加的复杂,Join中的每个表都有自己的进行数据处理的方式,如ref索引扫描,全表扫描,range索引扫描等等,这些都会影响到最终的并行扫描的代价。
关于并行的理论的部分很复杂,我们暂时先放到一边,我们先从实际的情况来,来对PolarDB的并行的部分进行一个感性的认知。
四、PolarDB的并行参数
PolarDB-M
max_parallel_degree : 参数主要是负责单个查询的最大并行度,范围0-1024,PolarDB优化器可能会对主查询和子查询分别并行执行,如果同时并行执行,它们的最大Worker数不能超过max_parallel_degree的值。
parallel_degree_policy: 云原生数据库查询并行度的策略,这里有三个策略 1 Typical:直接进行并行,对于系统的负载不考虑 2 Auto: 根据数据库的负载进行是否进行并行的选择,主从库均会进行查询的并行负载执行 3 Replica_AUTO:这是默认的选项,仅仅读库进行查询的并行开启,且要考虑具体的CPU负载情况
parallel_workers_policy: 1 local: 强制本机进行并行 2 AUTO:开启弹性并行,在本地资源不足的情况下,去使用其他节点的资源来进行SQL的计算,比如你有两个只读的节点,A节点资源不足,A节点进行并行的时候,直接找B节点CPU进行SQL的计算。3 Multi_nodes: 强制多机器并行进行查询的支持
records_threshold_for_parallelism:在优化器估算语句的情况下,当扫描的记录数超过阈值,优化器会考虑使用并行计划 默认值 10000
cost_threshold_for_parallelism: 在优化器进行估算查询代价时,串行超过该阈值,优化器会考虑选择并行执行计划。 默认值:50000
records_threshold_for_mpp: 在表扫描中,行数超过阈值则进行堆积并行的执行方式 默认值0
cost_threshold_for_mpp: 查询语句的串行代价超过法治后,优化器就会考虑并行的执行方式
说完这些参数后,可能有些没有学过PostgreSQL的老师,可能对这个部分比较的模糊,但学过PostgreSQL的知识和参数后,发现这和PostgreSQL可以任意调整COST引擎计算值的方案如出一辙。
这里简单的总结,PolarDB for MySQL里面对于并行的灵活调配的程度是非常高的,这里参数如果分类可以分为
1 单条语句是否要进行并行
2 JOIN 多条语句是否要并行
3 是否采用多主机的并行资源共享
4 并行的范围,读写节点,读节点,关闭
相对来说,我们也可以通过变量来进行数据库状态的分析
Parallel_worker_created
从Session启动开始,生成Parallel Worker的个数
Gather_records
Gather记录总数
PQ_refused_over_total_workers
由于总Worker数限制没有启用并行的查询数
PQ_REFUSED_OVER_MAX_QUEUING_TIME
由于并行查询排队超时没有启动并行的查询数
Total_running_parallel_workers
当前正在运行的Parallel Worker的数目。
写到这里,我们要开始利用这些参数来帮助我们针对并行的问题做点什么
1 到底当前的主机的CPU够不够用,当并行开启后,一定要对主机的状态有一个判断,而不是去光分析慢查询语句,在发现慢查询语句的同时,要针对由于资源不足导致的语句没有走并行的语句进行一个统计。
MySQL []> show status like 'PQ_REFUSED_OVER_MAX_QUEUING_TIME';
+----------------------------------+-------+
| Variable_name | Value |
+----------------------------------+-------+
| PQ_refused_over_max_queuing_time | 0 |
+----------------------------------+-------+
1 row in set (0.004 sec)
MySQL []> show status like 'PQ_refused_over_total_workers';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| PQ_refused_over_total_workers | 0 |
+-------------------------------+-------+
1 row in set (0.004 sec)
通过这个命令来,针对查看基于总体的资源应该用并行,但没有走并行的语句,在一个时间段是否在快速增长,且持续增长。从这里就可以看出两个问题。
1 CPU资源不足
2 配置参数需要优化
3 有大量的语句需要进行优化
MySQL [dba_test]> explain SELECT
-> s.student_id,
-> s.name,
-> AVG(sc.math_score) AS avg_math_score,
-> AVG(sc.english_score) AS avg_english_score,
-> AVG(sc.chinese_score) AS avg_chinese_score
-> FROM
-> students s
-> JOIN
-> scores sc ON s.student_id = sc.student_id
-> GROUP BY
-> s.student_id, s.name;
+----+-------------+-------------+------------+------+---------------+------------+---------+-----------------------+-------+----------+--------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------+------------+---------+-----------------------+-------+----------+--------------------------------------------+
| 1 | SIMPLE | <gather1.1> | NULL | ALL | NULL | NULL | NULL | NULL | 91399 | 100.00 | NULL |
| 1 | SIMPLE | s | NULL | ALL | PRIMARY | NULL | NULL | NULL | 22850 | 100.00 | Parallel scan (4 workers); Using temporary |
| 1 | SIMPLE | sc | NULL | ref | student_id | student_id | 5 | dba_test.s.student_id | 3 | 100.00 | NULL |
+----+-------------+-------------+------------+------+---------------+------------+---------+-----------------------+-------+----------+--------------------------------------------+
3 rows in set, 1 warning (0.003 sec)
从上面的语句可以看到PolarDB for MySQL中启用了并行,且还是4个线程的并行。
这里修改了参数,将max_parallel_degree修改成2 ,这里需要注意如果在之前的已经连接的POLARDB-M 的线程中,这个参数还是 4 是无法改变的,参数生效只针对新的连接,这点需要注意。
MySQL [dba_test]> explain SELECT s.student_id, s.name, AVG(sc.math_score) AS avg_math_score, AVG(sc.english_score) AS avg_english_score, AVG(sc.chinese_score) AS avg_chinese_score FROM
-> students s JOIN scores sc ON s.student_id = sc.student_id GROUP BY s.student_id, s.name;
+----+-------------+------------------+------------+------+---------------+------------+---------+-----------------------+-------+----------+---------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------------+------------+------+---------------+------------+---------+-----------------------+-------+----------+---------------------------+
| 1 | SIMPLE | <gather1.1> | NULL | ALL | NULL | NULL | NULL | NULL | 91399 | 100.00 | NULL |
| 1 | SIMPLE | <repartition1.2> | NULL | ALL | NULL | NULL | NULL | NULL | 45700 | 100.00 | Using temporary |
| 1 | SIMPLE | <repartition1.3> | NULL | ALL | NULL | NULL | NULL | NULL | 45700 | 100.00 | Using temporary |
| 1 | SIMPLE | s | NULL | ALL | PRIMARY | NULL | NULL | NULL | 45700 | 100.00 | Parallel scan (2 workers) |
| 1 | SIMPLE | sc | NULL | ref | student_id | student_id | 5 | dba_test.s.student_id | 3 | 100.00 | NULL |
+----+-------------+------------------+------------+------+---------------+------------+---------+-----------------------+-------+----------+---------------------------+
5 rows in set, 1 warning (0.003 sec)
前两天,梁大师SQL的一篇文章也提到了并行,并行本身只是一种技术,他可以提高你的SQL效率,也可以降低,这点我在PostgreSQL上也深有体会,开了并行比不开并行还快的真实场景。但并行本身是一种技术的进步,且并行在云原生数据库上的并行还有更深的发挥余地和比单体数据库更大的扩展空间。
写到这里,还没有写到真正的PolarDB的黑科技,跨机并行,不过一看字数2229了,那就先写到这里,后面可以继续写一些云原生数据库中更深的东西。
最后写一写最近学习数据库的感触,干数据库这个工作也20年了,经历了Sql SERVER---> MySQL--->Tidb---> MongoDB--->PostgreSQL--->Redis--->PolarDB-M --->OceanBase--->PolarDB-P。
传统数据库-->缓存数据库--->分布式存储数据库---云原生数据库--->分布式云原生数据库
这一路有些数据库的学习越来越有趣,有些库已经离我越来越远,有些数据库越来越近,不过一直在学习和往前走着,没有停下,数据库的架构一直在更新,已经和我10年前,5年前,甚至3年前的东西相比日新月异,这证明他们也在进步,那么正在读这篇文章的你呢?加油
OceanBase 相关其他文章
置顶文章:
往期热门文章:
阿里云数据库--市场营销聊胜于无--3年的使用感受与反馈系列
阿里云数据库产品 对内对外一样的卷 --3年阿里云数据库的使用感受与反馈系列
阿里云数据库使用感受--客户服务问题深入剖析与什么是廉价客户 --3年的使用感受与反馈系列
阿里云数据库使用感受--操作界面有点眼花缭乱 --3年的使用感受与反馈系列
PolarDB 最近遇到加字段加不上的问题 与 使用PolarDB 三年感受与恳谈
PostgreSQL 稳定性平台 PG中文社区大会--杭州来去匆匆
MySQL 的SQL引擎很差吗?由一个同学提出问题引出的实验
临时工访谈:从国产数据库 到 普罗大众的产品 !与在美国创业软件公司老板对话
PostgreSQL 熊灿灿一句话够学半个月 之 KILL -9
临时工访谈:庙小妖风大-PolarDB 组团镇妖 之 他们是第一 (阿里云组团PK笔者实录)
临时工访谈:金牌 “女” 销售从ORACLE 转到另类国产数据库 到底 为什么?
临时工访谈:无名氏意外到访-- 也祝你好运(管理者PUA DBA现场直播)