python构建leaf-spine tree 和fat tree

1. leaf-spine tree

主要过程就是构造一个树字典,随机构成一个receiver和多个sender,然后根据生成的sender和receiver就可以知道leaf的位置,然后构成sender_host->sender_leaf->spine->recv_leaf->receiver_host的过程。
如果在同一个leaf下,只需要sender_host->sender_leaf->receiver_host。

python构建leaf-spine tree 和fat tree_第1张图片

def gen_leaf_spine_tree(spine_num, leaf_num, host_num_per_leaf, sender_num):
    host_num = host_num_per_leaf * leaf_num  # 总用户数
    hosts = random.sample(range(host_num), sender_num + 1)  # 所需用户数
    recv_host = random.choice(hosts)  # 选择一个receiver
    recv_leaf = 'L{0}'.format(recv_host // host_num_per_leaf)
    tree = {recv_leaf: set(['H{0}'.format(recv_host), ])}  # receiver叶子指向receiver主机

    sender_host = [n for n in hosts if n != recv_host]  # 剩余都为发送者
    sender_leaf_nodes = set()
    for i in sender_host:  # 为每一个发送主机指向对应叶子
        leaf_s = 'L{0}'.format(i // host_num_per_leaf)
        tree.setdefault('H{0}'.format(i), set()).add(leaf_s)
        sender_leaf_nodes.add(leaf_s)
    sender_leaf_nodes.discard(recv_leaf)
    if len(sender_leaf_nodes) > 0:  # 为每一个发送叶子分配spine
        for ls in sender_leaf_nodes:
            spine = 'S{0}'.format(random.randint(0, spine_num - 1))
            tree.setdefault(ls, set()).add(spine)
            tree.setdefault(spine, set()).add(recv_leaf)
    for key in tree.keys():
        tree[key] = list(tree[key])
    return tree

2. fat tree

从论文中,每个交换机最大连接数是k,共有(k/2)2个core switch,每个pod中有k/2个aggregation switch和edge switch,因此除去与edge switch的端口连接,aggregation switch还有k/2个端口与core switch相连。因此,k/2个aggregation switch的( k / 2 )*( k / 2 )个端口正好与(k/2)2个core switch相连。
那么,在某个pod中的aggregation switch的序号为 aggre_seq = core_s // aggre_num。
还要在考虑edge和pod的关系,其实就是pod_seq = edge // edge_per_pod

python构建leaf-spine tree 和fat tree_第2张图片
python构建leaf-spine tree 和fat tree_第3张图片

def gen_fat_tree(k, sender_num):
    pod_num = k
    core_num = int((k / 2) ** 2)
    aggre_per_pod = edge_per_pod = host_per_edge = int(k / 2)
    # print(type(aggre_per_pod), type(core_num))
    host_num = int(pod_num * edge_per_pod * host_per_edge)
    hosts = random.sample(range(host_num), sender_num + 1)  # 所需用户数
    recv_host = random.choice(hosts)  # 选择一个receiver
    recv_edge = recv_host // host_per_edge
    recv_pod_seq = recv_edge // edge_per_pod
    tree = {'E{0}'.format(recv_edge): set(['H{0}'.format(recv_host), ])}

    sender_host = [n for n in hosts if n != recv_host]  # 剩余都为发送者
    sender_edge_nodes = set()
    for i in sender_host:  # 为每一个发送主机指向对应edge
        edge_s = i // host_per_edge
        tree.setdefault('H{0}'.format(i), set()).add('E{0}'.format(edge_s))
        sender_edge_nodes.add(edge_s)
    sender_edge_nodes.discard(recv_edge)  # 只给在不是接收edge下的edge分配core

    if (len(sender_edge_nodes) > 0):
        for se in sender_edge_nodes:
            core_s = random.randint(0, core_num - 1)  # 随机得到core层的switch序号
            aggre_seq = core_s // aggre_per_pod
            sender_pod_seq = se // edge_per_pod
            sender_aggre_seq = sender_pod_seq * aggre_per_pod + aggre_seq  # 计算发送端aggre层的switch序号

            recv_aggre_seq = recv_pod_seq * aggre_per_pod + aggre_seq  # 计算接收端aggre层的switch序号
            if (recv_pod_seq == sender_pod_seq):
                # 直接连接E->A->E,不需要C
                tree.setdefault('E{0}'.format(se), set()).add('A{0}'.format(sender_aggre_seq))
                tree.setdefault('A{0}'.format(sender_aggre_seq), set()).add('E{0}'.format(recv_edge))
            else:
                # 连接发送端E->A->C
                tree.setdefault('E{0}'.format(se), set()).add('A{0}'.format(sender_aggre_seq))
                tree.setdefault('A{0}'.format(sender_aggre_seq), set()).add('C{0}'.format(core_s))
                # 连接接收端C->A->E
                tree.setdefault('C{0}'.format(core_s), set()).add('A{0}'.format(recv_aggre_seq))
                tree.setdefault('A{0}'.format(recv_aggre_seq), set()).add('E{0}'.format(recv_edge))

    for key in tree.keys():
        tree[key] = list(tree[key])
    return tree

你可能感兴趣的:(网络学习)