《Ceph源码分析》——第3章,第1节Ceph网络通信框架

简介: 本节书摘来自华章出版社《Ceph源码分析》一书中的第3章,第3.1节Ceph网络通信框架,作者常涛,更多章节内容可以访问云栖社区“华章计算机”公众号查看 第3章Ceph网络通信 本章介绍Ceph网络通信模块,这是客户端和服务器通信的底层模块,用来在客户端和服务器之间接收和发送请求。

本节书摘来自华章出版社《Ceph源码分析》一书中的第3章,第3.1节Ceph网络通信框架,作者常涛,更多章节内容可以访问云栖社区“华章计算机”公众号查看

第3章
Ceph网络通信
本章介绍Ceph网络通信模块,这是客户端和服务器通信的底层模块,用来在客户端和服务器之间接收和发送请求。其实现功能比较清晰,是一个相对较独立的模块,理解起来比较容易,所以首先介绍它。

3.1 Ceph网络通信框架
一个分布式存储系统需要一个稳定的底层网络通信模块,用于各节点之间的互联互通。对于一个网络通信系统,要求如下:
高性能。性能评价的两个指标:带宽和延迟。
稳定可靠。数据不丢包,在网络中断时,实现重连等异常处理。
网络通信模块的实现在源代码src/msg的目录下,其首先定义了一个网络通信的框架,三个子目录里分别对应:Simple、Async、 XIO 三种不同的实现方式。
Simple是比较简单,目前比较稳定的实现,系统默认的用于生产环境的方式。 它最大的特点是:每一个网络链接,都会创建两个的线程,一个专门用于接收,一个专门用于发送。这种模式实现比较简单,但是对于大规模的集群部署,大量的链接会产生大量的线程,会消耗CPU资源,影响性能。
Async模式使用了基于事件的I/O多路复用模式。这是目前网络通信中广泛采用的方式,但是在Ceph中,官方宣称这种方式还处于试验阶段,不够稳定,还不能用于生产环境。
XIO方式使用了开源的网络通信库accelio来实现。这种方式需要依赖第三方的库accelio稳定性,需要对accelio的使用方式以及代码实现都比较熟悉。目前也处于试验阶段。特别注意的是,前两种方式只支持TCP/IP协议,XIO可以支持Infiniband网络。
在msg目录下定义了网络通信的抽象框架,它完成了通信接口和具体实现的分离。在其下分别有msg/simple子目录、msg/Async子目录、msg/xio子目录,分别对应三种不同的实现。

3.1.1 Message
类Message 是所有消息的基类,任何要发送的消息,都要继承该类,格式如图3-1所示。
`


55ecacce8f2796ea3382280751c9bd86b9880074

`
图3-1 消息发送格式
消息的结构如下:header是消息头,类似一个消息的信封(envelope),user_data是用于要发送的实际数据,footer是一个消息的结束标记,如下所示:
class Message : public RefCountedObject {
  ceph_msg_header  header;       // 消息头
  ceph_msg_footer  footer;       // 消息尾
  //用户数据
  bufferlist      payload;       // "front" unaligned blob
  bufferlist      middle;        // "middle" unaligned blob
  bufferlist      data;          // data payload (page-alignment will be preserved where possible)
  //消息相关的时间戳
  utime_t recv_stamp;            //开始接收数据的时间戳
  utime_t dispatch_stamp;        // dispatch的时间戳
  utime_t throttle_stamp;        //获取throttle的slot的时间戳
  utime_t recv_complete_stamp;   //接收完成的时间戳

  ConnectionRef connection;      //网络连接类
  uint32_t magic;                //消息的魔术字
  bi::list_member_hook<> dispatch_q;  //boost::intrusive需要的字段
}

下面分别介绍其中的重要参数。
ceph_msg_header为消息头,它定义了消息传输相关的元数据:
struct ceph_msg_header {
__le64 seq; //当前session内消息的唯一序号
__le64 tid; //消息的全局唯一的id
__le16 type; //消息类型
__le16 priority; //优先级
__le16 version; //消息编码的版本
__le32 front_len; // payload的长度
__le32 middle_len; // middle的长度
__le32 data_len; // data的长度

__le16 data_off; //对象的数据偏移量

struct ceph_entity_name src;//消息源

//一些旧的代码,用于兼容,如果为零就忽略
__le16 compat_version;
__le16 reserved;
__le32 crc; //消息头的crc32c校验信息
} attribute ((packed));
ceph_msg_footer为消息的尾部,附加了一些crc校验数据和消息结束标志:
struct ceph_msg_footer {
__le32 front_crc, middle_crc, data_crc;

                  //分别对应crc效验码

__le64 sig; //消息的64位signature
__u8 flags; //结束标志
} attribute ((packed));
消息带的数据分别保存在payload、middle、data这三个bufferlist中。payload一般保存Ceph操作相关的元数据,middle目前没有使用到,data一般为读写的数据。
在源代码src/messages下定义了系统需要的相关消息,其都是Message类的子类。

3.1.2 Connection
类Connection对应端(port)对端的socket链接的封装。其最重要的接口是可以发送消息:

struct Connection : public RefCountedObject {
  mutable Mutex lock;         //锁保护Connection的所有字段
  Messenger *msgr;     
  RefCountedObject *priv;     //链接的私有数据

  int peer_type;              //链接的peer类型
  entity_addr_t peer_addr;    //peer的地址
  utime_t last_keepalive, last_keepalive_ack;  
                  //最后一次发送keeplive的时间和最后一次接收keepalive的ACK的时间

private:
  uint64_t features;          //一些feature的标志位
public:
  bool failed;                //当值为true时,该链接为lossy链接已经失效了

  int rx_buffers_version;     //接收缓存区的版本
  
  map<ceph_tid_t,pair<bufferlist,int> > rx_buffers;  //接收缓冲区
         消息的标识ceph_tid --> (buffer, rx_buffers_version)的映射
}
其最重要的功能就是发送消息的接口:
virtual int send_message(Message *m) = 0;

3.1.3 Dispatcher
类Dispatcher是消息分发的接口,其分发消息的接口为:
`virtual bool ms_dispatch(Message *m) = 0;
virtual void ms_fast_dispatch(Message *m);`
Server端注册该Dispatcher类用于把接收到的Message请求分发给具体处理的应用层。Client端需要实现一个Dispatcher函数,用于处理收到的ACK应对消息。

3.1.4 Messenger
Messenger是整个网络抽象模块,定义了网络模块的基本API接口。网络模块对外提供的基本功能,就是能在节点之间发送和接受消息。
向一个节点发送消息的命令如下:
virtual int send_message(Message *m, const entity_inst_t& dest) = 0;
注册一个Dispatcher用来分发消息的命令如下:
void add_dispatcher_head(Dispatcher *d)

3.1.5 网络连接的策略
Policy定义了Messenger处理Connection的一些策略:

struct Policy {
  bool lossy;      //如果为true,该当该连接出现错误时就删除
  bool server;     //如果为true,为服务端,都是被动连接
  bool standby;    //如果为true,该连接处于等待状态
  bool resetcheck; //如果为true,该连接出错后重连
 
  //该connection相关的流控操作
  Throttle *throttler_bytes;
  Throttle *throttler_messages;

  //本地端的一些feature标志
  uint64_t features_supported;
  //远程端需要的一些feature标志
  uint64_t features_required;
}

3.1.6 网络模块的使用
通过下面最基本的服务器和客户端的实例程序,了解如何调用网络通信模块提供的接口来完成收发请求消息的功能。

  1. Server程序分析
    Server程序源代码在test/simple_server.cc里,这里只展示有关网络部分的核心流程。

1)调用Messenger的函数create 创建一个Messenger的实例,配置选项g_conf->ms_type为配置的实现类型,目前有三种方式:

simple、async、xio:
messenger = Messenger::create(g_ceph_context, 
            g_conf->ms_type, entity_name_t::MON(-1),
            "simple_server",
            0 /* nonce */);
2)设置Messenger的属性:
messenger->set_magic(MSG_MAGIC_TRACE_CTR);
messenger->set_default_policy(
  Messenger::Policy::stateless_server(CEPH_FEATURES_ALL, 0));
3)对于Server,需要bind服务端地址:
r = messenger->bind(bind_addr);
if (r < 0)
    goto out;
common_init_finish(g_ceph_context);
4)创建一个Dispatcher,并添加到Messenger:
dispatcher = new SimpleDispatcher(messenger);
messenger->add_dispatcher_head(dispatcher); 
5)启动Messenger:
messenger->start();
messenger->wait(); //本函数必须等start完成才能调用 
SimpleDispatcher函数里实现了ms_dispatch,用于把接收到的各种请求消息分发给相关的处理函数。
  1. Client程序分析
    源代码在test/simple_client.cc里,这里只展示有关网络部分的核心流程。

1)调用Messenger的函数create创建一个Messenger的实例:

messenger = Messenger::create(g_ceph_context, g_conf->ms_type,
            entity_name_t::MON(-1),
            "client",
            getpid());

2)设置相关的策略:
`messenger->set_magic(MSG_MAGIC_TRACE_CTR);
messenger->set_default_policy(Messenger::Policy::lossy_client(0, 0));`
3)创建Dispatcher类并添加,用于接收消息:
`dispatcher = new SimpleDispatcher(messenger);
messenger->add_dispatcher_head(dispatcher);
dispatcher->set_active(); `
4)启动消息:
`r = messenger->start();
if (r < 0)

goto out;`

5)下面开始发送请求,先获取目标Server的链接:
conn = messenger->get_connection(dest_server);
6)通过Connection来发送请求消息。这里的消息发送方式都是异步发送,接收到请求消息的ACK应答消息后,将在Dispatcher的 ms_dispatch或者ms_fast_dispatch处理函数里做相关的处理:
`Message *m;
for (msg_ix = 0; msg_ix < n_msgs; ++msg_ix) {
//如果需要,这里要添加实际的数据
if (! n_dsize) {

m = new MPing();

} else {

m = new_simple_ping_with_data("simple_client", n_dsize);

}
conn->send_message(m);
}`
综上所述,通过Ceph的网络框架发送消息比较简单。在Server端,只需要创建一个Messenger实例,设置相应的策略并绑定服务端口,然后就设置一个Dispatcher来处理接收到的请求。在Client端,只需要创建一个Messenger实例,设置相关的策略和Dispatcher用于处理返回的应答消息。通过获取对应Server的connection来发送消息即可。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
11月前
|
监控 安全
从 Racket 语言出发,创新员工网络监控软件的框架
在数字化企业环境中,员工网络监控软件对于保障信息安全和提升效率至关重要。Racket 语言凭借其独特特性和强大功能,为开发创新的监控软件提供了新可能。通过捕获和分析网络数据包、记录员工网络活动日志,甚至构建复杂的监控框架,Racket 能够满足企业的定制化需求,为企业信息安全和管理提供强有力支持。未来,基于 Racket 的创新解决方案将不断涌现。
130 6
|
3月前
|
机器学习/深度学习 API TensorFlow
BayesFlow:基于神经网络的摊销贝叶斯推断框架
BayesFlow 是一个基于 Python 的开源框架,利用摊销神经网络加速贝叶斯推断,解决传统方法计算复杂度高的问题。它通过训练神经网络学习从数据到参数的映射,实现毫秒级实时推断。核心组件包括摘要网络、后验网络和似然网络,支持摊销后验估计、模型比较及错误检测等功能。适用于流行病学、神经科学、地震学等领域,为仿真驱动的科研与工程提供高效解决方案。其模块化设计兼顾易用性与灵活性,推动贝叶斯推断从理论走向实践。
135 7
BayesFlow:基于神经网络的摊销贝叶斯推断框架
|
10月前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
414 6
|
11月前
|
机器学习/深度学习 人工智能
类人神经网络再进一步!DeepMind最新50页论文提出AligNet框架:用层次化视觉概念对齐人类
【10月更文挑战第18天】这篇论文提出了一种名为AligNet的框架,旨在通过将人类知识注入神经网络来解决其与人类认知的不匹配问题。AligNet通过训练教师模型模仿人类判断,并将人类化的结构和知识转移至预训练的视觉模型中,从而提高模型在多种任务上的泛化能力和稳健性。实验结果表明,人类对齐的模型在相似性任务和出分布情况下表现更佳。
276 3
|
11月前
|
安全 网络安全 区块链
网络安全与信息安全:构建数字世界的防线在当今数字化时代,网络安全已成为维护个人隐私、企业机密和国家安全的重要屏障。随着网络攻击手段的不断升级,从社交工程到先进的持续性威胁(APT),我们必须采取更加严密的防护措施。本文将深入探讨网络安全漏洞的形成原因、加密技术的应用以及提高公众安全意识的重要性,旨在为读者提供一个全面的网络安全知识框架。
在这个数字信息日益膨胀的时代,网络安全问题成为了每一个网民不可忽视的重大议题。从个人信息泄露到企业数据被盗,再到国家安全受到威胁,网络安全漏洞如同隐藏在暗处的“黑洞”,时刻准备吞噬掉我们的信息安全。而加密技术作为守护网络安全的重要工具之一,其重要性不言而喻。同时,提高公众的安全意识,也是防范网络风险的关键所在。本文将从网络安全漏洞的定义及成因出发,解析当前主流的加密技术,并强调提升安全意识的必要性,为读者提供一份详尽的网络安全指南。
|
12月前
|
存储 SQL 安全
网络安全与信息安全:守护数字世界的坚盾在这个高度数字化的时代,网络安全和信息安全已经成为个人、企业乃至国家安全的重要组成部分。本文将深入探讨网络安全漏洞、加密技术以及安全意识的重要性,旨在为读者提供一个全面的网络安全知识框架。
随着互联网技术的飞速发展,网络安全问题日益凸显。从个人信息泄露到企业数据被盗,再到国家安全受到威胁,网络安全事件层出不穷。本文将从网络安全漏洞的定义与分类入手,探讨常见的网络攻击手段;随后深入解析加密技术的原理及其在保护信息安全中的作用;最后强调提升公众与企业的安全意识的重要性,并提出具体的建议。通过综合运用这些知识点,我们可以更好地构建起一道道坚固的防线,守护我们的数字世界。
|
12月前
|
编解码 分布式计算 网络协议
Netty高性能网络框架(一)
Netty高性能网络框架(一)
|
6月前
|
监控 安全 Cloud Native
企业网络架构安全持续增强框架
企业网络架构安全评估与防护体系构建需采用分层防御、动态适应、主动治理的方法。通过系统化的实施框架,涵盖分层安全架构(核心、基础、边界、终端、治理层)和动态安全能力集成(持续监控、自动化响应、自适应防护)。关键步骤包括系统性风险评估、零信任网络重构、纵深防御技术选型及云原生安全集成。最终形成韧性安全架构,实现从被动防御到主动免疫的转变,确保安全投入与业务创新的平衡。
|
9月前
|
机器学习/深度学习 算法 PyTorch
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
本文探讨了图神经网络(GNN)与大型语言模型(LLM)结合在知识图谱问答中的应用。研究首先基于G-Retriever构建了探索性模型,然后深入分析了GNN-RAG架构,通过敏感性研究和架构改进,显著提升了模型的推理能力和答案质量。实验结果表明,改进后的模型在多个评估指标上取得了显著提升,特别是在精确率和召回率方面。最后,文章提出了反思机制和教师网络的概念,进一步增强了模型的推理能力。
415 4
基于图神经网络的大语言模型检索增强生成框架研究:面向知识图谱推理的优化与扩展
|
10月前
|
人工智能 自然语言处理
WebDreamer:基于大语言模型模拟网页交互增强网络规划能力的框架
WebDreamer是一个基于大型语言模型(LLMs)的网络智能体框架,通过模拟网页交互来增强网络规划能力。它利用GPT-4o作为世界模型,预测用户行为及其结果,优化决策过程,提高性能和安全性。WebDreamer的核心在于“做梦”概念,即在实际采取行动前,用LLM预测每个可能步骤的结果,并选择最有可能实现目标的行动。
236 1
WebDreamer:基于大语言模型模拟网页交互增强网络规划能力的框架

热门文章

最新文章