程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java 7 SDP:一次編寫,到處運行,有時還運行得超炫!

Java 7 SDP:一次編寫,到處運行,有時還運行得超炫!

編輯:關於JAVA

本文將簡單介紹Java 7 SDK裡引入的Java套接字直接協議(Sockets Direct Protocol,SDP),這項新技術是個非常激動人心的突破。如果要對InfiniBand的遠程直接內存存取(Remote Direct Memory Access,RDMA)進行native訪問,SDP就能讓超高性能計算(Ultra High Performance Computing,UHPC)社區在這種不常見的場景下使用Java通用的特性和優勢。RDMA為低延遲應用提供了一種協議,可以直接訪問其他計算機的內存,而不需要操作系統的參與。UHPC社區對低延遲和高吞吐量的要求最為嚴格,而且不容妥協,UHPC自然就需要使用最好的RDMA。隨著Java 7引入SDP,UHPC社區就可以利用Java平台編寫能直接利用InfiniBand RDMA功能的應用代碼了。

在深入了解新的Java SDP之前,讓我們簡要回顧一下Java網絡編程和套接字API的歷史。

Sun Microsystems於1995年推出Java,並宣揚Java能“一次編寫,到處運行”,這句口號現在已然廣為人知。我們都知道這背後的思想其實很簡單:用C++代碼編寫的應用要在所有環境下構建/部署是極其困難的,追求接近“到處運行”的可移植性就更難了,但現在你可以用一種叫Java的語言編寫應用代碼,應用可以在虛擬機(並不是底層的操作系統執行環境)上構建/部署。這極大地減少了Java應用程序員對可移植性的關注,而是把可移植性完全交給Java虛擬機(JVM)去處理。JVM承諾:如果你的Java代碼可以在針對某個特定底層操作系統的JVM上構建/部署,只要其他操作系統有可用、兼容的JVM,平台就能確保完全相同的代碼可以在上面運行。而不需要額外的編譯和預處理器宏指令。(有人記得C++裡的#ifdef麼?JVM可以讓應用程序員擺脫這種痛苦。)

這種思想非常有用,得到了應用編程社區的廣泛認可。正如我們所知,Java非常迅速地流行起來——以前所未有的速度被全面接受,計算機歷史上的很多編程語言平台都沒有這麼迅速地普及過。

Sun一開始提供的JVM只能運行在三個操作系統上:1、Solaris,2、Linux,3、Windows。微軟在1993年發布的Windows就帶有WinSOCK協議棧,所以Windows可以做TCP/IP網絡編程,而且完全支持API。各種*nix系統從二十世紀七十年代起就一直在支持TCP/IP。微軟引入WinSOCK對Java的成形來說絕對必要。沒有WinSOCK,就不能發布支持java.net.*和java.io.*這些APIs的Windows VM。沒有WinSOCK,Java構建的VM在壟斷世界桌面的操作系統上就不具備完整的網絡功能了。隨著Windows完全支持TCP/IP,運行Java的桌面數量可能增加了上千倍。

事情發生了變化

當然,Java仍然是“一次編寫,到處運行”。可移植性仍然是首要任務。但現在用Java 7和SDP,JVM能做更多的事情。可移植性不再是唯一的重點;對JVM來說,滿足超高性能用例的需求也是很重要的任務。借助SDP,JVM不需要修改網絡、套接字API,就可以直接利用InfiniBand天生的能力。InfiniBand要比以太網快很多。UHPC社區往往會選擇InfiniBand作為物理網絡層的提供者。

a 7 VM怎麼讓應用利用InfiniBand原生的功能。

 

有件有趣的事情要注意(特別是從歷史的角度來看):Java決定在兩個操作系統上提供SDP支持,而微軟Windows並不在其中。Java 7 SDP支持的兩個操作系統是Solaris和Linux。Solaris從版本10開始就對SDP提供了規范的支持。只要你有物理InfiniBand網卡,Java 7 SDP就可以立即工作。Linux則通過Open Fabrics Enterprise Distribution(OFED)包支持SDP。要確認Linux版本有沒有配置OFED設備驅動器,只需要在安裝物理InfiniBand網卡適配器之後簡單鍵入下面的命令:

egrep "^[ \t]+ib" /proc/net/dev

如果命令有輸出,就表明你可以在這個操作系統上使用Java 7 SDP。

所有的java.net.*和java.io.*應用代碼仍然能在微軟Windows上用Java 7 VM運行……但它用不了SDP,運行時的物理層提供者仍然是以太網。即使你在通過WinSOCK Direct子系統提供InfiniBand支持的Windows Server版本上運行,也用不了SDP。所有的內容仍然能在Windows上運行,但速度會比在非Windows(即*nix)上運行得慢。

事情確實發生了變化

現在讓我們談談Java裡面連接操作系統網絡協議棧的API。首先,下表顯示了網絡層標准的開放系統互連(OSI)模型。

從OSI網絡層的視角看,Java 7 SDP能讓Java應用代碼“更接近金屬”(物理層)。Java SDP提供了一種直接(SDP裡的D)的方式,借助VM就可以連接應用代碼和native、物理的InfiniBand。Java 7對SDP的支持不需要應用修改使用java.net.*和java.io.* APIs的代碼。此外,只要配置好JVM到InfiniBand操作系統設備和庫(即InfiniBand的VERBs層API)的特定連接點,使用java.net.*和java.io.*的應用代碼就能繞過傳統的網絡協議棧“直接”訪問InfiniBand(也就是使用Java針對OSI第四層傳輸層的API,就可以繞過OSI第三層網絡層和第二層數據鏈路層,直接訪問OSI第一層物理層)。對性能的影響和收到的回報都非常顯著。

借助Java 7和SDP,Java現在可以支持遠程直接內存存取(RDMA)

RDMA是跨網絡在兩個JVM進程(在*nix用戶地址空間中執行)之間移動應用緩沖區的一種方式。RDMA不同於傳統的網絡接口,因為它繞過了操作系統。這允許Java SDP通過RDMA提供:1、絕對最低的延遲,2、最高的吞吐量,3、最少的CPU占用率。

借助Java到RDMA的連接點,SDP也能讓Java具備非常有力的“零拷貝”能力。“零拷貝”操作指CPU不用將一個內存區域的數據拷貝到另一個內存區域。網絡協議棧的零拷貝版本大大提升了特定應用程序的性能,也能更有效地利用系統資源。CPU可以繼續處理其他任務,數據拷貝則由機器的另一部分並行處理,這樣就提升了性能。此外,零拷貝操作減少了在用戶空間和內核空間之間切換所消耗的時間。零拷貝也能更有效地利用系統資源,因為大量的拷貝操作是相對簡單的任務,如果其他簡單的系統組件就能做拷貝,那讓復雜的CPU去執行就太浪費了。需要注意的是,我們討論的零拷貝並不是指java.nio.channels.FileChannel的transferTo()實現的零拷貝。這裡的零拷貝性能更高。借助Java 7 SDP,你可以直接使用原生的InfiniBand零拷貝協議實現。

在典型的Java部署情況下,SDP直觀上是什麼樣的?

下圖中,Node 1(java.net.Socket寫入者)和Node 2(java.net.ServerSocket監聽器)部署在配置支持了SDP的Java 7 VM上,兩個JVMs可以跨InfiniBand網絡互相交換應用數據緩沖區,而不需要任何OS系統調用或服務調用。令人難以置信的是,Java數據傳輸完全繞過了兩個操作系統。

Java 7應用Node 1(JVM啟動時使用SDP)使用java.net.Socket API把應用數據塊跨網絡寫給java.net.ServerSocket監聽器。

JVM啟動時使用SDP,所以會完全繞過操作系統的TCP/IP棧——應用數據會直接寫到InfiniBand的RDMA(要求網卡的物理提供者是InfiniBand)。

Java 7應用Node 2(JVM啟動時也使用SDP)使用java.net.ServerSocket API監聽應用數據塊,應用數據塊由java.net.Socket寫入者經RDMA跨網絡寫入。(要求網卡的物理提供者是InfiniBand)

數據會直接寫入Java 7 VM的應用緩沖區!不需要操作系統或服務調用——既不需要Node 1的操作系統,也不需要Node 2的操作系統。這就是Java 7 SDP的功能。

同樣的應用運行在支持SDP的Java 7上和運行在Java 6上,為什麼會有性能差異?

查看本欄目

下圖深入、詳細地解釋了上圖裡的Node 2在兩種場景下的情形:

使用配置了SDP的Java 7(下圖左邊):Node 2要接收Node 1傳輸的數據,經過InfiniBand的VERBS/RDMA協議棧、到達Java應用需要幾個步驟?只需要一個!(這對UHPC Java應用來說是個好消息;UHPC社區現在可以用Java 7完成他們需要的功能了)。

使用沒有SDP的Java 6(下圖右邊):Node 2要接收Node 1傳輸的數據,是怎樣經過OSI網絡層協議棧、到達Java應用的呢?又需要幾步呢?需要五步。(這是我們熟悉的TCP/IP協議棧,而不是SDP。它適用於大多數情景,但不能解決UHPC社區的問題。UHPC社區使用Java 6可是枉然)。

怎樣管理、配置Java 7 VM,讓它支持SDP?

下面的配置部分摘取自Oracle介紹Java 7 SDP的教程。

SDP配置文件是個文本文件,JVM啟動時會從本地文件系統讀取該文件。SDP配置文件有兩種不同類型的條目。不論哪種類型,每個條目都寫成一行:

一種是SDP配置注釋行

一種是SDP配置規則行

注釋行以#字符開頭,#字符後面的所有內容都會被忽略。

至於規則行,有兩種類型:

bind規則

connect規則

bind規則表示,只要TCP套接字綁定到與規則匹配的地址和端口,就會使用SDP協議進行傳輸。connect規則則表示,沒有綁定的TCP套接字嘗試連接匹配規則的地址和端口時,就會使用SDP協議進行傳輸。

在SDP配置文件裡指定規則後,JVM就能明確知道什麼時候用InfiniBand的VERBS/RDMA協議棧去替換普通的TCP/IP協議棧。

第一個關鍵字用來表明規則是bind還是connect。第二部分指定主機名或IP地址。當指定為IP地址時,你也可以指定表示IP地址范圍的前綴。第三部分即最後一個部分是端口號或端口號范圍。

我們看看示例配置文件裡的如下部分:

# 綁定到192.0.2.1時使用SDP

bind 192.0.2.1 *

# 連接到192.0.2.*上的所有應用服務時都使用SDP

connect 192.0.2.0/24 1024-*

示例文件裡的第一條規則指定,本地IP地址192.0.2.1上的所有端口(*)都會使用SDP。你應該為分配到InfiniBand適配器的每個本地地址都添加一條bind規則,其中InfiniBand適配器相當於支持InfiniBand的網卡。如果你有多個InfiniBand適配器,你應該為分配到這些適配器的每個地址都指定一條bind規則。

示例文件裡的第二條規則表明,只要連接到192.0.2.*,而且目標端口大於等於1024,就會使用SDP。IP地址裡的前綴/24表示,32位IP地址的前24位都符合指定的地址。IP地址的每一部分都占8位,所以24位就表明IP地址應該符合192.0.2,而且最後一個字節可以是任意值。端口部分的-*表示“及以上”。端口范圍(比如1024-2056)也是有效的,而且指定的范圍是閉區間。

如何啟動使用SDP的Java 7 VM?

&> java \
-Dcom.sun.sdp.conf=sdp.conf \
-Djava.net.preferIPv4Stack=true \
Application.class

需要注意的是,啟動時要指定網絡格式為IPv4Stack。盡管Java 7和InfiniBand都支持IPv6網絡格式,但Solaris和Linux都不支持兩者之間的映射。所以啟動支持SDP的Java 7 VM時,還是要使用基礎、可靠的IPv4網絡格式。

在支持SDP的Java 7 VM上運行應用,預計性能能提升多少?

這才是終極問題!使用Java 7 SDP到底能收獲什麼?本文顯然給不出確定的答案。性能的提升取決於多方面的因素。在本文快結束的時候,讓我們了解一下確定的內容:

InfiniBand要比以太網快很多。高性能計算咨詢委員會發布的研究給出了具體的指標,這些指標表明InfiniBand在低延遲方面比10G以太網好6倍,在吞吐量性能上也是10G以太網的3.7倍。

此外,Java 7 SDP使用RDMS和最好的零拷貝實現。數據傳輸完全繞過了操作系統的TCP/IP棧和上下文切換,數據傳輸如果經過TCP/IP棧,就需要在內核地址空間裡的系統調用和用戶地址空間裡的應用代碼緩沖區之間進行上下文切換。

所有這些,Java SDK API都做到了百分百的透明。使用java.net.*和java.io.*的Java應用代碼不需要修改任何內容。

盡管事情已經發生了很大的變化,但Java的核心精神仍然沒有變。最開始的時候,JVM負責將應用代碼和可移植性隔離開來,一如往昔,JVM再次獨自交付了重要功能:這次是SDP。事實上,Java原先的口號仍然適用,我們稍作修改就能體現現在令人激動的內容:Java 7 SDP——一次編寫,到處運行,有時還運行得超炫!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved