5709 stories
·
2 followers

Principles of Web API Design: Delivering Value with APIs and Microservices

1 Share
Principles of Web API Design: Delivering Value with APIs and Microservices
Read the whole story
fengbin
13 days ago
reply
Share this story
Delete

SOLID: The Software Design and Architecture Handbook

1 Share
SOLID: The Software Design and Architecture Handbook
Read the whole story
fengbin
13 days ago
reply
Share this story
Delete

为什么极少有开源的Paxos库?

1 Share

你是不是也很奇怪, Paxos 既然被称为唯一的共识算法(分布式一致性算法), 是分布式系统的基石, 那么为什么极少看到开源的 Paxos 库呢? 反观 Raft, 有 etcd 开源的 go 语言写的库, 有 PingCap(tidb)开源的 Rust 语言写的, 还有百度, 阿里等等公司开源的各种语言的库. 既然 Paxos 那么牛逼, 为什么江湖中只有它的传说, 却从来没有人见过它的身影呢?

原因很简单, Paxos(准确的说是 Basic Paxos) 是共识算法, 用于对一个实例的状态形成共识, 这个用途和工程上的一致性协议基本是金属铁块和汽车的关系. 工程师对 Paxos 最大的疑问经常是:

  • 什么是实例? 一整个 database 是一个实例吗? 一个 key 是实例吗?
  • 共识是什么? 是一个 key 对应的 value 吗? 形成共识之后就不能更改? 有什么用?

所以, Basic Paxos 不是问题的解决之道. 有所谓的 Multi Paxos, Paxos 的论文中对这个模型(有人认为就是复制状态机)的定义和讨论非常不完善, 一千个人有一千种看法, 而且大多还是错的.

Raft 提出了工程上的分布式一致性协议的核心本质: 选主和日志复制状态机.

管你什么 Multi Paxos, E-Paxos, X-Paxos, ABC-Paxos, 通通都是日志复制状态机. 管你成员显式选主还是客户端认主, 通通都是选主.

你说 Paxos 不需要 Leader, 那还不是要求客户端根据 Hash 算法认定一个节点作为 Leader? 你说你的日志序列支持空洞, 还支持乱序 Apply 日志(执行指令), 但两条指令执行的顺序不同必然导致结果不同, 结果(状态)都不相同, 你还谈什么一致性?

做来做去, 还不是 Raft 所总结的那一套方法吗? - 就是选主和日志复制状态机!

所以, 为什么没人开源 Paxos 库? 因为工程上要做的工作, Paxos 只占 1% 的工作量, 你把 1% 的微小工作包装成一个库? 有啥卵用? 没有人会用的, 因为这个库什么功能也没有, 什么问题也没解决(准确地说只解决了 1%).

还要什么 Paxos 开源库? 要的是选主, 日志复制状态机, 成员变更, 就是 Raft 那个样子, 即使你心里面极度排斥 Raft, 但最终你还是会把一个 Paxos 库实现成 Raft 的样子.

Related posts:

  1. Paxos和Raft读优化 – Quorum Read 和 Read Index
  2. Paxos 与分布式强一致性
  3. 分布式存储名词解析 – 一致性
  4. 什么是 Paxos 的日志空洞?
  5. 为什么 Leader Based 的分布式协议 Raft 是更好的
Read the whole story
fengbin
125 days ago
reply
Share this story
Delete

程序员必读书单 1.0 -- 六年后的回顾

1 Share

年更系列(继续保持一年一次的更新频率 o_O)

六年之前,我写了 程序员必读书单 这篇文章,两万五千多字介绍了近 100 本书,覆盖基础理论,编程语言,程序设计等十余个领域。然后从中精选出 30 本书用于入门和提升。

当时写这篇文章的初衷是想写一个不会过时的书单。书单写于 2015,现在 2021,是否还适用呢?

必读书单

先放下 2015 年的书单:

入门书籍

程序设计:

  1. 基础理论 : 编码:隐匿在计算机软硬件背后的语言
  2. 编程语言 :
    • C : C 和指针
    • C++ : C++ 程序设计原理与实践
    • Java : Java 核心技术(第9版)
    • C# : 精通 C#(第6版)
    • JavaScript : JavaScript DOM编程艺术(第2版)
    • Python : Python 基础教程(第二版)
  3. 编程语言理论 : 编程语言实现模式
  4. 程序设计 : 程序设计方法
  5. 算法与数据结构 : 算法(第4版)
  6. 程序调试 : 调试九法——软硬件错误的排查之道

软件开发:

  1. 编程实践 : 程序设计实践
  2. 面向对象程序设计 : Head First设计模式
  3. 重构 : 重构
  4. 软件测试 : How to Break Software
  5. 项目管理 : 极客与团队
  6. 专业开发 : 程序员修炼之道:从小工到专家
  7. 大师之言 : 奇思妙想:15 位计算机天才及其重大发现
  8. 界面设计 : 写给大家看的设计书
  9. 交互设计 : 通用设计法则

个人成长:

  1. 职业规划 : 软件开发者路线图
  2. 思维方式 : 程序员的思维修炼:开发认知潜能的九堂课
  3. 求职面试 : 金领简历:敲开苹果微软谷歌的大门
  4. 英语写作 : The Only Grammar Book You’ll Ever Need

必读书籍

程序设计:

  1. 基础理论 : 深入理解计算机系统(第 2 版)
  2. 编程语言 :
    • C : C 程序设计语言(第 2 版)
    • C++ : C++程序设计语言(第 4 版)
    • Java : Effective Java(第 2 版)
    • C# : CLR via C#(第 4 版)
    • JavaScript : JavaScript 语言精粹
    • Python : Python参考手册(第 4 版)
  3. 编程语言理论 : 程序设计语言——实践之路(第 3 版)
  4. 程序设计 : 计算机程序的构造与解释(第 2 版)
  5. 算法与数据结构 : 编程珠玑(第 2 版)
  6. 程序调试 : 调试九法——软硬件错误的排查之道

软件开发:

  1. 编程实践 : 代码大全(第 2 版)
  2. 面向对象程序设计 : 设计模式
  3. 重构 : 修改代码的艺术
  4. 软件测试 : xUnit Test Patterns
  5. 项目管理 : 人月神话
  6. 专业开发 : 程序员职业素养
  7. 大师之言 : 编程人生:15 位软件先驱访谈录
  8. 界面设计 : 认知与设计:理解UI设计准则(第 2 版)
  9. 交互设计 : 交互设计精髓(第 3 版)

个人成长:

  1. 职业规划 : 软件开发者路线图
  2. 思维方式 : 如何把事情做到最好
  3. 求职面试 : 程序员面试金典(第 5 版)
  4. 英语写作 : 风格的要素

回顾

  1. 我会把 程序员必读书单 改为 程序员书单:去掉 必读 ——没有什么书必须要读,书籍只是一个知识的获取渠道。论文,代码,项目,文档都可能是更好的知识来源
  2. 删减一些分类,比如 求职面试 和 大师之言:前者现在更依赖与网络上的面经和 OJ ,而非书籍,后者属于 anecdotes,大师的经历大概率对普通人没有适用性,下面会聊下

变动

程序设计:

  1. 基础理论:没有变化。编码:隐匿在计算机软硬件背后的语言 和 深入理解计算机系统 依然是最好的基础理论入门和进阶读物
  2. 编程语言:去掉这个分类。
    • 入门,书籍只要不是太差,基本没什么区别
    • 进阶,官方文档/源码更值得阅读,而非某本书籍
    • 2015 年推荐的书籍在 2021 年大多已经有了新版,懒得一个个更新
    • 如果非要推荐:K&R 的 The C Programming Language 是必读,其它都可选
  3. 编程语言理论:没有变化,Programming Language Pragmatics 依然是程序设计语言的绝佳读物
  4. 程序设计:没有变化。计算机程序的构造与解释 依然是程序设计读物的 paramount
  5. 算法与数据结构:没有变化。算法 和 编程珠玑 就够用。依然不推荐 CLRS 或是 TAOCP,除非你要当科学家。
  6. 程序调试:没有变化。

软件开发:

  1. 编程实践:没有变化。程序设计实践 和 代码大全 依然是最好的编程实践书籍
  2. 程序设计:略有变化。Head First 设计模式 并不值得推荐,Clean Code 实操更强,加上 Philosophy of Software Design
  3. 重构:没有变化。
  4. 软件测试:略有变化。How Google Test Software 也许可以提供一些大公司做测试的 insights
  5. 项目管理:略有变化。加上 Software Estimation
  6. 专业开发:略有变化。Effective Engineer 和 Manager’s Path 提供了更多 Senior engineer 的 insights
  7. 大师之言:去掉这个分类。大师的成长轨迹,对多数人并不适用,可以当成 anecdotes 看着乐一乐,但绝非必读
  8. 界面设计:去掉这个分类。并非所有开发者都需要 UI 设计知识
  9. 交互设计:略有变化。通用设计法则 换成 设计心理学
  10. 系统设计:新增这个分类。系统设计是程序员进阶的必备知识,但由于我的系统设计知识大多源自于阅读代码和项目,这里没有书籍推荐。

个人成长:

  1. 职业规划:去掉软件开发者路线图(那本书并不适合程序员爬 ladder),换为 Manager’s Path 和 Show Your Work。
  2. 思维方式:去掉这个分类。励志书籍已经够多了。
  3. 个人管理:增加这个分类。HBR 的套装很好。尤其是 On Managing Oneself,此外 Andy Groove 的 High Output Management 也值得一看。
  4. 求职面试:去掉这个分类。程序员求职现在有更好的资源,不需要看书。
  5. 英语写作:去掉这个分类。写作是必须的技能,但看书可能用处不大。

延伸阅读

之前我在每个分类下都提供了一些延伸阅读。

其实没必要读那么多,一个领域一两本就够用。

所以请直接无视。

现在回想,我当时也只是为了凑够 100 本。

回答一些疑问

Q: 推荐那么多书,你有都看过吗?
A: 并没有。必读书单里面的必读书(30 余本)我都看过,但并没有都读完(读完的大致占 7-8 成)。至于延伸阅读(70 本左右)里面有不少并未读过,6 年前写文章时多少有点装 13 凑数

Q: 读了这么多书,现在应该混的很不错吧?
A: 并没有,我正式工作 8 年,现在还只是在大厂搬砖。原因:

  1. 书单里面的书大多是我在学生时期读的,所以很多内容并没有吸收,很多知识需要工作后才能理解并运用,然而我并没有重读
  2. 工作级别和技术能力并不存在直接联系。级别更多需要的是眼光,时机,和个人规划,而这几样我都很欠缺
  3. 写程序,只是实现公司业务的一个途径。我过去读的书过于偏重具体技术,忽略了人际关系,业务方向等更重要的内容,导致我在相当长时间都在原地打转搬砖

Q: 程序员书单 2.0?
A: 开什么玩笑。工作之后我的阅读量大幅下降,现在的自己也不像 6 年前那般好为人师。所以我既没有能力,也没有动力去写一个新的书单。不过 程序员书单 1.0 绝大多数书籍仍未过时,对在校学生或是刚入门的程序员应该还有帮助。

Q: 为什么不写博客了?
A: 懒。

Read the whole story
fengbin
217 days ago
reply
Share this story
Delete

Tele 酱:基于 Telegram 和 Vercel 的开源 Server 酱实现

1 Share

项目地址:https://github.com/easychen/telechan

为啥不直连 Telegram bot api ?

  • ① 直推在大陆有网络问题
  • ② bot 不能服务多人,会泄露 api token
  • ③ 接口还是麻烦了点,

之前在做 Server 酱新通道选型的时候,telegram 本来是一个不错的候选,但是因为它的 api 接口在大陆网络无法访问,考虑到自建中间层的网络稳定性,所以没有支持。

但前几天我发现 Vercel 其实是支持 Serverless function 的 && Vercel 在大陆地区目前是能访问的,于是就有了这一个应用。

提供两个选择:

① 懒人方案,直接用我搭好的 bot

  1. 添加 @TeleChan8Bot
  2. 发送 /sendkey 获得 key 和 url
  3. 通过 url 发送请求即可

参数和 Server 酱 基本一致:

  • sendkey,required
  • text,required
  • desp,optional

desp 支持 telegram 提供的 Markdown 子集

服务由 Vercel 提供,应该还算稳定,唯一的问题是 sendkey 泄露不能重置,自己保存好。

② DIY 方案,自己搭一个,反正代码是开源的

搭建其实也不复杂,几分钟无脑搞定:直接 fork 以后部署到 vercel,在部署设置里添加下环境变量就行。

做了个教学视频放到 B 站,欢迎顺便关注下我

image
Read the whole story
fengbin
217 days ago
reply
Share this story
Delete

并发编程的核心技术 – 多版本(Multi Version)

1 Share

在单机编程时代, 每一项数据只有唯一的一份, 对数据的修改也是 in-place 的. 但是, 在并发编程领域, 包括分布式系统, 数据多版本(Multi Version, Versioning)是核心.

我们先从单机编程的内存操作出发. 对于内存的操作, 都是原地(in-place)更新的. 对象和内存空间强绑定, 当更新对象时, 是将对象的内存空间擦除然后用新数据写覆盖. 到了多线程编程时代, 就引入了锁机制, 因为擦除和写操作过程不是原子性的, 可能擦除到一半时, 就被其它线程读取了, 因此要加锁.

单机的硬盘操作, 基本也是借鉴内存操作, 也是对象和硬盘空间强绑定. 至少大部分程序员的思想是这样的, 这样比较直观. 跟内存操作一样, in-place 也遇到了操作的原子性挑战. 内存本来就是易失的(掉电后丢失), 但硬盘不一样, 数据需要持久化(掉电不丢失), 即使靠加锁解决了访问原子性问题, 但解决不了数据丢失问题. 所以, 硬盘操作是最先引入多版本技术的. 当需要修改某个对象时, 在另外的地方保存对象的新数据, 然后在另外的地方原子性地修改指向新数据的"指针". 事实上, 指针的修改也是多版本的, 不是 in-place 的, 后面会细说.

有趣的是, SSD 硬盘技术的内部实现, 也不是 in-place 的, 其内部也是有类似"指针"的地址表的东西.

把硬盘上的多版本技术, 反哺回内存操作, 将会如何帮助并发编程呢? 如果更新某个对象时, 并不是在对象原来的内存空间里进行修改, 而是分配新的内存空间来保存对象, 保存完毕后, 再原子性地修改指向对象的"指针", 是不是就不需要锁了呢?

确实是这样的, 在旧的内存空间中的对象(旧版本), 因为永远不会被修改, 所以, 在读取时完全不需要加锁, 因为我们加锁是为了保证原子性(完整性). 也许修改"指针"指向时需要加锁, 但至少访问对象本身时是 Lock Free 的.

多版本(Multi Version)技术或者思想有什么优势? 它的借鉴意义是什么?

我认为, 这项技术借鉴意义在于, 只要我们引入一个极小成本的"指针", 就能让极大成本的访问对象的操作可以并发执行, 从而提高了性能. 如果这个对象不是在内存, 而是在磁盘的不同位置, 或者在不同的机器, 那样, 便可达到分布式并发处理能力. 所以, 这个技术(思想)是非常强大的.

数据库内核有很多地方都会用到多版本技术, 例如 MVCC(Multi Version Concurrency Control)技术, 名字上就带有 Multi Version. 在数据库领域, 我们把数据写入文件, 原始的做法会对读和写操作加互斥锁. 在引入多版本技术之后, 我们打开文件两次, 获取两个文件描述符(fd), 一个 fd 用于写, 另一个 fd 用户读. 写操作永远只追加写, 所以我们在内存中维护指向上一次写的位置(指针), 然后可以通过另一个 fd 去读文件, 只要不超过内存中维护的指针的位置即可. 这样, 就实现了并发地操作(读和写)同一个对象(文件).

从 in-place 到 Multi Version 的转变, 是从点到线的重大转变. 前者数据是一个点, 后者数据则是一个列表. 掌握了 Multi Version 技术的真谛之后, 你才能真正地了解数据的本质, 真正地掌握并发技术.

总结一下: 不要 in-place 修改对象的数据, 而是维护对象的多个版本, 引入一个极小成本的"指针", 指向对象的某一个版本.

理论结合实践

讨论了理论之后, 我们看看理论是如何指导实践的. 以 Multi Version 在数据库事务领域的作用为例.

考虑有 A, B 两个银行资金账户, 初始时(t0) A 有 100 元, 而 B 有 0 元. A 要转账 10 元给 B. 因为 A 和 B 的资金账户是独立的, 所以, 需要独立地修改两次, 一次修改 A 的余额, 一次修改 B 的余额.

现实中, 修改两个账户一定会有先后顺序, 不可能完全"同时的". 所以, 在 t1 时刻将 A 的余额修改为 90, 而此时 B 的余额还是 0.

我们把时间作为数据的版本号, 那么对于 t1 版本, 就出现了所谓的不符合原子性问题: 整个系统丢失了 10 元钱. 在 t2 时刻, "丢失"的 10 元钱终于进到 B 的账户里了.

t0 t1 t2
A 100 90
B 0 0 10

我们在额外的地方引入一个"指针", 指向 t2, 并且保证这个"指针"永远不指向 t1, 也就保证了整个系统永远不会丢失 10 元. (注意, 在 t2 时刻, A 没有对应的版本, 所以往前找, 找到 t1)

这个所谓的"指针", 就是数据库事务技术的 Commit Point(提交点).

所以说, Multi Version 技术(思想)是非常强大的, 能解释许多问题, 能指导很多工作.

Related posts:

  1. Redis 的作者狂喷某 NoSQL 数据库
  2. 为什么 Leader Based 的分布式协议 Raft 是更好的
  3. Paxos学习-instance
  4. HBase 在 Linux 下安装和配置
  5. Paxos 与分布式强一致性
Read the whole story
fengbin
217 days ago
reply
Share this story
Delete
Next Page of Stories