È possibile sviluppare un potente motore di ricerca web usando Erlang, Mnesia e amp; Framboesia?
-
10-07-2019 - |
Domanda
Sto pensando di sviluppare un motore di ricerca web usando Erlang, Mnesia & amp; Framboesia. È possibile creare un motore di ricerca Web potente e veloce utilizzando questi software? Cosa sarà necessario per raggiungere questo obiettivo e come posso iniziare?
Soluzione
Oggi Erlang può creare il web crawler più potente. Lascia che ti accompagni attraverso il mio semplice cingolato.
Passaggio 1. Creo un semplice modulo di parallelismo, che chiamo mapreduce
-module(mapreduce). -export([compute/2]). %%===================================================================== %% usage example %% Module = string %% Function = tokens %% List_of_arg_lists = [["file\r\nfile","\r\n"],["muzaaya_joshua","_"]] %% Ans = [["file","file"],["muzaaya","joshua"]] %% Job being done by two processes %% i.e no. of processes spawned = length(List_of_arg_lists) compute({Module,Function},List_of_arg_lists)-> S = self(), Ref = erlang:make_ref(), PJob = fun(Arg_list) -> erlang:apply(Module,Function,Arg_list) end, Spawn_job = fun(Arg_list) -> spawn(fun() -> execute(S,Ref,PJob,Arg_list) end) end, lists:foreach(Spawn_job,List_of_arg_lists), gather(length(List_of_arg_lists),Ref,[]).
gather(0, _, L) -> L; gather(N, Ref, L) -> receive {Ref,{'EXIT',_}} -> gather(N-1,Ref,L); {Ref, Result} -> gather(N-1, Ref, [Result|L]) end.
execute(Parent,Ref,Fun,Arg)-> Parent ! {Ref,(catch Fun(Arg))}.
Passaggio 2. Il client HTTP
Normalmente si userebbe il modulo httpc inets
incorporato in erlang o ibrowse
. Tuttavia, per la gestione e la velocità della memoria (riducendo al minimo la stampa del footprint di memoria), un buon programmatore di erlang sceglierebbe di usare curl
. Applicando il os: cmd / 1 che prende quella riga di comando ricciolo, si otterrebbe l'output direttamente nella funzione di chiamata erlang. Tuttavia, è ancora meglio far arricciare i propri output in file e quindi la nostra applicazione ha un altro thread (processo) che legge e analizza questi file
Command: curl "http://www.erlang.org" -o "/downloaded_sites/erlang/file1.html"In modo da poter generare molti processi. Ti ricordi di sfuggire all'URL e al percorso del file di output mentre esegui quel comando. Esiste invece un processo il cui lavoro è guardare la directory delle pagine scaricate. Queste pagine le legge e le analizza, quindi può eliminare dopo l'analisi o salvare in una posizione diversa o, meglio ancora, archiviarle utilizzando il
In Erlang
os:cmd("curl \"http://www.erlang.org\" -o \"/downloaded_sites/erlang/file1.html\"").
modulo zip
folder_check()-> spawn(fun() -> check_and_report() end), ok. -define(CHECK_INTERVAL,5). check_and_report()-> %% avoid using %% filelib:list_dir/1 %% if files are many, memory !!! case os:cmd("ls | wc -l") of "0\n" -> ok; "0" -> ok; _ -> ?MODULE:new_files_found() end, sleep(timer:seconds(?CHECK_INTERVAL)), %% keep checking check_and_report(). new_files_found()-> %% inform our parser to pick files %% once it parses a file, it has to %% delete it or save it some %% where else gen_server:cast(?MODULE,files_detected).
Passaggio 3. Il parser html.
Meglio usare questo html di mochiweb parser e XPATH
. Questo ti aiuterà ad analizzare e ottenere tutti i tuoi tag HTML preferiti, estrarre i contenuti e quindi fare il meglio. Gli esempi seguenti, mi sono concentrato solo sul Parole chiave
, descrizione
e titolo
nel markup
Test del modulo in shell ... risultati fantastici !!!
2> spider_bot:parse_url("http://erlang.org"). [[[],[], {"keywords", "erlang, functional, programming, fault-tolerant, distributed, multi-platform, portable, software, multi-core, smp, concurrency "}, {"description","open-source erlang official website"}], {title,"erlang programming language, official website"}]
3> spider_bot:parse_url("http://facebook.com"). [[{"description", " facebook is a social utility that connects people with friends and others who work, study and live around them. people use facebook to keep up with friends, upload an unlimited number of photos, post links and videos, and learn more about the people they meet."}, {"robots","noodp,noydir"}, [],[],[],[]], {title,"incompatible browser | facebook"}]
4> spider_bot:parse_url("http://python.org"). [[{"description", " home page for python, an interpreted, interactive, object-oriented, extensible\n programming language. it provides an extraordinary combination of clarity and\n versatility, and is free and comprehensively ported."}, {"keywords", "python programming language object oriented web free source"}, []], {title,"python programming language – official website"}]
5> spider_bot:parse_url("http://www.house.gov/"). [[[],[],[], {"description", "home page of the united states house of representatives"}, {"description", "home page of the united states house of representatives"}, [],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], [],[],[]|...], {title,"united states house of representatives, 111th congress, 2nd session"}]
Ora puoi capire che, possiamo indicizzare le pagine in base alle loro parole chiave, oltre a un buon programma di revisori delle pagine. Un'altra sfida è stata come creare un crawler (qualcosa che si sposterà su tutto il Web, da un dominio all'altro), ma quello è facile. È possibile analizzando un file HTML per i tag href. Crea il parser HTML per estrarre tutti i tag href e quindi potresti aver bisogno di alcune espressioni regolari qua e là per ottenere i collegamenti direttamente in un determinato dominio.
Esecuzione del crawler
7> spider_connect:conn2("http://erlang.org"). Links: ["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"] okConservazione : è uno dei concetti più importanti per un motore di ricerca. È un grosso errore archiviare i dati dei motori di ricerca in un RDBMS come MySQL, Oracle, MS SQL e.t.c. Tali sistemi sono completamente complessi e le applicazioni che si interfacciano con essi impiegano algoritmi euristici. Questo ci porta a Key-Value Stores , di cui i due di i miei migliori sono
Couch Base Server
e Riak
. Questi sono ottimi file system cloud. Un altro parametro importante è la memorizzazione nella cache. La memorizzazione nella cache viene ottenuta utilizzando dire Memcached
, di cui gli altri due i sistemi di archiviazione di cui sopra ne hanno il supporto. I sistemi di archiviazione per i motori di ricerca dovrebbero essere schema DBMS
, che si concentra su Disponibilità piuttosto che sulla coerenza
. Maggiori informazioni sui motori di ricerca da qui: http://en.wikipedia.org/wiki/Web_search_engine
Altri suggerimenti
Consiglierei CouchDB invece di Mnesia.
- Mnesia non ha Map-Reduce, CouchDB sì (correzione - vedi commenti)
- Mnesia è digitata staticamente, CouchDB è un database di documenti (e le pagine sono documenti, vale a dire un migliore adattamento al modello informativo secondo me)
- Mnesia è principalmente destinata a essere un database residente in memoria
YAWS è abbastanza buono. Dovresti anche considerare MochiWeb.
Non sbaglierai con Erlang
Nel 'rdbms' contrib , esiste un'implementazione dell'algoritmo Porter Stemming. Non è mai stato integrato in "rdbms", quindi è praticamente solo seduto lì fuori. L'abbiamo usato internamente e ha funzionato abbastanza bene, almeno per i set di dati che non erano enormi (non l'ho testato su enormi volumi di dati).
I moduli pertinenti sono:
rdbms_wsearch.erl
rdbms_wsearch_idx.erl
rdbms_wsearch_porter.erl
Poi c'è, ovviamente, il Framework per la riduzione della mappa della discoteca .
Non so dire se tu sia il motore più veloce là fuori. Esiste un mercato per un motore di ricerca più veloce ? Non ho mai avuto problemi con la velocità di es. Google. Ma una struttura di ricerca che ha aumentato le mie possibilità di trovare buone risposte alle mie domande mi interesserebbe.