目次
(3)ADSレイヤーからMysqlにデータを同期し、orcまたは寄木細工としてデータを保存する問題
0まえがき
重要なデータ同期ツールとして、sqoopはビッグデータにおいて重要な位置を占めています。この記事では、Sqoopの本番環境で発生する一般的な問題を要約し、具体的な解決策を示します。
1生産における一般的な問題
(1)Sqoopnull値の問題
ハイブでヌル下部には「\ Nの店に」、およびMySQLの中にヌル下部には、ヌル両側に同期したデータを保存する矛盾につながります。Sqoopは、同期時に両端のデータ形式とデータ型が同じであることを厳密に確認する必要があります。同じでない場合、例外が発生します。
オプション1:独自のパラメーターに依存する
1)データをエクスポートするときに2つのパラメータ--input-null-stringと--input-null-non-stringが使用されます。
2)データをインポートするときは--null-stringと--null-non-stringを使用します。
オプション2:テーブルの作成時にハイブの基になるストレージを変更し、 ''(空の文字列)に変更します
ハイブをエクスポートするときは、エクスポートする必要のあるテーブルの一時テーブルを作成します。このテーブルは、Mysqlによって同期されるテーブル、フィールド、およびタイプと厳密に一致します。エクスポートする必要のあるデータをテーブルに挿入します。一時テーブルを作成するときテーブル、ハイブのNull基になるストレージ "/ N"が "(空の文字列)に変更されます。具体的には、次の文を追加できます
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' with serdeproperties('serialization.null.format' = '')
例は次のとおりです。
drop table $output_table;
CREATE TABLE IF NOT EXISTS $output_table(
gw_id STRING,
sensor_id STRING,
alarm_level STRING,
alarm_state STRING,
alarm_type STRING,
alarm_scene STRING,
dyear string,
dmonth string,
count BIGINT,
compute_month BIGINT)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' with serdeproperties('serialization.null.format' = '')
location '/apps/hive/warehouse/phmdwdb.db/$log_dir';
- 次に、エクスポートする必要のあるデータを一時テーブルに挿入します
- 最後に、sqoopexportコマンドを使用してデータをMysqlにエクスポートします
同じことがデータのインポートにも当てはまり、再度説明することはありません。
- 2番目のソリューションは本番環境で推奨されます。面倒ですが、sqoopによって引き起こされる不要なトラブルを減らすことができ、問題を特定しやすくなります。ロジックは明確です。sqoopをエクスポートする場合は、基本的なエクスポートを作成するだけで済みます。このようにして、sqoopを簡単に一般的なスクリプトにしてスケジュールを設定できます。
(2)Sqoopデータの整合性の問題
1 )シーン1 :としてSqoopのへのエクスポートのMysql使用した場合。4番目のマップタスク、プロセスがいる2タスクが失敗し、この時間というMySQLの二つの追加に保存されている地図データタスクは、ちょうどこの場合ボスレポートデータを見るために、導入されました。開発エンジニアは、タスクが失敗したことを発見すると、問題をデバッグし、最後にすべてのデータをMySQLに正しくインポートします。次に、上司はレポートデータを再度確認し、今回表示されたデータが前のデータと矛盾していることを確認します。これは実稼働環境では許可されていません。
公式ウェブサイト:http ://sqoop.apache.org/docs/1.4.6/SqoopUserGuide.html
Sqoopはエクスポートプロセスを複数のトランザクションに分割するため、エクスポートジョブが失敗すると、部分的なデータがデータベースにコミットされる可能性があります。これにより、場合によっては挿入の衝突が原因で後続のジョブが失敗したり、他の場合にはデータが重複したりする可能性があります。この問題は、エクスポートされたデータをステージングするために使用される補助テーブルとして機能する--staging-tableオプションを介してステージングテーブルを指定することで解決できます。ステージングされたデータは、最終的に1回のトランザクションで宛先テーブルに移動されます。
- Sqoopはエクスポートプロセスを複数のトランザクションに分解するため、エクスポートジョブが失敗すると、データの一部がデータベースに送信される可能性があります。これにより、場合によっては挿入の競合が原因で後続のジョブが失敗したり、他のジョブでデータが重複したりする可能性があります。この問題は、エクスポートされたデータをステージングするための補助テーブルとして機能する--staging-tableオプションを使用してステージングテーブルを指定することで解決できます。段階的なデータは、最終的に1回のトランザクションでターゲットテーブルに移動されます。
-ステージングテーブルの方法
- (一時テーブルを作成し、sqoopを介して一時テーブルにインポートし、成功後にトランザクションを介してmysqlのビジネスデータテーブルに一時テーブルのデータをインポートします。Sqoopは、データのインポートおよびエクスポート時に一時テーブルを作成することで多くの問題を解決できます。 、だから賢い一時的なテーブルになることを学ぶ)
- --staging-tableオプションを使用して、最初にhdfsのデータを一時テーブルにインポートします。hdfsのデータが正常にエクスポートされると、一時テーブルのデータがトランザクションのターゲットテーブルにエクスポートされます(つまり、このプロセスには、完全に成功していない、または完全に失敗している必要があります)。
- ステージングオプションを使用できるようにするには、タスクを実行する前にステージングテーブルを空または空にするか、ステージングテーブルにデータがある場合は--clear-staging-table構成を使用し、-clear -staging-tableオプションを使用すると、sqoopエクスポートタスクが実行される前に、ステージングテーブル内のすべてのデータが削除されます。
注:-direct importが使用されている場合、ステージングモードは使用できません。また、-update-keyオプションが使用されている場合、ステージングモードは使用できません。
sqoop export --connect jdbc:mysql://192.168.137.10:3306/user_behavior
--username root \
--password 123456 \
--table app_cource_study_report \
--columns watch_video_cnt,complete_video_cnt,dt \
--fields-terminated-by "\t" \
--export-dir "/user/hive/warehouse/tmp.db/app_cource_study_analysis_${day}" \
--staging-table app_cource_study_report_tmp \
--clear-staging-table \
--input-null-string '\N' \
2 )シナリオ2 :マップの数を1に設定します(非推奨)
複数のマップタスクが使用されている場合でも、–staging-tableメソッドはデータの整合性の問題を解決できます。
(3)ADSレイヤーからMysqlにデータを同期し、orcまたは寄木細工としてデータを保存する問題
Sqoopのエクスポート中に、エクスポートされたテーブルがorcまたはparquetとして保存されている場合、エラーが報告されます。具体的なエラーは次のとおりです。
実際、エラーは明らかではありません。ヤーンの特定のログを確認してください。
2020-04-22 11:24:47,814 FATAL [IPC Server handler 5 on 43129]
org.apache.hadoop.mapred.TaskAttemptListenerImpl: Task:
attempt_1586702868362_6282_m_000003_0 - exited : java.io.IOException: Can't export data,
please check failed map task logs at org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:122) at
org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:39) at
org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:146) at
org.apache.sqoop.mapreduce.AutoProgressMapper.run(AutoProgressMapper.java:64) at
org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:787) at
org.apache.hadoop.mapred.MapTask.run(MapTask.java:341) at
org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:170) at
java.security.AccessController.doPrivileged(Native Method) at
javax.security.auth.Subject.doAs(Subject.java:422) at
org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1866) at
org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:164) Caused by:
java.lang.RuntimeException: Can't parse input data: '�aҩ;����%�G8��}�_yd@rd�yd�$�����瑑
g�7V!o���+��O��s�4���R�v�p)�ћȜB��X�'���F!�
�!_@�^�,��ȃ�|�|�YX�~?����>�a�i��6�=���g��?��r��-
�љ�ɪ���șk���ȅȥJȕߑk� �+ wS �. �Cw' at appv_phm_switch_master_min_orc.__loadFromFields(appv_phm_switch_master_min_orc.java:1345)
at appv_phm_switch_master_min_orc.parse(appv_phm_switch_master_min_orc.java:1178) at
org.apache.sqoop.mapreduce.TextExportMapper.map(TextExportMapper.java:89) ... 10 more
Caused by: java.util.NoSuchElementException at
java.util.ArrayList$Itr.next(ArrayList.java:854) at
appv_phm_switch_master_min_orc.__loadFromFields(appv_phm_switch_master_min_orc.java:1230)
... 12 more
sqoopはORC形式のファイルを解析できないことがわかります。
解決:
(1)SqoopとHCatalogの統合により、SqoopがORCをサポートしないという問題を解決します(より面倒です)。
(2)保守的なアプローチ:(推奨される方法)
tmpテーブルをmysqlに変更してデフォルトのtexfile形式にすることをお勧めします
tmpテーブルが元のテキストファイル形式に変更され、正常に実行されます。
dwsレイヤーまたはADSレイヤーの場合、一時テーブルtmpは、sqoopからMysqlにインポートされたテーブルから構築されます。このテーブルはMysqlテーブルと厳密に一致しています。主にMysqlとのインターフェイスに使用されます。テーブルはデフォルトの戦略を維持します。(テキストファイル形式)
(4)データスキューの問題
Sqoopのデータセグメンテーション戦略は、データスキューを引き起こすのに十分ではありません
sqoop :主に二つのパラメータの数に関連する並列ポンピングNUM-によるマッパ:スタートNマップデフォルトによって並列にインポートデータを、4ヶ月、スプリットによって:表の列に応じて、作業の分割単位。
- データの偏りを回避するために、指定されたフィールドによる分割の要件はint型であり、データは均等に分散されます。この要件を満たすことができるのは、自動インクリメントの主キーを備えたごく少数のテーブルのみです。基本的な考え方は、整然とした均一な自己インクリメントIDを生成し、それをマップの分割軸として使用することです。これにより、各マップを均一なデータに分割でき、数値を設定することでスループットを向上させることができます。マップの。
提案:
データ量が500w未満の場合は、4つのマップを使用してください。
データ量は500wを超え、8で十分です。多すぎるとデータベースが加圧され、他のシナリオではパフォーマンスが低下します。
データの特別なガイド用である場合、ダウンストリーム計算との並列度を適切に高めることができます。
主要なシナリオ:通常、split-byに対応するzizengID列を指定してから、-num-mappersまたは-mを使用して、マップの数、つまり同時抽出プロセスの数を指定できます。ただし、自動インクリメントIDまたは整数の主キーを追加しないテーブルが多数ある場合や、主キーが不均一に分散されている場合は、ジョブ全体のプロセスが遅くなります。
- sqoopソースコードの設計によれば、–queryステートメントを使用して自動インクリメントIDを分割パラメーターとして追加すると同時に、自動インクリメントID範囲を設定することで境界を設定できます。 。
コア構文は次のとおりです。
```bash
--query 方式:涉及参数 --query、--split-by、--boundary-query
--query: select col1、 col2、 coln3、 columnN from (select ROWNUM() OVER() AS INC_ID, T.* from table T where xxx ) where $CONDITIONS
--split-by: INC_ID
--boundary-query: select 1 as MIN , sum(1) as MAX from table where xxx
完全な構文例:
password-fileは、echo -n "password content"> passsword-fileによって取得されるため、異常な文字は含まれません。
sqoop import --connect $yourJdbConnectURL \
--username $yourUserName
--password-file file;///localpasswordFile or hdfs relative Path
--query "" \
--split-by "" \
-m 8 \
-boundary-query “select 1 as min , sum(1) as max from table where xx” \
--other parames
参照リンク:https://blog.csdn.net/qq_27882063/article/details/108352356?utm_medium = distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source = distribute.pc_relevant-task-t0.none -ブログ-BlogCommendFromMachineLearnPai2-1.channel_param
(5)マップタスクの並列処理設定が1より大きい問題
並列処理でデータをインポートする場合、セグメント化するフィールドを指定する必要があります。このフィールドは通常、主キーまたは自己増加する非反復数値フィールドです。そうでない場合、次のエラーが報告されます。
Import failed: No primary key could be found for table. Please specify one with --split-by or perform a sequential import with ‘-m 1’.
つまり、マップタスクの並列処理が1より大きい場合は、次の2つのパラメータを同時に使用する必要があります。
--Split-by idは、idフィールドに従って分割することを指定します
-Mnはnマップの並列処理を指定します
2まとめ
この記事では、Sqoopの本番環境で発生する一般的な問題を要約し、具体的な解決策を示します。