嗨!每当我需要使用UNIX工具进行批处理处理时,我都会对Unix命令的简单性和鲁棒性感到惊讶。但是,它们与其他批处理工具相比如何? 让我们了解使用Unix命令的批处理处理的利弊。
让我们假设您有一个带有网络流量的文件。 您的目标是计算最常见的源和目标IP端口组合。您将如何做?
我们可以从Kaggle a dataset with network traffic flows下载。 让我们首先使用PANDAS库在Python中解决问题,这可能是用于快速数据分析的最常用库。有更好的方法可以解决问题,但是出于本文的目的,让我们使用幼稚的方法。
简单,对吗?我们从文件,源和目标IP和端口组中加载所有数据,对重复组合进行计数,按计数排序值,取得前20个结果,然后将它们存储在文件中。自己尝试!
现在让我们仅使用unix命令解决它。
我们读取文件(标头除外),仅过滤所需的列(源IP,源端口,目标IP和目标端口),按该组合进行排序,计数重复组合,再次按计数排序,进行前20个结果并将其存储在文件中。与Python方法非常相似,如果您不习惯Unix,但仍然易于理解,也许不那么阅读。让我们比较这两种方法。
似乎 Python方法比Unix命令更快!有趣,但是为什么呢?在讨论问题之前,让我们调整我们的输入。让我们复制我们的数据集8 并重新运行脚本。您可以轻松地猜测应该需要更多的时间来运行,而您是对的。但是另一件事发生了 -
哇,看来Python脚本是由内核终止的,但是Unix命令成功运行。让我们仔细研究发生的事情。
在运行Python脚本时,RAM内存。 RAM内存在崩溃之前上升到100%。
查看RAM内存,似乎使用Python脚本,内存不足以处理整个数据集。与UNIX命令进行比较,对RAM没有影响内存。
在运行Python脚本时使用cpu。终止脚本之前,几乎总是有一个CPU接近100%使用。
在运行UNIX命令时使用cpu。每个CPU的CPU使用量从未超过70%。
此外,它看起来像 Python脚本总是使用一个CPU核心达到100%,而UNIX命令在可用的CPU上分配负载。如何发生这种情况?它是自动的吗?
发生的事情是 pandas处理整个数据集中内存。如果数据集大于内存大小,则脚本将崩溃。熊猫的另一个缺点是它只使用单个CPU核心,而不是利用所有CPU内核。由于这些原因, pandas更适合较小的数据集,由于所有内存处理,因此它可能比Unix命令更快。但是,对于大于可用RAM内存的数据集,PANDA可能不是最好的方法。
另一方面,UNIX命令更适合大型数据集。 该排序实用程序会自动处理比内存数据集更大的数据集,通过将数据分成批量,这些数据被分类在内存中,然后存储在临时文件中。只有这些临时文件才合并在一起。这样,您永远不会用完RAM内存。此外,排序实用程序还平行于在多个CPU内核上排序,使瓶颈读取磁盘文件的速率。
t -temporary文件由我的 /tmp文件夹中的sort命令创建。< /p>
这太棒了,对吗?这也类似于另一个编程模型
mapreduce管道。在Berkeley CS61A Lab 13。
您听说过MapReduce吗?这是一个用于分布式系统中批处理处理的编程模型,由Google工程师在2004年提出。其目标是通过将所有处理步骤分为两个任务:映射器,主要执行映射,过滤和分类,将大型数据集分布在服务器之间。和还原器,执行聚合操作。对于上面的练习,每个映射器都会对数据集进行分类,并将排序的批量发送到另一个任务,该任务将执行合并。
我们可以看到,MapReduce采用了UNIX方法处理大型数据集并将其应用于分布式计算。看到Unix命令的鲁棒性考虑到MapReduce的鲁棒性比创建于1969年创建的Unix的稳健性。
。。UNIX中是否有更多突破性的想法?让我们看一下它的理念。
让每个程序做得很好
UNIX哲学的核心是将每个处理步骤的逻辑分开。这意味着,Unix不是拥有一个具有很多功能的整体核,而是针对具有很多公用事业的小核。 cat , sort , ls 或 awk 不在Unix内核中,而是单独的工具,可以帮助完成需要工作。这种方法是UNIX今天仍然相关的原因之一:即使世界已经改变并且技术已经发展,这些简单的程序仍然每天都有用:用户仍然需要对内容进行排序,列出目录并读取文本文件。
在当今的分布式和复杂的系统中,该原理仍在今天应用,尤其是在Microservices模式中。 Microservices的目标是,而不是拥有具有许多功能的单个服务,而是拥有多个服务,每个服务都专注于做一项工作。这具有许多操作好处,主要是更轻松的代码维护,更好监视和更好的可伸缩性。
期望每个程序的输出成为另一个程序的输入
在UNIX中,每个程序都有一种标准的方式进行交流。管道保证您可以轻松地将程序输出并用作另一个程序的输入,充当统一的编程接口。 这具有显而易见的优势,即易于使用UNIX命令 - 无需预处理或后处理数据。简单程序的合成性的简单性使Unix成为强大的工具。
有趣的是,当今的大多数系统都不像1969年的Unix那样组合。许多时间仍然花在试图解决系统之间的集成。但是,现在通过事件驱动的体系结构广泛采用了服务输出成为另一个输入的想法。许多大型企业发现它是在服务之间进行交流的最佳方法 - 每种服务都从感兴趣的流中消耗掉,并将其输出发布到另一个流。如果另一个服务对数据感兴趣,它可以订阅输出流。同样,这与UNIX中的管道设计非常相似:每个服务都可以完成自己的作业,并将结果发布给输出,不知道任何可能消耗数据的服务。主要区别在于,虽然Unix接口使用文本文件在过程之间进行通信,但服务主要使用消息经纪(例如,Apache Kafka或Rabbitmq)。
设计和构建软件要尽早尝试,理想情况下在数周之内
在1969年,UNIX开发人员的理念是必须尽早尝试软件。奇怪的是,在70年代,瀑布诞生了,并席卷了软件世界。长期以来对软件进行了测试和发货。在此期间,仅在完成所有设计和编码后才测试软件。
直到2001年,当敏捷宣言写了,大型软件企业才开始再次遵循UNIX原理,并提早设计和构建软件(其中一些仍然使用瀑布方法,几乎没有成功)。 我们花了30年的时间才了解瀑布方法不太适合大多数软件开发,并且Unix哲学一直是正确的!
使用工具优先使用工具来帮助减轻编程任务
最后一个原则可能是最难理解的。当遇到可以手动解决的问题时,UNIX开发人员宁愿构建解决该工具来解决该工具,也不愿自行解决该工具。该原则诞生了现在日常生活中使用的许多工具。如果这些问题经常出现,那么已经有一个工具来解决它们。
创建了许多软件工具作为侧项目来解决特定问题,并最终以更大的规模使用。 Apache Kafka最初是在LinkedIn中创建的,以使大量数据摄入lambda体系结构(there is an old but excelent post about it)。 GraphQL最初是在Facebook中创建的,目的是解决Facebook移动应用程序中过度取回和取消效果的问题。 Cassandra最初是在Facebook中开发的,可以为收件箱搜索功能供电。最重要的是,在许多其他情况下,我们试图解决的问题也可能出现。如果我们能够解决一次,我们将能够使用相同的软件更轻松地解决它。
尽管它是在半个多世纪前写的,但 Unix哲学仍然是每个软件开发人员的重要建议。创建的工具仍然很有用,并且比当今许多软件都更好。,一件软件在创建后50年以上,在全球范围内保持有用和大量使用,其主要功能并不常见保持不变。
尽管有时会忘记,但是在单台计算机中使用大型数据集进行数据处理时,UNIX可能是您的最佳工具。
感谢您的阅读!
ps:有一种方法可以运行上面的Python脚本并使用更少的内存。您是否尝试过仅加载需要内存的列? ð
另外,您可以阅读有关Python,R和Unix here的有趣咆哮。