異步編程框架Seastar介紹

使用Seastar進行異步(Asynchronout)編程

介紹

我們在本文中介紹的Seastar,是一個用于在現代多核機器上,編寫高效復雜的服務器應用程序的C++庫。

傳統上,用于編寫服務器應用程序的編程語言庫和框架已經分為兩個不同的陣營:那些注重效率的陣營和側重于復雜性的陣營。一些框架是非常高效的,但是只允許構建簡單的應用程序(例如,DPDK允許單獨處理數據包的應用程序),而其他框架允許構建極其復雜的應用程序,代價是運行時效率。 Seastar是我們努力獲得兩全其美的方法:創建一個允許構建高度復雜的服務器應用程序,但實現最佳性能的庫。

Scylladb第一個使用了Seastar,它是對Apache Cassandra的重寫。 Cassandra是一個非常復雜的應用程序,然而,通過Seastar,我們能夠讓吞吐量提高10倍,同時顯著的降低一致性的延遲。

Seastar提供了一個完整的異步編程框架,它使用了 futrues 和 continuations 的概念,來統一表示和處理每種類型的異步事件,包括網絡IO,磁盤IO以及其他事件的復雜事件。

由于現代多核和多插槽機器在核心之間共享數據(原子指令,高速緩存行反彈和內存隔離)具有很高的代價,Seastar程序使用無共享編程模型,即可用內存隔離,每個核心都在自己的內存部分進行數據處理,內核之間的通信通過顯式的消息傳遞(當然這發生在使用SMP的共享內存硬件的情況下)

異步編程

用于網絡協議的服務器(如經典的HTTP(Web)或SMTP(電子郵件)服務器)處理是并行的:多個客戶端并行發送請求,在完成處理一個請求之前,我們無法開始處理下一個請求:因為各種原因,一個請求可能并經常需要阻塞磁盤IO,例如一個完整的TCP窗口(即一個慢速連接),甚至是持有非活躍連接的客戶端。服務器需要處理其他連接也是如此。

經典網絡服務器(如Inetd,Apache Httpd和Sendmail)處理這種并行連接所采用的最直接的方法是對每個連接使用單獨的操作系統進程。這種技術經過多年的發展,以提高其性能:剛開始,使用一個新的進程來處理每個新的連接;后來,使用進程池,每一個新的連接都被分配到池中的一進程。最后,進程被線程所取代。但是,所有這些實現背后的共同思想是,在每一個時刻,每個進程只處理一個連接。因此,服務器代碼可以自由使用帶阻塞的系統調用,例如讀取或寫入連接,或者從磁盤讀取數據,如果這個過程阻塞了,也沒關系,因為我們有許多額外的進程可以處理其他連接。

對每個連接使用一個進程(或一個線程)的服務器編程稱為同步編程,因為代碼是線性執行的,在上一行完成后,下一行代碼開始運行。例如,代碼可能會從套接字讀取請求,解析請求,然后零碎地從磁盤讀取文件并將其寫回套接字。這樣的代碼很容易編寫,就像傳統的非并行程序一樣。事實上,甚至可以運行一個外部的非并行程序來處理每個請求 - 例如Apache HTTPd如何運行“CGI”程序,生成第一個動態Web頁面。

>注意:盡管同步服務器應用程序是以線性,非并行的方式編寫的,但內核可以幫助確保所有事情都是并行發生的,并且可以充分利用機器的資源(CPU,磁盤和網絡)。除了進程并行(我們有多個進程并行處理多個連接)之外,內核甚至可以并行化一個單獨連接的工作 - 例如處理一個未完成的磁盤請求(例如,從磁盤文件中讀取)并行處理網絡連接(發送緩沖區中尚未發送的數據,并緩沖新接收的數據,直到應用程序準備好讀取它)。

但是同步的,每個連接的過程,服務器編程并不是沒有缺點或成本的。服務器作者慢慢地但是確定地意識到,開始一個新的進程是緩慢的,上下文切換很慢,每個進程都伴隨著大量的開銷,最顯著的是它的堆棧大小。服務器和內核作者努力減輕這些開銷:他們從進程切換到線程,從創建新線程到線程池,降低了每個線程的默認堆棧大小,增加了虛擬內存大小以允許部分利用的堆棧。但是,同步設計的服務器的性能并不理想,隨著并發連接數量的增長,服務器的性能也不盡人意。 1999年,Dan Kigel普及了“C10K問題”,需要一臺服務器來高效地處理10,000個并發連接,其中大部分是緩慢甚至不活動的。

該解決方案在接下來的十年中變得流行,它放棄了舒適但低效的同步服務器設計,轉而采用新型服務器設計 - 異步服務器或事件驅動服務器。事件驅動的服務器只有一個線程,或者更準確地說,每個CPU有一個線程。這個單線程運行一個緊密的循環,在每次迭代時,使用poll()(或更高效的epoll)檢查許多打開文件描述符(例如套接字)上的新事件。例如,一個事件可以是一個套接字變得可讀(新的數據已經從遠端到達)或變得可寫(我們可以在這個連接上發送更多的數據)。應用程序通過做一些非阻塞操作來處理這個事件,修改一個或多個文件描述符,并且保持它對這個連接狀態的知識。

然而,異步服務器應用程序的作者面臨著今天仍面臨的兩大挑戰:

*?復雜性:編寫簡單的異步服務器非常簡單。但是編寫一個復雜的異步服務器是非常困難的。單個連接的處理,而不是一個簡單易讀的函數調用,現在涉及大量的小型回調函數和一個復雜的狀態機,以記住每個事件發生時需要調用哪個函數。

*?非阻塞:每個內核只有一個線程,對于服務器應用程序性能很重要,因為上下文切換很慢。但是,如果我們每個內核只有一個線程,則事件處理函數不能阻塞,否則內核將保持空閑狀態。但是一些現有的編程語言和框架讓服務器作者別無選擇,只能使用阻塞函數,因此也不能使用多線程。例如,Cassandra被編寫為一個異步服務器應用程序;但是因為磁盤I/O是用mmaped文件實現的,所以在訪問時可以不受控制地阻塞整個線程,它們被迫在每個CPU上運行多個線程。

而且,當需要盡可能好的性能時,服務器應用程序及其編程框架不得不考慮以下因素:

*?現代機器:現代機器與十年前的機器非常不同。它們具有許多內核和深層內存層次結構(從L1緩存到NUMA),這些有利于某些編程實踐,卻帶來一些問題:不可擴展的編程實踐(如鎖定)會破壞許多內核的性能;共享內存和無鎖同步原語是可用的(即,原子操作和內存排序的屏障),但是比僅涉及單個內核的緩存中的數據的操作慢得多,并且也阻止應用程序擴展到多個內核。

*?編程語言:諸如Java,Javascript和類似的“現代”語言的高級語言是很方便的,但是每一種語言都有自己的一套假設,與上面列出的要求相沖突。這些旨在可移植的語言也使編程人員無法控制關鍵代碼的性能。為了獲得最佳的性能,我們需要一種編程語言,使程序員能夠完全控制,零運行時間的開銷,另一方面, 編譯時代碼的復雜性和優化。

Seastar是一個用于編寫異步服務器應用程序的框架,旨在解決上述所有四個難題:這是一個用于編寫復雜的異步應用程序(包括網絡和磁盤I / O)的框架。該框架的高效運行途徑完全是單線程(每核心),并可擴展到多個內核,并最小化在內核之間使用昂貴的內存共享。它是一個C ++ 14庫,為用戶提供了復雜的編譯時功能和對性能的全面控制,而無需運行時間的開銷。

Seastar

Seastar是一個事件驅動的框架,允許您以相對直接的方式編寫非阻塞的異步代碼。它的API基于 futures(c++11新特性)。 Seastar利用以下概念來實現卓越的性能:

*?Cooperative micro-task scheduler(合作的微任務調度器):每個核心運行一個合作任務調度器,而不是運行線程。每個任務通常都是非常輕量級的,只要處理最后一次I/O操作的結果并提交一個新的結果就可以運行。

*?Share-nothing SMP architecture(無共享SMP架構):每個內核獨立于SMP系統中的其他的內核運行。內存,數據結構和CPU時間不共享;相反,核心間通信使用顯示的消息傳遞。 Seastar core 通常被稱為 shard。

TODO:更多在資料訪問?scylladb/seastar

*?Future based APIs(基于future的API):futures允許您提交I/O操作,并鏈接完成I/O操作時要執行的任務。這是很容易并行運行多個I/O操作。例如,在響應TCP連接請求時,可以發出多個磁盤I/O請求,或發送相同的系統上的消息給其他核,或者發送請求到集群中的其他節點,等待一些或全部結果完成,匯總結果并發送響應。

*?Share-nothing TCP stack(無共享TCP堆棧):雖然Seastar可以使用主機操作系統的TCP堆棧,但它還提供了自己的高性能TCP/IP堆棧,該堆棧構建在任務調度器和無共享架構之上。堆棧在兩個方向上提供零拷貝:您可以直接從TCP堆棧的緩沖區處理數據,并將您自己的數據結構的內容作為消息的一部分發送,而不會產生副本。

*?DMA-based storage APIs(基于DMA的存儲API):與網絡堆棧一樣,Seastar提供零拷貝存儲API,允許您將數據存入存儲設備。

本教程面向已經熟悉C ++語言的開發人員,并將介紹如何使用Seastar創建新的應用程序。

參考鏈接:

scylladb/seastar

異步編程框架Seastar介紹

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41968.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41968.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41968.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

環境與能源創新專題:地級市綠色創新、碳排放與環境規制數據

數據簡介:推動綠色發展,促進人與自然和諧共生是重大戰略舉措。綠色發展強調“綠水青山就是金山銀山”,人與自然和諧共生重在正確處理生態環境保護與經濟發展的關系。在著力于實現綠色發展的過程中,綠色創新是綠色發展的重要驅動因…

關于API數據接口獲取商品的數據的說明

獲取商品數據已經成為許多應用程序的重要組成部分。為了實現這一目標,許多公司和技術開發者使用API數據接口來獲取相關數據。本文將詳細介紹如何使用API數據接口獲取商品數據,并使用Python作為編程語言示例來展示相關代碼。 API數據接口是一種通信協議&…

WPF的CheckBox中的三個狀態

WPF的CheckBox中的三個狀態 CheckBox控件和RadioButton控件是繼承自ToggleButton類,這意味著用戶可切換他們的開關狀態,其中IsChecked屬性是可空的Boolean類型,這意味著該屬性可以設置為true,false或null。 null值表示不確定狀態…

spring.HttpMessageNotReadableException: JSON parse error

實體類如下: Value public class Search{//搜索內容String value;//是否模糊搜索boolean fuzzy true; //其實這樣寫并不是“默認”模糊搜索,而是“一定是”模糊搜索 }spring.HttpMessageNotReadableException: JSON parse error: Cannot construct ins…

GPU Microarch 學習筆記 [1]

WARP GPU的線程從thread grid 到thread block,一個thread block在CUDA Core上執行時,會分成warp執行,warp的顆粒度是32個線程。比如一個thread block可能有1024個線程,分成32個warp執行。 上圖的CTA(cooperative thre…

10條SQL優化技巧

一、一些常見的SQL實踐 (1)負向條件查詢不能使用索引 select * from order where status!0 and stauts!1 not in/not exists都不是好習慣 可以優化為in查詢: select * from order where status in(2,3) (2)前導模…

Codeforces Round 893 (Div. 2)B題題解

文章目錄 [The Walkway](https://codeforces.com/contest/1858/problem/B)問題建模問題分析1.分析所求2.如何快速計算每個商販被去除后的餅干數量代碼 The Walkway 問題建模 給定n個椅子,其中有m個位置存在商販,在商販處必須購買餅干吃,每隔…

Python程序設計——字符串處理的特殊方法

學習目標: 學習如何創建字符串使用len、min和max函數獲取一個字符串的長度、串中的最大和最小的字符使用下標運算符([])訪問字符串中的元素使用截取運算符str[ start:end]從較長的字符串中得到一個子串使用運算符連接兩個字符串,通過*運算符復制一個字符…

【Odroid C4】交叉編譯工具鏈安裝以及QT交叉編譯環境搭建

【Odroid C4】交叉編譯工具鏈安裝以及QT交叉編譯環境搭建 虛擬機環境,UBUNTU20.04 文章目錄 【Odroid C4】交叉編譯工具鏈安裝以及QT交叉編譯環境搭建一、Odroid C4交叉編譯工具鏈安裝二、QT下載及編譯安裝1.QT下載2.交叉編譯QT 配置QtCreator可以[參考](https://bl…

快速入門vue3新特性和新的狀態管理庫pinia

(創作不易,感謝有你,你的支持,就是我前行的最大動力,如果看完對你有幫助,請留下您的足跡) 目錄 Vue3.3新特性 defineOptions defineModel pinia 介紹 與 Vuex 3.x/4.x 的比較 安裝 核心概念 定義…

前饋神經網絡多分類任務

pytorch深度學習的套路都差不多,多看多想多寫多測試,自然就會了。主要的技術還是在于背后的數學思想和數學邏輯。 廢話不多說,上代碼自己看。 import torch import numpy as np import torch.nn as nn import torchvision import torchvisi…

【騰訊云Cloud Studio實戰訓練營】使用Cloud Studio社區版快速構建React完成點餐H5頁面還原

陳老老老板🦸 👨?💻本文專欄:生活(主要講一下自己生活相關的內容) 👨?💻本文簡述:生活就像海洋,只有意志堅強的人,才能到達彼岸。 👨?💻上一篇…

成集云 | 用友U8采購請購單同步釘釘 | 解決方案

源系統成集云目標系統 方案介紹 用友U8是中國用友集團開發和推出的一款企業級管理軟件產品。具有豐富的功能模塊,包括財務管理、采購管理、銷售管理、庫存管理、生產管理、人力資源管理、客戶關系管理等,可根據企業的需求選擇相應的模塊進行集…

什么是原子交換?

安全地在各個區塊鏈網絡之間傳輸資產對于釋放被困流動性并吸引更多用戶進入這一領域至關重要,同時也保持 Web3 的信任最小化核心價值。原子交換是一種讓兩個人在不依賴于中介來促成交易的情況下,在不同的區塊鏈網絡之間交換通證資產的方式。這為 DeFi 用…

Linux硬鏈接和軟連接

1、硬鏈接 硬連接指通過索引節點來進行連接。在 Linux 的文件系統中,保存在磁盤分區中的文件不管是什么類型都給它分配一個編號,稱為索引節點號(Inode Index)。在 Linux 中,多個文件名指向同一索引節點是存在的。比如:A 是 B 的硬…

數據結構之隊列詳解(包含例題)

一、隊列的概念 隊列是一種特殊的線性表,特殊之處在于它只允許在表的前端(front)進行刪除操作,而在表的后端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操…

【Windows 常用工具系列 5 -- Selenium IDE的使用方法 】

文章目錄 Selenium 介紹Selenium IDE 介紹 Selenium IDE安裝Chrome 瀏覽器安裝Selenium IDE使用 Selenium 介紹 Selenium是一個用于Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。 Selenium家庭成員有三個,分別是S…

Ubuntu 20.04 與 ROS noetic安裝 gtsam 編譯 LIO-SAM 的適配版本

Ubuntu 20.04 基于 ROS noetic安裝 gtsam, 編譯 LIO-SAM 的適配版本 摘要安裝GTSAM(ros-noetic-gtsam版本)編譯LIO-SAM的適配版本 摘要 本文簡介在 Ubuntu 20.04 下以 ROS noetic 為基礎安裝 GTSAM 并成功編譯 LIO-SAM 的適配版本。 安裝GTSAM(ros-noetic-gtsam版…

騰訊云國際站代充-阿里云ECS怎么一鍵遷移到騰訊云cvm?

今天主要來介紹一下如何通過阿里云國際ECS控制臺一鍵遷移至騰訊云國際CVM。騰訊云國際站云服務器CVM提供全面廣泛的服務內容。無-需-綁-定PayPal,代-充-值騰訊云國際站、阿里云國際站、AWS亞馬遜云、GCP谷歌云,官方授權經銷商!靠譜&#xff0…

視頻匯聚集中存儲EasyCVR平臺調用iframe地址視頻無法播放,該如何解決?

安防監控視頻匯聚平臺EasyCVR基于云邊端一體化架構,具有強大的數據接入、處理及分發能力,可提供視頻監控直播、云端錄像、視頻云存儲、視頻集中存儲、視頻存儲磁盤陣列、錄像檢索與回看、智能告警、平臺級聯、云臺控制、語音對講、AI算法中臺智能分析無縫…