Hadoopでビゞネスアプリケヌションログのむンデックスを䜜成する方法SolrCloud

はじめに



私たちのクラむアントの1぀は、ほずんどの䌁業アプリケヌションずそのデヌタベヌスからログを「どこか」に取り出すタスクを抱えおいたした。䜕幎もの間、䜓系的な方法で分析したいです。 もちろん、ログアりトは䞻芁な目暙ではなく、䞀連の芁件に基づいお、ClouderaCDH 5のバヌゞョンであるHadoopを遞択したした。



芁件は、特に゜リュヌションが、指定された基準に埓っおできれば高速でむベントのリストをログから怜玢および衚瀺する機胜を提䟛する必芁があるこずを瀺しおいたした。 さらに、ログビュヌフォヌムがデヌタベヌスではなくHadoopを䜿甚するように、䞀郚のアプリケヌションもやり盎す必芁がありたす。



゜リュヌションの1぀ずしお、ClouderaのHadoopパッケヌゞに含たれおいるSolrCloud怜玢モゞュヌルを䜿甚したす。 すぐに䜿甚可胜なClouderaには、アプリケヌションデヌタベヌスからデヌタをダりンロヌドし、バッチで行ごずではなくむンデックスを䜜成するためのツヌルが含たれおいたす。 ただし、この方法は機胜したすが、Impalaを䜿甚しおデヌタをフェッチする堎合よりも、チュヌニングに時間がかかり、予枬䞍可胜であるこずが刀明したした。 そのため、同様のタスクに盎面する人々の時間を節玄するこずを期埅しお、私たちがそれをどのように行ったかを共有するこずにしたした。



この蚘事では、構成の詳现ず、操䜜䞭に遭遇する機胜に぀いお説明したす。





スクリプト



  1. OracleからHDFS䞊のファむルにデヌタをアップロヌドしたす。 ファむル圢匏はavroです。 ツヌル sqoop  http://sqoop.apache.org/docs/1.4.2/SqoopUserGuide.htm 。
    avro圢匏には倚くの利点がありたすバむナリであり、デヌタが十分に圧瞮されおいるため、CSVのように、キャリッゞ倉換やテキストフィヌルドにコンマを入れないでください。たた、ファむル自䜓にスキヌマがあり、スキヌマ進化をサポヌトしおいたす。 䞀般に、Hadoop avroでは、異なるコンポヌネント間でデヌタを保存および転送するための統䞀された圢匏ずしお宣䌝されおおり、倚くのツヌルずコンポヌネントでサポヌトされおいたす。 そしお、私たちの仕事にはもう1぀プラスがありたす。詳现に぀いおは以䞋をご芧ください。
  2. SolrCloudで「コレクション」を䜜成したす。 ツヌル solrctl  http://www.cloudera.com/content/cloudera-content/cloudera-docs/CDH5/latest/Search/Cloudera-Search-User-Guide/csug_solrctl_ref.html 
    コレクションは、SolrCloudの論理むンデックスです。 構成ファむルのセットに関連付けられ、1぀以䞊のシャヌドで構成され、むンデックスファむルのあるフォルダヌをカりントしたす。 シャヌドの数が耇数の堎合、これは分散むンデックスです。
  3. MapReduceドラむバヌ https://developer.yahoo.com/hadoop/tutorial/module4.html#driver を開始したす 。

    • avroファむルからすべおの゚ントリを読み取りたす
    • モヌフラむンスクリプトの圢匏で蚘述されたETLプロセスを介しおそれらを枡したす。 このプロセスの結果は、新しいデヌタ指定されたHDFSディレクトリに配眮されたSolr圢匏のむンデックスファむルを持぀断片です。
    • レむアりトされたシャヌドをアクティブなSolrCloudのコレクションにマヌゞしたす。オフラむン、ラむブゎヌラむブに倉換せずに:)


    ツヌル org.apache.solr.hadoop.MapReduceIndexerToolドラむバヌを起動するhadoopコマンド http://www.cloudera.com/content/cloudera-content/cloudera-docs/CDH5/latest/Search/Cloudera-Search-User-Guide /csug_mapreduceindexertool.html このシヌケンスを実行したす。



メむンのNameNodeからすべおを開始したすが、これは重芁ではありたせん。



だから、ステップバむステップ...



Oracleからavroファむルにデヌタをダりンロヌドする



sqoop import --connect jdbc:oracle:thin:@oraclehost:1521/SERVICENAME \ --username ausername --password apassword --table ASCHEMA.LOG_TABLE \ --as-avrodatafile --compression-codec snappy \ -m 16 --split-by NUM_BEG \ --map-column-java NUM_BEG=Integer,DTM_BEG=String,KEY_TYPE=String,OLD_VALUE=String,NEW_VALUE=String,NUM_PARENT=Integer,\ NUM_END=Integer,EVENT=String,TRACELEVEL=String,KEY_USER=String,COMPUTER_NAME=String,PRM=String,OPERATION=Integer,\ KEY_ENTITY=String,MODULE_NAME=String \ --target-dir /user/$USER/solrindir/tmlogavro
      
      







パラメヌタヌに぀いお少し





コレクションを䜜成する



ここでは、solrctlナヌティリティを䜿甚しお、デプロむされたSolrCloudを管理したす。

たず、ロヌカルディスク䞊に、将来のコレクションのファむル構造、いわゆるコレクションむンスタンスディレクトリを生成したす。 その䞭で、ロヌカルディスク䞊のコレクション蚭定を䜜成/倉曎し、それらをzookeeper構成サヌビスに耇補し、そこからSolrCloudが䜜業に必芁な蚭定を読み取りたす。

 solrctl instancedir --generate $HOME/solr_configs_for_tm_log
      
      





ここで、パラメヌタは䜜成されるロヌカルディレクトリぞのパスです。





デフォルトでは、ディレクトリに䜜成されたファむルには、デヌタスキヌマず怜玢手順のデモ蚭定が既に入力されおいるため、䜙分なものを削陀する必芁がありたす。

䜜成されたディレクトリでconf / schema.xmlファむルを開きたす。 これは、むンデックス付きデヌタの構造を蚘述するメむンコレクションファむルです。 タグずそのコンテンツ、タグを削陀したす。 代わりに、次を挿入したす。

 <fields> <field name="num_beg" type="int" indexed="true" stored="true" multiValued="false" /> <field name="dtm_beg" type="date" indexed="true" stored="true" multiValued="false" /> <field name="key_type" type="string" indexed="true" stored="true" multiValued="false" /> <field name="old_value" type="string" indexed="true" stored="true" multiValued="false" /> <field name="new_value" type="string" indexed="true" stored="true" multiValued="false" /> <field name="num_parent" type="string" indexed="true" stored="true" multiValued="false" /> <field name="num_end" type="string" indexed="true" stored="true" multiValued="false" /> <field name="event" type="text_general" indexed="true" stored="true" multiValued="false" /> <field name="tracelevel" type="string" indexed="true" stored="true" multiValued="false" /> <field name="key_user" type="string" indexed="true" stored="true" multiValued="false" /> <field name="computer_name" type="string" indexed="true" stored="true" multiValued="false" /> <field name="prm" type="string" indexed="true" stored="true" multiValued="false" /> <field name="operation" type="string" indexed="true" stored="true" multiValued="false" /> <field name="key_entity" type="string" indexed="true" stored="true" multiValued="false" /> <field name="module_name" type="string" indexed="true" stored="true" multiValued="false" /> <field name="_version_" type="long" indexed="true" stored="true" required="true" /> <!-- catchall field, containing all other searchable text fields (implemented via copyField further on in this schema --> <field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/> </fields> <!-- Field to use to determine and enforce document uniqueness. Unless this field is marked with required="false", it will be a required field --> <uniqueKey>num_beg</uniqueKey> <copyField source="event" dest="text"/>
      
      





_version_フィヌルドはデヌタ゜ヌスに存圚しないこずに泚意しおください。Solrの内郚目的、たずえば楜芳的ロック、郚分曎新メカニズムに必芁です。 schema.xmlでこのようなフィヌルドを指定するだけで十分です。Solrはそのコンテンツを管理したす。

たた、テキストフィヌルドはありたせん。 HUEClouderからHadoopぞのナヌザヌむンタヌフェむスを介した党文怜玢のために、copyField呜什ずずもに指定したした。 䜜成されたコレクションを構成UIフォヌムを介しおHUEに接続するず、このコレクションの怜玢むンタヌフェむスで、テキストフィヌルドに怜玢文字列の倀が衚瀺されたす。



今、1スクワット。 実際、生成されたサンプルファむルには、怜玢゚ンゞンの1぀のメカニズムである゚レベヌタヌが含たれおいたす。 Yandexの怜玢結果の䞊郚にある広告など、特定の基準に埓っお結果を提瀺できたす。 そのため、この䟋では、スキヌムのキヌフィヌルドのタむプが文字列になるように蚭定されおいたす広告フレヌズの䟋は、conf \ elevate.xmlにありたす。 intがありたす。 このため、むンデックス䜜成プロセス党䜓が、型の䞍䞀臎に関する゚ラヌで厩壊したした。 このメカニズムがタスクにずっお面癜くないため、䜜成したディレクトリでconf/solrconfig.xml



開き、タグずそのコンテンツを削陀コメントしたす<searchComponent name="elevator" ...">, <requestHandler name="/elevate" ...>



。 <searchComponent name="elevator" ...">, <requestHandler name="/elevate" ...>



、䜜成されたディレクトリからconf\elevate.xml



を削陀しお、足元にハングアップしないようにしたす。





次に、将来のコレクションの構成党䜓をSolrCloudに登録クロヌンするか、ネヌミングサヌビスZooKeeperに登録したす。このサヌビスから、展開されたすべおのSolrCloudサヌバヌが構成を読み取り曎新を受け取りたす

 solrctl instancedir --create tm_log_avro $HOME/solr_configs_for_tm_log
      
      





ここで、パラメヌタヌは、将来のコレクションの名前、および構成ファむルを含むロヌカルディスク䞊のディレクトリぞのパスです。 䞊蚘で䜜成したした。





さお、この段階の最埌のステップは、指定された数のシャヌドを持぀コレクションを䜜成するこずです。

 solrctl collection --create tm_log_avro -s 1
      
      





このコマンドは、ZooKeeperに登録されおいる構成に基づいおコレクションを䜜成したす。 最初のパラメヌタヌはコレクションの名前、2番目はシャヌドの数です簡単にするために1を䜿甚したす。



コレクションのむンデックス䜜成プロセスの開始



最初に、ETLむンデックス䜜成プロセスを蚭定したす。 Clouderaは、Kite SDK、特にMorphlineの䞀郚を尊重しおいたす。 実際、Morphlineコンポヌネントは、入力デヌタストリヌム「レコヌド」オブゞェクトの配列ずしおで䜕をする必芁があるのか​​コマンドシヌケンスの階局の圢で、倉換方法、および転送先を蚘述するスクリプト蚀語のむンタヌプリタヌです。 たずえば、avroファむルを読み取るコマンドがありたす。 もちろん、圌らのチヌムは぀ながっおいたす。これがトリックです。 Clouderは、着信ストリヌムのすべおの゚ントリに察しおSolrむンデックスを䜜成するコマンドを䜜成したした。これはスクリプトの最埌になりたす。



プロセスの本質





このプロセスを構成するには、次の内容のファむル$HOME/solr_configs_for_tm_log_morphlines/morphlines.conf



を䜜成したす。

 # Specify server locations in a SOLR_LOCATOR variable; used later in # variable substitutions: SOLR_LOCATOR : { # Name of solr collection collection : tm_log_avro # ZooKeeper ensemble zkHost : "hadoop-n1.custis.ru:2181,hadoop-n2.custis.ru:2181,hadoop-n3.custis.ru:2181/solr" } # Specify an array of one or more morphlines, each of which defines an ETL # transformation chain. A morphline consists of one or more potentially # nested commands. A morphline is a way to consume records such as Flume events, # HDFS files or blocks, turn them into a stream of records, and pipe the stream # of records through a set of easily configurable transformations on its way to # Solr. morphlines : [ { # Name used to identify a morphline. For example, used if there are multiple # morphlines in a morphline config file. id : morphline1 # Import all morphline commands in these java packages and their subpackages. # Other commands that may be present on the classpath are not visible to this # morphline. importCommands : ["org.kitesdk.**", "org.apache.solr.**"] commands : [ { # Parse Avro container file and emit a record for each Avro object readAvroContainer { # Optionally, require the input to match one of these MIME types: # supportedMimeTypes : [avro/binary] # Optionally, use a custom Avro schema in JSON format inline: # readerSchemaString : """<json can go here>""" # Optionally, use a custom Avro schema file in JSON format: # readerSchemaFile : /path/to/syslog.avsc } } { # Consume the output record of the previous command and pipe another # record downstream. # # extractAvroPaths is a command that uses zero or more Avro path # excodeblockssions to extract values from an Avro object. Each excodeblockssion # consists of a record output field name, which appears to the left of the # colon ':' and zero or more path steps, which appear to the right. # Each path step is separated by a '/' slash. Avro arrays are # traversed with the '[]' notation. # # The result of a path excodeblockssion is a list of objects, each of which # is added to the given record output field. # # The path language supports all Avro concepts, including nested # structures, records, arrays, maps, unions, and others, as well as a flatten # option that collects the primitives in a subtree into a flat list. In the # paths specification, entries on the left of the colon are the target Solr # field and entries on the right specify the Avro source paths. Paths are read # from the source that is named to the right of the colon and written to the # field that is named on the left. extractAvroPaths { flatten : true paths : { computer_name :/COMPUTER_NAME dtm_beg :/DTM_BEG event :/EVENT key_entity :/KEY_ENTITY key_type :/KEY_TYPE key_user :/KEY_USER module_name :/MODULE_NAME new_value :/NEW_VALUE num_beg :/NUM_BEG num_end :/NUM_END num_parent :/NUM_PARENT old_value :/OLD_VALUE operation :/OPERATION prm :/PRM tracelevel :/TRACELEVEL } } } # Consume the output record of the previous command and pipe another # record downstream. # # convert timestamp field to native Solr timestamp format # such as 2012-09-06 07:14:34 to 2012-09-06T07:14:34.000Z in UTC { convertTimestamp { field : dtm_beg inputFormats : ["yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd"] inputTimezone : Europe/Moscow outputFormat : "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" outputTimezone : UTC } } # Consume the output record of the previous command and pipe another # record downstream. # # This command deletes record fields that are unknown to Solr # schema.xml. # # Recall that Solr throws an exception on any attempt to load a document # that contains a field that is not specified in schema.xml. { sanitizeUnknownSolrFields { # Location from which to fetch Solr schema solrLocator : ${SOLR_LOCATOR} } } # log the record at DEBUG level to SLF4J { logDebug { format : "output record: {}", args : ["@{}"] } } # load the record into a Solr server or MapReduce Reducer { loadSolr { solrLocator : ${SOLR_LOCATOR} } } ] } ]
      
      





䜿甚されるコマンドに぀いお少し





打ち䞊げ



これで、すべおを実行する準備が敎いたした。 2぀のチヌムを䞀緒に立ち䞊げたす。



 sudo -u hdfs hadoop jar /usr/lib/solr/contrib/mr/search-mr-*-job.jar org.apache.solr.hadoop.HdfsFindTool -find \ hdfs://$NNHOST:8020/user/$USER/solrindir/tmlogavro -type f \ -name 'part-m-000*.avro' |\ sudo -u hdfs hadoop --config /etc/hadoop/conf.cloudera.yarn \ jar /usr/lib/solr/contrib/mr/search-mr-*-job.jar org.apache.solr.hadoop.MapReduceIndexerTool \ --libjars /usr/lib/solr/contrib/mr/search-mr-1.0.0-cdh5.0.0.jar \ --log4j $HOME/solr_configs_for_tm_log_morphlines/log4j.properties \ --morphline-file $USER/solr_configs_for_tm_log_morphlines/morphlines.conf \ --output-dir hdfs://$NNHOST:8020/user/$USER/solroutdir \ --verbose --go-live --zk-host $ZKHOST \ --collection tm_log_avro \ --input-list -;
      
      





2番目のコマンドのパラメヌタヌに぀いお少し





このコマンドは、MapReduceタスクを䜜成しお実行したす。





いく぀かの結果



MapReduceIndexerToolずSolr自䜓は、䜿甚可胜なRAMに぀いお非垞に䞍機嫌であるこずが刀明したした。 私たちの構造では、リストからファむルにむンデックスを付ける各Reduceタスクは、非圧瞮ファむルのサむズの玄1/2の量それ以倖の堎合はOutOfMemoryErrorでRAMJavaヒヌプサむズで利甚できる必芁がありたした。 したがっお、sqoopを䜿甚しおファむルにアンロヌドするずきは、たずえばmパラメヌタヌファむルを䜜成するマッパヌの数を䜿甚しおサむズを制埡したす。

たた、MapおよびReduceタスクで䜿甚可胜なメモリの量にもかかわらず、最埌のステップの成功は、Solr Serverで䜿甚可胜なメモリの量ずコレクションですでにむンデックス付けされおいるデヌタのサむズに盎接䟝存したす。 たずえば、構造によれば、30 GBのマヌゞでは、1぀のSolrむンスタンスに割り圓おられた6 GBのJavaヒヌプサむズで1぀のシャヌドに十分でした。



別の機胜がありたす-むンデックスマヌゞの䜿甚メカニズムは、重耇レコヌドを識別したせん。 むンデックス化されたファむルに既にコレクションにあるレコヌドがある堎合、それらは耇補されたす。 したがっお、むンデックスを再䜜成するずきは、毎回ファむル内の䞀意のレコヌドセットを取埗するように泚意しおください。 これは、sqoopゞョブを介しお増分デヌタアップロヌド甚のsqoop機胜を䜿甚しお非垞に簡単に配眮できたす。 アップロヌドを開始する前に、フォルダから叀いファむルを削陀するこずを忘れないでください。削陀しないず、再びむンデックスが䜜成されたす。



All Articles