这是学习笔记的第二篇,这篇主要是记录我完成MIT-6.824 lab 2 的思路和想法
Lab2 Overview
这部分的实验主要会实现容错的机制并且完成一个K/V service的雏形。容错的机制其实就是用主备系统来实现。这里用一种叫viewservice的server来完成lab。viewservice会不断监控每一个server是否还alive,如果primary server或者backup server出现问题,就采取对应的措施。如果primary挂了,就会让一个backup取代成为primary。如果一个backup挂了,并且“集群”中海油空闲的server,就会让他变成backup。这时候primary会把自己完整的database内容发送给新的backup,并随后通过Put来验证backup的K/V database是否保持一致性。
因为这个lab是在单机上模拟的分布式的一些特性,所以一些地方需要注意,比如说这个databases的数据是放在内存里而不是放在disk当中的。以及各个server和client等之间的通信只能通过RPC,而不能通过直接的golang对象或者文本IO来实现。
因为这是模拟出来的分布式逻辑,所以下面的一些容错机制和限制会导致真正的分布式系统会too weak,比如
- view service是很脆弱的,因为没有复制。这其实就是类似hadoop中的HA的问题。相当于master节点只有一个的话,是很危险的,容易过载。
- 像之前说的,一个空闲的sever变成backup的时候,需要从primary复制databses来完成备份的效果,这个是很慢的。尤其当网络不好的时候。
- server并没有将K/V databases存储在disk中, so they can’t survive simultaneous crashes (e.g., a site-wide power failure).
- 如果出现暂时性的问题导致primary和backup间的通讯出现延迟或者中断,那么只有两个办法来解决。第一是改变view来将backup移除,或者keep trying。如果通信问题出现的很频繁,那以上两个方法都不好用。
- 这个实验的primary/backup结构有些类似 Flat Datacenter Storage和Monge DB,还有Chain Replication,当然他们的设计和实现更详细。
Part A
好了首先我们来实现这个View Service,就是完成primary/backup结构。
整体思路大概是这样的,client和server通过Ping()方法,也就是RPC请求来通信。client向view server发送的ping带两个参数,me:string,viewnum:int 也就是client的name和viewnum。其中me用来判断是primary还是backup或者是空闲的server。viewnum用来判断是否现在的primary已经被知晓。
从上面的逻辑我们可以很简单的完成client的代码,其实工程中很多的方法和接口已经写好了,核心部分我们只要完成viewservice/client.go 中的Ping()方法就行。如下:
|
|
然后是服务端接收到ping并且得到传来的参数后作出的反应。在viewservice/server.go中。如下:
|
|
主要就是根据me和viewnum来判断情况。如果me是primary,则判断viewnum是否和现在的viewnum相同,相同则说明primary已经被ack了,记下时间。不同则说明现在的primary可能已经挂了。就要将backup变成primary,执行promoteBackup()函数。
|
|
若是me是backup,则判断viewnum和现在的是否相等。不等的话就移除这个backup。
Part B
这部分就是在之前primary/backup的基础上,加上K/V service。未完待续!
Golang RPC
未完待续!