是否可以使用 Erlang、Mnesia 和 Yaws 开发强大的网络搜索引擎?

Posted

技术标签:

【中文标题】是否可以使用 Erlang、Mnesia 和 Yaws 开发强大的网络搜索引擎?【英文标题】:Is it possible to develop a powerful web search engine using Erlang, Mnesia & Yaws? 【发布时间】:2010-09-16 18:50:34 【问题描述】:

我正在考虑使用 Erlang、Mnesia 和 Yaws 开发一个网络搜索引擎。是否有可能使用这些软件制作一个功能强大且速度最快的网络搜索引擎?它需要什么来实现这一点,我该如何开始?

【问题讨论】:

您是否在问这个问题,认为有人已经做过并且有经验告诉您? :) 罗伯特 P!它不是那样的;)。实际上,我正在使用这些语言。用于我公司的产品开发。基本上,这个框架(erlang、mnesia 和 yaws)在印度并不为人所知。但是我正在考虑使用这些语言开发上述搜索引擎,但不知道它会如何反应? 【参考方案1】:

Erlang 可以成为当今最强大的网络爬虫。让我带你了解我的简单爬虫。

第 1 步。我创建了一个简单的并行模块,我称之为 mapreduce

-模块(mapreduce)。 -出口([计算/2])。 %%================================================== ====================== %% 使用示例 %% 模块 = 字符串 %% 功能 = 代币 %% List_of_arg_lists = [["file\r\nfile","\r\n"],["muzaaya_joshua","_"]] %% Ans = [["file","file"],["muzaaya","joshua"]] %% 两个进程正在完成的工作 %% 即没有。产生的进程数 = 长度(List_of_arg_lists) 计算(模块,功能,List_of_arg_lists)-> S = 自我(), 参考 = erlang:make_ref(), PJob = fun(Arg_list) -> erlang:apply(Module,Function,Arg_list) end, Spawn_job = fun(Arg_list) -> spawn(fun() -> 执行(S,Ref,PJob,Arg_list) end) 结尾, 列表:foreach(Spawn_job,List_of_arg_lists), 收集(长度(List_of_arg_lists),参考,[])。 聚集(0,_,L)-> L; 聚集(N,参考,L)-> 收到 Ref,'EXIT',_ -> 聚集(N-1,Ref,L); Ref, Result -> 聚集(N-1, Ref, [Result|L]) 结束。 执行(父级,Ref,Fun,Arg)-> 家长! Ref,(catch Fun(Arg))。

第 2 步。HTTP 客户端 通常会使用 erlang 内置的inets httpc module@987654321@。然而,为了内存管理和速度(尽可能降低内存占用),优秀的 erlang 程序员会选择使用@987654322@。通过应用采用 curl 命令行的@987654323@,可以将输出直接输入到 erlang 调用函数中。然而,最好让 curl 将其输出放入文件中,然后我们的应用程序有另一个线程(进程)来读取和解析这些文件

命令: curl "http://www.erlang.org" -o "/downloaded_sites/erlang/file1.html"在 Erlang 中 os:cmd("curl \"http://www.erlang.org\" -o \"/downloaded_sites/erlang/file1.html\"")。 所以你可以产生许多进程。您记得在执行该命令时转义 URL 以及输出文件路径。另一方面,有一个进程,它的工作是监视下载页面的目录。它读取并解析这些页面,然后可以在解析后删除或保存在不同的位置,甚至更好,使用zip module
 将它们存档
文件夹检查()->
    spawn(fun() -> check_and_report() end),
    好的。

-定义(CHECK_INTERVAL,5)。

check_and_report()->
    %% 避免使用
    %% 文件库:list_dir/1
    %% 如果文件很多,内存!!!
    case os:cmd("ls | wc -l") of
        “0\n” -> 好的;
        “0” -> 好的;
        _ -> ?MODULE:new_files_found()
    结尾,
    睡眠(定时器:秒(?CHECK_INTERVAL)),
    %% 继续检查
    检查和报告()。

new_files_found()->
    %% 通知我们的解析器选择文件
    %% 一旦它解析一个文件,它必须
    %% 删除或保存一些
    %% 还有什么地方
    gen_server:cast(?MODULE,files_detected)。

第 3 步。html 解析器。 最好使用这个@987654324@。这将帮助您解析和获取所有您喜欢的 HTML 标签,提取内容,然后一切顺利。下面的例子,我只关注标记中的Keywordsdescriptiontitle

在 shell 中进行模块测试...很棒的结果!!!

2> spider_bot:parse_url("http://erlang.org")。 [[[],[], “关键字”, "erlang, 函数式, 编程, 容错, 分布式, 多平台, 便携, 软件, 多核, smp, 并发", "description","开源erlang官网"], title,"erlang编程语言,官网"] 3> spider_bot:parse_url("http://facebook.com")。 [[“描述”, “ facebook 是一种社交工具,可以将人们与朋友以及在他们周围工作、学习和生活的其他人联系起来。人们使用 facebook 来与朋友保持联系,上传无限数量的照片,发布链接 和视频,并详细了解他们遇到的人。", "机器人","noodp,noydir", [],[],[],[]], title,"不兼容的浏览器 | facebook"] 4> spider_bot:parse_url("http://python.org")。 [[“描述”, " python 的主页,一种解释性的、交互式的、面向对象的、可扩展的\n 编程语言。它提供了清晰性和\n 多功能性的非凡组合,并且免费且 全面移植。", “关键字”, "python 编程语言面向对象的网络免费源", []], title,"python 编程语言-官网"] 5> spider_bot:parse_url("http://www.house.gov/")。 [[[],[],[], “描述”, "美国众议院主页", “描述”, "美国众议院主页", [],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[] ,[],[],[], [],[],[]|...], title,"美国众议院,第 111 届国会,第 2 届会议"]

您现在可以意识到,我们可以根据它们的关键字对页面进行索引,以及一个很好的页面重访计划。另一个挑战是如何制作一个爬虫(可以在整个网络上移动,从一个域到另一个域的东西),但是这个很容易。它可以通过为 href 标签解析 Html 文件来实现。使 HTML 解析器提取所有 href 标记,然后您可能需要一些正则表达式来获取给定域下的链接。运行爬虫

7> spider_connect:conn2("http://erlang.org")。 链接:["http://www.erlang.org/index.html", "http://www.erlang.org/rss.xml", "http://erlang.org/index.html","http://erlang.org/about.html", "http://erlang.org/download.html", "http://erlang.org/links.html","http://erlang.org/faq.html", "http://erlang.org/eep.html", "http://erlang.org/starting.html", "http://erlang.org/doc.html", "http://erlang.org/examples.html", "http://erlang.org/user.html", "http://erlang.org/mirrors.html", "http://www.pragprog.com/titles/jaerlang/programming-erlang", "http://oreilly.com/catalog/9780596518189", "http://erlang.org/download.html", "http://www.erlang-factory.com/conference/ErlangUserConference2010/speakers", "http://erlang.org/download/otp_src_R14B.readme", "http://erlang.org/download.html", "https://www.erlang-factory.com/conference/ErlangUserConference2010/register", "http://www.erlang-factory.com/conference/ErlangUserConference2010/submit_talk", "http://www.erlang.org/workshop/2010/", "http://erlangcamp.com","http://manning.com/logan", "http://erlangcamp.com","http://twitter.com/erlangcamp", "http://www.erlang-factory.com/conference/London2010/speakers/joearmstrong/", "http://www.erlang-factory.com/conference/London2010/speakers/RobertVirding/", "http://www.erlang-factory.com/conference/London2010/speakers/MartinOdersky/", "http://www.erlang-factory.com/", "http://erlang.org/download/otp_src_R14A.readme", "http://erlang.org/download.html", "http://www.erlang-factory.com/conference/London2010", "http://github.com/erlang/otp", "http://erlang.org/download.html", "http://erlang.org/doc/man/erl_nif.html", "http://github.com/erlang/otp", "http://erlang.org/download.html", "http://www.erlang-factory.com/conference/ErlangUserConference2009", "http://erlang.org/doc/efficiency_guide/drivers.html", "http://erlang.org/download.html", "http://erlang.org/workshop/2009/index.html", "http://groups.google.com/group/erlang-programming", "http://www.erlang.org/eeps/eep-0010.html", "http://erlang.org/download/otp_src_R13B.readme", "http://erlang.org/download.html", "http://oreilly.com/catalog/9780596518189", "http://www.erlang-factory.com", "http://www.manning.com/logan", "http://www.erlang.se/euc/08/index.html", "http://erlang.org/download/otp_src_R12B-5.readme", "http://erlang.org/download.html", "http://erlang.org/workshop/2008/index.html", "http://www.erlang-exchange.com", "http://erlang.org/doc/highlights.html", "http://www.erlang.se/euc/07/", "http://www.erlang.se/workshop/2007/", "http://erlang.org/eep.html", "http://erlang.org/download/otp_src_R11B-5.readme", "http://pragmaticprogrammer.com/titles/jaerlang/index.html", "http://erlang.org/project/test_server", "http://erlang.org/download-stats/", "http://erlang.org/user.html#smtp_client-1.0", "http://erlang.org/user.html#xmlrpc-1.13", "http://erlang.org/EPLICENSE", "http://erlang.org/project/megaco/", "http://www.erlang-consulting.com/training_fs.html", "http://erlang.org/old_news.html"] 好的 存储:是搜索引擎最重要的概念之一。将搜索引擎数据存储在 mysql、Oracle、MS SQL 等 RDBMS 中是一个大错误。这样的系统非常复杂,与它们交互的应用程序采用启发式算法。这将我们带到 Key-Value Stores,其中我最好的两个是 @987654326@@987654327@。这些都是很棒的云文件系统。另一个重要参数是缓存。使用<b>@987654328@</b> 实现缓存,上面提到的其他两个存储系统都支持它。搜索引擎的存储系统应该是schemaless DBMS,重点是Availability rather than Consistency。从这里阅读更多关于搜索引擎的信息:http://en.wikipedia.org/wiki/Web_search_engine

【讨论】:

在上面的代码中,我使用了 re 模块,正则表达式,但是现在有一种更好的方法来解析 HTML,使用 Erlang 中内置的 XPATH 实现 Mochiweb。关注这个:ppolv.wordpress.com/2008/05/09/… @MuzaayaJoshua 非常感谢您的回答!几年前,我用 php 编写了一个网络蜘蛛。然而,它已经远远超出了最初的预期,现在它需要正确运行的服务器资源根本不现实。在内部,我们正在考虑用 Erlang 或 C 重新设计它,但对 Erlang 非常感兴趣,因为它具有性能和可扩展性优势。你有没有比较它与其他语言的同一个蜘蛛的表现如何?你试过其他语言吗?如果是这样,它是如何比较的? 另外,在上面的代码中,你有一个关于 %% 如果文件很多,内存!!!您遇到什么类型的内存使用情况?我的蜘蛛每天发现和处理大约 350,000 个链接。这会被认为是“很多”,还是你在蜘蛛网中搜索更大的数字?数字更小? 哇!你的实际上好多了。你是用mochiweb Xpath解析文件吗? 我猜这也取决于 HTTP 客户端可用的带宽。无论如何,让我们继续完善它。总有一天,有人会用Erlang 和可能Couchbase 构建一个智能搜索引擎【参考方案2】:

据我所知Powerset的自然语言处理搜索引擎是使用erlang开发的。

您是否将couchdb(也是用erlang 编写的)视为一种可能的工具来帮助您解决途中遇到的一些问题?

【讨论】:

【参考方案3】:

我会推荐 CouchDB 而不是 Mnesia。

Mnesia 没有 Map-Reduce,CouchDB 有(更正 - 请参阅 cmets) Mnesia 是静态类型的,CouchDB 是文档数据库(页面是文档,即我认为更适合信息模型) Mnesia is primarily intended to be a memory-resident database

YAWS 很不错。您还应该考虑 MochiWeb。

Erlang 不会出错

【讨论】:

顺便说一句,Bjnortier! Mnesia 有 Map-reduce。它有一个函数“lists:map()”和“lists:foldl”,它们分别执行 Map 和 reduce 的功能。更多信息可以参考gotapi.com/erlang。 同意。但是 CouchDB 具有增量 Map-Reduce,即它仅在文档实际发生更改时重新计算地图并减少输出。 Mnesia is intended to be memory resident DB 的声明意味着 Mnesia 在 RAM 中的表现如此出色。但是,我们使用 Mnesia 作为Disc Only Database,我们的应用程序非常好。你听说过Fragmentation 吗?好吧,mnesia 在这方面非常出色,当表格碎片化时,所有限制都消失了。自己尝试一下,当表碎片化时,可以将具有多个表的 mnesia DB 填充到 Tera 字节的数据,但在查找时速度损失可以忽略不计。并发就是一切,Mnesia 在并发方面是神圣的【参考方案4】:

在'rdbms' contrib 中,有一个 Porter Stemming 算法的实现。它从未集成到“rdbms”中,所以它基本上只是坐在那里。我们在内部使用过它,而且效果很好,至少对于不是很大的数据集(我还没有在海量数据上测试过)。

相关模块有:

rdbms_wsearch.erl
rdbms_wsearch_idx.erl
rdbms_wsearch_porter.erl

当然还有Disco Map-Reduce framework。

你能否制造出最快的引擎,我不能说。 更快的搜索引擎有市场吗?我从来没有遇到过速度问题,例如谷歌。但是,一个能增加我找到问题的好答案的机会的搜索工具会让我感兴趣。

【讨论】:

好吧,搜索引擎的“速度”与其他所有内容并不真正意味着相同,因为当您查询时,您正在读取索引并且所有构建都会定期发生......但您知道这一点已经 Ulf ;)

以上是关于是否可以使用 Erlang、Mnesia 和 Yaws 开发强大的网络搜索引擎?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Erlang Mnesia 中创建和使用(或模拟)多列索引

Erlang:Mnesia:连续更新单个字段值

Erlang:为 mnesia 指定工作目录?

在 Elixir/Erlang 中的(本地)Mnesia 实例上实现最佳写入性能

Erlang-如何在没有记录的情况下使用 Mnesia

使用 Erlang mnesia:read/2 不返回任何内容