数据库cpu?数据库消耗内存大还是cpu大
大家好,关于数据库cpu很多朋友都还不太明白,今天小编就来为大家分享关于数据库消耗内存大还是cpu大的知识,希望对各位有所帮助!
数据库服务器对硬件有哪些要求
我们从五个方面入手,帮助您系统的了解数据库服务器对服务器硬件有哪些要求.选择数据库服务器的五个原则:1)高性能原则保证所选购的服务器,不仅能够满足运营系统的运行和业务处理的需要,而且能够满足一定时期业务量的增长.一般可以根据经验公式计算出所需的服务器TpmC值(Tpmc是衡量计算机系统的事务处理能力的程序),然后比较各服务器厂商和TPC组织公布的TpmC值,选择相应的机型.同时,用服务器的市场价/报价除去计算出来的TpmC值得出单位TpmC值的价格,进而选择高性能价格比的服务器.结论:服务器处理器性能很关键,CPU的主频要高,要有较大的缓存2)可靠性原则可靠性原则是所有选择设备和系统中首要考虑的,尤其是在大型的、有大量处理要求的、需要长期运行的系统上.考虑服务器系统的可靠性,不仅要考虑服务器单个节点的可靠性或稳定性,而且要考虑服务器与相关辅助系统之间连接的整体可靠性,如:网络系统、安全系统、远程打印系统等.在必要时,还应考虑对关键服务器采用集群技术,如:双机热备份或集群并行访问技术,甚至采用可能的完全容错机.结论:服务器要具备冗余技术,同时像硬盘、网卡、内存、电源此类设备要以稳定耐用为主,性能其次.3)可扩展性原则保证所选购的服务器具有优秀的可扩展性原则.因为服务器是所有系统处理的核心,要求具有大数据吞吐速率,包括:I/O速率和网络通讯速率,而且服务器需要能够处理一定时期的业务发展所带来的数据量,需要服务器能够在相应时间对其自身根据业务发展的需要进行相应的升级,如:CPU型号升级、内存扩大、硬盘扩大、更换网卡、增加终端数目、挂接磁盘阵列或与其他服务器组成对集中数据的并发访问的集群系统等.这都需要所选购的服务器在整体上具有一个良好的可扩充余地.一般数据库和计费应用服务器在大型计费系统的设计中就会采用集群方式来增加可靠性,其中挂接的磁盘存储系统,根据数据量和投资考虑,可以采用DAS、NAS或SAN等实现技术.结论:服务器的IO要高,否则在CPU和内存都是高性能的情况下,会出现瓶颈.除此之外,服务器的扩展性要好,为的是满足企业在日后发展的需要. 4)安全性原则
数据库消耗内存大还是cpu大
作者王文安,腾讯CSIG数据库专项的数据库工程师,主要负责腾讯云数据库 MySQL的相关的工作,热爱技术,欢迎留言进行交流。文章首发于腾讯云+社区的腾讯云数据库专家服务专栏。
在日常工作中,发现 MySQL的状态不太对劲的时候,一般都会看看监控指标,很多时候会看到熟悉的一幕:CPU使用率又爆了。本文将给大家介绍 MySQL和 CPU之间的关系,对此有一定的了解之后可以更准确的判断出问题的原因,也能够提前发现一些引发 CPU问题的隐患。
怎么看懂CPU使用率
以 Linux的 top命令为例,效果如下:
Top命令
在%CPU这一列就展示了 CPU的使用情况,百分比指代的是总体上占用的时间百分比:
%us:表示用户进程的 CPU使用时间(没有通过 nice调度)
%sy:表示系统进程的 CPU使用时间,主要是内核使用。
%ni:表示用户进程中,通过 CPU调度(nice)过的使用时间。
%id:空闲的 CPU时间
%wa:CPU运行时在等待 IO的时间
%hi:CPU处理硬中断花费的时间
%si:CPU处理软中断花费的时间
%st:被虚拟机偷走的 CPU时间
通常情况下,我们讨论的 CPU使用率过高,指的是%us这个指标,监控里面的 CPU使用率通常也是这个值(也有用其他的方法计算出来的,不过简单起见,不考虑其他的情况)。其他几个指标过高也代表出 MySQL的状态异常,简单起见,这里主要还是指%us过高的场景。
MySQL和线程
MySQL是单进程多线程的结构,意味着独占的 MySQL服务器里面,只能用 top命令看到一行数据。
TOP命令效果
这里能看到的是 MySQL的进程 ID,如果要看到线程的情况,需要用top-H
TOP命令效果
在这里能看到的是 MySQL各个线程的 ID,可以看到 MySQL在启动之后,会创建非常多的内部线程来工作。
这些内部线程包括 MySQL自己用来刷脏,读写数据等操作的系统线程,也包括处理用户 SQL的线程,姑且叫做用户线程吧。用户线程有一个特殊的地方:程序端发送到 MySQL端的 SQL,只会由一个用户线程来执行(one-thread-per-connection),所以 MySQL在处理复杂查询的时候,会出现“一核有难,多核围观”的尴尬现象。
参考%us的定义,对于 Linux系统来说,MySQL进程和它启动的所有线程都不算内核进程,因此 MySQL的系统线程和用户线程在繁忙的时候,都会体现在 CPU使用率的%us指标上。
什么时候CPU会100%
MySQL干什么的时候,CPU会 100%?从前文的分析来看,MySQL主要是两类线程占用 CPU:系统线程和用户线程。因此 MySQL独占的服务器上,只需要留意一下这两类线程的情况,就能 Cover住绝大部分的问题场景。
系统线程
在实际的环境中,系统线程遇到问题的情况会比较少,一般来说,多个系统线程很少会同时跑满,只要服务器的可用核心数大于等于 4的话,一般也不会遇到 CPU 100%,当然有一些 bug可能会有影响,比如这个:
MySQL BUG
虽然情况比较少,但是在面对问题的常规排查过程中,系统线程的问题也是需要关注的。
用户线程
提到用户线程繁忙,很多时候肯定会第一时间凭经验想到慢查询。确实 90%以上的时候都是“慢查询”引起的,不过作为方法论,还是要根据分析再去得出结论的~
参考 us%的定义,是指用户线程占用 CPU的时间多少,这代表着用户线程占用了大量的时间。
一方面是在进行长时间的计算,例如:order by,group by,临时表,join等。这一类问题可能是查询效率不高,导致单个 SQL语句长时间占用 CPU时间,也有可能是单纯的数据量比较多,导致计算量巨大。另一方面是单纯的 QPS压力高,所以 CPU的时间被用满了,比如 4核的服务器用来支撑 20k到 30k的点查询,每个 SQL占用的 CPU时间并不多,但是因为整体的 QPS很高,所以 CPU的时间被占满了。
问题的定位
分析完之后,就要开始实战了,这里根据前文的分析给出一些经典的 CPU 100%场景,并给出简要的定位方法作为参考。
PS:系统线程的 bug的场景 skip,以后有机会再作为详细的案例来分析。
慢查询
在 CPU 100%这个问题已经发生之后,真实的慢查询和因为 CPU 100%导致被影响的普通查询会混在一起,难以直观的看 processlist或者 slowlog来发现尊敬的大船,这时候就需要一些比较明确的特征来进行甄别。
从前文的简单分析可以看出来,查询效率不高的慢查询通常有以下几种情况:
全表扫描:Handler_read_rnd_next这个值会大幅度突增,且这一类查询在 slowlog中 row_examined的值也会非常高。
索引效率不高,索引选错了:Handler_read_next这个值会大幅度的突增,不过要注意这种情况也有可能是业务量突增引起的,需要结合 QPS/TPS一起看。这一类查询在 slowlog中找起来会比较麻烦,row_examined的值一般在故障前后会有比较明显的不同,或者是不合理的偏高。
比如数据倾斜的场景,一个小范围的 range查询在某个特定的范围内 row_examined非常高,而其他的范围时 row_examined比较低,那么就可能是这个索引效率不高。
排序比较多:order by,group by这一类查询通常不太好从 Handler的指标直接判断,如果没有索引或者索引不好,导致排序操作没有消除的话,那么在 processlist和 slowlog通常能看到这一类查询语句出现的比较多。
当然,不想详细的分析 MySQL指标或者是情况比较紧急的话,可以直接在 slowlog里面用 rows_sent和 row_examined做个简单的除法,比如 row_examined/rows_sent> 1000的都可以拿出来作为“嫌疑人”处理。这类问题一般在索引方面做好优化就能解决。
PS:1000只是个经验值,具体要根据实际业务情况来定。
计算量大
这一类问题通常是因为数据量比较大,即使索引没什么问题,执行计划也 OK,也会导致 CPU 100%,而且结合 MySQL one-thread-per-connection的特性,并不需要太多的并发就能把 CPU使用率跑满。这一类查询其实是是比较好查的,因为执行时间一般会比较久,在 processlist里面就会非常显眼,反而是 slowlog里面可能找不到,因为没有执行完的语句是不会记录的。
这一类问题一般来说有三种比较常规的解决方案:
读写分离,把这一类查询放到平时业务不怎么用的只读从库去。
在程序段拆分 SQL,把单个大查询拆分成多个小查询。
使用 HBASE,Spark等 OLAP的方案来支持。
高 QPS
这一类问题单纯的就是硬件资源的瓶颈,不论是 row_examined/rows_sent的比值,还是 SQL的索引、执行计划,或者是 SQL的计算量都不会有什么明显问题,只是 QPS指标会比较高,而且 processlist里面可能什么内容都看不到,例如:
processlist
实际上 CPU 100%的问题其实不仅仅是单纯的%us,还会有%io,%sys等,这些会涉及到 MySQL与 Linux相关联的一部分内容,展开来就会比较多了。本文仅从%us出发尝试梳理一下排查&定位的思路和方法,在分析%io,%sys等方面的问题时,也可以用类似的思路,从这些指标的意义开始,结合 MySQL的一些特性或者特点,逐步理清楚表象背后的原因。
mssql数据库占用CPU过高
CPU占用过高诊断思路
mpstat-P ALL 1,查看cpu使用情况,主要消耗在sys即os系统调用上
perf top,cpu主要消耗在_spin_lock
生成perf report查看详细情况
CPU主要消耗在mutex争用上,说明有锁热点。
采用pt-pmp跟踪mysqld执行情况,热点主要集中在mem_heap_alloc和mem_heap_free上。
Pstack提供更详细的API调用栈
Innodb在读取数据记录时的API路径为
row_search_for_mysql--》row_vers_build_for_consistent_read--》mem_heap_create_block_func--》mem_area_alloc--》malloc--》 _L_unlock_10151--》__lll_unlock_wait_private
row_vers_build_for_consistent_read会陷入一个死循环,跳出条件是该条记录不需要快照读或者已经从undo中找出对应的快照版本,每次循环都会调用mem_heap_alloc/free。
而该表的记录更改很频繁,导致其undo history list比较长,搜索快照版本的代价更大,就会频繁的申请和释放堆内存。
Linux原生的内存库函数为ptmalloc,malloc/free调用过多时很容易产生锁热点。
当多条 SQL并发执行时,会最终触发os层面的spinlock,导致上述情形。
解决方案
将mysqld的内存库函数替换成tcmalloc,相比ptmalloc,tcmalloc可以更好的支持高并发调用。
修改my.cnf,添加如下参数并重启
[mysqld_safe]malloc-lib=tcmalloc
上周五早上7点执行的操作,到现在超过72小时,期间该实例没有再出现cpu长期飙高的情形。
以下是修改前后cpu使用率对比
数据库cpu和数据库消耗内存大还是cpu大的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!