日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Ceph Async RDMA网络通信性能优化

發布時間:2023/12/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Ceph Async RDMA网络通信性能优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Ceph Async RDMA網絡性能優化

濟南友泉軟件有限公司

?

目錄

一、???????? 現有代碼分析

1.1.?????? Reactor模型

1.1.1.??? Reactor模型的優點

1.1.2.??? Reactor模型的優點.

1.2.?????? 有限狀態機模型

1.3.?????? Async模塊

1.2.1.??? Async工作原理

1.2.2.??? Async主要組件

1.4.?????? RDMA

1.3.1.??? RDMA三種不同的硬件實現

1.3.2.??? 相關組件

二、???????? 性能優化工作匯總

2.1??????? RDMA網絡通信配置

2.2??????? RoCE網絡通信的實現

2.3??????? 性能測試平臺開發

2.2.1??? aysnc_server/async_client

2.2.2??? ceph_perf_msgr_server/ceph_perf_msgr_client

2.4??????? QueuePair發送隊列

2.5??????? TCMalloc優化內存分配

2.6??????? 工作線程數調優

2.7??????? 多線程Reactor模型

2.8??????? 消息接收緩存

附錄(Ⅰ):連接過程狀態遷移圖

參閱資料

?

  • 現有代碼分析

網絡通信模塊的實現在源代碼src/msg的目錄下,該目錄主要包括Messenger、Connection、Message、Dispatch等類,這些類定義了網絡通信的框架與接口。三個子目錄simple、async、xio分別對應三種不同的網絡通信模型。simple、xio在最新的版本中已經被廢棄,async是目前系統默認的網絡通信方式。因此,本次網絡通信優化的工作主要在async基礎之上開展。

Reactor模型

為了處理高并發的網絡I/O流,async模塊采用了Reactor模型。在Reactor中,每一種handler會出處理一種event。這里會有一個全局的管理者selector,我們需要把channel注冊感興趣的事件,那么這個selector就會不斷在channel上檢測是否有該類型的事件發生,如果沒有,那么主線程就會被阻塞,否則就會調用相應的事件處理函數即handler來處理。

Reactor模型原理

Reactor模型主要組件

  • Reactor模型的優點
  • 響應快,不必為單個同步時間所阻塞,雖然Reactor本身依然是同步的;編程相對簡單,可以最大程度的避免復雜的多線程及同步問題,并且避免了多線程/進程的切換開銷; 可以方便的通過增加Reactor實例個數來充分利用CPU資源;reactor框架本身與具體事件處理邏輯無關,具有很高的復用性;

  • Reactor模型的缺點
  • 相比傳統的簡單模型,Reactor增加了一定的復雜性,因而有一定的門檻,并且不易于調試; Reactor模式需要底層的Synchronous Event Demultiplexer支持,比如Java中的Selector支持,操作系統的select系統調用支持,如果要自己實現Synchronous Event Demultiplexer可能不會有那么高效;Reactor模式在IO讀寫數據時還是在同一個線程中實現的,即使使用多個Reactor機制的情況下,那些共享一個Reactor的Channel如果出現一個長時間的數據讀寫,會影響這個Reactor中其他Channel的相應時間,比如在大文件傳輸時,IO操作就會影響其他Client的相應時間,因而對這種操作,使用傳統的Thread-Per-Connection或許是一個更好的選擇,或則此時使用Proactor模式。

  • 有限狀態機模型
  • 有限狀態機(Finite State Machine, FSM),是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。

    FSM模型把模型的多狀態、多狀態間的轉換條件解耦;可以使維護變得容易,代碼也更加具有可讀性。

    AsyncConnection連接建立過程中地狀態遷移圖參閱附錄(Ⅰ)。

    ?

  • Async模塊
  • Async工作原理
  • Async主要組件
  • AsyncMessenger

    管理網絡連接

    AsyncConnection

    網路通信連接,定義網絡通信應用層協議

    NetworkStack

    管理Worker對象及其對應地線程

    Worker

    網絡I/O流處理單元,每個Worker對應一個工作線程

    ServerSocket/ServerSocketImpl

    C/S模式監聽套接字,向上屏蔽了各種不同的網絡編程接口

    ConnectedSocket/ConnectedSocketImpl

    C/S模式連接套接字,向上屏蔽了各種不同的網絡編程接口

    EventCenter

    事件分發器,負責事件注冊、事件分發

    EventCallback

    當對應的事件發生時,由EventCenter負責回調

    EventEpoll

    對epoll進行封裝,輪詢網絡I/O事件

    ?

  • RDMA
  • RDMA是Remote Direct Memory Access的縮寫,通俗的說可以看成是遠程的DMA技術,為了解決網絡傳輸中服務器端數據處理的延遲而產生的。

    ???????????????????????? RDMA工作原理

  • RDMA三種不同的硬件實現
  • 目前,有三種RDMA協議的實現:Infiniband、RoCE、iWARP。由于RoCE具備明顯性能和成本優勢,將逐漸成為市場主流。

    軟件棧對比

    ?

    ?

    Infiniband (IB)

    iWARP

    RoCE

    標準組織

    IBTA

    IETF

    IBTA

    性能

    最好

    稍差

    與IB相當

    成本

    網卡廠商

    Mellanox

    Chelsio

    Mellanox

    Emulex

    性能、成本對比

    ?

    Infiniband網絡最好,但網卡和交換機是價格也很高,然而RoCEv2和iWARP僅需使用特殊的網卡就可以了,價格也相對便宜很多。

  • 相關組件
  • Device/DeviceList

    抽象RDMA網卡,根據icfs.conf配置網卡參數

    Infiniband

    封裝IB Verbs網絡編程接口及組件

    RDMAConnectedSocketImpl

    仿socket連接套接字,采用偽fd實現網絡I/O流的數據讀寫

    RDMAConnTCP

    為RDMAConnectedSocketImpl服務,利用利用TCP/IP協議建立RDMA連接

    RDMAServerSocketImpl

    仿socket服務套接字,定義服務接口

    RDMAServerConnTCP

    實現RDMAServerSocketImpl接口,利用TCP/IP協議建立RDMA連接

    ?

    RDMADispatcher

    輪詢RDMA網絡I/O流可讀事件,將網絡I/O流可讀數據分發到對應RDMAConnectedSocketImpl

    輪詢RDMA網絡I/O流可寫事件,將網絡I/O流可寫數據分發到某個RDMAWorker

    RDMAWorker

    網絡I/O流處理單元,每個RDMAWorker對應一個工作線程

    RDMAStack

    管理RDMAWorker對象及其對應地線程

    ?

    ?

    ?

    • 性能優化工作匯總
  • RDMA網絡通信配置
  • 在安裝完網卡及其驅動之后,需要啟動openibd,運行以下命令

    service openibd start

    chkconfig openibd on

    對于IB網絡,還需要啟動opensmd,

    service opensmd start

    chkconfig opensmd on

    網絡啟動之后,通過ibstat可以查看當前網絡設備狀態,

    [root@server42 ~]# ibstat

    CA 'mlx5_0'

    ???? CA type: MT4119

    ???? Number of ports: 1

    ???? Firmware version: 16.25.1020

    ???? Hardware version: 0

    ???? Node GUID: 0xb8599f0300bd417a

    ???? System image GUID: 0xb8599f0300bd417a

    ???? Port 1:

    ????????????? State: Active

    ????????????? Physical state: LinkUp

    ????????????? Rate: 40

    ????????????? Base lid: 0

    ????????????? LMC: 0

    ????????????? SM lid: 0

    ????????????? Capability mask: 0x04010000

    ????????????? Port GUID: 0xba599ffffebd417a

    ????????????? Link layer: Ethernet

    CA 'mlx5_1'

    ???? CA type: MT4119

    ???? Number of ports: 1

    ???? Firmware version: 16.25.1020

    ???? Hardware version: 0

    ???? Node GUID: 0xb8599f0300bd417b

    ???? System image GUID: 0xb8599f0300bd417a

    ???? Port 1:

    ????????????? State: Active

    ????????????? Physical state: LinkUp

    ????????????? Rate: 40

    ????????????? Base lid: 0

    ????????????? LMC: 0

    ????????????? SM lid: 0

    ????????????? Capability mask: 0x04010000

    ????????????? Port GUID: 0xba599ffffebd417b

    ????????????? Link layer: Ethernet

    通過ib_send_bw、ib_send_lat等工具可以測試網絡帶寬、延遲等性能。

    Async提供了posix、rdma兩種底層網絡通信的方式,為了使用RDMA協議實現高帶寬、低延遲的網絡通信,需要配置rdma網絡及軟件定義參數。

    使用rdma verbs創建QueuePair時,需要通信雙方rdma設備的硬件信息,通常利用TCP/IP完成rdma連接雙方的硬件參數的交換,因此需要配置集群網段,即

    public_network = 100.7.45.0/20

    cluster_network = 188.188.44.0/20

    Async模塊默認采用TCP/IP協議進行網絡通信,需要改成rdma協議

    ms_type = async

    ms_async_transport_type = rdma

    RDMA Verbs API按照設備名對設備進行操作,為了兼容Linux操作系統的命名,需要進行設備網絡名到設備名的轉換,Mellanox驅動提供了以下命令用于獲取設備名與網絡名之間的映射關系:

    [root@server42 ~]# ibdev2netdev

    i40iw0 port 1 ==> eno1 (Up)

    mlx5_0 port 1 ==> enp59s0f0 (Up)

    mlx5_1 port 1 ==> enp59s0f1 (Up)

    據此,可以在配置環境中設置網絡通信設備的名稱,即

    ms_async_rdma_public_device_name = enp59s0f0

    ms_async_rdma_cluster_device_name = enp59s0f1

  • RoCE網絡通信的實現
  • 由于Infiniband與RoCE網絡開發采用相同上層Verbs API,因此,IB網絡通信代碼可以完全在RoCE硬件上運行,整個代碼幾乎不需要改動。

  • 性能測試平臺開發
  • 為了能夠對網絡模塊通信性能及優化效果進行定性、定量地深入研究,需要一套相對獨立地RDMA網絡通信性能測試工具。

  • aysnc_server/async_client
  • async_client向async_server發送MSG_DATA_PING類型地數據包,async_server當受到2000個數據包之后會自動關閉連接,async_client監測到async_server端關閉之后,async_client會停止發送數據包,同時輸出網絡通信性能地統計信息。

    async_server命令參數

    --addr X ip to listen

    --port X port to bind

    ?

    async_client命令參數:

    --msgs X number of msg to transport

    --dszie X size of each msg to transport

    --addr X ip of the server

    --port X port of the server

    這種測試工具其實是利用async_server端連接關閉作為消息數據包發送結束的標志,因為async_client感知到async_server連接關閉需要一定的時間,從而導致不能夠準確地測試網絡性能。

  • ceph_perf_msgr_server/ceph_perf_msgr_client
  • 采用“請求-應答”模式,具體實現上與實際的OSD業務通信流程比較相似,因此可以較好的反映網絡通信性能。

    client向server端發送指定數量的MOSDOp消息,server端對于收到的每個MOSDOp消息,都會向client端發送MOSDOpReply消息。

    但是,ceph_perf_msgr_client在ClientThread::entry()中存在一個Bug,即

    ??? void *entry() {

    ????? lock.Lock();

    ????? for (int i = 0; i < ops; ++i) {

    ??????? if (inflight > uint64_t(concurrent)) {

    ????????? cond.Wait(lock);

    ??????? }

    ??????? MOSDOp *m = new MOSDOp(client_inc.read(), 0, oid, oloc, pgid, 0, 0, 0);

    ????? ??m->write(0, msg_len, data);

    ??????? inflight++;

    ??????? conn->send_message(m);

    ??????? //cerr << __func__ << " send m=" << m << std::endl;

    ????? }

    由于調用write()函數之后,data內的數據會被清空,所以第一次調用之后,后面發送的數據包其實沒有數據,需要改成

    ??? void *entry() {

    ????? lock.Lock();

    ????? for (int i = 0; i < ops; ++i) {

    ??????? if (inflight > uint64_t(concurrent)) {

    ????????? cond.Wait(lock);

    ??????? }

    ??????? MOSDOp *m = new MOSDOp(client_inc.read(), 0, oid, oloc, pgid, 0, 0, 0);

    ??????? /*

    ??????? m->write(0, msg_len, data);

    ??????? */

    ??????? bufferlist msg_data(data);

    ??????? m->write(0, msg_len, msg_data);

    ?

    ??????? inflight++;

    ??????? conn->send_message(m);

    ??????? //cerr << __func__ << " send m=" << m << std::endl;

    ????? }

    ????? lock.Unlock();

    ????? msgr->shutdown();

    ???? ?return 0;

    }

    ?

    server 41

    server 42

    Client性能

    Server配置
    RoCE,event

    Client
    RoCE,event

    并行數
    worker threads

    并行數
    numjobs

    隊列深度
    concurrency

    request個數
    ios

    耗時(us)

    IOPS

    延時(us)

    1

    1

    32

    100K

    4324564

    23123.72

    43.24564

    1

    2

    32

    100K

    3464919

    57721.41

    34.64919

    1

    4

    32

    100K

    4003939

    99901.62

    40.03939

    1

    8

    32

    100K

    5313240

    150567.3

    53.1324

    1

    16

    32

    100K

    11167830

    143268.7

    111.6783

    1

    32

    32

    100K

    27079705

    118169.7

    270.7971

    1

    64

    32

    100K

    68204271

    93835.77

    682.0427

    1

    64

    64

    100K

    66653653

    96018.74

    666.5365

    ?

    ?

    ?

    ?

    server 41

    server 42

    Client性能

    Server配置
    RoCE,polling

    Client
    RoCE,polling

    并行數
    worker threads

    并行數
    numjobs

    隊列深度
    concurrency

    request個數
    ios

    耗時(us)

    IOPS

    延時(us)

    1

    1

    32

    100K

    4952843

    20190.424

    49.52843

    1

    2

    32

    100K

    3712582

    53870.864

    37.12582

    1

    4

    32

    100K

    3664009

    109170.038

    36.64009

    1

    8

    32

    100K

    5526721

    144751.291

    55.26721

    1

    16

    32

    100K

    11834255

    135200.737

    118.3426

    1

    32

    32

    100K

    33805670

    94658.6771

    338.0567

    1

    64

    32

    100K

    67214894

    95216.9916

    672.1489

    1

    64

    64

    100K

    68273589

    93740.4946

    682.7359

    ?

    從以上測試結果來看,主要有以下結論:

    • 無論采用polling還是event輪詢模式,網絡性能幾乎一樣。
    • 隨著連接數的增大,網絡性能逐漸達到性能瓶頸,最大IOPS為14萬左右。
    • 當連接數增大到一定程度,IOPS維持在9萬左右。
  • QueuePair發送隊列
  • 通過讀取ms_async_rdma_receive_buffer與ms_async_rdma_send_buffers來配置注冊內存大小,在Device::create_queue_pair()中,會根據ms_async_rdma_send_buffers來創建QueuePair.,即

    Infiniband::QueuePair* Device::create_queue_pair(IcfsContext *cct, ibv_qp_type type)

    {

    ? Infiniband::QueuePair *qp = new QueuePair(

    ????? cct, *this, type, active_port->get_port_num(), srq, rx_cq, rx_cq, max_send_wr, max_recv_wr);

    ?

    ? if (qp->init()) {

    ??? delete qp;

    ??? return NULL;

    ? }

    ? return qp;

    }

    ?

    但是ms_async_rdma_send_buffers設置較大會導致創建QueuePair失敗,需要獨立地設置注冊內存以及QueuePair的創建,

    Infiniband::QueuePair* Device::create_queue_pair(IcfsContext *cct, ibv_qp_type type)

    {

    //<nene>: use the "ms_async_rdma_qp_max_send_wr" instead of "max_send_wr"

    /*

    ? Infiniband::QueuePair *qp = new QueuePair(

    ????? cct, *this, type, active_port->get_port_num(), srq, rx_cq, rx_cq, max_send_wr, max_recv_wr);

    */

    ? uint32_t qp_max_send_wr = cct->_conf->ms_async_rdma_qp_max_send_wr;

    ? Infiniband::QueuePair *qp = new QueuePair(

    ????? cct, *this, type, active_port->get_port_num(), srq, rx_cq, rx_cq, qp_max_send_wr, max_recv_wr);

    //</nene>

    ? if (qp->init()) {

    ??? delete qp;

    ??? return NULL;

    ? }

    ? return qp;

    }

    經過修改之后,達到了以下效果,

    • 注冊內存buffer大小(ms_async_rdma_buffer_size)可由4096增加到131072
    • 注冊內存buffer數量(ms_async_rdma_send_buffers/ms_async_receive_buffers)可由1024增加到10240
    • 解決了1M大小數據塊測試過程中數據斷流問題
  • TCMalloc優化內存分配
  • TCMalloc全稱Thread-Caching Malloc,即線程緩存的malloc,實現了高效的多線程內存管理,用于替代系統的內存分配相關的函數(malloc、free,new,new[]等)。

    icfs_perf_msgr_server/icfs_perf_msgr_client測試工具沒有采用TCMalloc,但是msg模塊卻使用了TCMAlloc進行優化,為了更加準確地描述網絡模塊地性能,需要對測試程序配置對TCMalloc的支持。

    在測試程序中采用TCMalloc分配內存,測試結果如下,

    server 41

    server 42

    Client性能

    Server配置
    RoCE,event,tcmalloc

    Client
    RoCE,event,tcmalloc

    并行數
    worker threads

    并行數
    numjobs

    隊列深度
    concurrency

    request個數
    ios

    耗時(us)

    IOPS

    延時(us)

    1

    1

    32

    100K

    3208947

    31162.87

    32.08947

    1

    2

    32

    100K

    3432609

    58264.72

    34.32609

    1

    4

    32

    100K

    3349781

    119410.8

    33.49781

    1

    8

    32

    100K

    4502944

    177661.5

    45.02944

    1

    16

    32

    100K

    6317459

    253266.4

    63.17459

    1

    32

    32

    100K

    12766794

    250650.2

    127.6679

    1

    64

    32

    100K

    25002414

    255975.3

    250.0241

    1

    64

    64

    100K

    25310469

    252859.8

    253.1047

    從上面地優化結果可以看出,

    • 經過TCMalloc內存分配優化,最大IOPS增加近160%
    • 連接數增大到一定程度,整體性能不再提高,1S1C情況下,最大IOPS25萬左右。
  • 工作線程數調優
  • 每個AsyncMessenger根據ms_async_op_threads生成Worker線程,每個Worker線程包含一個事件分發器EventCenter來處理網絡I/O流事件及其回調函數分發。

    對于單個AsyncMessenger,增大ms_async_op_threads,生成多個Worker線程,研究不同情況地網絡通信性能。

    ?

    ?

    ?

    server 41

    server 42

    Client性能

    CPU占有率

    Server配置
    RoCE,event,tcmalloc
    ms_async_op_threads=3

    Client
    RoCE,event,tcmalloc
    ms_async_op_threads=3

    并行數
    worker threads

    并行數
    numjobs

    隊列深度
    concurrency

    request個數
    ios

    耗時(us)

    IOPS

    延時(us)

    1

    1

    32

    100K

    3331462

    30016.85

    33.31462

    69.1%

    1

    2

    32

    100K

    3372494

    59303.29

    33.72494

    133.4%

    1

    4

    32

    100K

    3927981

    101833.5

    39.27981

    231.1%

    1

    8

    32

    100K

    6795892

    117718.2

    67.95892

    284.8%

    1

    16

    32

    100K

    11972282

    133642

    119.7228

    343%

    1

    32

    32

    100K

    19545797

    163718.1

    195.458

    342.9%

    1

    64

    32

    100K

    34377666

    186167.4

    343.7767

    362.8%

    1

    64

    64

    100K

    29780075

    214908.8

    297.8008

    369.5%

    ?

    ?

    server 41

    server 42

    Client性能

    CPU占有率

    Server配置
    RoCE,event,tcmalloc
    ms_async_op_threads=10

    Client
    RoCE,event,tcmalloc
    ms_async_op_threads=10

    并行數
    worker threads

    并行數
    numjobs

    隊列深度
    concurrency

    request個數
    ios

    耗時(us)

    IOPS

    延時(us)

    1

    1

    32

    100K

    3208947

    31162.87

    32.08947

    53.5%

    1

    2

    32

    100K

    3432609

    58264.72

    34.32609

    114.6%

    1

    4

    32

    100K

    3349781

    119410.8

    33.49781

    249%

    1

    8

    32

    100K

    4502944

    177661.5

    45.02944

    356%

    1

    16

    32

    100K

    6317459

    253266.4

    63.17459

    616%

    1

    32

    32

    100K

    12766794

    250650.2

    127.6679

    654%

    1

    64

    32

    100K

    25002414

    255975.3

    250.0241

    649%

    1

    64

    64

    100K

    25310469

    252859.8

    253.1047

    691%

    ?

    從結果來看,Worker線程數由3增加到10,最大IOPS增加19%,但是相應地CPU占有率增加近87%

  • 多線程Reactor模型
  • Async模塊采用Reactor模型,當網絡I/O流事件發生時,EventCenter會調用對應對應地事件回調函數EventCallback進行處理,由于同一EventCenter內地事件回調函數地執行是順序地,所以當存在較耗時地回調函數調用時,EventCenter::process_events就成為了整個網絡通信性能瓶頸。

    為了改進這種高性能網絡I/O流模型,主要有兩種思路:

    • 增加EventCenter地數量,達到降低單個EventCenter內地事件回調數量地目的。
    • 采用多線程模型,異步地執行同一EventCenter內的事件回調。

    經過測試分析,多線程Reactor模型并未達到預期地效果,性能沒有提升。

    主要代碼如下:

    ThreadPool cb_tp;

    ? class EventCallbackWQ : public ThreadPool::WorkQueue<EventCallback> {

    ??? list<EventCallback*> callbacks;

    ?

    ?? public:

    ??? EventCallbackWQ(time_t timeout, time_t suicide_timeout, ThreadPool *tp)

    ????? : ThreadPool::WorkQueue<EventCallback>("EventCenter::EventCallback", timeout, suicide_timeout, tp) {}

    ?

    ??? bool _enqueue(EventCallback *cb) {

    ????? auto iter = std::find(callbacks.begin(), callbacks.end(), cb);

    ????? if (iter == callbacks.end()) {

    ??????? callbacks.push_back(cb);

    ????? }

    ????? return true;

    ??? }

    ??? void _dequeue(EventCallback *cb) {

    ????? assert(0);

    ??? }

    ??? bool _empty() {

    ????? return callbacks.empty();

    ??? }

    ??? EventCallback *_dequeue() {

    ????? if (callbacks.empty())

    ??????? return NULL;

    ????? EventCallback *cb = callbacks.front();

    ????? callbacks.pop_front();

    ????? return cb;

    ??? }???

    ??? void _process(EventCallback *cb, ThreadPool::TPHandle &handle) override {

    ????? if (cb) {

    ??????? cb->do_request(cb->fd_or_id);

    ????? } else {

    ??????? assert(0);

    ????? }

    ??? }

    ??? void _process_finish(EventCallback *cb) { }

    ??? void _clear() {

    ????? assert(callbacks.empty());

    ??? }

    ? } cb_wq;

    ?

  • 消息接收緩存
  • 當網絡I/O流存在可讀數據的時候,EventCenter::process_events()會調用AsyncConnection::process()函數來讀取消息數據。

    在讀取消息的data部分的時候,會不斷地調用alloc_aligned_buffer()來申請內存,從而嚴重地影響程序地性能。為了提高內存分配地利用效率,通過封裝boost::pool內存池來完成bufferlist中內存分配。

    目前這項工作還在進行中,需要進一步地分析驗證。

    主要代碼如下:

    ? class buffer::boost_buffer : public buffer::raw {

    ??? boost::pool<> &mempool;

    ??? unsigned chunk_size = 0;

    ??? unsigned chunk_num = 0;

    ? public:

    ??? explicit boost_buffer(unsigned l, boost::pool<> &p) : raw(l), mempool(p) {

    ????? if (len) {

    ??????? chunk_size = p.get_requested_size();

    ??????? chunk_num = len/chunk_size+1;

    ??????? if (len%chunk_size==0) {

    ????????? --chunk_num;

    ??????? }

    ??????? data = static_cast<char *>(mempool.ordered_malloc(chunk_num));

    ????? }

    ?

    ????? assert(data != nullptr);

    ?

    ????? inc_total_alloc(len);

    ????? bdout << "boost_buffer" << this << " alloc " << (void *)data << " " << l << " " << buffer::get_total_alloc() << bendl;

    ??? }

    ??? ~boost_buffer() {

    ????? mempool.ordered_free(data, chunk_num);

    ?

    ????? dec_total_alloc(len);

    ????? bdout << "boost_buffer " << this << " free " << (void *)data << " " << buffer::get_total_alloc() << bendl;

    ??? }

    ??? raw* clone_empty() {

    ????? return new boost_buffer(len, mempool);

    ??? }

    ? };

    ? buffer::raw* buffer::create_boost_buffer(unsigned len, boost::pool<> &p) {

    ??? return new buffer::boost_buffer(len, p);

    ? }

    ?

    static void alloc_boost_buffer(boost::pool<> &p, unsigned len, bufferlist &data)

    {

    ? // create a buffer to read into that matches the data alignment

    ? assert(len != 0);

    ?

    ? bufferptr ptr

    ? (

    ??? buffer::create_boost_buffer

    ??? (

    ????? len, p

    ??? )

    ? );

    ? data.push_back(std::move(ptr));

    }

    ?

    ????? case STATE_OPEN_MESSAGE_READ_DATA_PREPARE:

    ??????? {

    ????????? // read data

    ????????? unsigned data_len = le32_to_cpu(current_header.data_len);

    ????????? unsigned data_off = le32_to_cpu(current_header.data_off);

    ????????? if (data_len) {

    ??????????? // get a buffer

    ??????????? map<icfs_tid_t,pair<bufferlist,int> >::iterator p = rx_buffers.find(current_header.tid);

    ?????? ?????if (p != rx_buffers.end()) {

    ????????????? ldout(async_msgr->cct,10) << __func__ << " seleting rx buffer v " << p->second.second

    ????????????????????????????????? << " at offset " << data_off

    ????????????????????????????????? << " len " << p->second.first.length() << dendl;

    ????????????? data_buf = p->second.first;

    ????????????? // make sure it's big enough

    ????????????? if (data_buf.length() < data_len)

    ??????????????? data_buf.push_back(buffer::create(data_len - data_buf.length()));

    ????????????? data_blp = data_buf.begin();

    ??????????? } else {

    ????????????? ldout(async_msgr->cct,20) << __func__ << " allocating new rx buffer at offset " << data_off << dendl;

    ????????????? //<nene>: Use the memepool

    ????????????? //alloc_aligned_buffer(data_buf, data_len, data_off);

    ????????????? alloc_boost_buffer(mempool, data_len, data_buf);

    ????????????? data_blp = data_buf.begin();

    ??????????? }

    ????????? }

    ?

    ????????? msg_left = data_len;

    ????????? state = STATE_OPEN_MESSAGE_READ_DATA;

    ??????? }

    ?

    ?

    附錄(Ⅰ):連接過程狀態遷移圖

    ?

    ?

    參閱資料

  • 羅軍舟.? <TCP/IP協議及網絡編程技術>, 清華大學出版社.
  • 游雙. <Linux高性能服務器編程>, 機械工業出版社.
  • 陳碩. <Linux多線程服務端編程>, 電子工業出版社。
  • 謝希仁. <計算機網絡>, 電子工業出版社。
  • Mellanox. RDMA Aware Networks Programming User Manual.
  • 羅劍鋒. Boost程序庫完全開發指南, 電子工業出版社.
  • Douglas C. Schmidt. An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events.
  • Stephen Prata. C++ Primer Plus, 人民郵電出版社.
  • 嚴蔚敏. 數據結構(C語言描述), 清華大學出版社.
  • 總結

    以上是生活随笔為你收集整理的Ceph Async RDMA网络通信性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。