注意
本文档适用于 Ceph 的开发版本。
网络协议
本文档描述了 Ceph 使用的网络协议。为了理解这些结构的定义方式,建议先阅读 网络编码 的介绍。
Hello
协议从握手开始,握手确认两个节点都在使用 ceph 协议并共享一些基本信息。
连接
一旦 banner 经过验证且地址已交换,连接协商就开始了。首先,客户端发送一个包含其信息的 ceph_msg_connect 结构。
// From src/include/msgr.h
struct ceph_msg_connect {
u64le features; // Supported features (CEPH_FEATURE_*)
u32le host_type; // CEPH_ENTITY_TYPE_*
u32le global_seq; // Number of connections initiated by this host.
u32le connect_seq; // Number of connections initiated in this session.
u32le protocol_version;
u32le authorizer_protocol;
u32le authorizer_len;
u8 flags; // CEPH_MSG_CONNECT_*
u8 authorizer[authorizer_len];
}
连接回复
一旦发送了连接请求,连接就已有效打开,但服务器发送的第一个消息必须是连接回复消息。
struct ceph_msg_connect_reply {
u8 tag; // Tag indicating response code.
u64le features;
u32le global_seq;
u32le connect_seq;
u32le protocol_version;
u32le authorizer_len;
u8 flags;
u8 authorizer[authorizer_len];
}
MSGR 协议
这是一种用于传输消息的低级协议。此级别的消息由一个标签字节(用于标识消息类型)后跟消息数据组成。
// Virtual structure.
struct {
u8 tag; // CEPH_MSGR_TAG_*
u8 data[]; // Length depends on tag and data.
}
data 的长度由标签字节决定,并且根据消息类型,通过 data 数组本身中的信息来确定。
注意
如果您不理解消息类型,则无法确定消息的长度。
消息标签在 src/include/msgr.h 中定义,下面列出了当前的消息标签及其包含的数据。请注意,定义的结构在源代码中并不存在,仅用于表示协议。
CEPH_MSGR_TAG_CLOSE (0x06)
struct ceph_msgr_close {
u8 tag = 0x06;
u8 data[0]; // No data.
}
关闭消息指示连接正在关闭。
CEPH_MSGR_TAG_MSG (0x07)
struct ceph_msgr_msg {
u8 tag = 0x07;
ceph_msg_header header;
u8 front [header.front_len ];
u8 middle[header.middle_len];
u8 data [header.data_len ];
ceph_msg_footer footer;
}
// From src/include/msgr.h
struct ceph_msg_header {
u64le seq; // Sequence number.
u64le tid; // Transaction ID.
u16le type; // Message type (CEPH_MSG_* or MSG_*).
u16le priority; // Priority (higher is more important).
u16le version; // Version of message encoding.
u32le front_len; // The size of the front section.
u32le middle_len; // The size of the middle section.
u32le data_len; // The size of the data section.
u16le data_off; // The way data should be aligned by the receiver.
ceph_entity_name src; // Information about the sender.
u16le compat_version; // Oldest compatible encoding version.
u16le reserved; // Unused.
u32le crc; // CRC of header.
}
// From src/include/msgr.h
struct ceph_msg_footer {
u32le front_crc; // Checksums of the various sections.
u32le middle_crc; //
u32le data_crc; //
u64le sig; // Cryptographic signature.
u8 flags;
}
消息是 Ceph 的业务逻辑。它们用于在节点之间发送数据和请求。消息头包含消息长度,因此可以优雅地处理未知消息。
消息类型常量有两个名称 CEPH_MSG_* 和 MSG_*。两者唯一的区别是第一个被认为是“公共”的,而第二个仅供内部使用。协议级别没有区别。
CEPH_MSGR_TAG_ACK (0x08)
struct ceph_msgr_ack {
u8 tag = 0x08;
u64le seq; // The sequence number of the message being acknowledged.
}
CEPH_MSGR_TAG_KEEPALIVE (0x09)
struct ceph_msgr_keepalive {
u8 tag = 0x09;
u8 data[0]; // No data.
}
CEPH_MSGR_TAG_KEEPALIVE2 (0x0E)
struct ceph_msgr_keepalive2 {
u8 tag = 0x0E;
utime_t timestamp;
}
CEPH_MSGR_TAG_KEEPALIVE2_ACK (0x0F)
struct ceph_msgr_keepalive2_ack {
u8 tag = 0x0F;
utime_t timestamp;
}