【案例】说说time_zone 带来的性能问题

一 背景  
   相信大家对time_zone参数的意义和使用方式并不陌生,MySQL 通过设置 time_zone来控制时区,不过本文从另外一个角度来了解该参数对系统性能的影响。认识到这个问题的起因是因为数据库出现usr cpu 增大,load 上升 ,thread running陡高等现象。还有另外一个同事发现的问题一个应用接口调用分布到不同的机器,但是性能存在差异。

二 分析过程
2.1 timezone的参数设置
我们常用的time_zone 有两种设置方式  SYSTEM  和UTC具体的时区比如+08:00,设置为SYSTEM表示数据库系统的时区和os 系统的时区一致。对于国内而言 我们一般选择东八区也即'+08:00' ,更加具体详细的信息请移步官方手册 time_zone  
2.2 性能压测

为了直观表现性能差异,这里使用mysqlslap 对同一个实例进行压测:80个并发会话 执行1000w次 select now()查询,得到不同参数模式下,消耗的时间。


[3306-RW-2Inst@rac1 ~]
 
$mysql -uroot -e 'select @@time_zone' 

+-------------+

| @@time_zone |

+-------------+

| SYSTEM |

+-------------+

[3306-RW-2Inst@rac1 ~]

$mysqlslap --no-defaults -uroot --create-schema=test -S/u01/my3306/run/mysql.sock --number-of-queries=10000000 --concurrency=80 ' --query=select now()' 

Benchmark

        Average number of seconds to run all queries: 47.706 seconds

        Minimum number of seconds to run all queries: 47.706 seconds

        Maximum number of seconds to run all queries: 47.706 seconds

        Number of clients running queries: 80

        Average number of queries per client: 125000 

结果说明 time_zone设置为SYSTEM时,80个并发会话查询1000w次 需要47.7秒。


[3306-RW-2Inst@rac1 ~]
 
$mysql -uroot -e 'select @@time_zone' 

+-------------+

| @@time_zone |

+-------------+

| +08:00 |

+-------------+

[3306-RW-2Inst@rac1 ~]

$mysqlslap --no-defaults -uroot --create-schema=test -S/u01/my3306/run/mysql.sock --number-of-queries=10000000 --concurrency=80 '--query=select now()' 

Benchmark

        Average number of seconds to run all queries: 30.039 seconds

        Minimum number of seconds to run all queries: 30.039 seconds

        Maximum number of seconds to run all queries: 30.039 seconds

        Number of clients running queries: 80

        Average number of queries per client: 125000 

结果说明 time_zone设置为+08:00时,80个并发会话查询1000w次 需要30秒, 性能明显比前者更好,有 30%+左右的提升
2.3 使用pt-pmp工具分析 
设置SYSTEM时 MySQL 比设置为+08:00 模式多了 一层时间转化的函数调用, __tz_convert,Time_zone_system::gmt_sec_to_TIME,gmt_sec_to_TIME,set_datetime导致cpu 使用率上升 ,sql执行时间变长 引发一些列的性能风暴效应。
$pt-pmp -p 150842
Sun Oct 11 16:10:05 CST 2015
61 __lll_lock_wait_private,_L_lock_2163,__tz_convert,Time_zone_system::gmt_sec_to_TIME,gmt_sec_to_TIME,set_datetime,Item_func_now::fix_length_and_dec,Item_func::fix_fields,setup_fields,JOIN::prepare,mysql_prepare_select,mysql_select,handle_select,execute_sqlcom_select,mysql_execute_command,mysql_parse,dispatch_command,do_handle_one_connection,handle_one_connection,start_thread,clone
搜索MySQL bugs 查看到一个 bug  中有一样的现象,设置为非系统默认的时区的性能比默认的高很多。

time_zone='SYSTEM'的pt-pmp 分析结果


time_zone='+08:00'的pt-pmp 分析结果


三 结论
 
  1  任何性能现象细致入微之后,满满的都是问题,需要细心深挖,探究问题本质。
  2  推荐大家将系统的time_zone修改为非默认值 ,比如+08:00 ,避免性能隐患。


### 正确配置 Django 的 TIME_ZONE 在 Django 中,`TIME_ZONE` 是用于定义默认时区的一个重要配置项。它决定了服务器运行环境中的时间表示方式以及未指定时区的时间对象的行为[^1]。 #### 配置 `TIME_ZONE` 在项目的 `settings.py` 文件中,可以通过如下方式进行设置: ```python # 设置默认时区为 UTC TIME_ZONE = 'UTC' ``` 如果希望使用其他时区(例如中国标准时间 CST),可以将其更改为 `'Asia/Shanghai'` 或者任何支持的 IANA 时区名称列表中的值。 #### 使用 `USE_TZ` 控制时区感知行为 除了 `TIME_ZONE` 外,还需要考虑另一个重要的配置项——`USE_TZ`。该参数控制是否启用时区感知(timezone-aware)的功能。当 `USE_TZ=True` 时,Django 将会以 UTC 存储所有时间数据,并自动完成客户端与数据库之间的时区转换[^2]。 推荐的做法是在生产环境中始终开启此选项 (`USE_TZ=True`),以便更好地支持多时区应用开发需求。 #### 数据库层面的影响 需要注意的是,在启用了 `USE_TZ=True` 后,对于模型字段如 `DateTimeField` 如果设置了属性 `auto_now_add=True` 或 `auto_now=True` ,则这些时间戳会被记录成带有时区信息的形式并保存到数据库里。 以下是带有这两个特性的例子: ```python from django.db import models class ExampleModel(models.Model): created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间") ``` 上述代码片段里的 `created_at` 和 `updated_at` 字段都将按照当前活动时区来填充具体时刻的数据。 #### 时间操作建议 为了确保应用程序能够正确处理不同时区下的业务逻辑,应该遵循以下几点最佳实践: - 始终以外部输入为基础进行本地化展示; - 利用 Python 的 pytz 库或者 zoneinfo (Python 3.9+) 来辅助实现复杂的跨区域调度任务; - 对于用户界面部分,则需依据实际访问者的偏好调整最终呈现样式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值