略過巡覽連結首頁 > 產品與服務 > 技術分享

技術分享

[經驗分享] NSADI RSOCKETS使用經驗分享

作者/黃俊源
前言

HPE NonStop X系列主機的NSADI (NonStop Application Direct Interface)產品支援RDMA (Remote Direct Memory Access)通訊模式,採用RDMA可大幅降低傳輸延遲時間與系統CPU資源耗用。目前NSADI產品提供下列三種使用方式。

一、IB Verbs/RDMA CM (Communication Manager):

RDMA_CM是一個通訊管理函式庫,提供NonStop X與Linux間建立一個可靠的資料傳輸,此種API是以socket為基礎,並且納入Queue Pair (QP)語法,透過指定的RDMA設備進行通訊,資料傳輸則為message-based模式。

二、RDMA Sockets (rsockets):

屬於IB Verbs/RDMA CM的前端,rsockets可直接套用在一般socket-based的程式,基本上只需將sockets API轉換為對應的rsockets API,實際上程式只需要對原有socket-level API名稱前加上r,例如rrecv()、rsend()。

三、Preload Library:

允許原有socket-based應用程式可以在不修改程式情況下,bind library後直接進行RDMA資料傳輸。

這三種方式中,如果以IB Verbs開發,除了需宣告繁複的元件外,首先需要建立protection domain、completion channel、completion queue,而且之後需要建立queue pair,接著便需保留記憶體空間位置,針對記憶體註冊到對應的pd,而且針對接收與發送均需個別註冊對應的記憶體空間,在等候資料接收或是發送是否完成期間,還需針對completion queue做poll以便後續確認是否完成,接著poll動作後面還需要呼叫requesting notification,後續還需取得completion queue的event以便確認動作是否完成,而且還需要針對這個event做acknowledged ,這樣才完成一個簡單的發送或接收的動作。

相較於IB Verbs,rsockets則相對簡單許多,它的使用與行為像sockets,連線方式像sockets,byte streaming transfer像sockets,因此可以簡單轉換現有sockets程式,直接架構在RDMA環境底下,如同下面的架構圖,可以忽略RDMA CM底層所需控制的工作,用戶便可直接開發類似sockets程式之rsockest程式做RDMA資料傳輸。


《圖一》


NonStop目前所支援的RSOCKETS

目前NSADI的rsockets僅支援TCP-based socket並且指定SOCK_STREAM type,其他如UDP/SOCK_DGRAM等連線方式並不支援。而且目前NonStop rsockets屬於blocking I/O,目前尚不支援nonblocking,因此這也確保所呼叫的function return後代表I/O完成,相對應使用的變數均可安心異動或是使用。

NonStop rsockets主要是以Linux版本的rsockets的應用為依據,因此針對回傳的錯誤訊息可能與標準TCP/IP sockets有所不同。詳細各function可能會傳的error code,可以參考OSS上man對各function之說明。

目前NonStop X所支援的RSOCKETS API依功能分類列出如下:

一、連線部分:

rsocket、rbind、rlisten、raccept、rconnect、rshutdown、rclose。
  • rsocket目前僅支援SOCK_STREAM。


  • rbind不可使用INADDR_ANY。

二、資料傳輸:

rrecv、rrecvfrom、rrecvmsg、rread、rreadv、rsend、rsendto、rsendmsg、rwrite、rwritev。

三、Socket參數設定:rsetsockopt、rgetsockopt。
  • 針對rsocket option,目前NonStop支援SOL_SOCKET level包含SO_RCVBUF、SO_SNDBUF、SO_KEEPALIVE、SO_OOBINLINE。


  • 雖然socket send/recv buffer可做設定,不過針對這設定值上限不可超過1MB,建議針對rsockets可以不須指定socket send/recv buffer。當資料要傳送或是接收時,直接指定應用於傳送或接收的message pointer即可,不過需注意的是目前NSADI並沒有針對這個message大小做設限,因此所使用的記憶體空間均會取自於系統,所以這部分需小心注意。另外針對發送與接收需指定不同的message pointer,以避免發生複寫。

四、其他API:

rgetpeername、rgetsockname。

rsocket程式編譯注意事項

目前NSADI僅支援OSS 64bit program開發,編譯時相關注意事項彙整如下:

一、library位置放置於/G/SYSTEM/ZXDLL/WUIBDLL,編譯時link library可以指定-lwuibdll以便連結。

二、編譯時需要指定-D_PRELOAD_SUPPORT_FUNCTIONS的compiler directive。

三、NSADI相關include file均放置於/usr/include/infiniband以及/usr/include/rdma底下,因此於編譯時亦可考慮指定-I/usr/include/infiniband -I/usr/include/rdma路徑位置。

另外,Linux端rsocket程式針對編譯時相關注意事項彙整如下:

一、Linux程式編譯rsocket時需要連結兩個library檔案,因此於編譯時需指定-lrdmacm –libverbs。

二、如果編譯一般TCP/IP socket程式採用preload方式執行時,可不須指定-lrdmacm –libverbs,不過於程式執行時需指定

LD_PRELOAD=/usr/lib64/rsocket/librspreload.so.1

後面再指定object名稱;若以preload方式啟動程式,如下列範例:
/usr/lib64/rsocket/librspreload.so.1 ./client -p 21262 10.1.3.0

NonStop X與Linux程式編譯範例分述如下:

一、OSS make file範例:




二、Linux make file範例:



程式邏輯範例說明

一、Server端邏輯範例:
  • 建立socket
    sock = rsocket(AF_INET , SOCK_STREAM , 0);


  • 設定local要綁定的IP address,NSADI所使用的IP address必須依照external server configuration規範指定IP address。
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = ip_addr;
    server.sin_port = htons(port);


  • 針對socket綁定IP address。
    rbind(sock,(struct sockaddr *)&server , sizeof(server));


  • 針對socket執行listen等待連線需求。
    rlisten(sock , 3);


  • 接收連線需求。
    client_sock = raccept(sock, (struct sockaddr *)&client, (socklen_t*)&c);


  • 資料接收及資料發送。
    read_size = rrecv(client_sock ,msg_ptr , (except_size - recv_len), 0);
    send_size = rsend(client_sock , server_reply , msg_size , 0);


  • 結束連線。
    rclose(sock);

二、Client端邏輯範例:
  • 建立socket
    sock = rsocket(AF_INET , SOCK_STREAM , 0);


  • 設定連接到server端的IP address,NSADI所使用的IP address必須依照external server configuration規範指定IP address。
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = ip_addr;
    server.sin_port = htons(port);


  • 連接到server端。
    ret = rconnect(sock , (struct sockaddr *)&server , sizeof(server));


  • 資料接收及資料發送。
    send_size = rsend(sock , message , msg_size , 0);
    read_size = rrecv(sock ,msg_ptr , (except_size - recv_len), 0);


  • 結束連線。
    rclose(sock);

NSADI IP address使用規範

NonStop端所使用的IP address A.B.C.D規範如下:

A:系統預設值為10。

B:由於OSS process所使用的physical resource type屬於CPU,故依照程式透過X或是Y的路徑決定。如果是透過X則為1,如果是Y則為129。

C:對應Expand Node number,可以透過SYSINFO指令確認。其輸出如下列範例


D:OSS process直接對應到所在CPU number。

Linux端其InfiniBand網卡須設定的IP address A.B.C.D規範如下:

A:比照NonStop端使用10的預設值。

B:依樣區分透過X或是Y的路徑決定。故可應用之數值如下表:


C:比照NonStop端,對應Expand Node number。

D:設定0(Linux based instance)。

舉例:

若Expand node number為252,如果於NonStop端CPU 2底下啟動server,Linux端啟動client,NonStop透過X fabric與Linux端連線,則server需指定IP address為10.1.252.2,client端IP address可指定為10.10.252.0。如果同樣環境改以Y fabric,則server需指定IP address為10.129.252.2,client端IP address則調整為10.138.252.0。

結論

藉由rsockets API可以比照原有TCP/IP socket程式簡單升級成以NSADI介面進行RDMA溝通,不過由於現階段主要提供SOCK_STREAM以及blocking I/O,因此原有TCP/IP程式仍需做相對應的調整。不過相較於IB verbs而言,簡化應用門檻,亦可達到高速傳遞及減少系統資源使用之優勢,適用於NonStop與Linux端資料大量交換和低延遲需求之應用。

參考資料

1.NonStop Application Direct Interface Reference Manual
2.Sean Hefty rsockets workshop
3.HPE David J & Nelson Wong support

 

回上一頁