Hekaton的神话与误解

最近这段时间,我花了很多时间来更好的理解Hekaton——SQL Sever 2014里的全新内存表技术。我看了很多文章,了解了Haktaon的各种内部数据存储结构(主要是哈希索引和Bw-tree)。另外我也看了不少关于这方面的讲座。

但不止一次,有很多的误报,神话和误解出现,人们对Hektaton的认识发生了错误。从大家对Hekaton的提问就可以看出,我们需要整理Hekaton的知识,向大家重新传达它的相关知识,让大家更好的理解Hekaton,在Hekaton合适的场景来更好的使用它。

下面只是一些我罗列听到的大家关于Hekaton的问题:

  • “Hekaton是内存存储技术,是否意味着数据不再永驻?”
  • “Hekaton只在特定架构的CPU里可以运行?”
  • “当你迁移到Hekaton,对于你的工作量,你会获得100倍的性能提升?”
  • “在Hekaton里,没有锁,阻塞,自旋锁。”

这只是在过去我听到的误解中,头条的一部分。因此这篇文章的目的澄清这些最大误解和问题,我也会告诉你为什么它们是错误的。嗯,让我们从我的最头条开始(没特定顺序)!

“对于事务,Hekaton也提供ACID属性么?”

当我开始讨论Hekaton时,这个总是我第一个想澄清的:当你使用Hekaton时,对于你的事务,它还是有ACID属性的!Hekaton里的事务一直是有原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)的。SQL Server只是内部使用不同的概念和方法来保证这4个重要属性。

  • 原子性(Atomicity):对于你处理的事务,还是可以前滚(rolled forward)和后滚(rolled back),即使你的SQL Server崩溃,对于你启用Hekaton的数据库,SQL Server还是可以通过故障修复(crash recovery )(只要通过SQL Server重启,你的数据还是持续的(persisting )——下面会详细描述)
  • 一致性(Consistency):Hekaton也提供“总是”有一致的数据。这个在当前很容易做到,因为Hekaton的最大局限性之一是不能创建外键(Foreign-Keys),只能本身约束。因此基本上启用Hekaton的表,是在内部进行约束的。
  • 隔离性(Isolation):几天前,有人想说服我,Hekaton提供你脏读(Dirty Reads),因为没有锁和阻塞(Locking and Blocking)。错了!!!Hekaton使用所谓的多版本并发控制(Multi Version Concurrency Control ,MVCC)的方法,才有没锁的神奇可能。当你读取数据的时候,你取回的是在你开始的语句/事务后不在有效的数据(取决于使用的事务隔离级别(Transaction Isolation Level))。因此在Hekaton里没有脏读(Dirty Reads)。
  • 持久性(Durability):这个要分情况。当你使用架构和数据(DURABILITY=SCHEMA_AND_DATA)持久性创建你的Hekaton表,在SQL Server崩溃时,数据还是存在的。它会从事务日志里恢复,即Hekaton写的检查点文件。这点非常重要:当你想要你的数据持久时,Hekaton还是会使用事务日志,这也意味着你的事务日志是Hekaton的最后性能瓶颈之一。当和传统基于传统硬盘的表相比,Hekaton这里使用非常高效的日志模型。这里其中一个改变是,只有数据修改被日志,不是在索引级别。当你在基于传统硬盘表里执行INSERT,SQL Server需要为“每个”索引(聚集和非聚集索引)的INSERT日志。在Hekaton里,SQL Server只日志一次INSERT,因为在SQL Server启动期间,所有的Hekaton索引(哈希索引,范围索引)都会重建。因此对事务日志的影响是尽可能小的。

当你使用只有架构,不包含数据(DURABILITY = SCHEMA_ONLY)的Hekaton表时,你的Hekaton事务的持久性就没有了:当你的SQL Server崩溃了,或者你重启SQL Server,在Hekaton表里的所有数据会丢失。因此没有持久性。因此在事务日志里也没有日志记录。当然这个用法只在特殊场景里使用才有意义,例如为你的数据仓库进行数据加载。如果SQL Server崩溃,你就要重启你的ETL进程。你是可以重建你丢失的数据。

“Hekaton是微软提供的No-SQL方法?”

这个误解也非常有意思。有人想说服我说Hekaton是微软开发的No-SQL的新方法。得了吧,使用Hekaton我们还是在讨论有所有ACID属性的关系数据库(参阅刚才说的)。Hekaton和No-SQL是2个完全不同的东西,也没有共同点。Hekaton内部使用优雅而快速的方法来实现关系数据库的特性——就这样!

“Hekaton只在特定架构的CPU上运行?”

哇哦,我想我站错了地方!Hekaton只在特定模型/架构上运行,因为Hekaton内部使用所谓的原子CAS运算(原子比较与交换Atomic Compare & Swap, or Atomic Compare & Exchange)。那句话是完全错误的!当然,内部的Bw-tree使用CAS运算作为多个原子步骤做出树里SMOs(结构修改运算,Structure Modification Operations)。Hekaton这里内部使用“InterlockedCompareExchange”的WIN32 API函数。这个函数只在特定内存位置的值和原始值比较,如果2个一样的话,在内存位置会写入新值。函数本身在CPU级别作为一个原子汇编指令执行,意味着没有别的线程可以干涉那个汇编函数。它作为一个原子块(atomic block)从开始到结束执行。

这里的神话是,需要的汇编函数只在特定CPU架构上支持。这没错,但是这个汇编函数从奔腾处理器开始就支持了!在386和486架构上,函数本身是不支持的……从刚才提到的MSDN文章里的要求部分看到,支持的最低系统版本是Windows XP!因此当你在前Windows XP系统里安装SQL Server 2014时,这个神话倒是真的!

“在Hekaton里,没有锁,阻塞,自旋锁。”

理论上这句话是对的。这句话可以从不同方面辩论。我们从第1个方面开始。Hekaton“本身”是没有锁,阻塞和自旋锁的,但是你还是和SQL Server的传统关系引擎打交道。这就意味着,当你离开Hekaton宇宙时,你还是和基于原始代码的SQL Server打交道(对此,我表示遗憾……),例如事务日志管理器( Transaction Log Manager)。这些代码还是有闩锁(latches)和自旋锁(spinlocks)用来保持不同线程访问的同步。从这个角度来说,上述语句是部分正确的。

第2个方面在Hekaton里你还是有阻塞(blocking)的地方是,当你进行原子CAS操作时,一个原子CAS操作不能被不同的线程中断。因此在Bw-Trees里SMOs(结构修改运算,Structure Modification Operations)可以以聪明、优雅的方式实现。着也意味着当你想在同个Bw-Tree里的同个页里同时执行一个SMO是,一个线程会胜出,其他的线程需要重试原子CAS操作。同时发生了什么呢?线程会旋转,再次尝试CAS操作。我的基本理解是,原子CAS操作本身是就像一个Criticial Section同步概念包装的汇编函数。这就意味着你的线程需要旋转,你在丢失CPU周期,并增加了你事务的闭锁性。当然,SMOs应该非常非常少见,因此这没什么大不了的——但还是有线程旋转的可能,当有为底层同步对象(或者汇编函数)的竞争时。

这是我在原子CAS操作上的基本理解。如果我对此的理解是错误的,欢迎随时纠正我!

“因为在Hekaton里不支持INT IDENTITY值,使用序列(Sequences)?”

这句也非常有意思。我没有在吹嘘这句话!为什么?因为在你的SQL Server数据库里,序列(Sequences)是一个共享对象,意味着访问的当前值是由SQL Server同步的。这个同步在竞争中结束,意味着你不能延伸你的工作量,Hekaton的一切都是延伸工作量。

我用序列值在CTP1上做过一些测试,一旦你在你的Hekaton表/存储过程上执行大量的并行线程,你就会触发序列生成器(Sequence Generator)里的竞争。当然在一些内部页,序列生成器(Sequence Generator)存储着当前值,当序列生成器读写这些特定页时,就会发生闩锁(latch) 。在序列生成器里,你就用闩锁竞争(Latch Contention)结束它了,你的Hekaton工作量也不会延伸。在我的测试里也没太大区别,如果我请求整个范围的序列值,或者当我使用缓存,也没有区别。序列生成器始终是瓶颈。

那你如何克服这个特定问题?使用老好朋友UNIQUEIDENTIFIER。这些值彼此间是完全独立生成的,意味着当你生成新值时,没有涉及到共享资源,因此你可以剔除这个瓶颈,直到你触发CPU 的100%的使用率(包括像事务日志,网络带宽等其他瓶颈)前,Hekaton的工作量是可以不断延伸的。

“对于你的程序,Hekaton是完全透明的(is completely transparent)。”

这句话是对的,只要你对数据库设计没想法。我刚才已提过,在第1个发布里不能创建外键(Foreign-Keys)来检查约束。我从没看过任何基于磁盘的表,可以逐个迁移到内存优化表(Memory-Optimized table)。还记得么,INT IDENTITY 值目前尚不支持。当你迁移到Hekaton时,你做的不只是简单的切换来获得100倍的性能提升。抱歉!

“对于你的程序,Hekaton是完全透明的。”

这句话是对的,只要你对数据库设计没想法。我刚才已提过,在第1个发布里不能创建外键(Foreign-Keys)来检查约束。我从没看过任何基于磁盘的表,可以逐个迁移到内存优化表(Memory-Optimized table)。还记得么,INT IDENTITY 值目前尚不支持。当你迁移到Hekaton时,你做的不只是简单的切换来获得100倍的性能提升。抱歉!

“对于范围索引(Range Indexes),Hekaton使用传统的B+树结构。”

错!范围索引使用所谓的Bw-Tree,这个当前SQL Server为聚集和非聚集索引使用的B+树结构几乎一样。Bw-tree是基于B-Link tree——大家可能有点迷糊了,和传统的B+树相比,Bw-Tree有3个重大不同:

  • 中间层的页存储大范围的键值,在下一层的页存储小范围的键值。因为在页上存储了大范围的键值,Smos(例如页分裂)可以在2个原子操作实现(通过2个原子CAS执行)。这个概念来自于B-Link tree的设计原则。
  • 页“从不”改变,因此这个会导致CPU缓存线无效,这个会穿越传播到整个内存架构,这是非常昂贵的(在浪费CPU周期这方面)。当Hekaton需要改变内存中的页,不会接触到原始内存位置,Hekaton只创建一个新的Delta记录,这就是修改操作。所谓的”页面映射表(Page Mapping Table)“指向新的Delta记录,Delta记录对应的原始记录并未修改。因为这个方式CPU缓存线无效可以避免。
  • 页大小是弹性的,并不是一直的8kb大小。

“在数据库里,Hekaton提供你超快的业务逻辑。”

从微软观点来说这个是对的,因为自SQL Server 2012起SQL Server是在CPU核心层授权的。你用的CPU周期越多,需要的CPU就越多,你付给微软的授权就越多。但从架构观点来说是错的!数据库处理的是存储和获取数据,但是数据库不是一个应用服务器,应用服务器才处理业务……想想看。当你有CPU竞争时,因为你在数据库服务器里运行大量的业务逻辑,你应该重构你的数据库,因此你把你的业务逻辑移向专用的应用服务器,作为SQL Server的授权完全不一样——你为操作系统付钱,这就是错的原因!

“我如何迁移我的整个SAP数据库到Hekaton。微软对此有提供工具么?”

当你想把整个数据库迁移到Hekaton时,请先好好想想。Hekaton是用来解决特定问题的,像闩锁竞争(Latch Contention)。只有把特定的表和存储过程迁移到Hekaton时才有意义——并不是“所有”的数据库!对于每个数据库对象(表,存储过程),SQL Server需要把它们编译和链接成对应的DLL文件(然后载入sqlservr.exe的运行空间,这样要花费时间)。当你重启你的SQL Server时或者进行故障群集转移时,也会执行编译和链接。这会直接影响你HA方式的目标恢复时间(Recovery Time Objective,RTO)

小结

我希望已经帮你澄清了Hekaton的一些神话,误报和误解。而且我一直强调的是:如果是“对的”问题,Hekaton可以帮解决;如果你有传统的问题(错误的索引设计,糟糕的存储性能)果断放弃Hekaton吧,先做好你的家庭作业先。

Hekaton就像F1赛车:

你技术不好的话,F1赛车也帮不了你!

感谢关注,期待您的留言!

时间: 2024-10-12 23:58:36

Hekaton的神话与误解的相关文章

事务隔离级别神话与误解

在今天的文章里我想谈下SQL Server里现存的各种事务隔离级别的神话和误解.主要我会谈谈下列话题: 什么是事务隔离级别(Transaction Isolation Levels)? NOLOCK从不阻塞!? 提交读(Read Committed)不会持锁!? Key Range Locks只针对可串行化?! 好,让我们从第1个开始奠定SQL Server里事务隔离级别的基础. 什么是事务隔离级别(Transaction Isolation Levels)? 每次当我站在客户角度,处理各类乱七

第17/24周 悲观并发控制(Pessimistic Concurrency)

大家好,欢迎回到性能调优培训.今天标志着第5个月培训的开始,这个月我们会谈论SQL Server里的锁.阻塞和死锁(Locking, Blocking, and Deadlocking). SQL Server提供悲观和乐观并发控制模式,它们用来定义并发查询的执行.这期我会给你讲解悲观并发控制模式里各种隔离级别概况,下周我会进一步介绍自SQL Server 2005起引入的乐观隔离级别情况. 悲观隔离级别(Pessimistic Isolation Levels) 悲观隔离级别意味着读查询(SE

揭开IaaS云移动性的神话-【软件和信息服务】2014.05

生活中的很多事情极具欺骗性,包括最近刚刚看到专家的确认:自己的脐带血不能救自己.这样的事情同样发生在IT界,最近经常听到关于IaaS一些不切实际的想法,认为IaaS云上的负载可以简单地到处飘移,比如可以毫无障碍地跨越不同的服务商和私有云数据中心进行飘移.经常听到的几个典型说法包括: 我们使用了OpenStack,因此您的负载可以在任何地方自由翱翔: 我们使用了开源的Hypervisor, 因此您的负载可以在任何地方自由翱翔: 我们支持OVF(Open Virtual Format)标准格式的导入

《人月神话》小记

本文仅表达一下自己读完此书后留下的某些印象深刻的片段和自己的一点想法,若有错误还望各位同学老师指正.   从社会角度,软件的开发作为360行中的一行,和其他行业一样具有相似的社会特性,比如追求利益,批量化,产业化的生产等,当然每个行业都不是非常纯净的,从事软件的开发毕竟会走上社会化这条道路,如今评判一个软件好坏的标准竟然是那单一的下载量,我们生产我们学习方向和侧重点不能仅仅如此.   职业的苦恼与乐趣,我认为应该是也大于苦,舅舅今年30程序员一枚,每天坐在电脑面前8小时看起挺苦样子,但他却乐此不

《人月神话》读书笔记 第1篇

<人月神话>读书笔记 第1篇 第1章:焦油坑 第2章:人月神话 第3章:外科手术队伍 第4章:贵族专制.民主政治和系统设计 第5章:画蛇添足 第6章:贯彻执行 第7章:为什么巴比伦塔会失败 第8章:胸有成竹 继<梦断代码>之后,我又选了一本老师推荐的关于软件工程的书——<人月神话>,这本书读起来相对<梦断代码>就轻松多了,可能是翻译得较为通俗,并且每章前都有个寓言或者名句作为引子.并且举了相似的例子来说明,同样也列出了对立的情况来证实一些道理. 开篇书中提到

读&lt;&lt;人月神话&gt;&gt;

这本书在软件领域知名度很高,每次看到年度推荐的文章里面都有这本书且强烈推荐.出版30年了,可谓经典. 但我在读的过程中并没有那么深的体会.书中很多章节都是基于大型项目或者大型系统的经验总结,至今为止我还没有参与大于30人的项目.只能说自己的境界还不够. 第一章,焦油坑 再也找不到一个词比焦油坑更能形容,软件开发的过程了.我们都在挣扎.计划,计划,不断计划,但还是拖延,拖延,拖延.... 职业的乐趣: 创造性,贡献助人为乐,过程的魅力或者解决问题的成就感或写代码的快感,持续学习新事物,驾驭感. 职

javascript this的一些误解

太拘泥于"this"的字面意思就会产生一些误解.有两种常见的对于this 的解释,但是它们都是错误的. 介绍之前先解释下什么是动态作用域 简要地分析一下动态作用域,重申它与词法作用域的区别.但实际上动态作用域是JavaScript 另一个重要机制this 的表亲.词法作用域是一套关于引擎如何寻找变量以及会在何处找到变量的规则.词法作用域最重要的特征是它的定义过程发生在代码的书写阶段(假设你没有使用eval() 或with).动态作用域似乎暗示有很好的理由让作用域作为一个在运行时就被动态

投资银行的IT部门——不同之处与常见误解

投资银行的IT部门——不同之处与常见误解 说了这么多投资银行,投行里面的IT部门究竟是做什么的呢?在过去,投资银行仅靠纸.笔.计算器就能做生意了.但是在今天,所有的部门都要依靠IT技术.交易部门甚至是严重依赖IT技术. 我们可以从两个方面来看IT部门. 从工作的内容上,可以分为系统支持(System Analyst)和开发员(Application Developer).前者和其他公司的IT基本相同,需要维护公司内部的局域网.设备等等.与开发员相比,系统支持的数量要少很多.开发员的职责是开发公司

《人月神话》读后感

这个学期选择软件冲程这门课我受益匪浅.在这段学习的过程中读完了一本人月神话则是我认为最有价值的经理. 在软件领域中,很少能有像<人月神话>一样具有深远影响力和畅销不衰的著作.作者布鲁克斯被誉为“IBM System/360之父”,他曾是这一系统的项目经理,后来在设计期任360操作系统的项目经理.由于这一工作,他与Bob Evans和Erich Bloch 1985年曾获美国国家技术奖.Brooks博士早期曾担任IBM公司Stretch和Harvest计算机的体系结构设计师.1999年,他还荣获