今天已经是失业的第273天,失业期间每天都在尝试新的东西,疯狂地学习学的东西。进行自我反思,为什么直到失业后才开始学习,我的学习方式对吗,我学到了哪些东西呢?
这些问题其实二十多前就已经有人开始研究,Leslie Lamport 在1998年提出了 Paxos 一致性算法,解决分布式系统的共识问题,后面的Raft算法是以此为基础开发出来的。Seth Gilbert 和 Nancy Lynch 在 2002年证明了 CAP 定理,阐明了分布式系统的根本限制,效率与一致性不能同时满足。谷歌在 2013年发布了论文 F1: A Distributed SQL Database That Scales,揭示分布式数据库F1是如何设计的,还有谷歌的BigTable,chubby分布式锁,亚马逊的Aurora OLTP 分布式数据库,这些都是行业公开的知识,大量的资料可以去查。而且工作中也会涉及到分布式的问题,但是只有失业我才开始去了解这些相关的知识。往往一个知识只有在你真正理解它所要解决的问题后,你才能真正掌握这个知识本身。分布式的问题往大了说,就是一个沟通协调的问题,这个问题不只是存在于软件领域,在社会学,管理学等方向也通常比较难解决的问题之一,只是问题的表现形式不一样。但是往往我们看问题的视角是从下往上看到的,我们会用已知的知识去解决当下的问题,解决当下问题会产生另外一个问题,因为我们没在站在全局的视角看问题。至于为什么没有早点意识到呢,我觉得是思维模型的问题。
这里的经历比较有意思,在工作中我们几乎时时都在和事务打交道,但是我是真的没有理解事务的本质,相信我之前的同事大都多也跟我一样,不然也不会有那么多关于死锁的问题了。 面试的时候我们常会背诵数据库的ACID 4大特性:原子性,一致性,隔离性,持久性。但是实际上数据的事务常常会导致数据的不一致,ACID的定义都有明确的局限性,它们通常指的串行时单事务执行前后的性质,如果有并发事务执行,结果将变得不可预测。所以才衍生了真正重要的内容:隔离级别。不同的隔离级别,会产生不同的一致性。这里就比较有意思了,本来一致性的意思就只有一种,现在却变成了根据情况而定。比如在 Read Uncommitted隔离级别下,就没有一致性,可以读到未提交的数据,也就是说你可能会看到中间状态的数据,后面这个数据可能又会滚了或者怎么样。在 Read Commited 隔离级别只能看到已提交的数据,但是可能出现幻读,就是会看到新插入的数据(之前查某个数据查不到,后面又查到了,像幻觉一样,所以命名为幻读吧)。在 Repeated Read 隔离级别下,不会出现幻读并且只能读到已提交的数据。然后最后是串行化,就是保证事务是串行化运行,或者类似于串行化运行,不会出现任何非串行化的不一致性,如果出现了就是非串行化异常。然而这里不仔细研究又会有一些坑在里面,从 Repeated Read 到串行化隔离级别中间有哪些一致性问题,数据库是如何解决的,我们要相信隔离级别吗?这里有两个常见的一致性问题:lost update 丢失更新 和 write skew 写偏斜。丢失更新指的是一个事务正在更新一行数据并且还未提交,另一个事务就开始更新该行数据。这个问题比如好解决,MySQL 使用行锁等待并重试,而PostgreSQL则会并发写,等到第二个事务提交时才会检查冲突,并会立即失败。MySQL 和 PostgreSQL 实现隔离级别的方式完全不一样,相同的隔离级别提供的一致性也不一样。软件设计就跟大自然里的生物一样具有多样性,然而我之前并没有意识到这一点,一直困惑于MySQL的聚簇索引和B+Tree索引,死磕其中的一个知识点会让你陷入绝望,永远无法理解,也找不到链接其它相关的资料,信息链接断了。
学习Kafka我觉得花了挺大的劲,看了Kafka相关的书,让AI整理相关的资料,说实话让AI整理资料没有那么靠谱,有时候他并不会动脑筋,你让他去查资料,他就会去查资料,然后他们的博客整理一下直接搬过来,一些结论是错的,有些已经过时。然后我就自己把这些知识再通过 Excalidraw 再画一下,其实也没有多少东西是自己的,只是照着那个知识点画,然后对整个架构有了一点理解,在此之前我对Kafka说不上半内容,虽然工作中我是接触过的。
和其它消息中间件一样 Kafka 也由生产者,消息者以及 message broker 组成,称为生产者-消息者模型。kafka 功能就是传输消息,将消息从生产者传输到message broker中存储,然后感兴趣的消费者主动订阅消息并消费(跟现在的快递流程很像)。然后Kafka的所有设计围绕这个过程展开,Topic 是 消息发送的逻辑单元,就是生产者将消息以Topic的形式发送,消费者以Topic的形式接收消息。这里说到的逻辑单元就会有物理单元,对的,消息是以分片Partition的形式存储的。一个Topic通常会分为一个或者多个Partition,这里可以作一个类比,就像我们寄快递一样,我们将包裹放到菜鸟驿站,菜鸟驿站会根据特定的规则发到指定的快递公司,这里的快递公司就类似于 Partition 的概念,快递公司统一的仓库就类似于 kafka 的 broker,是用来存放指定 Partition 的消息。一般 broker 的磁盘空间可以放很多个Partition,所以broker 和 Partition 是一对多的关系。而消费者消费消息可以用家长给多个孩子买书作比较,比如一个topic叫课外书籍,父亲在网上书店订阅了书籍,他们会定期送书过来,然后他的4个孩子都喜欢看书,所以都订阅了这个父亲的这个活动。然后每个孩子有自己的书架,父亲买完书回来之后会按照一定的规则将书籍放到不同的书架上,然后孩子就可以在书架上看到父亲买的新书了。在这个故事中网上书店是生产者,课外书籍是topic, 孩子的书架是partition,孩子是消费者,装书架的房间就是一个broker。
然后我们再回到Kafka上,因为Kafka是高可用低延时高吞吐的事件流平台。要做到低延时就需要使用到分布式架构,水平拓展多个节点,将大流量分摊到多个节点,减小单节点负载。但是水平拓展虽然有好处,但是操作起来很多的问题,比如将broker扩容后,原来的partition要怎么迁移过来,在线迁移的话,如何避免影响用户使用。还有另外一个问题,就是高可用与一致性的问题,如果数据只存储在一个地方,如果服务宕机就会出现服务不可用的现象,然后宕机之后不会立马恢复,所以此时需要有一个可替代的服务出现,所以在 Kafka 中需要有 replica 副本的概念,replica 是 partition 的镜像,而不是 broker的镜像。假设一个 partition 有一个leader和两个follow,当leader正常工作的时候 follow只是同步follow的数据,当leader挂了,其中一个follow就会开始竞选当leader,这个过程很快,当选leader之后就可以正常对外提供服务了。leader和follow的概念其实也特别像人类组织中的概念,比如一个球队通常会有备用球员,当主队员受伤之后可以代替上场。replica 这个模型其实在Paxos 一致性算法中就有提到,已经是一个标准解法。在Kafka中还有一个Controller的概念,因为 Kafka 集群实例都是 Broker,也就是message broker 用来承担消息中间件的功能,需要有一个broker来管理 topic partition leader 和 follow的分配,topic元数据管理等工作。controller 是相对于partition leader 更高级别的存在,类似于国会或者中央相关于地方选举的概念。
然而当我们再仔细研读‘低延时’和‘高吞吐’时,会发现更多的问题。Kakfa的生产者并不是一有数据就往broker中发送,而是收集一定的量后批量发送,这样可以提高吞吐量,可以想像快递公司运输货物一件货一件货运,那得那慢啊,所以批量发送可以提高吞吐,但是如何流量比较小,如果批量的threshold设置比较大,可能会导致延迟比较高。所以这里需要trade off 妥协,需要 trade off 的地方不只这一个地方,比如
虚拟机运行机制,这些知识本应该在工作期间就掌握的。
看芒格在西科的演讲,看[[巴菲特之道书评|《巴菲特的投资之道》]] 并希望以此获得赚钱的机会。
想看看他们是如何从零到一打造成现今如此巨大的商业帝国的。然而成功往往不是单一因素,往往是优秀的人加上优秀的人,再加上时代的机遇。一个人的成功可能要追溯到他小的时候,王兴和张一鸣都是福建人,他们父辈都是生意人,走南闯北给了他们与普通不一样的认知,认知到教育的重要性。王兴和张一鸣在小时候就看到过很多的书,他们很可能在很小的时候就已经懂了长大才懂的道理,认识觉醒的越早,所能取得的成就就越大。
让遥控小车跑起来,通过ISP协议在小屏幕上播放动画,想硬件创业做一个网球放球机。这个时间段其实花了很多时间,但是没有产出,只有一些从网上抄袭来的冷冰冰的代码,没有文字记录,
学习线性代数,神经网络,深度学习,AI Agent工程,希望谋得一份算法或者AI相关的工作。
这本书给我的启示太多了,太多太多东西想要写下来…