SQLSERVER独特的任务调度算法"SQLOS"
SQLSERVER独特的任务调度算法"SQLOS" 微软开发SQLOS 的背景: SQLSERVER作为一个企业级数据库平台,一个基本的要求就是要有能力顺畅地同时处理成百上千的用户请求,SQLSERVER要使线程调度 得更加适应高并发的数据库应用。 由于以上背景: SQLSERVER在Windows
SQLSERVER独特的任务调度算法"SQLOS"
微软开发SQLOS的背景:
SQLSERVER作为一个企业级数据库平台,一个基本的要求就是要有能力顺畅地同时处理成百上千的用户请求,SQLSERVER要使线程调度
得更加适应高并发的数据库应用。
由于以上背景:
SQLSERVER在Windows的基础上开发出了一套自己的任务调度机制。所以SQLSERVER作为一个应用程序,又抽象出一般由操作系统代为
管理的功能,例如:
任务调度管理子系统
内存管理
错误,异常处理机制
死锁侦测和解决机制
运行第三方代码(dll,extended SP等)机制
SQLSERVER的管理功能组件又叫SQLOS SQL OPERATING SYSTEM ,而内存管理和任务调度管理是SQLOS的两大核心内容
对于SQLSERVER来讲,除了从DAC dedicated administrator connection过来的连接,其他用户连接对SQL来讲都是同等重要的,
而这样的连接在同一个时间点,可能会有成百上千。 所以SQLSERVER完全依赖Windows任务调度是不行的。
SQLSERVER的这一套任务调度机制的特点:
1、只有需要运行任务的连接才会被分配线程。出于空闲状态的连接,在SQLSERVER里会以一组数据结构表示,所以不会占用线程资源。大大降低
SQLSERVER进程需要的线程数目
2、对于每一个CPU,SQLSERVER内部会有一个调度(scheduler),由这个scheduler决定在某个时间点,到底是哪个SQLSERVER线程去运行。
所以在Windows层面,每个CPU最多只会对应一个处于运行状态的线程。大大降低Windows层面的上下文切换context switch
实践证明:很多有着1000~2000个并发用户的SQLSERVER,线程数也只需要一两百个。SQLSERVER完成的批处理量每秒钟可以达到3000~4000个。
SQLOS的几个概念:
scheduler
对于每个逻辑CPU,SQLSERVER会有一个scheduler与之对应,在SQL层面上代表CPU对象,只有拿到scheduler所有权的任务worker才能在这个逻辑CPU上运行
所谓逻辑CPU,就是SQLSERVER从Windows层面上看到的CPU数目,如果是一个双核的CPU,那么一个物理CPU在SQL看来就是两个逻辑CPU。如果系统还使用了
超线程hyper-threaded ,那对SQLSERVER来讲就是4个逻辑CPU
规则: 每个scheduler上的最大worker数目等于SQLSERVER的最大线程数除以scheduler的数目 ,在同一个时间点,只能有一个拥有scheduler的worker处于运行
状态,其他worker都必须处于等待状态。这样能降低每个逻辑CPU上的处于正在运行状态的线程数目,降低context switch,提供可扩展性
scheduler是SQLSERVER的一个逻辑概念,他不与物理CPU相绑定。也就是说,一个scheduler可以被Windows安排一会儿在这个CPU上,一会儿在那个CPU上。
但是,如果在sp_configure里设置了CPU affinity mask,那么scheduler就会固定在某个特定的CPU上
worker
每个worker跟一个线程(或纤程fiber)相对应,是SQLSERVER任务的执行单位。SQLSERVER不直接调度线程/纤程,而是调度worker,使得SQLSERVER能够控制
任务调度
规则: 每个worker会固定代表一个线程(或纤程),并且和一个scheduler相绑定。如果scheduler是固定在某个CPU上的(通过设置CPU affinity mask),那么
worker也会固定在某个CPU上
每个scheduler有worker的上限值,并且可以根据SQLSERVER工作负荷创建或释放worker,每次worker都会去运行一个完整的任务(task)。在任务做完之前不会
退出,除非这个任务主动进入等待状态。
scheduler只在有新任务要运行,而当前没有空闲的worker的情况下,才会创建新的worker。
某个worker空闲超过15分钟,scheduler可能会删除这个worker,以及其对应的线程。当SQLSERVER遇到内存压力的时,也会大量删除处于空闲状态的worker,以
节省multi-page的内存开销
各种CPU和SQLSERVER版本组合自动配置的最大工作线程数
CPU数 32位计算机 64位计算机
8 288 576
16 352 704
32 480 960
task
在worker上运行的最小任务单元。最简单的task就是一个简单batch。例如,客户发过来下面的请求:
<span>1</span> <span>SELECT</span> <span>@@SERVERNAME</span> <span>2</span> <span>GO</span> <span>3</span> <span>SELECT</span> <span>GETDATE</span><span>() </span><span>4</span> <span>GO</span>
那么这两个batch就分别是两个task。SQLSERVER会先分配给第一个batch(select @@servername)一个worker,将结果返回给客户端,再分配第二个batch
(select getdate())一个worker。这两个worker可能是不同的worker,甚至在不同的scheduler上
只要一个task开始运行,他就不会从这个worker上被移出。例如,如果一个select语句被其他连接阻塞住,worker就不能继续运行,只能进入等待状态。但是这个
select task 不会将这个worker释放,让他做其他任务。所以结果是这个worker所对应的线程会进入等待状态
yielding
SQLOS的任务调度算法的核心,就是所有在逻辑scheduler上运行的worker都是非抢占式的 (non-preemptive)。worker始终在scheduler上运行,直到他运行结束,或者主动将scheduler让出给其他worker为止。这个“让出”scheduler的动作,我们叫yieding
每个scheduler都会有一个runnable列表,所有等待CPU运行的worker都会在这个列表里排队,以先进先出的算法,等待SQL分配给他scheduler运行
SQLSERVER定义了很多yieding的规则,约束一个task在scheduler运行的时间。如果task比较复杂,不能很快完成,会保证task在合适的时间点做yieding,不至于占用scheduler太多时间。
常见时间点:
1、当worker每次要去读数据页的时候,SQLSERVER会检查这个worker已经在scheduler上运行了多久,如果已经超过4ms,就做yielding
2、每做64KB的结果集排序,就会做一次yielding
3、在做语句编译compile的过程中(这个过程比较占CPU资源),经常会有yieding
4、如果客户端不能及时把结果集取走,worker就会做yieding
5、一个batch里的每一句话做完,都会做一次yieding
正常来讲,哪怕一个task要做很久,他使用的worker是会经常做yieding的,不会长时间占用CPU不放。如果在一个scheduler上同时有很多worker要运行,
SQLSERVER通过worker自动yielding的方式调度并发运行。这个比Windows用上下文切换context switch更有效
下面用图来说明SQLOS的任务调度算法:
总结:
对于每个CPU,SQLSERVER都会有一个scheduler与之对应。在每个scheduler里,会有若干个worker,对应
于每个线程。在客户端发过来请求之后,SQL会将其分解成一个或多个task。根据每个scheduler的繁忙程度,
task会被分配到某个scheduler上。如果scheduler里有空闲的worker,task就会被分配到某个worker上。
如果没有,scheduler会创建新的worker,供task使用。如果scheduler里的worker已经到了他的上限值,
而他们都有task要运行,那么新的task只好进入等待worker的状态
使用下面两个SQL语句可以查看当前SQLSERVER有多少个workers在工作,有多少个tasks在运行
<span>1</span> <span>SELECT</span> <span>*</span> <span>FROM</span><span> sys.dm_os_workers </span><span>2</span> <span>SELECT</span> <span>*</span> <span>FROM</span> sys.dm_os_tasks
----------------------------------------------------------华丽的分割线---------------------------------------------------------
说一下上面的图的含义
SELECT * FROM sys.dm_os_workers
其他列的解释大家可以看一下MSDN
http://msdn.microsoft.com/zh-cn/library/ms178626(v=SQL.105).aspx
------------------------------------------------------------------------------------------------------------
SELECT * FROM sys.dm_os_tasks
任务的状态可以是下列选项之一:
PENDING:正在等待工作线程。
RUNNABLE:可运行,但正在等待接收量程。
RUNNING:当前正在计划程序中运行。
SUSPENDED:具有工作线程,但正在等待事件。
DONE:已完成。
SPINLOOP:陷入自旋锁
MSDN的解释:http://msdn.microsoft.com/zh-cn/library/ms174963(v=SQL.105).aspx
很久没有写文章了,希望大家看了我的文章能够更加深入了解SQLSERVER
要睡了,熬不住了~
----------------------------------------------------------
2013-6-3补充
附网上流传的手稿图一张
2014-2-2补充:
SQLOS所用的DLL

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제









SQL Server 데이터베이스에 이미 존재하는 동일한 이름을 가진 개체의 경우 다음 단계를 수행해야 합니다. 개체 유형(테이블, 뷰, 저장 프로시저)을 확인합니다. IF NOT EXISTS를 사용하면 객체가 비어 있는 경우 생성을 건너뛸 수 있습니다. 개체에 데이터가 있는 경우 다른 이름을 사용하거나 구조를 수정하세요. 기존 개체를 삭제하려면 DROP을 사용하세요. 주의하세요. 백업을 권장합니다. 삭제되거나 이름이 바뀐 개체에 대한 참조가 없는지 확인하려면 스키마 변경 사항을 확인하세요.

가져오기 단계는 다음과 같습니다. MDF 파일을 SQL Server의 데이터 디렉터리(일반적으로 C:\Program Files\Microsoft SQL Server\MSSQL\DATA)에 복사합니다. SSMS(SQL Server Management Studio)에서 데이터베이스를 열고 연결을 선택합니다. 추가 버튼을 클릭하고 MDF 파일을 선택합니다. 데이터베이스 이름을 확인하고 확인 버튼을 클릭합니다.

SQL Server 서비스가 시작되지 않는 경우 해결해야 할 몇 가지 단계는 다음과 같습니다. 오류 로그를 확인하여 근본 원인을 확인합니다. 서비스 계정에 서비스를 시작할 수 있는 권한이 있는지 확인하세요. 종속성 서비스가 실행 중인지 확인하세요. 바이러스 백신 소프트웨어를 비활성화합니다. SQL Server 설치를 복구합니다. 복구가 작동하지 않으면 SQL Server를 다시 설치하십시오.

SQL Server 포트 번호를 보려면 SSMS를 열고 서버에 연결합니다. 개체 탐색기에서 서버 이름을 찾아 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다. 연결 탭에서 TCP 포트 필드를 확인하세요.

실수로 SQL Server 데이터베이스를 삭제한 경우 다음 단계를 수행하여 복구할 수 있습니다. 데이터베이스 활동 중지, 데이터베이스 로그 확인, 백업에서 복원, DBCC CHECKDB 사용 파티 도구. 데이터 손실을 방지하려면 데이터베이스를 정기적으로 백업하고 트랜잭션 로깅을 활성화하십시오.

SQL Server 설치가 실패하면 다음 단계에 따라 정리할 수 있습니다. SQL Server 제거 레지스트리 키 삭제 파일 및 폴더 삭제 컴퓨터를 다시 시작합니다.

다음 단계에 따라 SQL Server 영어 설치를 중국어로 변경할 수 있습니다. SQL Server 서비스를 중지하고, 인스턴스 언어를 변경하고, 응용 프로그램을 다시 시작합니다.

C++의 기계 학습 알고리즘이 직면하는 일반적인 과제에는 메모리 관리, 멀티스레딩, 성능 최적화 및 유지 관리 가능성이 포함됩니다. 솔루션에는 스마트 포인터, 최신 스레딩 라이브러리, SIMD 지침 및 타사 라이브러리 사용은 물론 코딩 스타일 지침 준수 및 자동화 도구 사용이 포함됩니다. 실제 사례에서는 Eigen 라이브러리를 사용하여 선형 회귀 알고리즘을 구현하고 메모리를 효과적으로 관리하며 고성능 행렬 연산을 사용하는 방법을 보여줍니다.
