异步编程框架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.mzph.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算法中台智能分析无缝…