Blog

乐观协议的挑战

Content #

为啥乐观要改成悲观呢?主要是两方面的挑战,一是事务冲突少是使用乐观协议的前提,但这个前提是否普遍成立,二是现有应用系统使用的单体数据库多是悲观协议,兼容性上的挑战。

事务频繁冲突 #

事务冲突少这个前提,随着分布式数据库的适用场景越来越广泛,显得不那么有通用性了。

比如,金融行业就经常会有一些事务冲突多又要保证严格事务性的业务场景,一个简单的例子就是银行的代发工资。代发工资这个过程,其实就是从企业账户给一大批个人账户转账的过程,是一个批量操作。在这个大的转账事务中可能涉及到成千上万的更新,那么事务持续的时间就会比较长。如果使用乐观协议,在这段时间内,只要有一个人的账户余额发生变化,事务就要回滚,那么这个事务很可能一直都在重试、回滚,永远也执行不完。这个时候,我们就一点也不要乐观了,像传统单体数据库那样,使用最悲观的锁机制,就很容易实现也很高效。

当然,为了避免这种情况的出现,TiDB 的乐观锁约定了事务的长度,默认单个事务包含的 SQL 语句不超过 5000 条。但这种限制其实是一个消极的处理方式,毕竟业务需求是真实存在的,如果数据库不支持,就必须通过应用层编码去解决了。

遗留应用的兼容性需求 #

单体数据库都是悲观协议,甚至多数都是基于锁的悲观协议,所以在 SQL 运行效果上与乐观协议有直接的区别。

一个非常典型的例子就是 select for update。这是一个显式的加锁操作,或者说是显式的方式进行有效性确认,广义的乐观协议都不提供严格的 RVW,所以也就无法支持这个操作。

select for update 是不是一个必须的操作呢?其实也不是的,这个语句出现是因为数据库不能支持可串行化隔离,给应用提供了一个控制手段,主导权交给了应用。但是,这就是单体数据库长久以来的规则,已经是生态的一部分,为了降低应用的改造量,新产品还是必须接受。

Viewpoints #

From #

13 | 隔离性:为什么使用乐观协议的分布式数据库越来越少?

并发控制的三个阶段

Content #

在经典理论教材“Principles of Distributed Database Systems”中,作者将乐观协议和悲观协议的操作,都统一成四个阶段,分别是有效性验证(V)、读(R)、计算(C)和写(W)。两者的区别就是这四个阶段的顺序不同:悲观协议的操作顺序是 VRCW,而乐观协议的操作顺序则是 RCVW。因为在比较两种协议时,计算(C)这个阶段没有实质影响,可以忽略掉。那么简化后,悲观协议的顺序是 VRW,而乐观协议的顺序就是 RVW。

关于三个阶段的定义在不同文献中稍有区别,其中“Principles of Distributed Database Systems”对这三个阶段的定义通用性更强,对于 RVW 和 VRW 都是有效的,我们先看下具体内容。

  1. 读阶段(Read Pharse)每个事务对数据项的局部拷贝进行更新。

要注意,此时的更新结果对于其他事务是不可见的。这个阶段的命名特别容易让人误解,明明做了写操作,却叫做“读阶段”。我想它大概是讲,那些后面要写入的内容,先要暂时加载到一个仅自己可见的临时空间内。这有点像我们抄录的过程,先读取原文并在脑子里记住,然后誊写出来。

  1. 有效性确认阶段(Validation Pharse)验证准备提交的事务。

这个验证就是指检查这些更新是否可以保证数据库的一致性,如果检查通过进入下一个阶段,否则取消事务。再深入一点,这段话有两层意思。首先这里提到的检查与隔离性目标有直接联系;其次就是检查可以有不同的手段,也就是不同的并发控制技术,比如可以是基于锁的检查,也可以是基于时间戳排序。

  1. 写阶段(Write Pharse)将读阶段的更新结果写入到数据库中,接受事务的提交结果。

这个阶段的工作就比较容易理解了,就是完成最终的事务提交操作。

还有一种关于乐观与悲观的表述,也与三阶段的顺序相呼应。乐观,重在事后检测,在事务提交时检查是否满足隔离级别,如果满足则提交,否则回滚并自动重新执行。悲观,重在事前预防,在事务执行时检查是否满足隔离级别,如果满足则继续执行,否则等待或回滚。

Viewpoints #

From #

13 | 隔离性:为什么使用乐观协议的分布式数据库越来越少?

RVW 的三阶段划分,也见于研究乐观协议的经典论文“On Optimistic Methods for Concurrency Control”。

悲观协议与乐观协议

Content #

无论是学术界还是工业界,都倾向于将并发控制分为是悲观协议和乐观协议两大类。但是,这个界限在哪,其实各有各的解释。

所谓悲观与乐观,它和我们自然语言的含义大致是一样的,悲观就是对未来的一种负面预测,具体来说,就是认为会出现比较多的事务竞争,不容易获得充足的资源完成事务操作。而乐观,则完全相反,认为不会有太多的事务竞争,所以资源是足够的。这个定义虽然不那么精准,但大体表示了两种机制的倾向。

落到实现机制上,有一个广泛被提到的定义版本。乐观协议就是直接提交,遇到冲突就回滚;悲观协议就是在真正提交事务前,先尝试对需要修改的资源上锁,只有在确保事务一定能够执行成功后,才开始提交。

总之,这个版本的核心就是,悲观协议是使用锁的,而乐观协议是不使用锁的。这就非常容易把握了。

Viewpoints #

From #

13 | 隔离性:为什么使用乐观协议的分布式数据库越来越少?

导致弘光一朝武将跋扈局面的是史可法

Content #

史出马入,在许多史籍中认为是弘光朝廷夭折的一个重大关键。诚然,史可法远较马士英清廉正直,但如果认为他留在朝廷秉政,就可以保障江左,进而恢复中原,那就未免对史可法的政治眼光和魄力估计太高了,也不了解南明酝酿立国之时史可法受东林党骨干分子的牵制业已铸下大错。他本人不可能得到新天子的信任还在其次,真正的关键在于按伦序应继承帝位的朱由崧眼看将被东林诸公排斥,为了登上大宝不得不求助于武将,这样才造成了本来无功可录的武将一个个以定策元勋自居。马士英的政治投机虽然保证了他个人地位的上升,但是导致弘光一朝武将跋扈局面的并不是他,而是史可法。

一度掌握着拥立大权的史可法未能抓住这个稍纵即逝决定社稷安危大计的机会,定策之功落入军阀之手,弘光既立,无论他在朝辅政,还是在外督师,都改变不了武将胁制朝廷、无意进取的局面。史可法自食苦果,被迫让出首辅之位过江督师,只是证明他决策错误,事机已失,无可挽回。一批倾向东林党的士大夫大喊大嚷“秦桧在内,李纲在外”,国将不国,其实为时已晚。

后来的史学家没有弄清事情的因果关系,重复旧说,无助于总结历史的经验教训。在历史上,当权人物可以犯这样、那样的错误,但在关键时刻的关键问题上一步错则步步错,史可法的悲剧正是从这里展开,弘光一朝的毫无作为以至于土崩瓦解主要原因也在这里。

From #

司马光根本就不该跟皇帝赌这一盘

Content #

二月十一日,神宗发布司马光为枢密副使的任命,在接下来的十七天里,司马光连上六道奏札,坚辞不就。二十八日,神宗收回成命,下令司马光重回翰林学士院供职。“凡除两府,听其让遂止者,国朝未之有也。”[328]已经任命的两府成员,因为推辞谦让就收回成命的,本朝还从未有过这样的事儿。未上任就解职的二府大臣,司马光是“破天荒”的第一个!

凡前所未有之事,必有前所未有之因。

这一个枢密副使的位置,神宗之命,司马光之辞,所着眼的都不是人事任免,而是政策走向。司马光的这六篇报告,前三道与后三道的重点完全不同。前三篇的说辞简单老套,无非是“臣天性质朴,资质愚钝,不通时务;枢府要地,任重责大”,一言以蔽之,我不合适。后三道的理由也很简单,请陛下取消制置三司条例司,废除青苗法,陛下听我一言,胜过给我高官,如果陛下以为我的想法全无道理,那么我又有什么资格来当这个枢密副使呢?[329]一言以蔽之,司马光是在拿个人前途来赌政策走向。但是,显然他赌输了。司马光为什么会输?

在韩琦、文彦博看来,司马光根本就不该跟皇帝赌这一盘。

就在司马光极力辞任枢密副使的当口,韩琦的专使快马加鞭从河北大名府送信到了开封文彦博的府上。在信中,韩琦请文彦博转告司马光:“皇帝如此倚重,不如接受任命,说不定能践行自己的理想;真到了理想不能实现的那一天再离开,如何?”

韩琦想要告诉司马光的,无非是两个字—妥协,哪怕皇帝此时仍然坚持错误路线,也要留在皇帝身边,因为,留在皇帝身边才有可能影响政策。什么是妥协?妥协就是冲突各方在激烈的较量之后,各让一步,达成和解,建立平衡。能妥协才不会崩溃。妥协是一种智慧,而智慧要比聪明更高级。

From #

什么是反脆弱

Content #

把玻璃杯扔在地上会摔碎;把铁球扔在地上不会摔碎,但是它也没什么好处;把乒乓球扔在地上会弹起来。这三种分别代表什么?玻璃杯摔碎,是在不确定的事发生的时候受损;铁球不变,是在不确定的事发生的时候不变,这个叫坚固。

但它们都不是反脆弱。什么是反脆弱呢?就是在不确定的事发生的时候反而更好,这才叫反脆弱。

From #

思维的三重境界

Content #

《思辨与立场》这本书开篇就给读者提出了一个假设——如果一个人没有批判性思维会怎样?这就是思维的三重境界:

  1. 底层的人从来不反思,永远觉得自己是对的。
  2. 中间那层人虽然反思,但老觉得是别人不对。
  3. 顶级的那层人会反思自己,让自己的思维不断进步。

From #

可证伪与不可证伪

Content #

崇尚伪科学的人永远在自证。这就涉及不可证伪性。可证伪性其实就是一种冒险。一个科学发现越伟大,就要冒越大的风险。比如,爱因斯坦宣布广义相对论,他认为所有的光线在经过大质量星球的时候会发生扭曲,这是一个非常了不起的预言。这个预言冒了一个什么风险呢?

如果爱因斯坦说的是对的,那我们肯定能看到太阳背后的星星。光过来的时候它会绕个弯,所以能看到太阳或者星星。就算爱因斯坦相信自己,但万一后人测出来不成立怎么办?

那么,爱因斯坦所说的这些话可以被证明是错的。假如他的预言没实现,那就要立刻推翻自己,这叫作可证伪性。

什么叫不可证伪呢?

比如星座这件事。现在很多人相信星座。有人问我是什么星座的。我说白羊座。他说我不像白羊座,白羊座的人很强势、急躁,做事风风火火的,我这么温和,不像白羊座。

他也不知道该怎么解释,便说可能是我读书比较多,所以比较温和。就是当一个人检测的一件事情不如他的预期的时候,他会给出各种解释,不会承认这件事情本身可能是站不住脚的。

伪科学的特点就是只需要有人相信就行了。有人做过这样的实验,拿一段中性的文字描述给一些人看,这些人看完后,实验人员问,这段文字说得像他们吗?所有人都觉得太像了,简直就是自己的简介。这纯粹就是一个心理学上的接受过程,并不是科学。

From #

最没人看的是中年男人

Content #

在中央电视台的时候,我们有一套非常明确的体系。比如,这档节目里有人说英文,收视率肯定低;那档节目里如果有一个残疾人,收视率就会高。我们有一个粗略统计排序:残疾人>小孩>老人>女性,最没人看的是中年男人。

From #

主持人如何处理别人的指责

Content #

有一次,我们做辩论主题的样片。有一位嘉宾急了,就冲着我喊:“你们这样做不公平!”两边辩论队也急了,也说主持人不公平。然后我就说:“我们挺公平的,你看我们让你发言一次,他发言一次,有什么不公平?”

这就变成了主持人参与的一次“吵架事件”。下来以后,崔永元老师跟我复盘,说:“你看,别人指责你不公平。如果是我的话,我就扭头看那个女主持人,我说:‘说你呢。’就结束了。大家只要这么一笑,这事儿就化解了。但是你特认真,你还在跟他不断地辩论,你把这个节目带歪了,没有沿节目主题往下走,而且还丧失了风度。

From #