前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C|分布式|RPC&NFS

C|分布式|RPC&NFS

作者头像
朝闻君
发布2021-11-22 11:27:26
2510
发布2021-11-22 11:27:26
举报

Intro

随着单机性能进入瓶颈,storage与serve的压力与日俱增,因此,这两个职责被分布在不同服务器上。由于原本单机的文件访问变为跨服务器,因此NFS(Network File System)诞生了。

大存储服务器负责文件系统,应用服务器负责响应客户端

但是,如果我不想进行原本代码的修改,而想让通过网络进行的文件访问看起来如同之前本地的访问一样呢?我们现在一般使用RPC(Remote Procedure Call)在原有的单机文件系统上进行一层封装,使之成为NFS.程序员所面对的编程接口依然和往常的接口相同,而变化的仅仅是底层实现。

RPC

允许进程在远端执行而无需编码交互细节

我们使用Stub中间件隐藏通信的交互细节,真正的RPC通过Stub进行,而用户代码毫无察觉。

Stub隐藏了通信的细节,使得上层的调用无需修改

Client stub

  • request中放置参数
  • send requset to server
  • 等待response

Service stub

  • 等待message
  • 获取request参数
  • 进程调用
  • response中放置结果与状态(success?/accecpted?)
  • send respones to client

问题在于,message中应该放置什么,以下是一些比较重要的信息

当前的call的标识-Transaction ID

调用什么方法–Service ID (e.g., function ID)

身份认证-Auth Stuff

使用什么参数–Service parameter (e.g., function parameter)

由于引用失效,参数的再编排–Using marshal / unmarshal

//跨地址空间引用失效,因此需要进行序列化/反序列化(及处理网络通信的大小端)

Components

为了搭建一个RPC框架,我们需要

1.RPC格式标准(UDP or TCP or HTTP2?)

2.marshal / unmarshal工具库

3.Stub Generator:产生Stub

Client:marshal arguments, call, wait, unmarshal reply

Server:unmarshal arguments, call real function, marshal reply

4.Framework:

Client:

正确分发message到对应的server stub

跟踪所有发出去的请求

将收到的响应匹配到对应的call

多个caller共用一个socket

请求超时、重传的处理

Server:

对每个thread/callback正确分发reply(每个请求分配一个线程,或者请求多时维护线程池)

5.Binding:Client如何找到对应的Server

6.网络传输(如socket)

网络通信导致的Trade-off

1.性能开销(但不是传文本可以不用HTTP,会快些)

2.超时造成的额外问题

一旦发生超时,有这么几种解决方案,一般RPC使用第一或者第二

At Least Once:

重复resend,直到收到响应(但是可能会收到一堆响应)->要求调用无副作用

At Most Once:

重复resend, Server只保留一个request而忽略重复进行处理 -> 要求幂等性,多次调用如一

Exactly Once:

难以实现(没学)

3.错误隔离(C/S崩溃不影响彼此)


NFS

eg: mount –t nfs 10.131.250.6:/nfs/dir /mnt/nfs/dir

在应用程序调用文件系统接口时,NFS的所有调用如下。

NFS顺序图

值得注意的几点

fd<-->fh (file handler)

和下面Server无状态有关,而fd在Client内存中。因此传递对Server有用的fh,内含:

  • file system ID
  • inode number(path name可能会被rename)
  • generation number-维护一致性(如果inode被删除后,又被复用number)

NFS Server并没有open/close

Server stateless,状态由Client维护(即使Server崩溃重启,由于无状态,依然能处理request)

回传file attributes

维护Client上的metadata

Cache

Server Reply Cache:

由于网络传输延迟或丢包,Client可能重复request,因此根据Transaction ID建立Cache。这样重复的request可以返回相同的响应。

Client Cache:

存储一些最近使用的vnode(virtual node),attributes,blocks。减少RPC延迟。

Cache coherence :

Read/write:

与单机不同,无法保证获取最新数据,自行负责解决

Close-to-open:

open时获取modified time,与cache中进行比较,更新到最新数据。

close时写回(类似于cache被淘汰时写回内存)

左图中:C2open时能获取最新的数据

右图中:C2open时,由于C1未close,因此open时没有更新,因此read脏数据。

由于上述情况,一般需要另外进行并发的处理,例如对文件加锁。

Vnode

虚拟化

把文件属于local还是remote抽象化,左侧的箭头可以指向NFS client,也可能指向Local file system,从而让程序员忽视了实现细节。


GFS(Google FS)

随着规模的增大,单文件服务器也无法承受了。为了scalable,GFS使用一个服务器作为转发,多个文件服务器进行数据传输。这里的核心架构在于,将控制流和数据流解耦。

Flat Namespace

尽管namespace看起来有树形结构,实际上并没有directory,而是把整个路径映射到chunk上(因为目录访问需要多次访问chunk,而网络传输的开销远高于硬盘)

GFS Cluster

Single Master

内存中维护metadata(没有inode,没有symlink,没有hard link)

使用前缀编码进行压缩(每个entry小于64bytes)

  • namespace
  • 访问控制
  • 映射表
  • chunk的位置

Multiple Chunkserver

存储数据(chunk64mb)

传送heartbeat信息(如果崩溃了,需要让master保持同步)

Cache

Client和Chunkserver没有数据的cache(因为chunk的容量很大),但是Client有chunkserver的cache,下次访问可以不通过master。

(由master进行lease,进行临时的权限移交)

Fault Tolerance

Chunkserver

在这里使用三备份,当三个备份都写入完成后再进行response。三个buffer一般不会同时崩溃,所以写入buffer后就可以视为写入完成。

对于每个chunk产生32bit的checksum

定期扫描罕用文件,检查一致性

Master

  • 对于所有metadata修改log
  • shadow master
  • 状态在多机器冗余存储

Typical Workload

搜索引擎特点

大的流读取+小的随机读取(因此适合这种大chunk)

大量顺序写操作(append),先前爬取的数据较少修改

多client同时append一个文件(因此没有什么对已有内容的修改,写方面不追求效率)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RPC
  • NFS
  • GFS(Google FS)
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档