Comments (5)
线程是操作系统级别的并发机制,可以充分利用CPU的多个运算核心,在分布式系统中IO并发都会涉及多线程操作,比如启动一个线程等待其他Server返回IO信息时主线程可以继续处理下一个请求。多线程间可以共享数据信息,但是每个线程都会有自己的程序计数器(PC)、寄存器、栈等,线程是操作系统调度的最小资源单位。
Go语言支持程序多创建线程(在Go语言中表现为协程,即用户态线程,比操作系统级别的线程机制占用资源更少),通常线程数量比物理核数多,Go运行环境会调度这些线程在多核上运行,要注意线程也并非免费的,创建线程要比一个函数方法调用还是费资源。
使用线程时的挑战:
- 共享数据:处理临界资源(比如使用锁解决)
- 线程协调:等待资源容易导致死锁(使用Go语言的channel机制或WaitGroup解决)
- 并发粒度:并发度越大,越容易出现竞争和死锁
本期问题:请完成Crawler并发练习
需要解决两个挑战:
- 安排IO并发:获取一个URL内容的同时处理另一个URL
- 每个URL保证仅处理一次:避免浪费带宽,需要机制记录URL的访问历史
from mit-6.824.
解决方案思考: 查看Crawler示例,Go语言中的并发练习
- 方案,使用go协程和共享map结构:为每个url创建线程,需要使用lock和waitGroup保证顺序,同时保证map的存取操作原子性
- 方案,使用channels:go内部实现使用锁保证,会自动阻塞等待资源
最佳解决方案:
尽量使用channel取代共享变量(shared memory),与子线程同步使用channels
可以使用Go语言的并发检查机制
比如go test -race mypkg
from mit-6.824.
Remote Procedure Call (RPC)
分布式系统的关键部分(后面的实验都会涉及使用RPC),RPC理想上想把网络通信实现同本地函数调用一样,RPC的目的:
- 更容易编写网络通信程序
- 隐藏客户端服务器通信的细节
- 客户端调用更加像本地的过程调用
- 服务端处理更加像本地的过程调用
Go语言有比较好的实现机制
一些实现需要考虑的细节:
- 应该调用哪个服务器函数(handler)?
- 序列化:需要格式化数据到网络包中,可能需要处理棘手的数组,指针,对象等。还有些东西你不能传递,比如channels和function等。
- 绑定:客户端怎么知道应该跟谁通信?也许客户端使用服务器的hostname。也许使用命名服务,将服务名字映射到最好的服务器。
- 线程:客户端可能使用多线程,多于一个调用没有被处理,对应的处理器可能会缓慢;服务器经常将每个请求放置在独立的线程中处理。
特别是需要考虑怎么处理失败?比如:网络丢包,网络断线,服务器运行缓慢,服务器崩溃等问题。
客户端如何对待RPC请求失败?
- 客户端没有获取到服务器的回复。
- 客户端不知道服务器是否接收到请求!也许服务器的网络在发生请求前就失败了。
简单方案是实现“至少一次”机制:RPC库等待回复一段时间,如果还是没有回复到达,重新发生请求。重复多次,如果还是没有回复,那么返回错误给应用程序。但是需要应用处理可能出现的多个写副本(因为多次请求导致)
更好的方案是实现“至多一次”机制:服务器的RPC代码发现重复的请求,返回之前的回复,而不是重写运行。客户端让每一个请求带有唯一标示码XID(unique ID),相同请求使用相同的XID重新发送。
实现“至多一次”机制的困难之处:
- 怎么确认xid是唯一的?使用很大的随机数或是将唯一的客户端ID(比如ip地址)和序列号组合起来
- 老的RPC信息什么时候丢弃是安全的?使用唯一的客户端id、上一个rpc请求的序列号、客户端的每一个RPC请求包含"seen all replies <=X"、类似tcp中的seq和ack。保证每次只允许一个RPC调用,到达的是seq+1,那么忽略其他小于seq。客户端最多可以尝试5次,服务器会忽略大于5次的请求。
- 当原来的请求还在执行,怎么样处理相同seq的请求?服务器不想运行两次,也不想回复。需要给每个执行的RPC标识pending;等待或者忽略。
Go RPC实现的”最多一次“?
- 打开TCP连接
- 向TCP连接写入请求
- TCP也许会重传,但是服务器的TCP协议栈会过滤重复的信息
- 在Go代码里面不会有重试(即:不会创建第二个TCP连接)
- Go RPC代码当没有获取到回复之后将返回错误
-- 也许是TCP连接的超时
-- 也许是服务器没有看到请求
-- 也许服务器处理了请求,但是在返回回复之前服务器的网络故障
参考讲义翻译
from mit-6.824.
@chaozh 讲义翻译404了
from mit-6.824.
先看看Lab2实验代码labrpc.go中的实现,它很像Go的RPC包,但是带有模拟网络
- 这个模拟的网络会延迟请求和回复
- 这个模拟的网络会丢失请求和回复
- 这个模拟的网络会重新排序请求和回复
- 对之后的实验二(Raft实现)测试非常有用
注意:实验一 MapReduce实现使用的是Go的RPC包
程序结构描述
- 服务器(Server), 支持含有多个服务
srv := MakeServer() srv.AddService(svc)
- 客户端(ClientEnd),调用Call()函数,发生一个RPC请求并等待结果
reply := end.Call("Raft.AppendEntries", args, &reply)
- 通信(Network),每个结构都持有一个sync.Mutex
关键方法
- Server.AddService,可能在多个goroutine中调用,deter的作用是在函数退出前,调用之后的代码,就是添加完新服务后,做解锁操作。
- Server.dispatch,分发请求,为什么持有锁?跟AddService并发访问可能冲突。
- ClientEnd.Call,使用反射查找参数类型,使用“gob”序列化参数(Go的自带编解码包
gob.NewEncoder
),ClientEnd.ch(chan reqMsg)是用于发送请求的通道e.ch <- req
,需要一个通道从接收回复(<- req.replyCh) - Network.MakeEnd,创建客户端,使用一个线程或者goroutine模拟网络,每个请求分别在不同的goroutine处理。一个端点是否可以拥有多个未处理的请求???。为什么使用rn.mu.Lock()?锁保护了什么?保护Network中的活跃数组信息
- Network.ProcessReq,如果网络不可靠,可能会延迟或者丢失请求,在一个新的线程中分发请求。通过读取e.ch等待回复直到时间过去100毫秒。100毫秒只是来看看服务器是否崩溃。最后返回回复(req.replyCh <- reply),ProcessReq没有持有rn锁,是否安全?
- Service.dispatch,为请求找到合适的处理方法
from mit-6.824.
Related Issues (11)
- MIT6.824分布式系统欢迎你 HOT 5
- Lec 6:Raft实现 HOT 7
- 【错误提示】MIT-6.824/src/raft/raft.go 中import "labrpc"失败 HOT 2
- 求建新的群 HOT 5
- cannot find module providing package 6.824/diskv 6.824/lockservice: 6.824/pbservice: 6.824/viewservice:
- Lec1:入门介绍(以MapReduce为例) HOT 3
- Lab0:Go语言入门 HOT 4
- Lec3:GFS HOT 3
- Lec 4:主从备份 HOT 1
- Lec 5:Raft基本 HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mit-6.824.