热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Seastar:多核机器上编写高效复杂的服务器应用程序的C++库

目录官网联网为什么选择网络替代品?无共享设计核心数量增长,时钟速度保持恒定同时,IO继续提高速度海星模式:无共

目录

官网

联网

为什么选择网络替代品?

无共享设计

核心数量增长,时钟速度保持恒定

同时,I / O继续提高速度

海星模式:无共享

核心之间的明确通信

讯息传递

从程序员的角度

简化测试和故障排除

简介

Seastar

性能

性能

Seastar 应用




官网

http://seastar.io/

Seastar是一个先进的开源C ++框架,用于现代硬件上的高性能服务器应用程序。Seastar用于Scylla(与Apache Cassandra兼容的高性能NoSQL数据库)。使用Seastar的应用程序可以在Linux 或OSv上运行。




联网

Seastar在两个平台上支持四种不同的联网模式,所有这些都无需更改应用程序代码。可以将同一应用程序构建为专用服务器设备或基于unikernel的VM。


  • Linux上的DPDK网络:在Linux主机上运行的Seastar应用程序可以直接访问物理网络设备。当以访客身份运行,通过设备分配或在裸机上运行时,Seastar应用程序可以使用DPDK。此模式提供了低延迟,高吞吐量的网络。通信不需要系统调用,也不会进行数据复制。这是获得最佳性能的首选。
  • Linux标准套接字API:为了简化应用程序开发,可以将Seastar应用程序构建为使用普通的Linux网络。
  • Linux上的Seastar本机堆栈虚拟主机:将Linux virtio-net设备专用于Seastar应用程序,并绕过Linux网络堆栈。这主要用于开发Seastar TCP / IP堆栈本身。
  • OSv上的Virtio设备:在OSv平台而不是Linux上运行的本机堆栈网络:OSv将虚拟设备分配给Seastar应用程序。

为什么选择网络替代品?

Linux中可用的常规网络功能功能齐全,成熟且性能卓越。但是,对于真正的网络密集型应用程序,Linux堆栈受到限制:


  • 将网络堆栈的内核空间实现分隔为内核空间,意味着需要昂贵的上下文切换来执行网络操作,并且必须执行数据复制才能将数据从内核缓冲区传输到用户缓冲区,反之亦然。
  • 分时 Linux是一个分时系统,因此必须依靠缓慢而昂贵的中断来通知内核有新的数据包要处理。
  • 线程模型 Linux内核具有大量线程,因此所有数据结构均受锁保护。尽管付出了巨大的努力,Linux才具有很好的可扩展性,但这并非没有局限性,争用发生在大量内核上。即使没有争用,锁定原语本身也相对较慢并且会影响网络性能。

通过使用使用Seastar基本原语实现的用户空间TCP / IP堆栈,可以避免这些约束。Seastar本机网络享有零复制,零锁定和零上下文切换性能。

另一种用户空间网络工具包DPDK专为快速数据包处理而设计,通常每个数据包少于80个CPU周期。它与Linux无缝集成,以利用高性能硬件。

Seastar专为面向未来的开发而设计:您可以构建和运行相同的应用程序,以在部署时最有效的联网模式下运行,而不必事先做出经济上无法预测的技术选择。




无共享设计

http://seastar.io/shared-nothing/

现代工作负载必须在其上运行的硬件与当前编程范例所依赖的硬件以及当前软件基础结构所设计的硬件明显不同。


核心数量增长,时钟速度保持恒定

各个内核时钟速度的性能提升已停止。内核数量的增加意味着性能取决于多个内核之间的协调,而不再取决于单个内核的吞吐量。

在新硬件上,标准工作负载的性能更多地取决于跨内核的锁定和协调,而不是单个内核的性能。软件架构师面临两种不具吸引力的选择:粗粒度锁定(将看到应用程序线程争夺数据控制权,然后等待而不是产生有用的工作)和细粒度锁定(除了难以编程和调试之外)由于锁定原语本身,即使没有争用发生,开销也很大。


同时,I / O继续提高速度

现代系统上可用的网络和存储设备的速度也在持续增长。但是,CPU内核无法在任何一个内核上处理数据包。

在10GBps网络上以线速处理1024字节数据包的2GHz处理器,每个数据包只有1670个时钟周期。(来源:英特尔DPDK概述)


海星模式:无共享

由于跨内核共享信息需要昂贵的锁定,因此Seastar使用无共享模型将所有请求分片到各个内核。

Seastar每个内核运行一个应用程序线程,并且取决于显式消息传递,而不是线程之间的共享内存。这种设计避免了缓慢的,不可扩展的锁原语和缓存反弹。

跨内核的任何资源共享都必须明确处理。例如,当两个请求是同一会话的一部分,并且两个CPU各自获得依赖于同一会话状态的请求时,一个CPU必须将请求显式转发给另一个。任何一个CPU都可以处理任何一个响应。Seastar提供的功能会限制跨核通信的需求,但是当不可避免的通信时,它会提供高性能的非阻塞通信原语以确保性能不会下降。


核心之间的明确通信

Seastar提供了几个相关功能,用于内核之间的通信。最简单的是:

smp::submit_to(cpu, lambda)

这是一个承诺。它返回一个Future,即lambda的返回值。它在指定的cpu上运行lambda并返回结果。例如:

smp::submit_to(neighbor, [key] {return local_database[key];
}).then([key, neighbor] (sstring value) {print("The value of key %s on shard %d is %s\n", key, neighbor, value);
});

线程环境中的等效方法需要锁定数据库对象。锁定操作本质上是昂贵的,并且根据所使用的锁定方案,还可能迫使上下文切换或浪费CPU周期进行旋转。

跨核通信的其他变体允许将值广播到所有CPU,或允许将lambda发送到所有CPU,收集结果并应用转换以减小为单个值的映射/归约操作。




讯息传递

http://seastar.io/message-passing/

线程化应用程序固有地需要昂贵的锁定操作,而Seastar模型可以完全避免跨CPU通信的锁定

从程序员的角度来看,Seastar使用期货,承诺和延续(f / p / c)。使用epoll和用户空间库(如libevent)的传统事件驱动编程很难编写复杂的应用程序,而使用f / p / c可以更轻松地编写复杂的异步代码。

例如,发送方核心C0和接收方核心C1之间的以下交互可以发生,而无需锁定。* C0:发送者->等待队列输入(通常是立即进入)->排队请求,分配承诺。* C1:出队请求;执行->将结果移动到请求对象->将请求加入响应队列* C0:出队请求;提取响应,用它来实现承诺;销毁请求。

每个实际队列,一个用于请求,一个返回队列,用于满足请求,是一个简单的指针队列。

系统上每对CPU内核对有一个请求队列和一个返回队列。因为一个核心不与自身配对,所以一个16核心的系统将具有240个请求队列和240个返回队列。


从程序员的角度

Seastar提供了一组通用的编程结构来管理内核之间的通信。例如:

[1] return conn->read_exactly(4).then(temporary_buffer buf) {
[2] int id = buf_to_id(buf);
[3] return smp::submit_to(other_core, [id] {
[4] return lookup(id);
[5] });
[6] }).then([this] (sstring result) {
[7] return conn->write(result);
[8] });

第1行要求TCP告知我们4个字节何时可用,并将它们放在缓冲区中。它将尝试为我们提供一个直接指向包含数据的数据包区域的指针,但是如果不可能的话,它将分配一个缓冲区(例如,因为4个字节到达了不同的数据包)。

第2行在我们的四个字节到达时执行,并对请求进行解码(在这里,转换为项目ID)。

第3行要求other_core代表我们做某事,并在完成时通知我们。

第4行在另一个内核上执行。它调用查找函数来查询本地数据存储,并返回结果。

第5行让other_core的响应返回给我们。

第6行(在第3行之后立即执行)告诉第3行,当我们得到响应时该怎么做。

第7行收到来自other_core的响应,并将其写回到连接中。

在幕后,发生了很多事情。甲.then()功能可以决定立即执行其块(对于read_exactly(),如果数据恰好是可用; write()如果TCP发送缓冲器未满)。它可能决定推迟执行(如果数据不可用),在这种情况下,它会分配一小块内存,并将块的捕获存储在其中(这些捕获出现在方括号内,例如[id]第3行),并将其附加到任何内容这是我们在等待的诺言。

submit_to()做了类似但更专业的事情:它将块移动到新分配的内存区域,等待smp队列不太忙,将请求排队在核心到核心队列中,然后返回。最终,调度程序将轮询响应队列,在返回的路径中拾取相同的对象,并将结果移入Promise,从而触发继续。


简化测试和故障排除

并行编程是一种罕见的开发人员技能,随着CPU数量和工作负载并行化的增加,对并行编程的需求也越来越高。尽管必须有效利用CPU时间,但对于大多数项目而言,有效利用程序员时间就显得尤为重要。Seastar是实现世界一流性能和可理解,可测试的开发人员经验的唯一框架。




简介

https://www.jianshu.com/p/b4eb84c8dbc5

  有些框架非常高效,但只允许构建简单的应用程序(eg: DPDK 允许单独处理数据包的应用程序), 而其他框架则允许构建极其复杂的应用程序,代价是运行时效率。Seastar 是我们尝试获得两全其美的方法:创建一个允许构建高度复杂的服务器应用程序并实现最佳性能的库。

  Seastar 的灵感和首例使用案例是ScyllaDB,重写了Apache Cassandra,Cassandra 是一个分厂复杂的应用,同时通过 Seastar,我们能够重新实现吞吐量提高10倍,以及显着降低和更一致的延迟。Seastar提供了一个完整的异步编程框架,它使用两个概念 - 期货和延续 - 统一表示和处理每种类型的异步事件,包括网络I / O,磁盘I / O以及其他事件的复杂组合。

由于现代多核和多插槽机器在核心之间共享数据(原子指令,高速缓存行反弹和内存隔离)具有陡峭的惩罚,Seastar程序使用无共享编程模型,即可用内存在内核之间分配,每个内核都在其内存部分进行数据处理,内核之间的通信通过显式消息传递进行(当然,这本身就是使用SMP的共享内存硬件发生的)。

具有同步设计的服务器仍然具有令人不满意的性能,并且随着并发连接数量的增长而缩小。1999年,Dan Kigel普及了“C10K问题”—— 需要在一台服务器上有效处理 10,000个并发连接 —— 其中大多数是缓慢, 甚至是不活跃。(大四的时候,美团面试官也问过我这个问题)

对应的解决方案,在接下来的数十年中很流行,它将放弃舒适但低效的同步服务器设计,并转而采用 新型服务器设计 - 异步或事件驱动,服务器设计事件驱动的服务器只有一个线程,或者更准确地说,每个CPU有一个线程。这个单线程运行一个紧密的循环,在每次迭代中检查,使用poll()(或更有效epoll)用于许多打开的文件描述符上的新事件,例如套接字。例如,一个事件可以是一个可读的套接字(新数据已经从远程端到达)或变得可写(我们可以在这个连接上发送更多的数据)。应用程序通过执行一些非阻塞操作来处理此事件,修改一个或多个文件描述符并保持其对此连接状态的了解。
然而,异步服务器应用程序的作者在今天仍面临着两大挑战:


  • 复杂性:编写简单的异步服务器非常简单。但编写复杂的异步服务器是非常困难的。单个连接的处理,而不是一个简单易读的函数调用,现在涉及大量的小型回调函数,以及一个复杂的状态机,用于记忆每个事件发生时需要调用哪个函数。

  • 非阻塞:每个内核只有一个线程对于服务器应用程序的性能很重要,因为上下文切换很慢。但是,如果我们每个内核只有一个线程,则事件处理函数不能阻塞,否则内核将保持空闲状态。但是一些现有的编程语言和框架让服务器作者别无选择,只能使用阻塞函数,因此也不能使用多线程。例如,Cassandra被编写为异步服务器应用程序; 但是因为磁盘I / O是用mmaped文件实现的,mmaped文件在访问时可能不受控制地阻塞整个线程,所以它们被迫每个CPU运行多个线程。
    而且,当需要最佳性能时,服务器应用程序及其编程框架别无选择,只能考虑以下几点:

  • 现代机器:现代机器与十年前的机器非常不同。它们具有许多内核和深层存储器层次结构(从L1缓存到NUMA),这些层次会奖励某些编程实践并惩罚其他人:不可扩展编程实践(如锁定)可能会破坏许多内核的性能; 共享内存和无锁同步原语可用(即原子操作和内存排序的屏蔽),但比仅涉及单个内核高速缓存中的数据的操作要慢得多,并且还会阻止应用程序扩展到多个内核。

  • 编程语言:诸如Java,Javascript和类似的“现代”语言等高级语言很方便,但每种语言都有自己的一组假设,这些假设与上面列出的要求相冲突。这些旨在便携式的语言也使程序员无法控制关键代码的性能。为了获得最佳性能,我们需要一种编程语言,它为程序员提供完全控制,零运行时开销,另一方面 - 复杂的编译时代码生成和优化。

Seastar是一个用于编写异步服务器应用程序的框架,旨在解决上述所有四个难题:它是编写涉及网络和磁盘I / O的复杂异步应用程序的框架。该框架的快速路径完全是单线程(每核心),可扩展到多个内核,并最大限度地减少了在内核之间使用昂贵的内存共享。它是一个C ++ 14库,为用户提供了复杂的编译时功能和对性能的完全控制,而无需运行时间开销。


Seastar

Seastar是一个事件驱动的框架,允许您以相对直接的方式编写非阻塞的异步代码(一旦理解)。它的API基于期货。Seastar利用以下概念实现卓越性能:


  • 合作型微任务调度器:每个核心都运行一个协作式任务调度器,而不是运行线程。每个任务通常都非常轻量级 - 只需要处理最后一次I / O操作的结果并提交新结果即可运行。
  • 无共享SMP体系结构:每个内核独立于SMP系统中的其他内核运行。内存,数据结构和CPU时间不共享; 相反,核心间通信使用明确的消息传递。Seastar核心通常被称为碎片。TODO:更多https://github.com/scylladb/seastar/wiki/SMP
  • 基于未来的API:期货允许您提交I / O操作并链接完成I / O操作时执行的任务。并行运行多个I / O操作非常简单 - 例如,响应来自TCP连接的请求,您可以发出多个磁盘I / O请求,将消息发送到同一系统上的其他内核,或发送请求到集群中的其他节点,等待部分或全部结果完成,汇总结果并发送响应。
  • 无共享TCP堆栈:尽管Seastar可以使用主机操作系统的TCP堆栈,但它还提供了自己的高性能TCP / IP堆栈,该堆栈构建在任务调度器和无共享架构之上。堆栈在两个方向上提供零拷贝:您可以直接从TCP堆栈的缓冲区处理数据,并将您自己的数据结构的内容作为消息的一部分发送,而不会发生副本。...
  • 基于DMA的存储API:与网络堆栈一样,Seastar提供零拷贝存储API,允许您将数据存储在存储设备中或从存储设备中存取数据。

本教程面向已经熟悉C ++语言的开发人员,并将介绍如何使用Seastar创建新应用程序。


欢迎访问我的 个人博客 程序员的冷浪漫
作者:ColdRomantic
链接:https://www.jianshu.com/p/b4eb84c8dbc5
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。





性能

https://www.jianshu.com/p/b4eb84c8dbc5

Seastar 是一个高级,开源的 C++ 框架,支持现代化硬件的高性能服务器应用。Seastar 支持 Linux 和 OSv。


性能

上面的示例都是在 Linux 下运行,Memcached 版本是 1.4.17。

Seastar 是第一个集成了大量的架构创新的框架:


  • Shared-nothing 设计

  • 高性能网络

  • 未来和承诺

  • 消息传递


Seastar 应用

Seastar 当前专注于高吞吐量,低延迟 I/O 应用:


  • Scylla:NoSQL 数据库

  • Seastar HTTPD:Web 服务器

  • Seastar Memcached

 


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 本文介绍了如何在Mac上使用Pillow库加载不同于默认字体和大小的字体,并提供了一个简单的示例代码。通过该示例,读者可以了解如何在Python中使用Pillow库来写入不同字体的文本。同时,本文也解决了在Mac上使用Pillow库加载字体时可能遇到的问题。读者可以根据本文提供的示例代码,轻松实现在Mac上使用Pillow库加载不同字体的功能。 ... [详细]
author-avatar
水瓶颜如_991
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有