【MySQL】计算 TPS,QPS 的方式

本文通过模拟数据库在高峰期和低谷期的压力波动,并利用memcached缓存查询结果的方法,探讨了如何平滑数据库请求峰值,减轻服务器负载。通过实验对比不同缓存策略的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、最好的优化-----不查询!

这不是开玩笑.

如果一台服务器出现长时间负载过高 /周期性负载过大,或偶尔卡住,如何来处理?

大的思路--------

        是周期性的变化还是偶尔问题?

       是服务器整体性能的问题还是某单条语句的问题?

       具体到单条语句这条语句是在等待上花的时间,还是查询上花的时间.

       唯一的办法-----监测并观察服务器的状态.

    

1:观察服务器状态一般用如下2个命令

Show status;  Show processlist;

: mysql> show status;

   #mysqladmin ext (功能相同)


二、那我们来做一个实验:MySQL周期性波动试验


(一)、实验目的模拟数据库高低峰时的压力波动,并会观察绘制波动曲线

(二)、实验思路反复查询数据库并缓存入memcached, 缓存定期失效,

(三)、观察记录服务器参数,并作图表.

(四)、实验准备: nginx+php+memcached+awk+ab

    1: index.php  (随机访问3W条热数据,并储存在memcached

    2: memcached (储存查询结果)

    3: ab 压力测试工具

    4: awk脚本


三、实验步骤: 


总数据1300W以上,热数据3W,50个并发,每秒请求500-1000

请求结果缓存在memcache,生命周期为60秒,

(生命周期要结合请求周期来制定,比如3万条数据随机,每秒1000,30秒能走一遍,生命周期可设为60)

观察mysql连接数,每秒请求数的周期变化.



再打开一个窗口

50个并发,200000个总请求


缓存热数据脚本

[php]  view plain copy
  1. <?php  
  2.   
  3. // 30K hot news  
  4. $rangeid = rand(1,30000)+13000000;  
  5.   
  6. $mconn = memcache_connect('localhost',11211);  
  7.   
  8. if( ($com = memcache_get($mconn,$rangeid)) === false) {  
  9.  $conn = mysql_connect('localhost','root');  
  10.   
  11.  $sql = 'use bigdata';  
  12.  mysql_query($sql,$conn);  
  13.   
  14.  $sql = 'set names utf8';  
  15.  mysql_query($sql,$conn);  
  16.  $sql = 'select id,name,brief from lx_com where id=' . $rangeid;  
  17.   
  18.  $rs = mysql_query($sql,$conn);  
  19.  $com = mysql_fetch_assoc($rs);  
  20.   
  21.  memcache_add($mconn , $rangeid , $com , false, mt_rand(40,120));  
  22. else {  
  23.   echo 'from cache';  
  24. }  
  25. print_r($com);  

统计脚本status.sh

[php]  view plain copy
  1. #!/bin/bash  
  2. while true  
  3. do  
  4. mysqladmin -uroot ext|awk '/Queries/{q=$4}/Threads_connected/{c=$4}/Threads_running/{r=$4}END{printf("%d %d %d\n",q,c,r)}' >> status.txt  
  5. sleep 1  
  6. done  

让memcached后台运行

ab压力测试

在Excel画出图表

解决办法

1: 减少无关请求(业务逻辑层面,暂不讨论,但其实是最有效的手段)

2: 如果请求数是一定的,不可减少的我们要尽量让请求数平稳,不要有剧烈波动.

很多时候,不是服务器撑不住总的查询量,而是在某个时间段撑不住高峰请求.

----夜间负载低时,集中失效

短时间内会有波峰,但夜间访问量少,因此波峰并不剧烈,当到上午10点左右人多时,缓存已经建立了一部分白天时,波峰也不剧烈

或者让缓存的生命周期在一定范围内随机,也可以减缓波峰剧烈的情况

我们把实验中的生命周期由80,改为[40-120],其他实验条件不变.

得到如下曲线


可以看出,稳定运行后,请求在[1000-1500]之间波动,

而固定缓存周期是,请求在[500-1700]之间波动.


转载 :http://blog.youkuaiyun.com/wuming19900801/article/details/42193671

<think>我们计划创建一个监控MySQL TPSQPS的Shell脚本。TPS(Transactions Per Second)指每秒事务数,QPS(Queries Per Second)指每秒查询数。 计算方式: 1. QPS = (当前Queries值 - 上一次Queries值) / 时间间隔 2. TPS = (当前Com_commit值 + 当前Com_rollback值 - 上一次Com_commit值 - 上一次Com_rollback值) / 时间间隔 注意:我们使用`mysqladmin extended-status`或直接查询`SHOW GLOBAL STATUS`来获取状态变量。 为了避免权限问题,我们将使用具有适当权限的用户(例如,具有PROCESS和SUPER权限的用户)来连接MySQL。 脚本设计: 1. 设置连接MySQL的参数(用户名、密码等) 2. 设置采样间隔(例如1秒)和采样次数(可选) 3. 获取初始状态值 4. 循环获取当前状态值,计算差值并输出QPSTPS 5. 格式化输出,包括时间戳 参考之前用户提供的脚本片段,我们注意到权限问题(需要SUPER或REPLICATION CLIENT权限)可能导致错误,因此我们将确保使用有足够权限的用户。 我们将编写一个易于使用且健壮的脚本。 脚本内容如下:</think># MySQL TPS/QPS监控脚本 以下是一个专业的MySQL TPS/QPS监控Shell脚本,基于MySQL性能优化最佳实践设计: ```bash #!/bin/bash # MySQL TPS/QPS监控脚本 v1.3 # 作者: 数据库性能优化专家 # 最后更新: 2023-10-15 # ===== 配置区域 ===== MYSQL_USER="monitor_user" # 监控专用用户 MYSQL_PASSWORD="secure_password" # 用户密码 MYSQL_HOST="localhost" # MySQL主机 MYSQL_PORT="3306" # MySQL端口 INTERVAL_SEC=1 # 采样间隔(秒) LOG_FILE="/var/log/mysql_tps_qps.log" # 日志文件路径 # ==================== # 创建日志目录 mkdir -p $(dirname "$LOG_FILE") # 初始化日志文件头 echo "Timestamp | QPS | TPS | Threads_conn | Threads_run | Uptime" > "$LOG_FILE" echo "----------------------+-------+-------+--------------+-------------+--------" >> "$LOG_FILE" # 验证MySQL连接 check_mysql_connection() { if ! mysqladmin -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" ping &>/dev/null; then echo "[错误] 无法连接到MySQL服务器" >&2 return 1 fi return 0 } # 获取MySQL状态变量 get_mysql_status() { mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" \ -sN -e "SHOW GLOBAL STATUS WHERE Variable_name IN ('Queries', 'Com_commit', 'Com_rollback', 'Threads_connected', 'Threads_running', 'Uptime')" } # 主监控函数 monitor_tps_qps() { # 获取初始状态值 prev_stats=$(get_mysql_status) [ -z "$prev_stats" ] && { echo "无法获取初始状态值"; return 1; } # 解析初始值 prev_queries=$(echo "$prev_stats" | awk '$1=="Queries"{print $2}') prev_commit=$(echo "$prev_stats" | awk '$1=="Com_commit"{print $2}') prev_rollback=$(echo "$prev_stats" | awk '$1=="Com_rollback"{print $2}') while true; do sleep "$INTERVAL_SEC" # 获取当前状态值 current_stats=$(get_mysql_status) [ -z "$current_stats" ] && continue # 解析当前值 current_queries=$(echo "$current_stats" | awk '$1=="Queries"{print $2}') current_commit=$(echo "$current_stats" | awk '$1=="Com_commit"{print $2}') current_rollback=$(echo "$current_stats" | awk '$1=="Com_rollback"{print $2}') threads_connected=$(echo "$current_stats" | awk '$1=="Threads_connected"{print $2}') threads_running=$(echo "$current_stats" | awk '$1=="Threads_running"{print $2}') uptime=$(echo "$current_stats" | awk '$1=="Uptime"{print $2}') # 计算QPSTPS qps=$(( (current_queries - prev_queries) / INTERVAL_SEC )) tps=$(( ( (current_commit - prev_commit) + (current_rollback - prev_rollback) ) / INTERVAL_SEC )) # 更新前值 prev_queries="$current_queries" prev_commit="$current_commit" prev_rollback="$current_rollback" # 格式化输出 timestamp=$(date +"%Y-%m-%d %H:%M:%S") printf "%-20s | %-5d | %-5d | %-12d | %-11d | %-6d\n" \ "$timestamp" "$qps" "$tps" "$threads_connected" "$threads_running" "$uptime" | tee -a "$LOG_FILE" done } # 主程序入口 main() { echo "=== MySQL TPS/QPS监控启动 ===" echo "配置:" echo " - 用户: $MYSQL_USER" echo " - 主机: $MYSQL_HOST:$MYSQL_PORT" echo " - 采样间隔: ${INTERVAL_SEC}秒" echo " - 日志文件: $LOG_FILE" echo "============================" # 检查连接 if ! check_mysql_connection; then exit 1 fi # 启动监控 monitor_tps_qps } main ``` ## 关键特性与计算原理 ### 1. 核心指标计算 - **QPS(每秒查询数)**: $QPS = \frac{\Delta Queries}{\Delta t} = \frac{Queries_t - Queries_{t-1}}{采样间隔}$ - **TPS(每秒事务数)**: $TPS = \frac{\Delta Com\_commit + \Delta Com\_rollback}{\Delta t} = \frac{(Com\_commit_t - Com\_commit_{t-1}) + (Com\_rollback_t - Com\_rollback_{t-1})}{采样间隔}$ ### 2. 附加监控指标 - **Threads_connected**: 当前连接数 - **Threads_running**: 活跃线程数 - **Uptime**: MySQL服务运行时间(秒) ### 3. 权限要求 脚本需要MySQL用户具有以下权限: ```sql GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'monitor_user'@'localhost'; ``` ## 使用说明 1. **配置脚本**: - 修改脚本顶部的配置区域 - 创建监控专用用户并授权 2. **运行监控**: ```bash chmod +x mysql_monitor.sh ./mysql_monitor.sh ``` 3. **示例输出**: ``` Timestamp | QPS | TPS | Threads_conn | Threads_run | Uptime ----------------------+-------+-------+--------------+-------------+-------- 2023-10-15 14:30:25 | 1250 | 85 | 32 | 8 | 86400 2023-10-15 14:30:26 | 1320 | 92 | 33 | 9 | 86401 ``` 4. **停止监控**:`Ctrl+C` ## 高级配置建议 1. **生产环境优化**: ```bash # 降低采样频率减轻负载 INTERVAL_SEC=5 # 使用UNIX socket连接 MYSQL_SOCKET="/var/run/mysqld/mysqld.sock" ``` 2. **集成到Zabbix**: 修改`get_mysql_stats_wrapper.sh`脚本,添加用户名参数: ```bash RES=$(mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -e 'SHOW SLAVE STATUS\G' | egrep '(Slave_IO_Running|Slave_SQL_Running):' | awk -F: '{print $2}' | tr '\n' ',') ``` ## 性能指标意义 | 指标 | 健康范围 | 告警阈值 | |------|----------|----------| | QPS | < 1000 | > 5000 | | TPS | < 200 | > 1000 | | Threads_running | < 10 | > 50 | | Threads_connected | < 50 | > 200 | > **注意**:阈值取决于具体硬件配置和业务需求,建议根据基线调整[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值