1. 程式人生 > >Python3中使用零拷貝技術來提高網路檔案傳輸時的系統吞吐量

Python3中使用零拷貝技術來提高網路檔案傳輸時的系統吞吐量

首先,推薦一篇好文,這篇文章細緻地描述了零拷貝技術的原理,以及其與傳統拷貝過程的區別:http://www.linuxjournal.com/article/6345?page=0,0

從總體上來簡單總結一下零拷貝技術可以通過對比來理解:

傳統的拷貝過程大致是這樣一個過程:

1. 通過直接記憶體訪問資料進入作業系統核心的快取(資料拷貝到核心空間)——CPU將資料拷貝到使用者空間——CPU將資料寫入到套接字快取——記憶體直接訪問拷貝傳送資料;

零拷貝技術的過程是這樣的:

2. 通過直接記憶體訪問資料進入作業系統核心快取(資料拷貝到核心空間)——CPU直接呼叫sendfie系統呼叫直接將核心快取拷貝到套接字快取——記憶體直接訪問拷貝傳送資料;甚至通過進一步的優化,核心之內的那次資料複製也可以省掉,這是通過將核心快取的相關資訊傳遞給套結字快取,系統利用這些資訊直接讀取核心快取傳送資料。

至於具體效果如何,可以使用Python3提供的相關係統呼叫的封裝來測試對比一下。

首先,要實現一個簡單的檔案接收伺服器,實現起來非常簡單(zerocopyserver.py):

'''
Created on Aug 28, 2015

@author: felix
'''

import socket
import hashlib
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('0.0.0.0', 10000)
print('starting up on %s port %s' % server_address)
sock.bind(server_address)
sock.listen(1)

while True:
    print('Waiting for a connection')
    connection, client_address = sock.accept()
    size = 0
    try:
        i = 0
        while True:
            data = connection.recv(65536)
            #print('Received data: "%s"' % data)
            i += 1
            if data:
                size += len(data)
                #print(data)
                #cnt += data
                if i % 10000 == 0:
                    print('Current loop: ', i)
                #print('[%s]' % data)
            else:
                print('Done!')
                break
        print('I:', i)
        print('Total size: ', size)
        #print('Hash of received data :', hashlib.md5(cnt).hexdigest())
    finally:
        connection.close()

可以看到,我們統計了最終收到的資料的大小,以判斷兩種方式傳送的檔案是否是相同的。

下面是傳統的拷貝檔案的程式:copyclient.py

'''
Created on Aug 29, 2015

@author: felix
'''
import socket
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('127.0.0.1', 10000)
sock.connect(server_address)

start = time.time()
try:
    with open(r'/home/felix/Downloads/Forrest.Gump.1994.1080p.BluRay.x264.anoXmous/Forrest.Gump.1994.1080p.BluRay.x264.anoXmous_.mp4', 'rb') as f:
        message = f.read()
        sock.sendall(message)
finally:
    sock.close()

end = time.time()
print('Total time: ', end-start)

下面是使用零拷貝實現的版本zerocopyclient.py
'''
Created on Aug 29, 2015

@author: felix
'''
import os
import socket
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('127.0.0.1', 10000)
sock.connect(server_address)

start = time.time()
try:
    with open(r'/home/felix/Downloads/Forrest.Gump.1994.1080p.BluRay.x264.anoXmous/Forrest.Gump.1994.1080p.BluRay.x264.anoXmous_.mp4', 'rb') as f:
        #message = f.read()
        #sock.sendall(message)
        ret = 0
        offset = 0

        while True:
            ret = os.sendfile(sock.fileno(),  f.fileno(), offset, 65536)
            offset += ret
            if ret == 0:
                break
finally:
    sock.close()

end = time.time()
print('Total time: ', end-start)

在啟動檔案接收服務之後,我們就可以分別來測試兩種傳輸方式的差別了:
copyclient.py zerocopyclient.py
Total time:  1.2538435459136963 Total time:  0.5658297538757324
Total time:  1.0714919567108154 Total time:  0.5623219013214111

可以明顯看到,同樣傳輸2.4GB的資料,使用零拷貝技術的客戶端所消耗的時間要比傳統的拷貝方式更快一些。由於是本機測試,沒有經過物理網絡卡,如果經過網絡卡的話,總的傳輸時間會受限於網絡卡的傳輸速度。

這樣,對於只需要傳輸檔案,而不用使用者程式去處理檔案內容的情況下,這種零拷貝技術能夠極大提高本機的吞吐量,如果這樣的拷貝操作非常頻繁的話,通過零拷貝優化還是可以省出可觀的時間的,同時也節省了CPU的時鐘週期(可以用來做其它事情)。

PS:請使用Python3來執行以上的測試程式;在測試開始前先啟動測試的檔案接收服務(zerocopyserver.py);零拷貝技術需要系統核心支援(>=2.4.19),故測試之前請確認系統版本是否支援零拷貝系統呼叫。

相關推薦

Python3使用拷貝技術提高網路檔案傳輸系統吞吐量

首先,推薦一篇好文,這篇文章細緻地描述了零拷貝技術的原理,以及其與傳統拷貝過程的區別:http://www.linuxjournal.com/article/6345?page=0,0 從總體上來簡單總結一下零拷貝技術可以通過對比來理解: 傳統的拷貝過程大致是這樣一個過

Java拷貝一步曲——Linux 拷貝技術

引言 傳統的 Linux 作業系統的標準 I/O 介面是基於資料拷貝操作的,即 I/O 操作會導致資料在作業系統核心地址空間的緩衝區和應用程式地址空間定義的緩衝區之間進行傳輸。這樣做最大的好處是可以減少磁碟 I/O 的操作,因為如果所請求的資料已經存放在作業系統的高速緩衝儲存器中,那麼就不需要再進行實際的物

Linux 拷貝技術,第 1 部分

文章內容 引言 傳統的 Linux 作業系統的標準 I/O 介面是基於資料拷貝操作的,即 I/O 操作會導致資料在作業系統核心地址空間的緩衝區和應用程式地址空間定義的緩衝區之間進行傳輸。這樣做最大的好處是可以減少磁碟 I/O 的操作,因為如果所請求的資料已經存放在作業系統的高速緩衝儲存器

linux拷貝詳細描述

文章屬於轉載文章 這篇文章需要用到頁快取和記憶體對映的知識,所以建議先看之前的幾篇文章。 引言 傳統的 Linux 作業系統的標準 I/O 介面是基於資料拷貝操作的,即 I/O 操作會導致資料在作業系統核心地址空間的緩衝區和應用程式地址空間定義的緩衝區之間進行傳輸。這樣做最大的好處是可以

剖析linux下的拷貝技術(zero-copy)

背景   大多數的網路伺服器是基於server-client模式的。在這當中,下載是一個很常見的功能。此時伺服器端需要將主機磁碟上的檔案傳送到客戶端上去。傳統的 Linux 作業系統的標準 I/O 介面是基於資料拷貝操作的,即 I/O 操作會導致資料在作業系統

python3拷貝與深拷貝的實現方式、區別

python3淺拷貝與深拷貝的實現方式、區別: list1 = [1,2,3] list2 = list1 list1[0] = 0 print(list2) print(list1) 列印的結果: [0, 2, 3] [0, 2, 3] 小結: 通過把一個列表變數名賦

linux的拷貝技術

情景:將服務端主機磁碟中的檔案不做修改地從已連線的socket發出去,我們通常用下面的程式碼完成: while((n = read(diskfd, buf, BUF_SIZE)) > 0) write(sockfd, buf , n); 使

Linux拷貝技術,看完這篇文章就懂了

本文首發於我的公眾號 Linux雲端計算網路(id: cloud_dev),專注於乾貨分享,號內有 10T 書籍和視訊資源,後臺回覆 「1024」 即可領取,歡迎大家關注,二維碼文末可以掃。 本文講解 Linux 的零拷貝技術,雲端計算是一門很龐大的技術學科,融合了很多技術,Linux 算是比較基礎的技術

聊聊訊息佇列高效能的祕密——拷貝技術

# 一、前言 RocketMQ為什麼這麼快、Kafka為什麼這麼快?用了零拷貝技術?什麼是零拷貝技術,它們二者的零拷貝技術有不同嗎? # 二、為什麼需要零拷貝 在計算機產業中,I/O的速度相較CPU,總是太慢的。SSD硬碟的IOPS可以達到2W、4W,但是我們CPU的主頻有2GHz以上,也就意味著每秒會有2

Java位元組序(不同語言網路資料傳輸位元組序列轉換)

BIG-ENDIAN(大位元組序、高位元組序) LITTLE-ENDIAN(小位元組序、低位元組序) 主機位元組序 網路位元組順序 JAVA位元組序 1.BIG-ENDIAN、LITTLE-ENDIAN跟多位元組型別的資料有關的比如

Java程式碼如何通過 http上傳檔案

例子程式碼如下 package example.filetransfer; import java.io.*; import java.net.*; import java.util.*; public class HttpRequestUtil { /** * 傳送ge

Maven工程自動拷貝資原始檔的 pom檔案配置方法

<plugin> <groupId>org.apache.maven.plugins</groupId>

Python3 記錄日誌並輸出到 log 檔案的方法(防止輸出中文亂碼)

# -*- coding: utf-8 -*- import logging.handlers LOG_FILE = r'tst.log' handler = logging.handlers.

在QT使用tinyxml庫讀取XML檔案失敗的經歷

增加了一個配置項,XML節點名稱用的數字開頭的,如<11aa>0</11aa> 結果在儲存的時候能成功,但是讀取的時候一直load xml failed。 將其修改成<aa11>0</aa11>之後就好了 特此記錄!

青陽網路檔案傳輸系統 kiftd 1.0.10 正式釋出

   為更好地方便使用者使用kiftd,該版本增加了很多使用者們期待已久的、實用性較強的功能。使得搭建個人、家庭、團隊雲端儲存更加得心應手。本次更新如下: 【新版本v1.0.10】 檔案管理,現在,期待已久的本地檔案管理功能正式上線。該功能能夠幫助您隨時瀏覽kiftd中的檔

WinSock實現多執行緒網路檔案傳輸程式(一)(MFC+WinSock附原始碼)

相信很多人都用過CSocket類,用其實現網路 通訊非常方便,但其效率很低.這裡我講一講使用API函式Socket實現 網路檔案傳輸的方法,下面為例項程式的圖片: 下面先描述一下這個程式的原理,此程式為伺服器端與客戶端整合在一起的程式,程式會單獨為接收和傳送開新的 執行緒.

虛擬機器實現Linux與Windows之間的檔案傳輸

一、配置環境 虛擬機器Linux:Fedora 9 檔案傳輸工具:SSHSecureShellClient-3.2.9 二、實現步驟     1. 在Windows中安裝檔案傳輸工具SSHSecureShellClient-3.2.9,主介面如下:   左邊是Windows

Go網路檔案傳輸

流程分析 藉助TCP完成檔案的傳輸,基本思路如下: 傳送方(客戶端)向服務端傳送檔名,服務端儲存該檔名。 接收方(服務端)向客戶端返回一個訊息ok,確認檔名儲存成功。 傳送方(客戶端)收到訊息後,開始向服務端傳送檔案資料。 接收方(服務端)讀取檔案內容,寫入到之前儲存好的檔案中。 由於檔案傳輸需要穩定可靠

網路資料傳輸作業系統幹了什麼?

## 前言 最近在整理網路抓包分析相關的資料,同時又在閱讀《網路是怎樣連線的》。上一篇從網路協議層對裝置連網的過程和傳送資料的過程進行了探討。本篇討論的是TCP協議的資料收發的過程。 > 在討論本篇文章時,假設讀者對TCP協議有一定了解。 ## 建立Socket 由於TCP協議是需要建立連線的,

在並發編程使用生產者和消費者模式能夠解決絕大多數並發問題。該模式通過平衡生產線程和消費線程的工作能力提高程序的整體處理數據的速度。

容器 模板類 負責 速度 線程並發 進行 並發 耦合 所有 在並發編程中使用生產者和消費者模式能夠解決絕大多數並發問題。該模式通過平衡生產線程和消費線程的工作能力來提高程序的整體處理數據的速度。 在並發編程中使用生產者和消費者模式能夠解決絕大多數並發問題。該模式通過平衡