2017 6.824学习笔记 Lecture 2: RPC and threads
2017-11-19 17:23
204 查看
线程
线程是非常有用的构建工具再Go中线程称为goroutines,其他语言中叫做线程
他们通常比较棘手
为什么使用线程?
允许利用并发,这在分布式系统中很自然的体现出来再I/O并发中,允许在等待一个IO响应时,处理下一个请求
多线程可以平行运行在多核上
Thread = “thread of execution”
线程允许一个程序在逻辑上一次执行许多事情线程间有共享内存
每个线程包含自己的运行状态:
程序计数器
寄存器
栈
一个程序会有多少个线程?
尽可能多的“有用的”线程在一个应用中Go鼓励创建更多的线程
通常线程数会大于CPU核心数
Go的调度器将他们调度到可用的核心上
Go的线程也时有损耗的,但他要比通常意义中创建一个系统线程要轻量
使用线程的挑战?
共享数据:e.g. 一个线程读数据同时另一个线程改变数据,将导致竞争条件不要共享数据或者协调共享(使用互斥锁等)
线程间的协调:(e.g. 等待所有Map结束),导致死锁
使用Go的channel或者waitGroup
并发性的粒度
粗粒度:简单,较少的并发/并行
细粒度:更多的并发,但也有更多的竞争和死锁
远程过程调用(RPC)
概述
RPC是分布式系统中的一个关键机制目标:轻易地编写网络通信
隐藏许多客户端/服务端之间的通讯细节
客户端调用就像普通的程序调用
服务端的处理程序非常像普通程序
RPC使用非常广泛
理想中RPC让网络通讯就像函数调用一样:
Client: z = fn(x, y) Server: fn(x, y) { compute return z }
RPC的目标就是这个水平的透明度
RPC 通信模型
Client Server request---> <---response
RPC 软件结构
Software structure client app handlers stubs dispatcher RPC lib RPC lib net ------------ net
一些细节:
那个服务函数去处理调用?
在go中通过Call()
编码:格式化数据到网络包中
一些类型比较棘手,数组 指针 对象 引用等
Go的RPC包很强大,但是一些类型不允许传输(channel function等)
绑定:客户端如何选择服务端?
可能是客户端写死
可能是有一个服务名称映射服务来选择最优的服务端
RPC的问题:失败如何处理?
例如丢包,网络故障,慢服务,服务端崩溃
从RPC的客户端角度失败是什么样子的?
客户端从未收到服务器端的响应数据
客户端不会知道服务端有没有接收到请求报文
故障可能发生在服务端回复响应之前
解决方案:
最简单RPC行为“最少一次”:
RPC库一直等待响应结果,如果规定时间内没有接收到,则重新发送这个请求。这样一直尝试很多次后,若一直没有收到响应,则返回错误给调用程序
Q:对于应用来说“至少一次”是很容易处理的吗?
A:问题举例
客户端发送从银行账户扣除10元钱的请求,可能会导致多扣钱;
向数据库的同一个key赋值,当出现网络超时,导致重发时,先发送的写操作可能后到达
Put(“KEY1”,10)
Put(“KEY1”,20)
期望结果为20,但结果可能为10
Q:什么场景下可以使用“至少一次”模型?
A:
重复操作是可以接受的,比如只读操作
若应用程序有自己的方法去应对重复写入问题时,可以使用
更好的RPC行为“最多一次”
想法:服务端RPC代码中检测重复的请求,返回之前的结果提单重新运行的操作
Q:如何检测重复操作?
A:客户端使用唯一ID在每个请求中,超时重新请求时使用相同的唯一ID
server: if seen[xid]: r = old[xid] else r = handler() old[xid] = r seen[xid] = true
一些“最多一次”模型的难点:
1.如何保证唯一ID?
大的随机数?client的唯一地址?等
2.老的RPC结果最终是一定要删除(缓存RPC结果已保证“最多一次”)的
如何保证删除这些数据是安全的?
保证各客户端ID是不重的
方法1:每个RPC请求要保证之前的所有响应已经回复 像TCP通信中的SEQ ACK
方法2:只允许一个暂未结束的RPC请求,当seq+1到达时,删除掉
什么是恰好一次模型?
最多一次模型+无限重试+故障容忍服务
GO RPC库是 最多一次模型
打开TCP链接写请求到这个链接
TCP可能会重传,但是服务端的TCP会过滤掉这些重复数据
不会在Go的代码中重复
当Go RPC库没有获取到响应结果时会返回一个错误,这可能由以下原因导致:
TCP超时
服务端没由看到请求
服务端执行了请求但返回结果前网络出现了故障
相关文章推荐
- 2017 6.824学习笔记 Lecture 1: Introduction
- Lecture 2: 基础结构: RPC and threads
- Web Mining and Big Data 公开课学习笔记 ---lecture1
- [深度学习与计算机视觉] 斯坦福 CS231n 2017 学习笔记 -1 (Lecture 1: Introduction;课程介绍)
- Webservice学习笔记六,SOAP, REST and XML-RPC报文格式收集
- 台大李宏毅Machine Learning 2017Fall学习笔记 (2)Linear Regression and Overfitting
- 操作系统学习笔记:Threads and Locking
- [分布式系统学习] 6.824 LEC2 RPC和线程 笔记
- 台大李宏毅Machine Learning 2017Fall学习笔记 (3)Bias and Variance (v2)
- Devexpress 12.2.8.0 部分学习笔记1 【Docking and Popups】
- WPF and Silverlight 学习笔记(二十):WPF数据绑定概述
- 林轩田之机器学习课程笔记( combining predictive features之blending and bagging)(32之23)
- CSS布局学习笔记and一些小技巧
- 斯坦福大学iOS应用开发教程学习笔记(第一课)MVC.and.Introduction.to.Objective-C
- MSDN Kernel-Mode Driver Architecture学习笔记(3)——Device Objects and Device Stacks (4)
- WMI009-WMI学习笔记(九)——System.Management and System.Management.Instrumentation Namespaces(命名空间)
- ROS进阶学习笔记(11)- Turtlebot Navigation and SLAM - ROSMapModify - ROS地图修改
- 1.4 Mote-PC serial communication and SerialForwarder 学习笔记
- Programming in Objective-C 学习笔记10——Cocoa, Cocoa Touch and the iOS SDK
- Neural Networks and Deep Learning 学习笔记(三)