【问题标题】:When should we be concerned about Disk I/O?我们什么时候应该关注磁盘 I/O?
【发布时间】:2018-11-24 19:22:27
【问题描述】:

我们的 Web 应用程序每天 8 小时处理大量并发请求。此时,根据性能监视器,磁盘 I/O(特别是 tempdb 数据库日志文件)达到每秒 470 次读写。当此数字超过 500 时,性能监视器会将磁盘标记为繁忙。但使用的磁盘是高性能 SSD 驱动器,额定处理高达 5000 IOPS,托管在 AWS 上。

所以我的问题是磁盘可以在最多 8 小时内每秒进行 500 次读写吗?

【问题讨论】:

    标签: sql-server disk


    【解决方案1】:

    我认为您需要改变处理问题的方法,首先开始查看 SQL Server 中与 IO 相关的数字,例如 IO 延迟等指标。

    默认情况下,SQL Server 会为您收集此信息,如果您在 SQL Server 中看到较大的延迟,则继续使用 Server 并开始收集性能计数器和其他内容。

    没有考虑磁盘类型,工作负载等情况,没有数字太好或太坏。

    我建议,首先确保您尽可能遵循所有最佳实践,例如:

    1. Tempdb 的专用驱动器。
    2. 用于您的 tempdb 的多个数据文件(4-8 通常是一个不错的数字)。
    3. 启用跟踪标志 1118 和 1117。
    4. 用于所有数据库的数据文件的专用驱动器。
    5. 所有数据库的日志文件专用驱动器。
    6. 自动增长设置为正常的 MB 数,而不是默认的 10%。
    7. 还有一些其他的东西,只需 google 一下,你就会在网上找到很多东西。

    按照最佳实践中的定义设置数据库设置后,然后开始使用 SQL Server DMV 查看每个驱动器的 IO 延迟。我通常用来检查延迟的查询是:

    SELECT tab.[Drive], tab.volume_mount_point AS [Volume Mount Point], 
        CASE 
            WHEN num_of_reads = 0 THEN 0 
            ELSE (io_stall_read_ms/num_of_reads) 
        END AS [Read Latency],
        CASE 
            WHEN num_of_writes = 0 THEN 0 
            ELSE (io_stall_write_ms/num_of_writes) 
        END AS [Write Latency],
        CASE 
            WHEN (num_of_reads = 0 AND num_of_writes = 0) THEN 0 
            ELSE (io_stall/(num_of_reads + num_of_writes)) 
        END AS [Overall Latency],
        CASE 
            WHEN num_of_reads = 0 THEN 0 
            ELSE (num_of_bytes_read/num_of_reads) 
        END AS [Avg Bytes/Read],
        CASE 
            WHEN num_of_writes = 0 THEN 0 
            ELSE (num_of_bytes_written/num_of_writes) 
        END AS [Avg Bytes/Write],
        CASE 
            WHEN (num_of_reads = 0 AND num_of_writes = 0) THEN 0 
            ELSE ((num_of_bytes_read + num_of_bytes_written)/(num_of_reads + num_of_writes)) 
        END AS [Avg Bytes/Transfer]
    FROM (SELECT LEFT(UPPER(mf.physical_name), 2) AS Drive, SUM(num_of_reads) AS num_of_reads,
                 SUM(io_stall_read_ms) AS io_stall_read_ms, SUM(num_of_writes) AS num_of_writes,
                 SUM(io_stall_write_ms) AS io_stall_write_ms, SUM(num_of_bytes_read) AS num_of_bytes_read,
                 SUM(num_of_bytes_written) AS num_of_bytes_written, SUM(io_stall) AS io_stall, vs.volume_mount_point 
          FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vfs
          INNER JOIN sys.master_files AS mf WITH (NOLOCK)
          ON vfs.database_id = mf.database_id AND vfs.file_id = mf.file_id
          CROSS APPLY sys.dm_os_volume_stats(mf.database_id, mf.[file_id]) AS vs 
          GROUP BY LEFT(UPPER(mf.physical_name), 2), vs.volume_mount_point) AS tab
    ORDER BY [Overall Latency];
    

    您应该首先查看的数字是 Overall Latency,考虑到它是 SSD,您的总体延迟理想情况下应该小于 5。但即使超过 5 也不一定是坏数字。

    同样,这取决于工作量。如果有很多查询访问 tempdb(这在 OLTP 数据库中不应该真的发生),那么您可能需要开始查看您的代码并尝试优化经常访问 tempdb 的查询。

    长话短说,与其先查看性能计数器,然后再尝试找出是否存在问题,为什么不先询问 SQL Server 最困扰它的问题并尝试先解决该问题 :)

    尽管我的回答对于一个非常简短的问题来说看起来很长,但请相信我,在您得出任何结论之前,还有很多事情要做,还有很多事情要考虑。我的建议是阅读有关如何收集 SQL Server 指标以及如何将它们转化为真实结论的信息。

    没有任何一个指标可以单独得出一个问题或解决一个问题,它是一个企业应用程序,您需要在其上下文中查看很多东西才能得出有意义的结论。希望这可以帮助。

    【讨论】:

    • UV 来自我,但我会链接到关于您的要点的一些博客,因为我怀疑 OP 会知道他为什么需要专用驱动器(理想情况下是 SSD)、多个数据文件等。
    • M.Ali - 感谢您的意见!我一直在使用 DMV 查询来获取其他指标,但不太确定哪一个对测量任何磁盘压力有用。我想我可能使用了 sys.dm_io_virtual_file_stats,并没有看到任何惊人的数字。但我今天会再试一次!实际上,我已经实现了您的许多建议-(1)我有 8 个临时数据库数据文件(2)临时数据库和应用程序数据库的数据文件在 1 个驱动器上(3)临时数据库和应用程序数据库的日志文件在另一个驱动器上。 (4) 我尝试设置跟踪标志 1117 和 1118。(5) 自动增长设置为 300MB。
    • @SGK,欢迎您,起点应该是总体延迟,如果这个数字是可以接受的,那么转到其他指标,但如果它是一个很大的数字,那么深入挖掘并找出导致的原因整体延迟,无论是写入还是读取等。
    • @M.Ali - 我们有这个存储的过程,每个用户每 3 秒调用一次。这个存储过程确实创建了表变量和表值 sql 函数——这就是在 tempdb 上创建临时表的原因,并导致 tempdb 日志记录是我的猜测。我正在尝试消除其中一些临时表的使用,但由于逻辑原因,我确实需要其中一些。
    • 我认为你误读了我的建议,我建议为 tempdb(数据和日志文件)准备一个专用驱动器,将其放在尽可能快的驱动器、SSD 或 Fusions IO 驱动器上。另外,不要使用 300MB,而是使用 256MB 或 512MB(正确的位计算数)作为文件增量大小。
    猜你喜欢
    • 2011-03-21
    • 2011-01-18
    • 1970-01-01
    • 2021-09-07
    • 2019-12-07
    • 2014-05-20
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    相关资源
    最近更新 更多