如何统计数据库的QPS和TPS?
主要分享如何统计MySQL的QPS和TPS
一、相关概念
这两个都是衡量数据库性能的重要指标
QPS
Queries Per Second,意思是每秒请求数
很多人理解成每秒查询数,是数据库中的每秒执行查询sql的次数,我们来理解一下,其实是有偏差的
如果把Q理解为query查询的话,只统计DQL的话,那么数据库在只写的情况下,qps为0,这合理?显然不对
正常来说,SQL包含DDL、DQL、DML,所以说,Q应该是和SQL的Q是一个意思才对,应该指的是查询语句
所以,准确来说,应该和SQL的Q是一个意思,指的是所有SQL,也就是每秒请求数
TPS
Transactions Per Second,意思是每秒事务数
事务包含三个过程
- 向服务器发起请求
- 服务器内部处理
- 服务器返回结果给客户段
二、如何统计
1、QPS
前置知识
官方地址:https://dev.mysql.com/doc/refman/5.7/en/server-status-variables.html
可以通过官方提供的几个变量来统计
- Queries
服务器执行的语句数,包括存储程序中执行的语句,不统计COM_PIN、GCOM_STATISTICS命令。 - Questions
服务器执行的语句数, 仅包括客户端发送到服务器的语句,不统计COM_PING、COM_STATISTICS、COM_STMT_PREPARE、COM_STMT_CLOSE、COM_STMT_RESET命令。 - Uptime
服务器已启动的秒数
实际生产中,一般选取的是Queries变量,下面我们也是用这个来统计
方法
执行两次下面的命令,计算差值即可
show global status where variable_name in('Queries','uptime');
示例
mysql> show global status where variable_name in('Queries','Uptime');
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| Queries | 210350767 |
| Uptime | 2156149 |
+---------------+-----------+
2 rows in set (0.06 sec)
mysql> show global status where variable_name in('Queries','Uptime');
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| Queries | 210356995 |
| Uptime | 2156150 |
+---------------+-----------+
2 rows in set (0.06 sec)
qps = (210356995 - 210350767 )/(2156150 - 2156149 ) = 6228
2、TPS
思路
思路1
计算增删改查总和
采用以下命令来统计,计算差值,具体参考QPS的计算示例
show global status where variable_name in('Com_insert','Com_delete','Com_update','Com_select','Com_delete_multi','Com_update_multi','Uptime');
想想就不合理,因为一个事务可能包含多个操作
思路2
计算事务提交和回滚的总和,因为事务要么是提交,要么是回滚状态
采用以下命令来统计,计算差值,具体参考QPS的计算示例
show global status where variable_name in('Com_commit','Com_rollback','Uptime');
在MySQL中,事务是可以自动提交的,这种情况下,是统计不到的,所以这种方式也不对
但主从架构中,binlog是会自动补commit 语句,在复制到从库时,从库执行SQL,会带commit,所以可以去从库统计,或者监听binlog文件的变化。
思路3
有没有什么参数,记录了此刻的事务数?
查了资料,官方确实是有一个变量,Binlog_cache_use,表示使用了二进制日志缓存的事务数,每个事务可能包含多个操作(例如多个INSERT、UPDATE、DELETE语句),而这些操作会被缓存在二进制日志缓存中以待写入二进制日志文件,但它只统计了使用了缓存的事务数,并不能准确地代表实际的事务数,因为有些事务可能没有使用到缓存或者缓存已经被刷新到二进制日志文件中,所以也不太准确
思路4
GTID( Global Transaction Identifier)全局事务标识符,是MySQL中用于唯一标识每个事务的一个全局标识符。由两部分组成,分别是 source_id 和 transaction_id
- source_id:MySQL实例的唯一ID,由于会传递到slave,也可以理解为源ID
- transaction_id :事务ID,从 1 开始自增的序列号,一般表现为1-结束事务ID
作用:用于唯一标识每个事务并确保主从复制的数据一致性
扩展知识点
使用GTID进行主从复制时,主服务器会为每个事务分配一个唯一的GTID,并将GTID与该事务的binlog事件一起复制到从服务器上。从服务器会记录已经复制的最新的GTID,并在继续复制时检查该GTID,以确保只复制尚未复制的事务。
GTID还可以用于跨多个数据库实例的事务管理和故障转移。通过使用相同的GTID设置,可以确保来自不同数据库实例的事务具有相同的全局标识,从而简化跨实例的事务管理和处理。
所以,可以通过计算GTID差值,这个可以说是目前最准确的
命令如下:
SELECT @@global.gtid_executed;
总结
方式1(推荐)
通过GTID计算事务差异
SELECT @@global.gtid_executed;
方式2
去从库进行统计,计算事务提交和回滚的总和
show global status where variable_name in('Com_commit','Com_rollback','Uptime');
方式3
监听binlog文件的变化进行统计
可以利用MySQL的binlog解析工具,如mysqlbinlog
或第三方工具(如Canal
、Maxwell
等)来解析binlog文件,并提取出其中的事务信息。然后根据事务的提交时间戳和事务包含的操作数量,可以计算出每秒处理的事务量(TPS)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)