MIT课程
汇编在线
https://www.onlinecompiler.net/
https://godbolt.org/
OCW
首页 https://ocw.mit.edu/index.htm
最受欢迎 https://ocw.mit.edu/course-lists/most-popular-courses/
OCW 学术课程 https://ocw.mit.edu/course-lists/scholar-courses/
入门计算机 https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/lecture-videos/
计算机数学 https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-042j-mathematics-for-com ...
CF喂饭指南
CM喂饭指南
CF网站
Github地址
Cloudflare Worker 2 Vless & Sub
这是一个基于 Cloudflare Worker 平台的脚本,在原版的基础上修改了显示 VLESS 配置信息转换为订阅内容。使用该脚本,你可以方便地将 VLESS 配置信息使用在线配置转换到 Clash 或 Singbox 等工具中。
可以选择自行部署 WorkerVless2sub 订阅生成服务
Workers 部署方法
部署 Cloudflare Worker:
在 Cloudflare Worker 控制台中创建一个新的 Worker。
将 worker.js 的内容粘贴到 Worker 编辑器中。
将第 7 行 userID 修改成你自己的 UUID 。
访问订阅内容:
访问 https://[YOUR-WORKERS-URL]/[UUID] 即可获取订阅内容。
例如 https://vless.google.workers.dev/90cd4a77-141a-43c9-991b-08263cfe9c10 就是你的订阅地址。
给 workers绑 ...
公考学习目录
公考学习目录
时政新闻
求是网
人民日报、中国共产党新闻网
党政机关公文处理工作条例
网站:
考公资源网盘gongkao666:国省考资料,百度网盘
学习资料:资料丰富,基本都是夸克,更新很快,有很多其他资料。
竹叶数据:可以下载历年各省全国市公考真题,需要登录,其他功能需要付费
真题网站 哪里都能下看个人习惯
公考沉思录
公考资源
资料分享
国考省考
国省考资料
事业单位
2022山西事业FB
公基思维导图
02. Raft 代码总览
概述
通过 git 从这个 repo 拉下代码(如果你没有权限,请找作者加),切换到 main 分支,就可以在 src/raft/raft.go 中补充你的实现了。
1git clone https://github.com/storage-courses/raft-course.git
raft.go 中已经有一些框架代码和英文注释。所有测试代码在 src/raft/test_test.go 中,一共有 PartA~D 四个 Part,每个 Part 做完后测试通过之后再去做下一个 Part。Raft 部分所有样例实现在 raft 分支中,如果有遇到调试不过去的地方,可以切换过去参考。
举个例子,如果想切换到 PartA 的第二部分实现:心跳逻辑[06.Raft PartA 心跳逻辑],可以通过 git log 看对应 commit id,然后 checkout 过去即可。
123456789101112131415161718192021222324252627➜ raft git:(raft) git logcommit 0fd60c1082deb9fb6d808254410d ...
01. Raft 论文解读
从零实现 KV 和分布式 KV 有什么区别?
在学习本节之前,最好先自己看一遍 Raft Paper。如果英语不好,可以在网上搜翻译版来看。
使用场景
Raft 本质上是一种共识算法(consensus algorithm)。为什么要使用共识算法呢?什么场景下要使用共识算法呢?为什么共识算法逐渐成为了分布式系统的基石呢?
让我们来试着理一下内在逻辑:随着数字化的发展,当数据集(比如数据库中的一个 table)随着业务的增长,膨胀到一定地步之后,单机不再能存得下。因此需要将该数据集以某种方式切分成多个分片(Shard,也有地方称为 Partition、Region 等等)。分片之后,就可以将单个数据集分散到多个机器上。但是随着集群使用的机器数增多,整个集群范围内,单个机器的故障(各种软硬件、运维故障)概率就会增大。为了容忍机器故障、保证每个分片时时可用(可用性),我们通常会将分片冗余多份存在多个机器上,每个冗余称为一个副本(replication)。但如果分片持续有写入进来,从属于该分片的多个副本,由于机器故障、网络问题,就可能会出现数据不一致的问题。为了保证多副本间的数据一致性,我们引 ...
04. Raft PartA 状态转换
实现概要
该实验虽然功能最简单,但作为第一个实验,需要熟悉环境上手、构建整体代码框架(Raft 代码总览)、掌握用锁技巧(附录1)、掌握打日志方法和调试技术(附录2),因此需要花费的精力却可能最多。
本节主要实现不带日志的选主逻辑。对于两个主要逻辑来说:
AppendEntries RPC 请求只负责通过心跳压制其他 Peer 发起选举,心跳中不包含日志数据。
RequestVote RPC 请求中只会比较 term,会跳过谁的日志更 up-to-date 的比较。
在学习完代码框架(02.Raft 代码总览)一章感受了基本代码框架之后,我们可以将 PartA 的实现分为三部分:
状态转换:角色定义和三个状态转换函数
选举逻辑:定义选举 RPC 相关结构体,构造周期性发送请求的 Loop
心跳逻辑:定义心跳 RPC 相关结构体(只有心跳,因此不涉及日志),当选 Leader 后发送心跳
在开始实现逻辑之前,要根据[论文图 2]定义 Raft 用到的基本数据结构,如前所述,PartA 暂时不用管日志相关字段和逻辑。下面代码中,上面部分是代码框架为了测试默认给的,加粗部分是本部分新 ...
03. Raft PartA 领导者选举
实现要求
实现 Raft 选举和心跳逻辑(即不带日志条目的 AppendEntries)。本部分仅要求实现:
选出唯一的领导者,领导者选出后会持续进行心跳避免其他人发起选举
旧的领导者宕机或者网络故障无法触达时,选出新的领导者
PartA 并不需要实现日志同步逻辑,连带着在收到选举请求时,也都先忽略比较日志新旧的逻辑。
写完后在 src/raft 文件夹,使用 go test -run PartA -race 来测试代码逻辑是否正确、是否有数据竞态。
实现要点
下面罗列下实现概要:
遵照论文图 2 进行实现,但当前只需要关心收发 RequestVote 请求、选举相关的规则和状态转换
选举逻辑:填充 RequestVoteArgs 和 RequestVoteReply 结构体。修改 Make() 函数,在创建 Raft Peer 的时候,创建超时检测、发起选举的后台 goroutine。实现 RequestVote() 回调函数,以在 Leader 要票时进行投票。
心跳逻辑:为了保证 Leader 当选后压制其他 Peer 再次发起选举,你需要定义 AppendEntriesA ...
06. Raft PartA 心跳逻辑
PartA 只需要实现不带日志的心跳。
需要说明的是:在论文中心跳(不带日志)和日志复制是用的一个 RPC,毕竟他们在逻辑上唯一的区别就是带不带日志。但在工程实践中,为了提升性能,有的 Raft 实现会将其进行分开。我们的课程里,为了保持简洁,也就实现到一块了。因为对于初学者来说,简洁比性能重要。
和选举逻辑相对,我们也分三个层次来实现 RPC 发送方:
心跳 Loop:在当选 Leader 后起一个后台线程,等间隔的发送心跳/复制日志,称为 replicationTicker
单轮心跳:对除自己外的所有 Peer 发送一个心跳 RPC,称为 startReplication
单次 RPC:对某个 Peer 来发送心跳,并且处理 RPC 返回值,称为 replicateToPeer
当然,还有 RPC 接收方回调函数的逻辑。
心跳(日志复制)逻辑和选举逻辑实现层次一致、命名风格一致的好处在于,可以减少心智负担,方便调试和维护。
心跳 Loop
由于不用构造随机超时间隔,心跳 Loop 会比选举 Loop 简单很多:
12345678910func (rf *Raft) replic ...
05. Raft PartA 选举逻辑
我们以三个层次组织 RPC 发送方(也就是 Candidate)要票逻辑:
选举 loop:但按框架默认的命名方式,我们称之为 electionTicketor
单轮选举:超时成为 Candidate 之后,针对所有 Peer(除自己外)发起一次要票过程,我们称之为 startElection。
单次 RPC:针对每个 Peer 的 RequestVote 的请求和响应处理,由于要进行计票,需要用到一个局部变量 votes,因此我们使用一个startElection 中的嵌套函数来实现,称为 askVoteFromPeer。
还剩一块,就是 RPC 接受方(其他 Peer)的投票逻辑。
选举 Loop
基本逻辑是每次在循环时,要进行两项检查:
超时检查:看选举 Timer 是否已经超时,只有超时后才会真正发起选举。这里有个问题,就是为什么检查间隔(也就是循环中的 time.Sleep(time.Duration(ms) * time.Millisecond) )间隔也是随机的?因为只有检查间隔也随机才不会造成:超时间隔随机,但由于“等距”检查,造成同样检查间隔时,一同发起选举。
...
08. Raft PartB 日志同步
实现要求
在 PartA 的基础上,加入日志。即:
在进行领导者选举时,要加入日志的比较。
领导者收到应用层发来日志后(raft.Start),要通过心跳同步给所有 Follower。
在收到多数 Follower 同步成功的请求后,Leader 要推进 CommitIndex,并让所有 Peer Apply。
写完后在 src/raft 文件夹,使用 go test -run PartB -race 来测试代码逻辑是否正确、是否有数据竞态。
实现要点
由于实现细节很多,在第一步要保证 TestBasicAgreePartB() 测试能够过。该测试用到的代码流程是,先实现 Start(),然后通过 AppendEntries RPC 发送给所有 Follower,最后在每个 Peer 上再将所有已提交日志按顺序发送到 applyCh 中。
实现领导者选举时的限制,具体可以参考论文中 5.4.1 节。
一种常见的错误现象是,已经有 Leader 当选,但还是不断的有 Peer 发起选举。可以检查下选举超时和心跳间隔的配置是否正确、候选人当选 Leader 后是否立即发起心跳、发起选 ...