开源软件核心开发者流失的级联效应仿真
2021-05-11卢冬冬盛永祥张鹏臣
卢冬冬,吴 洁,刘 鹏,盛永祥,张鹏臣
(江苏科技大学经济管理学院,江苏 镇江 212003)
0 引言
近年来,开源软件蓬勃发展,广泛运用于大数据、云计算、人工智能等诸多领域[1]。这引起了社会各界的广泛关注,国务院也曾发文要将开源软件社区的建设纳入创新驱动战略中去。与传统商业软件不同的是,基于web2.0/3.0的在线社区是推动开源软件形成和发展的主要平台。来自世界各地的开发者通过开源软件社区协调合作,完成软件项目的开发与迭代[2]。但开源软件社区“集市型”的开发模式使得开发者能够自由加入或退出项目的开发进程[3]。一旦出现核心开发者的流失将会使开发进程遭受重创,并引发一系列的级联效应[4]。因此,从动态视角探究核心开发者流失对社区的影响并对其采取保护措施能够有效提高社区的创新产出。
目前开源软件社区已引起计算机、知识创新、管理等领域学者们的广泛研究[5-8]。研究内容主要包括了开发者的协作模式机制、开发者类型划分等。开发者协作模式机制方面:在Raymond提出的“集市模式”的基础上[3],一些学者认为开源软件社区作为一种典型的开放式创新社区[9],其开发过程是一种密集型的知识创造过程[10],社区成员间的协作行为存在偏好连接、同质相吸的特征[1,5];在子项目开发过程和开发者协作网络的协同演化过程中,子项目与协作网络中的社区结构存在显著的相关性[6]。
开发者类型划分方面:早期的研究中Mockus等人[11]基于简单统计计数方法,通过代码提交量区别开源软件社区的核心开发者和边缘开发者。继而有相关研究关注到用户行为:Nakakoji等[12]依据项目类型将开发者划分为8种类型。Oliva等[13]基于问卷、访谈的结果来总结描述核心开发者行为特点,并以此作为识别标准。近年来,众多学者基于复杂网络的视角进行了众多研究[6,14-18],但多是基于度中心性大小、介数中心性大小或将两者结合起来综合考虑区分核心开发者和一般开发者,并在此基础上通过探究网络鲁棒性(抗毁性)识别效果[6,14,17]。
上述研究使我们对开源软件社区中的协作模式机制和开发者类型划分方法有了更深入的认识,但还存在以下几点有待进一步深化。在区分核心开发者的过程中,目前的已有研究多是从开发者节点在整体网络中的拓扑结构特征(度、介数)出发。这些指标虽能反映开发者节点在网络中的影响力,但是却忽略了节点的局部特征社团结构(社区中开发者之间的协作关系形成的社团结构与项目开发存在显著相关性)。在检测识别效果方面,目前的研究中多是从静态视角仅考虑节点流失后对网络鲁棒性的影响,尚未从动态视角探讨节点流失对与其存在协作关系的开发者的影响。
由此,本文将以开源软件项目AngularJS为例,通过收集开发者代码提交记录,抓取开发者协作关系来构建开发者协作网络。在此基础上将开发者社团结构考虑进来,识别核心开发者,并从动态视角探究核心开发者流失对社区内其他开发者造成的级联效应。是对已有开发者类型区分方法的一种深化,也为网络鲁棒性检测提供了新的视角,同时也是大型自组织系统研究的进一步扩充。
1 网络构建及指标分析
1.1 开源软件开发者协作网络构建
本文选择了GitHub社区中的AngularJS项目为研究对象,该项目诞生于2009年,现被Google收购,作为一款优秀的开源前端JS框架,已被用于多款Google产品中。GitHub是一个优秀的开源服务平台,其Pull Request机制允许用户任意参与到项目中去[19],Git版本控制系统也记录下了不同时段内所有开发者的代码提交记录。
源数据使用课题组实现的爬虫工具,选取时间跨度为2010年8月(项目初始期)到2019年1月(本研究数据提取截止期),抓取AngularJS代码提交记录共计38 764条,记录内容包含开发者昵称、注册邮箱、代码提交日期、修改文件数量、名称和代码增减行数等。
基于源数据,构建开发者协作网络G=(V,E,W)。社区开发者用节点集合V表示,考虑到开发者昵称可能出现重复的问题,以开发者注册邮箱作为网络节点标识。开发者间的协作关系用节点间的关系集合E表示,通过Python编程抽取开发者协作关系。由于软件开发往往是基于旧版本的功能提升或完善,因此,在两个版本发布间隔时间内针对同一文件进行代码提交的开发者视为相互存在协作行为。两个开发者之间的协作次数视为连边的权重,用边权重集合W表示。使用Gephi软件可视化开发者协作网络,并计算网络基本拓扑参数(见表1)。网络构建过程如图1所示。
表1为构建的开发者协作网络整体拓扑特征,节点数为3 982,说明截至本研究时期共计3 982位来自世界各地的开发者为AngularJS项目贡献过自己的智慧。平均聚类系数为0.66,平均路径长度为4.135,说明该协作网络拥有小世界特性,社区中开发者协作关系紧密;模块度为0.593则说明社区中存在着明显的社团结构。
表1 开发者协作网络拓扑参数
1.2 评价指标分析
目前的大多数研究中均是以度或介数对节点的重要性进行排序,但社区内开发者之间相互协作关系形成的社团结构(小团体)与子项目的开发进程存在着显著相关性[6],开发者在团体内部和团体之间的交互行为也能够影响着开发者的重要性。基于此,将开发者节点的局部属性即网络的社团结构考虑进来,参照Guimera等[20]于2005年在生物新陈代谢网络的背景下提出的模块内参与度和模块间参与度进行综合分析。本文提出如下指标:
1)节点的度。度(ki)是指网络中与节点i相连的其他节点数量。度大小能够代表开发者的协作广度,即与之存在协作关系的开发者的个数。图2绘制了双对数坐标下度的累积分布和幂律拟合函数。拟合优度R2=0.949,拟合效果非常好,说明网络中存在着较明显的核心边缘结构,探究网络中的核心开发者具有重要意义。
图1 开发者协作网络构建过程
图2 度分布
2)节点加权度。加权度(Ki)是指网络中与节点i相连的所有连边权重总和。开源软件社区中边权重大小能够代表相连两个开发者的协作深度,即相连开发者之间的协作次数。开发者加权度则能够代表开发者的总协作次数,加权度越大能够表示开发者参与项目的积极性越高。
(1)
(2)
5)模块间参与度:模块间参与度(pi)用于衡量网络中节点i与其他社团之间的协作关系密切程度[21]。开源软件社区中,开发者的模块间参与度越高表示该开发者参与其他小团体的数量越多,所承担的小团体之间的“桥梁”作用越重要。式(3)为节点i的模块间参与度,NM表示整个网络中模块的个数,kis表示节点i在模块s中的度,ki表示节点i在整个网络中的度。
(3)
2 核心开发者识别
根据上述各公式计算网络中各节点的评价指标,计算结果如表2所示。
表2 开发者评价指标参数
已有研究中多采用度大小或介数中心性大小衡量核心开发者,本文考虑到开发者的社团结构属性,将采用模块内参与度和模块间参与度两个指标进行衡量。为了与已有研究形成对比,首先分别选取度大小排序、加权度大小排序、介数中心性大小排序下的前5位作为最重要的核心开发者,名单如表3所示。
针对多个评价指标组合,如传统方法中度和介数中心性的组合、本文提出的模块内参与度和模块间参与度的指标组合方式,本文拟采用基于熵权法定权的多属性决策方法对社区中有限的开发者进行重要性排序[22],具体方法如下所述。
社区中共有3 982个开发者,可视为存在3 982个决策方案,设为Q={Q1,Q2,…,Q3 982};4个评价指标(度、介数中心性、模块内参与度、模块间参与度)构成评价指标集S={S1,S2,S3,S4}。可构成3 982×4阶原始决策矩阵M=(xij)3 982×4。
对原始数据进行归一化处理形成标准决策矩阵N=(rij)3 982×4,其中:成本型指标认为指标数值越小越重要,效益型指标认为越大越重要,固定型指标认为越靠近某固定值越重要。故本文选取指标集中的指标均为效益型指标。接下来采用熵权法确定指标权重[22],最终得到决策方案的总评价得分:
(4)
由此,可先将指标集放在一起计算,按照度(k)、介数中心性(b)、模块内参与度(z)、模块间参与度(p)的顺序,计算得出原始矩阵M和标准化矩阵N如下:
采用熵权法计算指标权重,当指标选取度和介数中心性时,权重分别为
wk=0.297,wb=0.703
当指标选取模块内参与度和模块间参与度时,权重分别为
wz=0.571,wp=0.429
基于上述两种指标组合,计算最终评价得分,选取排序前5位作为最重要的核心开发者,名单如表4所示。
综上所述,结合已有研究中的指标和本文新提出的指标,最终识别出的核心开发者存在一定的相似性,但在重要性排序上存在着较明显的差别。因此,本文将上述方法识别的结果均视为核心开发者,节点编号分别是:97,632,1 907,2 628,2 756,451,148,2 929,1 905。
表3 度、加权度、介数中心性排名前5开发者
表4 传统指标和考虑社团结构指标识别的核心开发者
3 核心开发者流失的级联效应
3.1 级联效应描述
借鉴负载容量模型,探讨社区内核心开发者流失时造成的级联效应。一方面可以从动态视角探究核心开发者的流失对开源软件社区稳定性的影响,另一方面也能够借此揭示出开源软件社区这种大规模自组织模式下的社区成员间的协作关系形成机制,更好地为项目管理者提出社区管理对策建议、规划项目开发进程,促进社区的创新产出。目前的研究中[23-26],学者们大都假定网络中的节点存在“正常”和“失效”两种状态,即网络中各节点由于其自身属性问题会存在着一定的负载容量,当节点受到的负载大于其自身负载容量时,节点便处于“失效”状态,反之为“正常”状态。
对于本文而言,开源软件社区中的开发者流动性的特点下,核心开发者的流失不仅仅会对网络造成静态效果下的影响,其所承担的项目内容也将优先疏散到社区中与其存在协作关系的开发者,即工作负载会在社区开发者协作网络的连边中流动,进而可能会波及更多的开发者、造成范围较大的影响,阻碍、延缓项目的开发进行,甚至导致项目的失败。为了清晰地阐述这种动态的级联影响过程,本文将作相应分析。
图3 开发者流失的级联效应示意
图3反映了开发者节点流失后造成的级联效应:初始阶段(图3a)网络中各节点均处于正常状态,社区工作正常稳定进行;突然某个时刻(图3b)节点2出于自身或外界原因,选择离开社区,处于“失效”状态。原本需要开发者2负责的工作内容需要分配给与之存在协作关系,参与相同子项目的开发者(1,3,5,6,11,12)。此时(如图3c),面对新分配来的工作内容,有些开发者新的工作负载会大于其负载容量极限,不堪重负进入“失效”状态(1,4,12)。而这些新“失效”的开发者的工作内容又会继续分配给相应的开发者,造成更多的“失效”开发者8和9,如图3d所示。
3.2 负载容量模型构建
经典的负载容量模型的构建主要需要解决以下3个方面的问题:初始负载的定义、负载重分配过程和节点处理负载的能力[27]。基于此,本文将从节点开发者的初始工作负荷、节点开发者的最大工作负载容量和节点开发者流失后如何影响邻居节点三个方面构建开源软件社区中的负载容量级联失效模型。
开发者协作网络中,节点的度大小代表了开发者的协作广度,即与之存在协作关系的开发者个数。网络中的边则代表了开发者间的协作关系,边权重则代表了相连两个节点间的协作深度,即相连两个开发者之间协作的次数。节点的加权度大小能够综合考虑该开发者的协作广度和深度,可以基于度模型[23,28]构建改进的加权度负载容量模型。
1)节点的初始工作负荷:加权度大小能够代表节点开发者的总的协作次数,加权度越大节点的初始工作负荷也越大,两者之间存在着一定的关联性。因此,可假设网络中每一节点的初始工作负荷为它的加权度的函数,定义为
(5)
其中,Lj为节点j的初始工作负荷大小,Kj为节点j的加权度大小,α为可调参数,控制着不同加权度节点上的负荷差异性。
2)最大负载容量:通常情况下,节点处理负荷的能力均和其初始工作负荷有关,目前的众多研究中,节点的最大负载容量均和初始工作负荷存在正比的关系,定义为
Cj=βLj
(6)
其中,Cj为节点j的最大负载容量,β为容量系数,β≥1。
3)负载重分配原则:当节点开发者i流失或崩溃后,开发者i上的工作负荷则需要重新分配到他的合作伙伴(邻居节点)上。通常认为负载重分配原则受到开发者间的合作深度影响,即两个开发者间合作次数越多,合作关系越紧密,那么开发者i流失或崩溃后,开发者j收到的来自i的工作负荷越大,定义为
(7)
其中,ΔLji为节点j收到来自节点i的额外工作负荷,wij为节点i和节点j之间的连边权重。当节点i和节点j之间连边权重占节点i加权度的比重越大,节点j收到来自节点i的额外工作负荷也就越大。
当开发者j的邻居节点流失或失效后,开发者j的初始负荷加上来自失效节点的额外负荷大于开发者j的最大负载容量时,开发者j也会随之崩溃,处于“失效”状态,反之“正常”。因此,开发者j的工作状态sj可以表示为
(8)
其中,ΔLj*为节点j收到的所有失效邻居节点的额外负荷。
3.3 级联效应仿真
本文探究识别的核心开发者流失后对网络的动态影响,需要对网络进行蓄意攻击,模拟核心开发者流失,进行仿真分析。开源软件社区中,开发者均是利用自己的空闲时间自发进行知识贡献行为。因此,开发者的最大负载容量会存在限制。与此同时,开发者在进行代码提交时,其修改或提交内容都需要被项目维护者进行比较和挑选。项目维护者会挑选出最优的内容加入到原有项目库中。因此,被记录下来的提交次数均是具备相应的工作量的。而开发者在每次代码提交时涉及到的文件数有时并不只是1个,但由于开发者的空闲时间有限,每次提交所涉及到的知识贡献量以及开发者所能承受的最大工作量都不会很大,可对初始工作负荷中的可调参数取值α=1.1。最大负载容量通常不会比初始负荷大很多,容量系数越大,级联失效现象越不明显,拟对容量系数取值β=1.3。
仿真结果:核心开发者的流失势必会严重破坏网络的静态结构,同时还会造成众多开发者随之“失效”。根据图4一次传播的级联效应仿真结果,能够明显看出:核心开发者的流失会导致与之存在协作关系的大量开发者崩溃失效;其中一次传播失效影响最严重的是编号2756的开发者,其流失后会导致76位开发者随之失效,占据了其所有合作者数量的58.9%。该名开发者是本文所提出的模块内参与度和模块间参与度指标下识别出重要性排序第1的核心开发者;度排序第1的开发者97流失后导致54人失效;介数中心性排序第1,同时也是度和介数中心性综合考虑排序第1的开发者1907,其流失后导致59人失效;加权度排序第1的开发者148流失后导致失效的开发者人数相对较少,仅有41人,这也是所有核心开发者中除了451之外导致失效开发者最少的开发者,但失效节点占比却高达40.6%。
上述结果可以看出:节点的加权度决定了节点的初始工作负荷,当开发者节点加权度越大时,所承担的初始工作负荷也越大,若该开发者流失理应导致网络中多数的开发者随之“崩溃失效”。但是仿真结果却可以看出,网络中初始工作负荷最大的开发者148流失后却没有导致最多人数、最大占比的开发者随之“崩溃失效”。究其原因:开发者148仅少部分存在与之协作关系十分紧密的开发者,这部分的开发者在148流失后的负载重分配原则中收到了更多的来自148的额外工作负荷。而其余与148存在协作关系的开发者可能因其关系不紧密,收到的额外工作负荷相对较少。当我们考虑了开发者的社团结构特征后,最重要的开发者2756流失后造成的最多人数、最大占比的开发者随之崩溃失效。可以清楚地看出:尽管需要重新分配的工作负荷没有最大,但因其与协作者之间均能够保持着相对平均的协作密切程度,所以负载重分配过程中影响了更多的合作者随之崩溃失效。
图4 一次传播下的级联效应
图5 二次传播下的级联效应
考虑二次传播的级联效应时(见图5),可以发现在第二次传播过程中随之“崩溃失效”的开发者人数较多的分别是编号148导致119人失效,编号2628导致89人失效,编号1905导致88人失效。虽然考虑社团结构的编号2756开发者在第二次传播过程中仅导致79人随之“崩溃失效”,但失效占比中却是所有核心开发者中最高的。当考虑总失效人数时,最多的分别是编号148导致160人失效,编号2756导致155人失效,编号2929和2628均导致137人失效,编号1905导致134人失效,但失效人数总占比最高的仍然是开发者2756。
可以清晰地看出加权度大小排序下的核心开发者在二次传播中也能够影响较多的开发者随之失效,但占比却不是最高的。究其原因:一些度大的开发者之间会存在着相互协作关系,当发生二次传播时波及到的开发者人数较多,影响范围较广,失效的开发者也会随之增多,但是开发者间的协作关系并不紧密,导致失效人数占比不高。这也说明了社区知识创造过程中的“同质相吸”现象,度大的开发者之间存在紧密协作关系。当考虑社团结构所识别出的核心开发者,即那些既活跃在社团内部又游走于其他社团间的开发者,尽管他们的工作负荷并不是最大的,但由于与众多开发者间均存在紧密协作关系,能够造成极为严重的级联失效现象。
综上所述:拥有较大的工作负荷、占据网络中重要位置的核心开发者,如度、介数较大的开发者流失后会造成社区中众多开发者随之“崩溃失效”。核心开发者间的紧密协作关系也导致初始工作负荷较大的开发者在二次传播过程中造成了影响范围更广、更深远的级联失效现象。考虑社团结构识别出的核心开发者,既能占据其社团内部的核心位置,又是其他社团之间的“桥梁、要塞”,这类开发者尽管没有承担最强的工作负荷,却因其相对平均的协作关系密切程度,造成了极为严重的级联失效现象。
可见,开源软件社区自组织演化过程中的“同质相吸”现象会导致核心开发者间存在紧密协作关系,倘若出现核心开发者的流失将会导致极为严重的级联失效现象。在社区发展过程中,管理者有必要进行相应的人为干预。
4 结论与展望
为了探究核心开发者流失造成的级联失效现象,本文基于已有指标提出了考虑开发者节点局部属性的指标体系,基于多属性决策的方法识别出来核心开发者,并在此基础上构建了改进的负载容量模型,仿真模拟了一次传播和二次传播下核心开发者流失造成的级联效应。得到几点结论:1)开源软件社区网络中存在较明显的核心边缘结构,核心开发者之间也存在着紧密协作关系,这导致社区在面对核心开发者流失时会存在着较为明显的级联失效现象,会严重影响开源软件社区的创新产出。2)基于社团结构提出的模块内参与度和模块间参与度所识别出的核心开发者不管是在一次传播还是二次传播的级联效应下导致失效的开发者数量都相对较多。因此,在往后的研究中,有必要将开发者的局部属性考虑进去识别核心开发者。3)开源软件社区中,开发者的初始工作负荷和负载重分配原则对于级联效应影响较大,特别是二次传播情况下,初始工作负荷较大开发者会造成影响范围更广、更深远的级联失效现象。因此,有必要及时制止网络中级联失效现象的产生,杜绝二次传播的风险。
由此,对社区在管理运营过程中提出以下几点建议:在核心开发者识别上,不能再仅仅依靠传统指标如度、介数等,有必要将社区中的社团结构考虑进来。在项目开发过程中,要重点关注核心开发者,特别是那些既能活跃在其社团内部又能活跃于其他社团间的开发者的动态。当出现核心开发者流失的情况时,应及时填补空缺,遏制风险的二次传播。在工作内容发布时,应注重各子项目工作量的划分,时刻关注社区内部开发者的工作负荷分配情况,不能使少数开发者承担繁重的开发任务。管理者也应积极推广项目,吸引更多的新开发者加入进来,积极鼓励更多的开发者参与到核心技术的开发过程中去,使社区形成多核的局面,以此减少核心开发者之间的协作关系,降低级联失效的风险。
基于上述结论不难看出:借鉴负载容量模型,探讨社区内核心开发者流失时造成的级联效应具有一定的理论意义;将考虑了开发者局部属性的社团结构指标加入进来识别的核心开发者相对传统指标也具有更优的识别效果。一方面创新性地从动态视角探讨了核心开发者流失造成的影响,另一方面也是对开源软件社区这种大规模自组织工作模式研究的推进,也有利于项目管理者更好地规划项目开发进程,促进社区的集体智慧。
然而,本文目前仍然存在着一些不足。在构建负载容量模型时仅仅基于当前较为简单的度模型进行了简单的改进。仿真分析时,为了简化讨论过程网络中所有节点的容量系数均取β=1.3,这些都是理想化的,真实系统中每个开发者节点的容量系数并不一定完全相同。因此,模型复杂化、开发者流失和容量系数多样化这些均是本文后续研究的深化。