Ceph中的序列化

2021-07-11 01:41:09 字數 3389 閱讀 8152

yuandong| 2015.05.11

作為主要和磁碟、網路打交道的分布式儲存系統,序列化是最基礎的功能之一,今天我們來看一下ceph中序列化的設計與實現。

1 ceph序列化的方式

序列化(ceph稱之為encode)的目的是將資料結構表示為二進位製流的方式,以便通過網路傳輸或儲存在磁碟等儲存介質上,其逆過程稱之為反序列化(ceph稱之為decode)。 例如對於字串「abc」,其序列化結果為8個位元組(bytes):

03 00 00 00 61 62 63

其中頭四個位元組(03 00 00 00)表示字串的長度為3個字元,後3個位元組(61 62 63)分別是字元「abc」的ascii碼的16進製表示。 ceph採用little-endian的序列化方式,即低位址存放最低有效位元組,所以32位整數0x12345678的序列化結果為78 56 34 12。

由於序列化在整個系統中是非常基本,非常常用的功能,ceph將其序列化方式設計為乙個同一的結構,即任意支援序列化的資料結構,都必須提供一對定義在全域性命名空間上的序列化/反序列化(encode/decode)函式。例如,如果我們定義了乙個結構體inode,就必須在全域性命名空間中定義以下兩個方法:

encode(struct inode, bufferlist bl);

decode(struct inode, bufferlist::iterator bl);

在此基礎上,序列化的使用就變得非常容易 。 即對於任意可序列化的型別t的例項instance_t,都可以通過以下語句:

::encode(instance_t, instance_bufferlist);

將instance_t序列化並儲存到bufferlist類的例項instance_bufferlist中。

以下**演示了將乙個時間戳以及乙個inode序列化到乙個bufferlist中。

utime_t timestamp;

inode_t inode;

bufferlist bl;

::encode(timetamp, bl)

::encode(inode, bl);

序列化後的資料可以通過反序列化方法讀取,例如以下**片段從乙個bufferlist中反序列化乙個時間戳和乙個inode(前提是該bl中已經被序列化了乙個utime_t和乙個inode,否則會報錯)。

bufferlist::iterator bl;

::decode(timetamp, bl)

::decode(inode, bl);

2 資料結構的序列化ceph為其所有用到資料型別提供了序列化方法或反序列化方法,這些資料型別包括了絕大部分基礎資料型別(int、bool等)、結構體型別的序列化(ceph_mds_request_head等)、集合型別(vector、list、set、map等)、以及自定義的複雜資料型別(例如表示inode的inode_t等),以下分別介紹不同資料型別的序列化實現方式。

2.1 基本資料型別的序列化

基本資料型別的序列化結果基本就是該型別在記憶體中的表示形式。基本資料型別的序列化方法使用手工編寫,定義在include/encoding.h中,包括以下型別:

在手工編寫encode方法過程中,為了避免重複**,借助了write_raw_encoder和write_inttype_encoder兩個巨集。

2.2 結構體型別的序列化

結構體型別的序列化方法與基本資料型別的序列化方法一致,即使用結構體的記憶體布局作為序列化的形式。在結構體定義完成後,通過呼叫write_raw_encoder巨集函式生成結構體的全域性encode方法,例如結構體ceph_mds_request_head相關結構實現如下。

struct ceph_mds_request_head __attribute__ ((packed));

write_raw_encoder(ceph_mds_request_head)

其中:

template

inline void encode_raw(const t& t, bufferlist& bl)

template

inline void decode_raw(t& t, bufferlist::iterator &p)

2.3 集合資料型別的序列化集合資料型別序列化的基本思路包括兩步:

序列化集合大小,

序列化集合內的所有元素

例如vector& v的序列化方法:

template

inline void encode(const std::vector& v, bufferlist& bl)

其中元素的序列化通過呼叫該元素的encode方法實現。

常用集合資料型別的序列化已經由ceph實現,位於include/encoding.h中,包括以下集合型別:

集合型別的序列化方法皆為基於泛型(模板類)的實現方式,適用於所有泛型派生類。

2.4 複雜資料型別的序列化

除以上兩種業務無關的資料型別外,其它資料型別的序列化實現包括兩部分:

在型別內部現實encode方法,

將型別內部的encode方法重定義為全域性方法。

以下以utime_t類為例:

class utime_t tv;

void encode(bufferlist &bl) const

void decode(bufferlist::iterator &p) };

write_class_encoder(utime_t)

utime_t內部實現了encode和decode兩個方法,write_class_encoder巨集函式將這兩個方法轉化為全域性方法。

write_class_encoder巨集函式定義於include/encoding.h中,其定義如下:

#define write_class_encoder(cl)

inline void encode(const cl &c, bufferlist &bl, uint64_t features=0)

inline void decode(cl &c, bufferlist::iterator &p)

複雜資料結構內部的encode方法的實現方式通常是呼叫其內部主要資料結構的encode方法,例如utime_t類的encode方法實際上是序列化內部的tv.tv_sec和tv.tv_nsec兩個成員。

序列化(序列化)

原書上翻譯為序列化,msdn翻譯為序列化 作用 當需要儲存,或者網路傳輸 remoting時,資料 物件或值 需要序列化 類似於打包傳輸檔案。system.serializableattribute 序列化是指儲存和獲取磁碟檔案 記憶體或其他地方中的物件。在序列化時,所有的例項資料都儲存到儲存介質上...

序列化(模型序列化 序列化巢狀)

from rest framework import serializers from meituan.models import merchant,class merchantserializer serializers.modelserializer class meta model merch...

Python中的序列化和反序列化

python中的序列化和反序列化通常有兩種模組的使用 1 pickle模組 2 json模組 1 序列化 就是把不可傳輸的物件轉換為可儲存或可傳輸的過程 2 反序列化 就是把在磁碟,等介質中的資料轉換為物件 描述 對於大多數應用程式來講,dump 和load 函式的使用就是你使用pickle模組所需...