zoukankan      html  css  js  c++  java
  • sql server 任务调度与CPU

    一. 概述

        我们知道在操作系统看来, sql server产品与其它应用程序一样,没有特别对待。但内存,硬盘,cpu又是数据库系统最重要的核心资源,所以在sql server 2005及以后出现了SQLOS,这个组件是sqlserver和windows的中间层,用于CPU的任务调度,解决I/O的资源争用,协调内存管理等其它的资源协调工作。下面我来试着讲讲SQLOS下的Scheduler调度管理。

    二. CPU 的配置

        在Sql server 里点击数据库实例右键到属性,选择处理器进行配置。最大工作线程数的默认值是0 (注意这里配置的是worker它是对CPU的真正封装)。这使得SQL Server能够在启动时自动配置工作线程的数量。默认设置对于大多数系统是最好的。但是,根据您的系统配置,将最大工作线程数设置为一个特定的值有时会提高性能。当查询请求的实际数量小于最大工作线程数时,一个线程处理一个查询请求。但是,如果查询请求的实际数量超过最大线程量时,SQLServer会将Worker Threads线程池化,以便下一个可用的工作线程可以处理请求。

          配置如下图所示:

            

              也可以通过T-sql配置,下例通过sp_configure将max worker线程选项配置为900

    USE AdventureWorks2012 ;  
    GO  
    EXEC sp_configure 'show advanced options', 1;  
    GO  
    RECONFIGURE ;  
    GO  
    EXEC sp_configure 'max worker threads', 900 ;  
    GO  
    RECONFIGURE; 

        Max Worker Threads服务器配置选项不考虑的线程, 像高可用、Service Broker、 Lock 管理等其它。如果配置的线程数量超过了,下面的查询将提供关于系统任务产生的额外线程信息

           is_user_process = 0 表示系统任务,非用户任务。

    SELECT  s.session_id, r.command, r.status,  r.wait_type, r.scheduler_id, w.worker_address,  
    w.is_preemptive, w.state, t.task_state,  t.session_id, t.exec_context_id, t.request_id  
    FROM sys.dm_exec_sessions AS s  
    INNER JOIN sys.dm_exec_requests AS r  
    ON s.session_id = r.session_id  
    INNER JOIN sys.dm_os_tasks AS t  
    ON r.task_address = t.task_address  
    INNER JOIN sys.dm_os_workers AS w  
    ON t.worker_address = w.worker_address  
    WHERE s.is_user_process = 0;

        下面显示每个用户的活动会话数

    SELECT login_name ,COUNT(session_id) AS session_count  
    FROM sys.dm_exec_sessions 
    WHERE status<>'sleeping'
    GROUP BY login_name;  

        下表显示了各种CPU和SQLServer组合的最大工作线程的自动配置数量。

    Number of CPUs

    32-bit computer

    64-bit computer

    <= 4 processors

    256

    512

    8 processors

    288

    576

    16 processors

    352

    704

    32 processors

    480

    960

    64 processors

    736

    1472

    128 processors

    4224

    4480

    256 processors

    8320

    8576

        

      根据微软的建议:这个选项是一个高级选项,应该只由经验丰富的数据库管理员或经过认证的SQL Server专业人员更改。如果您怀疑存在性能问题,则可能不是工作线程的可用性。原因更像是I/O,这会导致工作线程等待。在更改最大工作线程设置之前,最好找到性能问题的根本原因。

    二.调度原理

      2.1 Scheduler任务调度

                  Sqlserver 的一个Scheduler对应操作系统上的一个逻辑CPU用于任务分配。调度分配从NUMA节点级别开始。基本算法是一个用于新连接的循环调度。当每个新的连接到达时,它被分配给基于循环的调度器。在相同的NUMA节点内,以最小的负载因子分配给调度器的新连接。

      2.2  Worker

         Worker又称为WorkerThread,每个Worker跟一个线程,是Sql server任务的执行单位。 多个Worker对应一个Scheduler,公式Workers=max worker threads/onlines scheduler。在一个Scheduler上,同一时间只能有一个Worker运行。例如4个处理器的64位操作系统,它的每个Scheduler的Worker是512/4=128。

      2.3  Task

        在Worker上运行的最小任务单元。最简单的Task就是一个简单的Batch,当一个会话发出一个请求时,Sql server会把这个请求拆分一个或多个任务(Tasks),然后关联对应个数的工作者线程(worker thread)。

                  例如下面是二个Task ,二个Task可能不是同一个Worker。二个Worker也可能不是同一个Scheduler.            

    select @@servername
    Go
    select getdate()
    GO

       每个Task线程都有3个状态:

        Running: 一个处理器在某个时间只能做一件事情,当一个线程正在一个处理器上运行时,这个线程的状态就是running。

        Suspended: 没有足够资源时,当前线程放弃占有处理器,变成挂起状态。

        Runnable: 一个线程已完成了等待,但还没有轮到它运行,就会变成runnable状态,这种信号等待(signal wait)

      2.4 Yielding

                    Yelding就是所有逻辑scheduler上运行的Worker都是非抢占式的, 在 Scheduler上Worker由于资源等待,让出给其它Worker就叫Yielding。

        下面讲述几种发生的状态:

        1. 当Woker在Scheduler上运行了超过4ms,就做Yielding。

        2. 每做64k的结果集的排序,就会做一次Yielding。

        3. 做语句Complie编译的过程中,这个过程比较占CPU资源时,经常会有Yielding等。

      2.5 调度关系图如下:

                  

      2.5  Task在调度运行图如下:

                     

    1. 当 Task 是Runnig时,它是Schedler的活动Worker。
    2. 当 Task只等待CPU运行时,它被放入Schedler可运行的队列中。
    3. 当 Task 在等待某个资源时(比如锁、磁盘输入/输出等)时,它处于“Suspended挂起状态” 状态。
    4. 如果Task Scheduler挂起状态完成了等待,那么它就会被放到Scheduler 的Runnable队列的末尾。
    5. 如果运行线程自动Yidlding让步,则将其放回Scheduler 的Runnable队列的末尾。
    6. 如果运行的线程需要等待某个资源,它将被调出Scheduler调度器并进入挂起状态Waiter list。
    7. 如果正在运行的线程完成它的工作,那么Runnable队列的顶部的第一个线程就变成了“运行”线程。

        

    三. 使用dmv任务查看

       3.1.  通过sys.dm_os_sys_info 查看scheduler与cpu的关系如下:

     SELECT cpu_count,max_workers_count,scheduler_count FROM sys.dm_os_sys_info

      

      3.2  查看最大Worker数  

    select max_workers_count from sys.dm_os_sys_info  

      3.3  查看Task与Worker关系

    --在每一个连接里,我们可能会有很多batch,分解成多个task以支持如并行查询
     select task_address,task_state,scheduler_id,session_id,worker_address  
     from sys.dm_os_tasks  where session_id>50
    
    select state,last_wait_type,tasks_processed_count,task_address, worker_address, scheduler_address
     from sys.dm_os_workers where  worker_address  =0x00000000043621A0

     

      3.4 查看Scheduler

    --scheduler_id<255 代表用户CPU,相反代表SYSTEM SCHEDULER
    SELECT
        scheduler_id,
        cpu_id,
        is_online,
        current_tasks_count,
        runnable_tasks_count,
        current_workers_count,
        active_workers_count,
        work_queue_count
      FROM sys.dm_os_schedulers
      WHERE scheduler_id < 255

      cpu_id:关联的cpu 。 CPU ID  >=255 这类Scheduler都用于系统内部使用。比如说资源管理、DAC、备份还原操作等。

       is_online: 0 调度器离线,1 在线。

      current_tasks_count:当前任务数,状态包括:(等待,运行,已完成)。

      runnable_tasks_count:以分配任务,并在可运行队列中等待被调度的任务数,使用率不高的情况下,这个值会是0。

      current_workers_count:此scheduler关联的线程数。包括处于空闲状态的线程work。

      active_workers_count:当前处理活动的线程数,它必须关联任务task,包括running,runnable,suspend。

      work_queue_count:队列中的任务task等待数,如果不为0,意味着线程用尽的压力。

           讲到这里,后面讲讲CPUf过高的分析...

    参考文献:

      Troubleshooting SQL Server Scheduling and Yielding

      Microsoft SQL Server企业级平台管理实践

      How It Works: SQL Server 2012 Database Engine Task Scheduling

  • 相关阅读:
    环境变量
    Python的简介和入门程序
    Mybatis的分页插件PageHelper的使用
    SQLyog 快捷键总结
    如何查看开发项目框架的版本信息
    Linux find命令示例 30
    转:数据库索引原理------MemCached
    array_merge 和 + 的区别
    [介绍]PHP设计模式:DAO(数据访问对象模式)
    PHP业务逻辑层和数据访问层设计
  • 原文地址:https://www.cnblogs.com/MrHSR/p/9087686.html
Copyright © 2011-2022 走看看