資料中心兩種常用流量模型運用mininet的實現

張歌發表於2015-05-02

編者按:在網路效能評估中一個巨大的挑戰就是如何生成真實的網路流量,還好可以通過程式來創造人工的網路流量,通過建立測試環境來模擬真實的狀況。本文就以資料中心網路為目標場景,來在mininet模擬環境中儘可能地還原資料中心內部的真實流量情況。目前有兩種常用的流量模型:

  • 隨機模型:主機向在網路中的另一任意主機以等概率傳送資料包
  • 概率模型:在網路中,編號為m的主機分別以概率Pt 、Pa 、Pc 、向主機編號為(m+i)、(m+j)、(m+k)的主機傳送資料包

資料中心兩種常用流量模型運用mininet的實現

我們使用mininet中的iperf工具在網路中生成UDP流量,iperf客戶端傳送資料流到iperf的服務端,由服務端接收並記錄相關信 息。mininet自帶控制檯可供使用的命令雖然已經比較豐富,但卻並未給出較為明確的API介面來支援使用者自定義命令。在諸如資料中心這樣複雜、網路節 點較多的模擬環境中做一些批處理的工作就需要非常大的,比如通過iperf在所有主機之間發生流量。所以我們需要將自定義命令新增到mininet中,在 mininet中完成新命令的擴充。

一、 mininet功能擴充

在mininet中進行功能擴充主要分為3步:
1. 修改mininet/net.py: net模組實現Mininet類,是模擬平臺mininet的主體類,該類完成節點新增配置、網路基本功能和一些選項功能的實現。我們需要將我們自定義的函式定義在該類中。

class Mininet(object):
    def function(self,**kwargs):
        #function code

2. 修改mininet/cli.py: cli模組定義了CLI類,為米你呢他提供命令列介面,用於解析使用者輸入的命令,之前定義的自定義命令需要在CLI類中通過註冊函式註冊這條自定義命令。

class CLI(Cmd):
    def do_function(self,line):
        #do_function code

完成命令註冊與繫結。

3. 修改bin/mn: 在完成命令註冊與繫結後,需要在mininet執行直譯器中註冊命令與對應執行函式的對映關係。

ALTSPELLING = {'pingall':'pingAll',
            'pingpair':'pingPair',
            'iperfudp':'iperfUdp',
            'function':'function'}

net.py和cli.py均在mininet/mininet目錄,mn檔案在在mininet/bin目錄中。在程式碼修改完成後需要重新編譯安裝一遍mininet,即執行:

$~/mininet/util/install.sh -n

二、 兩種流量模型在mininet中的實現

2.1 隨機模型

任意一臺主機以等概率隨機地向另外一臺主機發起一條UDP資料流。

修改mininet/net.py

首先,先在兩個主機之間進行iperf測試,並且在server端記錄,實現iperf_single函式:

def iperf_single( self,hosts=None, udpBw='10M', period=60, port=5001):
        """Run iperf between two hosts using UDP.
           hosts: list of hosts; if None, uses opposite hosts
           returns: results two-element array of server and client speeds"""
        if not hosts:
            return
        else:
            assert len( hosts ) == 2
        client, server = hosts
        filename = client.name[1:] + '.out'
        output( '*** Iperf: testing bandwidth between ' )
        output( "%s and %s/n" % ( client.name, server.name ) )
        iperfArgs = 'iperf -u '
        bwArgs = '-b ' + udpBw + ' '
        print "***start server***"
        server.cmd( iperfArgs + '-s -i 1' + ' > /home/zg/log/' + filename + '&')
        print "***start client***"
        client.cmd(
            iperfArgs + '-t '+ str(period) + ' -c ' + server.IP() + ' ' + bwArgs
            +' > /home/zg/log/' + 'client' + filename +'&')

著為mininet新增自定義命令iperfmulti,依次為每一臺主機隨機選擇另一臺主機作為iperf的伺服器端,通過呼叫 iperf_single,自身以客戶端身份按照指定引數傳送UDP流,伺服器生成的報告以重定向的方式輸出到檔案中,使用iperfmulti命令,主 機隨機地向另一臺主機發起一條恆定頻寬的UDP資料流。

def iperfMulti(self, bw, period=60):
    base_port = 5001
    server_list = []
    client_list = [h for h in self.hosts]
    host_list = []
    host_list = [h for h in self.hosts]

    cli_outs = []
    ser_outs = []

    _len = len(host_list)
    for i in xrange(0, _len):
        client = host_list[i]
        server = client
        while( server == client ):
            server = random.choice(host_list)
        server_list.append(server)
        self.iperf_single(hosts = [client, server], udpBw=bw, period= period, port=base_port)
        sleep(.05)
        base_port += 1

    sleep(period)
    print "test has done"

修改mininet/cli.py

def do_iperfmulti( self, line ):
    """Multi iperf UDP test between nodes"""
    args = line.split()
    if len(args) == 1:
        udpBw = args[ 0 ]
        self.mn.iperfMulti(udpBw)
    elif len(args) == 2:
        udpBw = args[ 0 ]
        period = args[ 1 ]
        err = False
        self.mn.iperfMulti(udpBw, float(period))
    else:
        error('invalid number of args: iperfmulti udpBw period/n' +
               'udpBw examples: 1M 120/n')

修改bin/mn

在mininet/bin目錄下修改mn檔案,將iperfpb加入到對應的列表中。

ALTSPELLING = { 'pingall': 'pingAll',
            'pingpair': 'pingPair',
            'iperfudp': 'iperfUdp',
            'iperfUDP': 'iperfUdp',
            'iperfpb':'iperfPb' }

最後,進入mininet/util目錄,重新編譯安裝mininet

$~/mininet/util/install.sh -n

重啟mininet,輸入iperf,可用table補全iperfpb,從而可使用iperfpb進行流量隨機模型的測試。

2.2 概率模型

為mininet新增自定義命令iperfpb,依次為每一臺主機(編號為m)分別以概率Pt 、Pa 、Pc 向主機編號為(m+i)、(m+j)、(m+k)的主機傳送資料包,通過呼叫iperf_single,自身以客戶端身份按照指定引數傳送UDP流,服務 器生成的報告以重定向的方式輸出到檔案中,使用iperfpb命令,主機按概率向其他被選擇的主機發起一條恆定頻寬的UDP資料流。

概率選擇函式

為完成以一定概率選擇主機,我們需要實現一個概率選擇函式randompick,這個函式可用於以不同的概率從一個列表中隨機地選擇一些元素。下面為randompick的實現過程:

def random_pick( self, _list, probabilities):  
    x = random.uniform(0,1)  
    p = None
    cumulative_probability = 0.0  
    for item, item_probability in zip(_list, probabilities):  
        cumulative_probability += item_probability
        p = item
        if x < cumulative_probability:break
    return p

修改mininet/net.py

    base_port = 5001
    server_list = []
    client_list = []
    client_list = [h for h in self.hosts]
    cli_outs = []
    ser_outs = []
    host_list = []
    host_list = [h for h in self.hosts]
    pc = 1 - pt - pa
    p_list = [pt,pa,pc]
    _len = len(self.hosts)
    for key in xrange(_len):
        client = host_list[key]
        access_host = [host_list[(key+i)%_len],host_list[(key+j)%_len],host_list[(key+k)%_len]]
        server = self.random_pick(access_host,p_list)
        server_list.append(server)
        self.iperf_single(hosts = [client, server], udpBw=bw, port=base_port)
        sleep(.05)
    sleep(period)
    print "test has done"

修改mininet/cli.py

def do_iperfpb(self, line):
    """Multi iperf UDP test with probablity"""
    args = line.split()
    if len(args) == 1:
        udpBw = args[ 0 ]
        self.mn.iperfMulti(udpBw)
    elif len(args) == 2:
        udpBw = args[ 0 ]
        period = args[ 1 ]
        err = False
        self.mn.iperfPb(udpBw, float(period))
    else:
        error('invalid number of args: iperfmulti udpBw period/n' +
               'udpBw examples: 1M 120/n')

修改bin/mn

在mininet/bin目錄下修改mn檔案,將iperfpb加入到對應的列表中。

ALTSPELLING = { 'pingall': 'pingAll',
            'pingpair': 'pingPair',
            'iperfudp': 'iperfUdp',
            'iperfUDP': 'iperfUdp',

最後,進入mininet/util目錄,重新編譯安裝mininet:

$~/mininet/util/install.sh -n

重啟mininet,輸入iperf,可用table補全iperfpb,從而可使用iperfpb進行流量的概率模型的測試。

相關文章