検索
ホームページ運用・保守Linuxの運用と保守Linux のゼロコピー テクノロジの簡単な分析


この記事では、Linux の 主要なゼロコピー テクノロジ と、ゼロコピー テクノロジの 適用可能なシナリオ について説明します。 。ゼロコピーの概念を迅速に確立するために、一般的に使用されるシナリオを紹介します。サーバーサイドプログラム (Web サーバーまたはファイルサーバー) を作成する場合、ファイルのダウンロードは基本的な機能です。このとき、サーバーのタスクは、接続されたソケットからサーバーのホスト ディスクにあるファイルを変更せずに送信することであり、通常は次のコードを使用して完了します:

while((n = read(diskfd, buf, BUF_SIZE)) > 0)
    write(sockfd, buf , n);

基本操作ファイルの内容をディスクからバッファにループで読み取り、バッファの内容をソケットに送信します。ただし、Linux I/O 操作はデフォルトでバッファリングされた I/O になります。ここで使用される 2 つの主なシステム コールは読み取りと書き込みですが、オペレーティング システムがそれらの中で何を行うかはわかりません。実際、上記の I/O 操作中に複数のデータ コピーが発生しました。

アプリケーションが特定のデータにアクセスすると、オペレーティング システムはまず、そのファイルが最近アクセスされたかどうか、またファイルの内容がカーネル バッファにキャッシュされているかどうかを確認します。オペレーティング システム read システム コールによって提供される buf アドレスに直接基づいて、カーネル バッファの内容を buf で指定されたユーザー空間バッファにコピーします。そうでない場合、オペレーティング システムはまずディスク上のデータをカーネル バッファにコピーします。このステップは現在主に DMA に依存して送信され、その後カーネル バッファの内容をユーザー バッファにコピーします。

次に、write システム コールはユーザー バッファーの内容をネットワーク スタックに関連するカーネル バッファーにコピーし、最後にソケットがカーネル バッファーの内容をネットワーク カードに送信します。 。ここまで述べたので、より明確にするために図を見てみましょう:

データ コピー

从上图中可以看出,共产生了四次数据拷贝,即使使用了DMA来处理了与硬件的通讯,CPU仍然需要处理两次数据拷贝,与此同时,在用户态与内核态也发生了多次上下文切换,无疑也加重了CPU负担。

在此过程中,我们没有对文件内容做任何修改,那么在内核空间和用户空间来回拷贝数据无疑就是一种浪费,而零拷贝主要就是为了解决这种低效性。

什么是零拷贝技术(zero-copy)?

零拷贝主要的任务就是避免CPU将数据从一块存储拷贝到另外一块存储,主要就是利用各种零拷贝技术,避免让CPU做大量的数据拷贝任务,减少不必要的拷贝,或者让别的组件来做这一类简单的数据传输任务,让CPU解脱出来专注于别的任务。这样就可以让系统资源的利用更加有效。

我们继续回到引文中的例子,我们如何减少数据拷贝的次数呢?一个很明显的着力点就是减少数据在内核空间和用户空间来回拷贝,这也引入了零拷贝的一个类型:

让数据传输不需要经过 user space。

使用 mmap

我们减少拷贝次数的一种方法是调用mmap()来代替read调用:

buf = mmap(diskfd, len);
write(sockfd, buf, len);

应用程序调用mmap(),磁盘上的数据会通过DMA被拷贝的内核缓冲区,接着操作系统会把这段内核缓冲区与应用程序共享,这样就不需要把内核缓冲区的内容往用户空间拷贝。应用程序再调用write(),操作系统直接将内核缓冲区的内容拷贝到socket缓冲区中,这一切都发生在内核态,最后,socket缓冲区再把数据发到网卡去。同样的,看图很简单:

Linux のゼロコピー テクノロジの簡単な分析

mmap

read の代わりに mmap を使用すると、コピーが 1 つ減ります。コピーされるデータの量が多い場合、間違いなく効率が向上します。ただし、mmap の使用にはコストがかかります。 mmap を使用すると、いくつかの隠れた落とし穴に遭遇する可能性があります。たとえば、プログラムがファイルをマップしているときに、そのファイルが別のプロセスによって切り捨てられると、書き込みシステム コールは不正なアドレスにアクセスするため、SIGBUS シグナルによって終了します。 SIGBUS シグナルはデフォルトでプロセスを強制終了し、コアダンプを生成します。この方法でサーバーが停止すると、損失が発生します。

#通常、この問題を回避するには次の解決策を使用します:

1. SIGBUS シグナルのシグナル ハンドラーを作成します

SIGBUS シグナルが発生すると、シグナル ハンドラーは単純に戻り、write システム コールは中断される前に書き込まれたバイト数を返し、errno は success に設定されますが、これは悪いアプローチです。問題の本当の核心に取り組んでいません。

2. ファイル リース ロックを使用する

通常、ファイル記述子にリース ロックを使用するには、この方法を使用します。カーネルはリース ロックを適用します。他のプロセスがファイルを切り詰めようとすると、カーネルはリアルタイムの RTSIGNALLEASE シグナルを送信し、ファイルに設定された読み取り/書き込みロックをカーネルが破棄していることを知らせます。このようにして、プログラムが不正なメモリにアクセスして SIGBUS によって強制終了される前に、書き込みシステム コールが中断されます。 write は書き込まれたバイト数を返し、errno を成功に設定します。

mmap ファイルを操作する前にロックし、ファイルを操作した後にロックを解除する必要があります:

if(fcntl(diskfd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {
    perror("kernel lease set signal");
return -1;
}
/* l_type can be F_RDLCK F_WRLCK  加锁*/
/* l_type can be  F_UNLCK 解锁*/
if(fcntl(diskfd, F_SETLEASE, l_type)){
    perror("kernel lease set type");
return -1;
}

使用sendfile

从2.1版内核开始,Linux引入了sendfile来简化操作:

#include<sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

系统调用sendfile()在代表输入文件的描述符infd和代表输出文件的描述符outfd之间传送文件内容(字节)。描述符outfd必须指向一个套接字,而infd指向的文件必须是可以mmap的。这些局限限制了sendfile的使用,使sendfile只能将数据从文件传递到套接字上,反之则不行。

使用sendfile不仅减少了数据拷贝的次数,还减少了上下文切换,数据传送始终只发生在kernel space。

Linux のゼロコピー テクノロジの簡単な分析

sendfile系统调用过程

在我们调用sendfile时,如果有其它进程截断了文件会发生什么呢?假设我们没有设置任何信号处理程序,sendfile调用仅仅返回它在被中断之前已经传输的字节数,errno会被置为success。如果我们在调用sendfile之前给文件加了锁,sendfile的行为仍然和之前相同,我们还会收到RTSIGNALLEASE的信号。

目前为止,我们已经减少了数据拷贝的次数了,但是仍然存在一次拷贝,就是页缓存到socket缓存的拷贝。那么能不能把这个拷贝也省略呢?

借助于硬件上的帮助,我们是可以办到的。之前我们是把页缓存的数据拷贝到socket缓存中,实际上,我们仅仅需要把缓冲区描述符传到socket缓冲区,再把数据长度传过去,这样DMA控制器直接将页缓存中的数据打包发送到网络中就可以了。

总结一下,sendfile系统调用利用DMA引擎将文件内容拷贝到内核缓冲区去,然后将带有文件位置和长度信息的缓冲区描述符添加socket缓冲区去,这一步不会将内核中的数据拷贝到socket缓冲区中,DMA引擎会将内核缓冲区的数据拷贝到协议引擎中去,避免了最后一次拷贝。

Linux のゼロコピー テクノロジの簡単な分析

带DMA的sendfile

不过这一种收集拷贝功能是需要硬件以及驱动程序支持的。

使用splice

sendfile只适用于将数据从文件拷贝到套接字上,限定了它的使用范围。Linux在2.6.17版本引入splice系统调用,用于在两个文件描述符中移动数据:

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include<fcntl.h>
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsignedint flags);

splice调用在两个文件描述符之间移动数据,而不需要数据在内核空间和用户空间来回拷贝。他从fdin拷贝len长度的数据到fdout,但是有一方必须是管道设备,这也是目前splice的一些局限性。flags参数有以下几种取值:

  • SPLICEFMOVE :尝试去移动数据而不是拷贝数据。这仅仅是对内核的一个小提示:如果内核不能从pipe移动数据或者pipe的缓存不是一个整页面,仍然需要拷贝数据。Linux最初的实现有些问题,所以从2.6.21开始这个选项不起作用,后面的Linux版本应该会实现。

  • SPLICEFNONBLOCK :splice 操作不会被阻塞。然而,如果文件描述符没有被设置为不可被阻塞方式的 I/O ,那么调用 splice 有可能仍然被阻塞。

  • SPLICEFMORE: 後続のスプライス呼び出しにはさらに多くのデータが含まれます。

スプライス呼び出しでは、Linux によって提案されたパイプ バッファー メカニズムが使用されるため、少なくとも 1 つの記述子がパイプである必要があります。

上記のゼロコピー テクノロジはすべて、ユーザー空間とカーネル空間の間のデータのコピーを削減することによって実装されていますが、場合によっては、ユーザー空間とカーネル空間の間でデータをコピーする必要があります。現時点では、ユーザー空間とカーネル空間でのデータコピーのタイミングについてのみ作業できます。 Linux では通常、システム オーバーヘッドを削減するためにコピー オン ライトが使用され、このテクノロジは COW と呼ばれることがよくあります。

紙面の都合上、この記事ではコピーオンライトについては詳しく紹介しません。一般的な説明は次のとおりです: 複数のプログラムが同時に同じデータにアクセスする場合、各プログラムはそのデータへのポインタを持ちます。各プログラムの観点からは、このデータを独立して所有します。プログラムが実行されたときのみ、データの内容が変更されると、そのデータの内容はプログラム自身のアプリケーション空間にコピーされ、初めてプログラムのプライベート データとなります。プログラムがデータを変更する必要がない場合、データを独自のアプリケーション空間にコピーする必要はありません。これにより、データのコピーが削減されます。執筆中にコピーしたコンテンツは、別の記事を書くために使用できます。 。 。

さらに、ゼロコピー テクノロジもいくつかあります。たとえば、従来の Linux I/O に O_DIRECT マークを追加すると、自動キャッシュを回避して直接 I/O が可能になります。成熟した fbufs テクノロジ。この記事ではすべてのゼロコピー テクノロジをカバーしているわけではありません。いくつかの一般的なテクノロジのみを紹介します。興味がある場合は、自分で勉強してください。一般に、成熟したサーバー プロジェクトでは、I/O 関連部分も変換されます。カーネル自体のデータを改善するための通信速度。

以上がLinux のゼロコピー テクノロジの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はLinux中文社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
Nginxログのセキュリティ問題を防ぐ方法Nginxログのセキュリティ問題を防ぐ方法Apr 13, 2025 am 07:36 AM

nginxログセキュリティは非常に重要であり、機密情報を漏らしたり、悪意のあるアクセスの試みを公開したりする可能性があります。この記事では、nginxログセキュリティの改善に役立つ一連の効果的な手段を提供します。アクセス制御:Nginxログファイルへのアクセスを厳密に制限します。許可された担当者のみがそれにアクセスし、ファイルシステム許可を使用してアクセスを制御できます。同時に、ログの回転とアーカイブ戦略を実装して、ログファイルのスケールを削減し、リスクを減らします。情報脱感作:ログ形式は、機密情報の記録(パスワード、クレジットカード情報など)の記録を避ける必要があります。ログ脱感作ツールまたはカスタムログ形式を使用して、機密データを非表示にします。リアルタイムの監視とアラーム:監視システムを展開して、Nginxログの異常な動作をリアルタイムで追跡します。アラームメカニズムを構成し、

Debianで損傷したバッグをリサイクルする方法Debianで損傷したバッグをリサイクルする方法Apr 13, 2025 am 07:33 AM

Debian Systemで破損したパッケージに遭遇しましたか?心配しないでください、この記事は、システムの安定性を回復するのに役立ついくつかの修理方法を提供します。ステップ1:パッケージリストを更新するパッケージリストが最新であることを確認してください。端末を開き、次のコマンドを実行します。SudoaptupDateステップ2:システムアップグレードすべてのパッケージをアップグレードしてみてください。破損したパッケージを修正することができます:sudoaptupgradeステップ3:依存関係を修正した依存関係を修復する場合は、依存関係を修復してください。

Debian Apacheログで悪意のあるアクセスを識別する方法Debian Apacheログで悪意のあるアクセスを識別する方法Apr 13, 2025 am 07:30 AM

悪意のあるウェブサイトへのアクセスに対する効果的な監視と防御は、Debianシステム上のApacheサーバーにとって重要です。 Apacheアクセスログは、そのような脅威を特定するための重要な情報源です。この記事では、ログを分析し、防御対策を講じる方法について説明します。悪意のあるアクセス動作を識別するApacheアクセスログDebian Systemsは、通常/var/log/apache2/access.logにあります。ログをさまざまな方法で分析できます。ログファイルの場所の確認:まず、Apacheアクセスログの正確な場所を確認してください。これは、システム構成によってわずかに異なる場合があります。コマンドラインツール分析:GREPコマンドを使用して、GREP「404」などの特定のパターンを検索します

Debianメールサーバーのスパムアンチスパムポリシーを設定する方法Debianメールサーバーのスパムアンチスパムポリシーを設定する方法Apr 13, 2025 am 07:27 AM

この記事では、主にPostgrey Graylistメカニズムとスパマッサシンスパムフィルターを使用して、Debian Mail Serverに強力なスパム防止システムを展開する方法を紹介します。 1。greyを使用して灰色のリストを構築してgreyのインストール:次のコマンドを使用してポストガレイソフトウェアパッケージをインストールします:sudoapt-getupdate && sudoapt-get-yinstallpostgreyconfigure postgrey:edit/etc/default/postgreyファイル、Postgrey_optsパラメーターを変更し、遅延時間を設定します(

DebianでTigervncのログを表示する場所DebianでTigervncのログを表示する場所Apr 13, 2025 am 07:24 AM

Debianシステムでは、Tigervncサーバーのログファイルは通常、ユーザーのホームディレクトリの.VNCフォルダーに保存されます。 Tigervncを特定のユーザーとして実行する場合、ログファイル名は通常XFに似ています。1。Log、XF:1はユーザー名を表します。これらのログを表示するには、次のコマンドを使用できます。CAT〜/.VNC/XF:1。LOGまたは、テキストエディターを使用してログファイルを開くことができます。NANO〜/.VNC/XF:1。LOGログファイルへのアクセスと表示には、システムのセキュリティの設定に応じてルート許可が必要になる場合があります。

Nginx SSL証明書更新DebianチュートリアルNginx SSL証明書更新DebianチュートリアルApr 13, 2025 am 07:21 AM

この記事では、DebianシステムでNGINXSSL証明書を更新する方法について説明します。ステップ1:最初にCERTBOTをインストールして、システムがCERTBOTおよびPython3-Certbot-Nginxパッケージがインストールされていることを確認してください。インストールされていない場合は、次のコマンドを実行してください。sudoapt-getupdatesudoapt-getinstolcallcertbotthon3-certbot-nginxステップ2:certbotコマンドを取得して構成してlet'sencrypt証明書を取得し、let'sencryptコマンドを取得し、nginx:sudocertbot - nginxを構成します。

Tigervncを介してリモートで管理する方法Tigervncを介してリモートで管理する方法Apr 13, 2025 am 07:18 AM

この記事では、リモートデスクトップ管理を実装するようにDebianシステムでTigervncを構成する方法を紹介します。 1. Tigervnc Serverシステムのインストール更新:最初にDebianシステムパッケージを更新:sudoaptupdatesudoaptupgradeインストールtigervnc:tigervncサーバー:sudoaptinstaltalltigervnc-standalone-server VNCデスクトップ環境の作成:必要なディレクトリと構成ファイルを作成:sudomkdir-p〜/.vncsudonano〜

Tigervnc与Debian兼容性问题大吗Tigervnc与Debian兼容性问题大吗Apr 13, 2025 am 07:15 AM

Tigervncは、Debianシステムの互換性が非常に高いです。この記事では、Debian SystemsのリモートデスクトップアクセスにTigerVNCをインストール、構成、使用する方法に関する詳細な指示を提供します。インストールと構成:Debian Systems(Debian10など)にtigervncをインストールするのは非常に便利です。次のコマンドを実行してサーバーとクライアントをインストールするだけです:sudoaptupdatedoaptinguaptinstinstigertaltigervnc-standalone-servertigervnc-commonインストールが完了した後、設定ファイルを介してデスクトップ環境、パスワード、その他の設定を調整できます。依存関係:ティグ

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境