http://msdn.microsoft.com/zh-cn/magazine/gg983490.aspx

使用 F#、MapReduce 和 Windows Azure 分析日志文件

Noah Gift

下载代码示例

作为一名长期使用 Python 的程序员,我对访问 F# 语言架构师 Don Syme 很感兴趣。 在访谈中,Don 提到“有些人把 [F#] 看作一种强类型的 Python,只是句法上存在差异。”这让我觉得有必要做进一步的调查。

事实证明,F# 是一种富有想像力且激动人心的新编程语言,但许多开发人员对它还并不了解。 F# 也能为人们提供 Ruby 和 Python 程序员近年来所享受到的效率优势。 与 Ruby 和 Python 一样,F# 是也一种高级语言,语法很少并且表达式很简洁。 而让 F# 真正变得独一无二的,是它将这些实用的特性与精妙的类型推理系统以及函数编程领域中的许多最佳创意融为一体。 这让 F# 变得无与伦比。

但是,除了新的高效编程语言之外,今天的您还将面对许多新鲜有趣的技术。

云平台(如 Windows Azure)的广泛应用,使得无论是单独的开发人员,还是成规模的大型公司,都能够获得分布式存储和计算资源。 云存储也包含一些有用的工具,例如可以水平扩展的 MapReduce 算法,使您能够很快编写出代码,对潜在的庞大数据集进行快速分析和排序。

利用这样的工具,您可以利用一个下午写上几行代码并部署到云中,然后就能处理上千兆的数据。 多么新奇的体验。

在本文中,我希望与您分享我对于 F#、Windows Azure 和 MapReduce 的一些兴奋之情。 我将把所有的想法集中起来,向您展示如何使用 F# 和 MapReduce 算法来分析 Windows Azure 上的日志文件。 首先,我会介绍一些原型制作技术,这些技术降低了 MapReduce 编程的复杂性;然后,我会把结果……带入云中。

利用 F# 解决问题

.NET 程序员可以通过 F# 获得一种新的工作方式,那就是许多 Perl、Python 和 Ruby 程序员习以为常的交互式工作流。 这种编程方式经常使用交互式编码环境(例如 Python shell 本身)或者某种提供 readline 自动完成功能的工具(例如 IPython)。 这样,开发人员就可以从模块中导入一个类,将其实例化,然后利用 Tab 键自动完成功能来发现对象的方法和数据。

对于 .NET 开发人员来说,常见的交互式开发是在 Visual Studio 中编写代码,然后将代码段发送至 F# Interactive 窗口进行执行。 使用 Alt+Enter 组合键发送当前选定的代码段,或者使用 Alt+单引号发送单独一行代码段。 图 1 显示了这种方法的效果示例。

图 1 使用 F# Interactive 窗口

此方法非常适合用于对 F# 程序进行应急调试,并且您开发的 F# 脚本上可以同时提供 IntelliSense 和 Tab 键自动完成功能。

第二种方法仍然是在 Visual Studio 中编写代码,然后将代码的一部分从 Visual Studio 复制并直接粘贴到独立的 F# Interactive 控制台中(请参见图 2)。 如果您使用这种方法,务必在粘贴的代码之后添加两个分号。这样才能更好地利用 Tab 键自动完成功能与代码进行交互。 当您逐渐习惯通过更具交互性的方式进行编程时,您会发现自己正不断地使用这种方法。

图 2 F# Interactive 控制台

您还可以直接在 Windows PowerShell 中运行代码,以便交互式开发 F# 程序。这种方法将脚本传递给 fsi.exe(F# Interactive 控制台的可执行程序)本身。 此方法的优点之一是可以快速建立脚本的原型并将结果打印到标准输出。 此外,您还可以使用轻便型文本编辑器(如 Notepad++)反复编辑代码。 图 3 显示了在 Windows PowerShell 中运行时 Map-Reduce 脚本输出的示例。本文通篇都将使用此示例。

图 3 在 Windows PowerShell 中运行 F# 脚本

 PS C:\Users\Administrator\Desktop> & 'C:\Program Files (x86)\FSharp-2.0.0.0\bin\fsi.exe' mapreduce.fsscript
192.168.1.1, 11
192.168.1.2, 9
192.168.1.3, 8
192.168.1.4, 7
192.168.1.5, 6
192.168.1.6, 5
192.168.1.7, 5 

这些不同的程序编写方法都有各自的用武之地,可帮助您处理复杂的算法、网络编程和云。 您可以编写一个应急原型,并从命令行运行该原型,了解其是否达到了预期的效果。 然后,您可以回到 Visual Studio,开始构建更大的项目。

将这些背景信息放到一边,让我们先深入探讨一些实际代码。

MapReduce 式日志分析

除了具有上述交互编程的优势以外,F# 代码还兼具简洁和强大的特色。 图 4 中的示例代码少于 50 行,然而它却包含了 Map-Reduce 算法的所有重要部分,可以计算一组日志文件中的前 10 个常见 IP 地址。

图 4 用于分析日志文件的 MapReduce 算法

 open System.IO
open System.Collections.Generic// Map Phase
let inputFile = @"web.log"
let mapLogFileIpAddr logFile =let fileReader logFile = seq { use fileReader = new StreamReader(File.OpenRead(logFile))while not fileReader.EndOfStream doyield fileReader.ReadLine() }    // Takes lines and extracts IP Address Out, // filter invalid lines out firstlet cutIp = let line = fileReader inputFile line|> Seq.filter (fun line -> not (line.StartsWith("#")))|> Seq.map (fun line -> line.Split [|' '|])|> Seq.map (fun line -> line.[8],1)|> Seq.toArraycutIp// Reduce Phase
let ipMatches = mapLogFileIpAddr inputFile
let reduceFileIpAddr = Array.fold(fun (acc : Map<string, int>) ((ipAddr, num) : string * int) ->if Map.containsKey ipAddr acc thenlet ipFreq = acc.[ipAddr]Map.add ipAddr (ipFreq + num) accelseMap.add ipAddr 1 acc)Map.emptyipMatches// Display Top 10 Ip Addresses
let topIpAddressOutput reduceOutput = let sortedResults = reduceFileIpAddr|> Map.toSeq|> Seq.sortBy (fun (ip, ipFreq) -> -ipFreq) |> Seq.take 10sortedResults|> Seq.iter(fun (ip, ipFreq) ->printfn "%s, %d" ip ipFreq);;reduceFileIpAddr |> topIpAddressOutput 

此独立版本(将来会变成网络版本)可分为三个不同的阶段:映射阶段、归约阶段和显示阶段。

阶段 1 是映射阶段。 mapLogFileIpAddr 函数采用一个日志文件作为参数。 此函数内部定义了另一个函数 fileReader,后者使用函数编程技术从日志文件中延迟获取一行文本(不过,C# 和 Python 等语言也具有此功能)。 接下来,tcutIp 函数解析每一行输入,丢弃注释行,然后返回 IP 地址和整数 1。

若要查看延迟的原因,请突出显示整个映射代码块,并且在 F# Interactive 窗口中运行该代码块以及以下代码行:

 let ipMatches = mapLogFileIpAddr inputFile 

您将看到以下输出:

 val ipMatches : seq<string * int> 

请注意,现在还没有进行任何实际操作,日志文件也还没有读取。 唯一发生的事情就是已经对表达式进行了计算。 通过这种方式,执行将被延迟到实际需要时才会进行,而不需要只是为了计算表达式就将数据获取到内存中。 这是一项强大的数据处理技术,当您利用它来分析数以千兆甚至兆兆计的庞大日志文件时效果会变得尤其明显。

如果您想比较差异并且更快地计算代码,只需向 cutIp 函数中添加一行代码,使其看起来像下面这样(请注意:|> Seq.toArray 行对于函数的构造来说完全是可选的;在示例中,它的目的是有意加快函数的处理速度,如果省略它,该函数就只是会比较慢地运行,就像 mapLogFileIpAddr 函数):

 let cutIp = let line = fileReader inputFile line|> Seq.filter (fun line -> not (line.StartsWith("#")))|> Seq.map (fun line -> line.Split [|' '|])|> Seq.map (fun line -> line.[8],1)|> Seq.toArray
cutIp 

如果您将此代码重新发送至 F# 解释器并且提供一个包含数千兆数据的大日志文件,您可能想去喝杯咖啡,因为您的计算机将会忙于读取整个文件并在内存中生成键/值映射。

在下一节的数据管道中,我将使用映射结果的输出,并将序列结果集中提供给一个匿名函数,以便计算 IP 地址在序列中出现多少次。 它通过递归不断增加 Map 数据结构,以此来达到此目的。 这种编程方式对于刚刚开始使用函数编程的开发人员来说可能很难理解,因此您可能需要在匿名函数中嵌入 print 语句,以便了解它到底在做什么。

在命令式编程方式中,您可以更新将每个 IP 地址存储为一个键的可变字典,循环访问 IP 地址序列,然后更新每个值的计数,以此来完成同样的操作。

最后一个阶段与 MapReduce 算法没有任何关系,但是有助于在原型制作阶段中编写脚本。 映射阶段的结果通过管道从 Map 数据结构传输到 Seq。 结果进行了排序,并且将打印出前 10 个结果。 请注意,这种数据管道化方式能使一个操作的结果顺利进入另一个操作,而不需要使用 for 循环。

MapReduce 加上 Windows Azure

在我的概念验证脚本完成后 - 只用了不到 50 行代码,请记住 - 现在应该将它转移到类似于生产环境的环境中去。 我会将示例从桌面转移到 Windows Azure,以作演示。

作为背景知识,您可能会发现,查看 code.msdn.microsoft.com/fsharpazure 上的 Windows Azure F# 示例以及安装 Windows Azure 模板很有帮助。 特别有趣的是 webcrawler 示例,其中的 F# 辅助角色会同时使用 Blob 和队列存储终结点。 当您深入探究将 F# 与 Windows Azure 结合使用时,此项目便于您展开学习。

我不打算详细说明如何设置多节点的 MapReduce 场。 而是从更高的层面来概括它。 有关详细信息,请参见MSDN杂志 上由 Josh Twist 撰写的文章“在 Windows Azure 中同步多个节点”(msdn.microsoft.com/magazine/gg309174)。

有几种方法可以在 Windows Azure 上设置 MapReduce 场。 图 5 演示了一个使用 F# 辅助角色的示例,这些角色将被平均分配为映射辅助角色和归约辅助角色。 回到脚本,此操作简单到几乎只需将映射函数复制并粘贴到映射辅助角色,将归约函数复制并粘贴到归约辅助角色。

图 5 Windows Azure 中的 MapReduce 场

由 Jeff Dean 和 Sanjay Ghemawat 所做的 MapReduce 演示是很有用的参考,因为它详细说明了分布式算法和可能的实现方法 (labs.google.com/papers/mapreduce-osdi04-slides/)。 尽管在图 5 的示例中,它展示了若干日志文件由 F# 辅助角色并行使用。 然后,它们通过 Windows Azure AppFabric 服务总线传递到归约辅助角色或者通过写入磁盘的形式,返回其输出,该输出包含 IP 地址键以及值 1。

接下来,归约辅助角色读取这些中间数据,生成键/值对的总数,并将其写到 Blob 存储中。 每个归约辅助角色会生成自己的汇总报告,需要先将这些报告综合起来,才能由主控辅助角色进行排序和显示。

辅助角色的创建和发布

完成原型并规划好高级体系结构后,下一步就是在 Visual Studio 2010 中创建必要的项目并将其发布到 Windows Azure。

创建 F# 辅助角色并不那么简单,因此让我们逐步讲解其过程。 首先,您需要下载上文提到的 Windows Azure F# 模板。 接着,您需要为 Windows Azure 创建一个 Visual C# 项目。 我把我的项目命名为 AzureFSharpProject。

接下来,您可以选择创建如图 6 所示的 F# 辅助角色。

图 6 创建 F# 辅助角色

此时,您可以将映射函数放到映射辅助角色中,或者将归约函数放到归约辅助角色中。 然后进一步创建辅助角色以便用于其他映射辅助角色或归约辅助角色,具体取决于您的数据处理需要的规模。 可供参考的规范参考资料是 labs.google.com/papers/-mapreduce.html 上的 Google MapReduce 文件。 它详细介绍了 Map-Reduce 的体系结构、注意事项和使用案例。

当您准备发布到 Windows Azure 时,可以右键单击项目,选择“发布”,然后选择“仅创建服务包”,如图 7 所示。

图 7 发布到 Windows Azure

最后,需要登录新的 Windows Azure 管理门户,并使用其界面创建辅助角色(请参见图 8)。

图 8 配置新的辅助角色

此时,您可以使用任何您觉得合适的方法来绑定节点,并且使用 MapReduce 分析云中的日志。 当然,除了简单的日志文件以外,这种方法也可以轻松应用到其他数据源。 此 F# MapReduce 算法的概要以及我在编码过程中演示的交互式技术,可用于任何分析、映射和归约工作。

后续步骤

F# 是一种强大的语言,可以快速制作简化方案并从中创建出更复杂的解决方案,从而方便您快速解决问题。在本文中,我利用它将 MapReduce 算法分解成更小的部分。 这样,我就能展示仅仅 50 行的 F# 是如何转变成基于 Windows Azure 的日志分析器的。

关于在 Windows Azure 上实现 MapReduce,您还可以看看这一主题的另外两篇有趣的文章。 首先,请查看 MSDN 上关于辅助角色和 MapReduce 的讨论文章“为 Windows Azure 构建可扩展的多租户应用程序”(msdn.microsoft.com/library/ff966483)。 另外,Juan G. Diaz 有一篇非常值得一读的博客文章“Amazon EC2 与 Windows Azure 的使用比较、云计算以及 MapReduce 的实现”(bit.ly/hBQFSt)。

如果您还没有看过 F#,我希望本文能让您尝试一下。 如果您有兴趣收听 Don Syme 访谈的全部内容(也正是它让我喜欢上了 F#),请访问 Simple-Talk 博客并收听该访谈 (bit.ly/eI74iO)。

转载于:https://www.cnblogs.com/JosephLiu/archive/2011/11/08/2240654.html

【转】使用 F#、MapReduce 和 Windows Azure 分析日志文件相关推荐

  1. windows服务器网站日志,windows服务器网站日志文件

    windows服务器网站日志文件 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. ...

  2. Linux运维之认识与分析日志文件(rsyslog服务),时间同步服务(chronyd服务)及时间管理命令(timedatectl)

    一.实验环境(rhel7.0版本) 主机环境:rhel7.0 各主机信息 主机名 IP server 172.25.254.1 client 172.25.254.2 二.日志文件介绍 1.Linux ...

  3. 几十个Shell分析日志文件脚本!

    点击蓝字 关注我们 因公众号更改推送规则,请点"在看"并加"星标"第一时间获取精彩技术分享 来源于网络,侵删 收集,整理一些服务器日志分析命令,可以用来分析自己 ...

  4. Linux之 Shell分析日志文件

    文章目录 前言 1. 查看有多少个IP访问及某一个页面被访问的次数 2.查看每一个IP访问了多少个页面及个IP访问的页面数进行从小到大排序 3.查看某一个IP访问了哪些页面及去掉搜索引擎统计的页面 4 ...

  5. Shell 分析日志文件命令全面总结!

    更多专业文档请访问 www.itilzj.com 自己的小网站跑在阿里云的ECS上面,偶尔也去分析分析自己网站服务器日志,看看网站的访问量.看看有没有黑阔搞破坏!于是收集,整理一些服务器日志分析命令, ...

  6. 鸟哥私房菜第19章——认识和分析日志文件

    1,日志记录系统在什么时候由哪个进程做了什么样的事情.日志文件可以解决系统方面的错误.解决网络服务的问题.过往事件记录薄. 2,日志文件可以帮助我们了解很多系统重要的事件,包括登陆者的部分信息,因此日 ...

  7. linux截取文件特定行,截取与分析日志文件的特定行数的操作

    在进行操作系统和数据库系统管理时,经常会遇到在日志文件中查找某个字符,或者按照时间截取某个时间段的日志进行分析. 今天早上就遇到一个MySQL数据库上的问题,mysql数据库在0-3点的时候,数据库会 ...

  8. java分析日志文件_java程序如何对监控软件的日志文件进行如下分析?

    一个监控软件的日志文件,内容如下: 日期               时间          接口       设备      状态 2016-09-01   08:00     J1         ...

  9. 使用logminer分析日志文件

    实验环境 win7 64  oracle PL/SQL Release 11.2.0.1.0 - Production http://blog.csdn.net/tianlesoftware/arti ...

最新文章

  1. 线性直接变换方法对摄像机进行标定
  2. mysql语句使用_Mysql基本使用语句
  3. ELK入门01—Elasticsearch安装
  4. Core Data 和 sqlite3的性能对比【图】3gs,iPhone4,4s,5的性能测试。
  5. java html2text_java-如何在html / text内容中获取文本?
  6. Python基础---循环、条件判断
  7. 51单片机c语言烧录软件,51单片机烧写程序的方法
  8. 修改pip下载存放和安装位置
  9. 计算机基础多选试题及答案,计算机基础试题及答案
  10. paypal支付(Java)
  11. 【Unity】优化工具Profiler
  12. FlashDB移植与应用
  13. 汇编语言 使用按键控制51单片机的数码管显示0~F
  14. 非线性回归分析及其Matlab实现
  15. 基于微信小程序java音乐播放器毕业设计论文/程序代码
  16. Vss、Vdd和Vcc
  17. MySQL 服务器是什么_什么是 MySQL?
  18. lottie实现动画效果
  19. 如何创建数仓指标体系?指标建模的基础理论
  20. 多目标优化(一)简单的 NSGA-Ⅱ

热门文章

  1. redhat下svn服务器搭建
  2. NAC、NAP及TNC安全接入技术对比分析
  3. html 轮播_Axure教程:使用动态面板实现轮播图
  4. 接收字节流_Java之IO流、属性配置文件
  5. 无法检测或故障_大众朗境挡位偶发缺失且无法启动
  6. mysql 子查询代替_MySQL查询优化:用子查询代替非主键连接查询
  7. PostgreSQL中的执行计划
  8. 麦块服务器显示连接已丢失,麦块服务器密码怎么设置
  9. linux卸载splunk,linux安装splunk-enterprise
  10. del服务器如何收系统日志,利用Rsyslog集中收集系统日志和用户操作记录以及相关处理方法...