服務(wù)網(wǎng)格的前世今生早期的微服務(wù)架構(gòu)上存在著服務(wù)發(fā)現(xiàn)、負(fù)載均衡、授權(quán)認(rèn)證等各種各樣的難題與挑戰(zhàn)。起初微服務(wù)踐行者們大多自己實(shí)現(xiàn)這么一套分布式通信系統(tǒng)來應(yīng)對這些挑戰(zhàn),但這無疑造成了業(yè)務(wù)功能的冗余,解決此問題的方法就是將共有的分布式系統(tǒng)通信代碼提取出來設(shè)計(jì)成一套框架,以框架庫的方式供程序調(diào)用。但這個(gè)看似完美的方法卻存在著幾個(gè)致命的弱點(diǎn):
框架大部分對業(yè)務(wù)來說是侵入式修改,需要開發(fā)者學(xué)習(xí)如何使用框架
框架無法做到跨語言使用
處理復(fù)雜項(xiàng)目框架庫版本的依賴兼容問題非常棘手,框架庫的升級經(jīng)常導(dǎo)致業(yè)務(wù)的被迫升級。
隨著微服務(wù)架構(gòu)的發(fā)展,以 Linkeerd/Envoy/NginxMesh 為代表的 sidecar 代理模式應(yīng)運(yùn)而生,這就是第一代的 serviceMesh。它作為一個(gè)基礎(chǔ)設(shè)施層,與業(yè)務(wù)進(jìn)程完全解耦,和業(yè)務(wù)一起部署,接管業(yè)務(wù)件之間的通信,將網(wǎng)絡(luò)數(shù)據(jù)收發(fā)單獨(dú)抽象出一層,在這層集中處理了服務(wù)發(fā)現(xiàn)、負(fù)載均衡、授權(quán)認(rèn)證等分布式系統(tǒng)所需要的功能,實(shí)現(xiàn)網(wǎng)絡(luò)拓?fù)渲姓埱蟮目煽總鬏?,較為完美的解決了微服務(wù)框架庫中的問題。
但在軟件開發(fā)領(lǐng)域沒有萬能的銀彈。ServiceMesh 帶來了這么多便利的同時(shí),也不可避免的存在著一些問題。傳統(tǒng)方式下,客戶端到服務(wù)端的消息僅需進(jìn)出一次內(nèi)核協(xié)議棧即可完成消息傳遞,但在 sidecar 模式中,一般選擇使用內(nèi)核的 iptables 能力劫持業(yè)務(wù)流量,這就造成了業(yè)務(wù)數(shù)據(jù)需要多次進(jìn)出內(nèi)核協(xié)議棧,導(dǎo)致業(yè)務(wù)時(shí)延增大,吞吐量變低。
openEuler 21.03 版本下進(jìn)行 sidecar(envoy)模式基準(zhǔn)測試發(fā)現(xiàn),with-envoy 與 non-envoy 模式下,時(shí)延有大幅增加
利用 ebpf 能力加速 ServiceMesh有沒有什么方法可以在享受 ServiceMesh 提供便利服務(wù)的基礎(chǔ)上同時(shí)降低并消除網(wǎng)絡(luò)時(shí)延帶來的影響呢?在這里就不得不說下 ebpf 技術(shù),ebpf 是在 kernel 中的一項(xiàng)革命性技術(shù),旨在提供不修改內(nèi)核代碼或加載內(nèi)核模塊的基礎(chǔ)上更加安全有效的擴(kuò)展內(nèi)核的能力。使用 ebpf 能力短接內(nèi)核網(wǎng)絡(luò)協(xié)議棧來降低網(wǎng)絡(luò)時(shí)延,提升 ServiceMesh 的使用體驗(yàn),這是目前業(yè)界通用的做法。
為了實(shí)現(xiàn)短接內(nèi)核網(wǎng)絡(luò)協(xié)議棧的目標(biāo),我們需要使用到 ebpf 提供的兩種能力,分別是:sockops 與 socket redirection,openEuler 使用的 kernel 版本為 5.10,已經(jīng)支持了 ebpf 的這兩種能力。
sockops 提供了在 tcp socket 創(chuàng)建連接時(shí)將 socket 使用 key(一般是四元組)標(biāo)識后保存在 sockmap 數(shù)據(jù)結(jié)構(gòu)中的能力
socket redirection 在傳輸 tcp 數(shù)據(jù)時(shí)支持使用 key 去 sockmap 中引用 socket,命中后可直接將數(shù)據(jù)轉(zhuǎn)發(fā)到此 socket 中
對于未在 sockmap 中找到的 socket,正常將數(shù)據(jù)包通過內(nèi)核網(wǎng)絡(luò)協(xié)議棧發(fā)送出去
將這些能力結(jié)合在一起,就可以在不經(jīng)過內(nèi)核網(wǎng)絡(luò)協(xié)議棧的前提下直接將數(shù)據(jù)包轉(zhuǎn)發(fā)到對應(yīng)的 socket 上,完成數(shù)據(jù)的一次傳輸,降低在內(nèi)核網(wǎng)絡(luò)協(xié)議棧上的時(shí)間消耗。
在 tcp socket 建立連接的過程中,實(shí)際上有兩次連接建立的過程,我們通常稱之為正向連接與反向連接。因正反向連接在建連過程中均需要通過 iptables 信息來獲取實(shí)際的 ip 地址與端口號,openEuler 在 iptables 的工作原理上新增 helper 函數(shù),將獲取對端信息的能力下沉到內(nèi)核中,可以在 ebpf 函數(shù)中主動獲取到 iptables 轉(zhuǎn)換過的地址。這樣我們可以建立一個(gè)輔助 map 用于存放正反向連接的對應(yīng)關(guān)系并在 socket redirection 轉(zhuǎn)發(fā)時(shí)先從輔助 map 中尋找到對端的連接信息,成功找到對端的連接信息后再進(jìn)行 socket 轉(zhuǎn)發(fā)動作。原理如下圖
通過 sockops 能力的加速,我們在 openEuler21.03 上實(shí)測的結(jié)果如下:
測試環(huán)境:openEuler-21.03 / 5.10.0-4.17.0.28.oe1.x86_64
組網(wǎng):fortio-envoy-envoy80
qps 提升約為 18%,平均時(shí)延提升 15%
下一步的工作:徹底消除 ServiceMesh 性能損耗從 openEuler21.03 實(shí)際測試中可以看出,sockmap 對于 ServiceMesh 可以進(jìn)行加速,但是加速的結(jié)果與不使用 ServiceMesh 相比仍然有較大差距。仔細(xì)分析,sockmap 并沒有消耗 socket buff 之間的數(shù)據(jù)拷貝,也沒有消耗 app/envoy 之間通信時(shí)的上下文切換,那問題可能仍然出在 ServiceMesh 架構(gòu)上。有沒有一種方法,既有 ServiceMesh 易管理、易部署的能力,又能消除其帶來的性能劣化影響?目前 openEuler sig-high-performance-network 正在嘗試這方面的工作,已經(jīng)有了初步進(jìn)展。
原文標(biāo)題:openEuler結(jié)合ebpf提升ServiceMesh服務(wù)體驗(yàn)的探索
文章出處:【微信公眾號:openEuler】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7102瀏覽量
89282 -
代碼
+關(guān)注
關(guān)注
30文章
4808瀏覽量
68812 -
openEuler
+關(guān)注
關(guān)注
2文章
319瀏覽量
5922
原文標(biāo)題:openEuler結(jié)合ebpf提升ServiceMesh服務(wù)體驗(yàn)的探索
文章出處:【微信號:openEulercommunity,微信公眾號:openEuler】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論