+インパラ必要があります

Kudu+Impala介绍

アウトライン

クーズーとインパラは、Apache財団にすべてのトップレベルプロジェクトClouderaの貢献です。クーズーとして低レイテンシ、高KV同時クエリをサポートしながら、保存され、スキャンは依然として良好なパフォーマンスを維持する基礎となる、それは考慮に入れタイプとOLAP OLTPクエリのカテゴリを取る理論的に可能である特性という。アドホッククエリに直面しているエンジンを解析するSQLのベテランとして、インパラ(アドホッククエリ)クラス要求の安定性と速度が広範囲にインパラ、業界で検証され、SQLを解析するための責任があり、独自のストレージエンジンを、持っていない、と接続されています基礎となるストレージエンジン。クーズー、インパラとクーズー後にリリースリリースインパラ主支持HDFSの初めに深い統合を行っています。

多くのビッグデータフレームワークの中で、似ていますが、SQLの実行時間のためにSQLを解析インパラ迅速なアドホッククエリを懸念インパラ位置決めハイブはまだハイブがより適切である、長すぎます。より高いインパラマシン構成要件は、メモリ128Gの公式は上記で示唆するように、他のGROUPBY SQLクエリで、計算インパラメモリが行われ、このような問題は、効率は低いが、底ハイブ従来のMapReduceコンピューティングフレームワークに対応するが、安定していますよく、マシン構成要件も低いです。

インパラは最大百倍異なる部分のクエリの実行速度、インパラはすでにはるかに高速ハイブよりも速度を解析している、その後、クーズーの追加により、さらに強力で、HDFSに格納されたデータの効率の最大の利点です。

それは、英語でクーズーとインパラはアフリカからカモシカの2話の異なる種に意図していることに注目すべきである、Clouderaのは、この会社は、自社製品の命名などの動物で高速に実行するのが好き。

背景

OLTPとOLAP

OLTP(オンライントランザクション処理)指向の高い同時低レイテンシーのCRUD(INSERT、DELETE、UPDATE、SELECT 、等。)。

OLAP(オンライン分析処理)を遅延するためのより高い耐性を有するBI分析データ要求のために意図され、データの量がはるかに大きくなるようにOLTP処理に比べ。

従来、OLTPは、MySQLおよびその他のリレーショナルデータベース、OLAPに対応し、データウェアハウスに対応します。データ記憶のためのOLTP及びOLAPクエリエンジンは、必要なインフラストラクチャも非常に異なっている場合、その要求処理と同じではない、異なっています。この機能は、データは、少なくとも2ヶ所、定期的またはリアルタイム同期が必要に格納する必要がなく、一貫性を維持する必要があることを意味し、データ開発エンジニアの特性は、学生がデータに多くの時間を無駄にし、多大な苦痛を引き起こしました検証と同期。クーズー+インパラは、この競合を、登場しないものの、この問題に対する完璧なソリューションを、それは否定できない、その容易。

これは4つの条件が満たされている重要なOLTPとそのトランザクションACIDではないことに注意してください。実際には、OLTPは、ACIDの出現よりもはるかに早い概念です。この論文などのデータ、同時性、待ち時間の要件、量の面でOLTPとOLAPの注目の概念では、トランザクションを懸念していません。

Kudu 来由

クーズーClouderaのが最初に開発、およびApache財団に2015年12月3日に寄贈されました2016年7月25日に卒業を発表し、トップレベルのApacheプロジェクトにアップグレードし、。クーズーの開発にコミッタのクーズーと、中国企業のキビ、深くクーズーの開発に携わっキビの間で強い支持を得ることは注目に値します。

卒業クーズー、まだ若いクーズーの時からわかるように、改善を必要とする多くの詳細がありますが、(トランザクションなど)を開発するためのいくつかの重要な特徴があります。しかし、より多くの企業であることのクーズー+インパラの練習の組み合わせは、Clouderaの会社は現在、新たなビッグデータ・ソリューションの主なプッシュです。

その他の用語集

  • HDFSは、最も基本的な生態系のサークルのHadoopストレージエンジンで、HDFSは、主に大規模なファイルストレージ、高スループットの読み取りおよび書き込みサービスのために設計されていることに注意してください、HDFSは、小さなファイルを格納するのに適していない、またそれは、ランダム読み取りおよび書き込みを多数サポートしていません。
  • MapReduceは、複数のマッパーと減速にタスクによって最も基本的なコンピューティングフレームワークを、コンピューティングは、コンピューティング・フレームワークは、大規模なデータの共通タスクでうまく動作分散しました。
  • Hadoopのは最初Hadoop2.0 3.0を解放するだけでなく、HDFS +のMapReduceで構成された、Hadoopのは、多くの機能を与えられています。
  • HBaseのは、 GoogleのBigtableの紙に触発され、プロジェクトが最初にPowersetの会社に始まりました。高いランダムアクセス性能とHDFSに基づいHBaseのは、典型的なOLTPクラス要求処理エンジンです。同時に、HBaseのスキャンにも優れた性能を持って、私たちはクラスのOLAP要求のいくつかのタイプを処理することができます。
  • スパークは、スパークは、分散コンピューティングタスクをより効率的に行うことができる豊かな分散コンピューティング・プリミティブを提供し、MapReduceのと比較して、コンピューティングエンジンの次の世代のいずれかで反復計算、流量計算を設定します。
  • アドホッククエリは、通常のように変換されるアドホッククエリは、データウェアハウスの重要な概念です。データ探索と分析アプリケーションは、通常、一緒に任意の一時的なSQLを入れて、検索をスピードアップするために一定の要件があり、総称して、アドホッククエリと呼ばれるクラスを照会します。
  • 記憶カラムに比べてラインメモリ、互いに同じ列のデータ記憶行。データは、同じ列に高度に繰り返されているので、それほどメモリは、より高い圧縮比を提供することができます。そして、ラインメモリに比べて、ほとんどのBI分析が唯一の列の一部を読んでいるので、カラムストアは、あなたがより速くクエリを提供できるように、データが、あまり読んで必要な列をスキャンする必要があります。一般的な柱状ストレージ合意寄木細工のように。

Kudu介绍

クーズーは何ですか

クーズーストレージエンジンは、Hadoopのエコシステムを中心に構築され、クーズーは、通常のサーバー上で実行するHadoopエコシステムと共通のデザイン哲学、分散規模な展開を持ち、業界の高可用性の要件を満たしています。以下のためのデザインコンセプトFASTデータ分析ON FAST。 ランダムアクセス性能を低減するように設計されてほとんどのクーズーのHBaseのシーンなど、スキャンの増加は、ほとんどのシナリオでは、同時にほぼクーズーHBaseのランダム読み取りを持っており、限り多くのスキャンパフォーマンスのHBaseよりも、パフォーマンスを書きます。

他のストレージエンジンは異なるHBaseのは、クーズーは、次のような利点があります。

  • OLAPクラスの高速クエリーの処理速度
  • 公式サポートのメンテナンスにより、ドライブに接続されたMapReduce、スパークおよびその他のHadoopエコシステム共通のシステムとの高い互換性
  • HDFSに比べインパラの深さとの統合は、+寄木張り+インパラの伝統的な建築、クーズー+インパラは、ほとんどのシナリオで優れた性能を持っています。
  • 強力で柔軟な一貫性モデルは、ユーザがそれぞれの要求も強い配列同一性のための別個の一貫性モデルを定義することを可能にします。
  • OLTPとOLAP要求の両方をサポートすることができ、かつ良好な性能を持っています。
  • クーズーはClouderaManager、運用・保守フレンドリーに統合しました。
  • 高可用性。モデルとしてマスターを使用して筏コンセンサスアルゴリズムは、選挙が失敗しても、データはまだ読み取り可能である、選挙に失敗しました。
  • 省スペース、より効率的なクエリの速度ながらデータは、構造化された、純粋な柱状のストレージをサポートしています。
クーズー典型的な使用シナリオ

リアルタイムシステムのシナリオをストリーミング

ストリーム・コンピューティングのシナリオは、一般的に、同時にこれらのデータはまた、ほぼリアルタイムの読み取りのためにサポートして書き込み、更新操作、連続書き込みの数が多いです。クーズーは、このシナリオを処理することができる設計します。

時系列のストレージエンジン(のTSDB)

地元のホットスポットTSDBリクエストクラスを避けるためにうまく動作するように設計されたハッシュクーズーフラグメント。スキャンパフォーマンスクーズーHBaseのより良いサポートの問い合わせを行うことができます効率的によりながら。

機械学習&データマイニング

データマイニングや機械学習の中間結果は、多くの場合、ランダムアクセス動作を少量ながら、高スループットの一括書き込み、読み出しが必要です。クーズーデザインは、これらの中間結果のストレージのニーズを満たすことができます。

歴史的遺産のデータと共存

産業部門の実際の運用環境では、多くの場合、遺産データの数が多いです。インパラは、HDFS、クーズー、より根本的なストレージエンジンをサポートすることができ、この機能はクーズーを利用し、クーズーに移行し、すべてのデータを入れてはいけません。

中クーズー重要な概念

柱状ストレージ

間違いありません、クーズーはHBaseのにちょうど列にデータを格納比べて、純粋な列ベースのストレージエンジンで、クーズー列ベースのストレージ近い寄木細工は、より効率的なスキャン操作のサポートで、それはまた、より少ないストレージスペースを取るされています。柱状ストレージが、主な理由の二つ:.データアクセス列の一部のみの通常の意味で1つのOLAPクエリを、そのような利点を有し、この場合、コラムストレージエンジンのサポートオンデマンドアクセスは、ラインストレージエンジンは、すべての行を取得する必要がありますデータ。同じ列のデータは、より高い類似性を有する傾向があるので、列の2.データは、より高い圧縮比を持つことになり、一緒に一般的な意味を置きます。

クドゥすべてのデータは、各テーブルは、テーブルの構造と、対応する主キーを有する、テーブルに格納され、主キーデータが順に格納されます。クーズーは、大規模なデータ量をサポートするように設計されたので、データは表の中では、断片に分割されます、タブレットと呼ばれます。

タブレット

タブレットと同様他の分散ストレージサービスと共に隣接データに錠剤を同時に、上方に配置され、異なるサーバ上の複数のコピーを持っているであろう、リーダーとして一つだけ錠剤があり、各コピーであることができますあなたが書き込みを同期させるために必要な一貫性を書き込み、別の読み取りを提供しています。

タブレットサーバー

タブレットサービス定義、タブレット上の読み取りおよび書き込み操作は、サービスによって行われます。与えられた錠剤については、後に詳細に説明された原則ラフトの整合性アルゴリズム、以下のリーダー、フォロワー、リーダー選挙や災害復旧などの他のように。限られた数のタブレットタブレットのサービスを運ぶことができることに注意してくださいまた、設定パーティションの合理的な数の必要性を必要とし、設計クーズーテーブル構造、少なすぎるあまりに過度のタブレット、タブレットサービスを引き起こす可能性があり、パフォーマンスの低下につながることができます圧力の原因となります。

マスター

すべてのメタ情報他のサービスが、同時に、最大で1つのマスターがリーダーとしてマスター・ストア、ダウンリーダー後のラフトコンセンサスアルゴリズムに従って再選挙となります。

マスターメタ情報読み書き動作は、今後クライアントを調整します。クライアントがマスターにリクエストを送信するときに、新しいテーブルを作成するときにたとえば、マスターは、タブレットやその他のサービスをcatelogするための要求を転送します。

データが格納されていない自分自身をマスタデータは、タブレットに格納され、コピーが正常錠剤に従ってバックアップされます。

タブレットサービスは、マスターとの毎秒ハートビート接続になります。

いかだコンセンサスアルゴリズム

クーズーは、選挙の原則の大多数のため、新たなリーダーになるためにリーダーノードがダウンしたときにラフトの整合性アルゴリズムは、ノードのフォロワー、候補者、リーダー3つの役割に分けて使用し、フォロワーと多数決原理によって候補となりますので、任意の時点で、リーダーの役割まで。リーダーは、フォロワーのほとんどが書き込むとき、命令を変更し、フォロワーに配布するためにデータをアップロードするクライアントを受けリーダーが成功した書き込みを考慮し、クライアントに通知します。

カタログ表

Catelogテーブルにはテーブルと錠剤を含むいくつかのメタデータクーズー、。

クーズーアーキテクチャの概要

図から分かるように、リーダーである3つのマスターがある、他の2つはフォロワーです。

4台のマシンにわたって分散錠と均等のコピーが存在4台のタブレットサーバは、N。各錠剤はリーダー、2人のフォロワーを持っています。各テーブルは、フラグメントの数に応じて錠剤に分割されます。

画像

インパラの紹介

インパラは何ですか

インパラは、SQL構文ハイブインパラは非常に互換性のある、インタラクティブSQL構文解析エンジンのHadoopのエコシステム上に構築され、そして標準的なODBCとJDBCインターフェースを提供することです。インパラは、基礎となるHDFS、クーズー、HBaseのも、アマゾンS3から利用可能なデータをデータ・ストレージ・サービスを提供していません。

最初のClouderaの会社が開発したImpapaは、Apacheのインパラのために、今その正式名称(インキュベート)12月15日、上のApache財団に貢献しました

インパラハイブ自体は、高スループットの要求数を実行するのに長い時間のための完全な代わるものではありません、ハイブは、その安定性はハイブと同等ではありませんが、それはSparkSQLであったとしても、まだ最も安定し、最適なオプションです。

ハイブとして良いインパラの安定性が、効率の面で、インパラは間違いなくスパイクハイブになることはできません。インパラ分散シャッフル用のインメモリコンピューティング・モデルを使用して、あなたは、現代のコンピュータのメモリとCPUリソースを可能な限り活用することができます。一方、そこインパラの前処理および分析技術は、データテーブルの後に挿入することができるCOMPUTE STATSデータランクのインパラ深さ分析を行うための命令。

インパラの利点
  • 多くの学習コストをかけずハイブとSQLの構文と非常に類似し、
  • SQL解析機能大規模データ、メモリとCPU使用率、急速なリターンSQLクエリの結果を効率的に使用します。
  • 複数の基礎となるデータソースを統合し、HDFS、クーズー、HBaseのインパラのベスト他のデータ共有により、データの同期が不要になります。
  • フエの深さとの統合、SQL操作とワークフローの視覚を提供します。
  • 事業の下流側へのシームレスなアクセスを容易にするための標準JDBCやODBCインタフェース。
  • 最も詳細には、著作権管理の列、データのセキュリティ要件を満たすために、実際の生産環境を提供します。
インパラとハイブSQLとの互換性?

インパラの高い互換性のハイブが、いくつかのハイブSQL機能を含め、インパラではサポートされていません。

  • データ型がサポートされていない、など
  • XMLとJSONの機能はサポートしていません。
  • DISTINCT複数には、以下の操作がDISTINCT複数を完了する必要があり、サポートされていません。

select v1.c1 result1, v2.c1 result2 from (select count(distinct col1) as c1 from t1) v1 cross join (select count(distinct col2) as c1 from t1) v2;

インパラと互換性のハイブのみ文法に反映されていない、フレームワークにインパラとハイブも互換性にかなりの程度を維持し、直接企業のため、ドルを用いてインパラハイブデータベースは、移行が必要にハイブテーブル構造にされています、インパラは、直接使用することができます。

クーズー+インパラは、私たちに何を意味します

クーズー+インパラは、リアルタイムのデータ・ウェアハウスのための優れたソリューションを提供します。このアーキテクチャはまた、ランダム読み取りをサポートしながら、優れたスキャン性能を維持し、書きながら、スパーククライアントやその他のストリーミング・コンピューティングフレームワークの正式サポート。これらの機能は、データがリアルタイムクーズーにリアルタイムで計算スパークに書き込むことができることを意味し、インパラは、上側のBI分析SQLクエリ、データマイニングアルゴリズムを提供し、他のニーズが直接クーズー反復スパークフレームワーク上の基礎となるデータを操作することができます。

クーズーとインパラ不十分

主キー制約クーズー
  • 表作成皇帝キーを変更することはできません。
  • 主キーの内容を、対応するラインは、更新操作を変更することはできません。行の主キー値、削除するための新しい行と新しいデータを変更し、及びアトミック操作を維持することができません。
  • これは、主キーDOUBLE、FLOAT、BOOLの種類をサポートしていない、とnull以外の主キー(NOT NULL)でなければなりません。
  • 自動生成された主キーがサポートされていません。
  • 各行は16キロバイトまでの一次鍵記憶部(CELL)に対応します。
クーズーリミットコラム
  • このようサポートされていないDECIMAL、CHAR、VARCHAR、DATE、ARRAYなどのMySQL、中のデータ型の一部。
  • データ・タイプ、およびそれが空白の列プロパティを変更することができないかどうか。
  • 300までのテーブル。
クーズー制限表
  • バックアップは、表の奇数、7の最大値でなければなりません。
  • 数は、バックアップセットの後に変更することはできません。
クドゥ制限手段(セル)の
  • 最大64キロバイトに対応するデータ部、及び圧縮前です。
制限断片クーズー
  • フラグメントは手動でのみサポートを指定して、自動シートをサポートしていません。
  • フラグメンテーション設定は、所望の変更スライスを設定するために、修正することができません「 - 誘導体データ - 新しいテーブルを作成、削除いとこ」動作。
  • ほとんど失われたバックアップ錠剤を手動で修復する必要があります。
クーズー容量の制約
  • タブレットサーバ推奨最大数は100です。
  • 巨匠の推奨最大数は3です。
  • 4Tまでに格納された各錠剤サーバ推奨データ(疑問は、なぜそのような小さな4T制限がある場合?)。
  • 1000年以内に錠剤サーバ記憶推奨に従って錠剤の数。
  • 単一の錠剤サーバ60に断片を格納するテーブルごとの錠剤の最大数。
クーズーその他の使用制限
  • クドゥは、対応するデータが、いくつかの問題に実行することができる大きすぎる各行の分析を使用するように設計されています。
  • そこプライマリキーインデックス、セカンダリインデックス(セカンダリインデックス)をサポートしていません。
  • マルチライントランザクション操作はサポートされていません。
  • こうした外部キ​​ーなどのリレーショナルデータの一部の機能は、サポートされていません。
  • テーブル名の列とUTF-8エンコーディングに強制し、最大256バイト。
  • すぐに領域を解放しない1削除、あなたは圧縮操作を実行する必要がありますが、圧縮をサポートしていない操作は手動で行います。
  • すぐにスペースを解放しますテーブル操作をドロップします。
インパラの安定性
  • インパラは、超長いSQL要求には適していません。
  • インパラ高い同時読み取りおよび書き込み操作も、クーズーがサポートされ、サポートされていません。
  • インパラとハイブいくつかの文法は互換性がありません。

よくある質問

インパラは高い同時読み取りをサポートし、それを書くには?

サポートされていません。インパラプラットフォームは、アドホッククエリを二するために設計されていますが、単一の実行SQLのその高いコストが低遅延、高並行性のシナリオをサポートしていませんが。

インパラハイブは、それを置き換えることができますか?

長いSQLへの要求を実行している、いない、メモリインパラの計算モデルは、その高効率設計されていますが、ハイブ未満の安定、ハイブはまだ最初の選択肢です。

インパラどのくらいのメモリを必要とされていますか?

スパークと同様、インパラは計算に可能な限りメモリにデータを入れ、十分でないメモリが、インパラは、ディスクによって計算されるが、メモリサイズがインパラの効率と安定性を決定することは間違いありません。インパラの関係者は、少なくとも128G以上、インパラに割り当てられたメモリの80%にメモリを推奨しました

インパラのキャッシュはありますか?

インパラは、テーブルのデータキャッシュしません、インパラは一部だけ、メタデータのテーブル構造をキャッシュします。現実ではあるが、セカンドランは、同じクエリが速くなるかもしれませんが、これは、基礎となるストレージ・システムまたはLinuxキャッシュでインパラキャッシュ、ではありません。

インパラは、カスタム機能を追加することができますか?

ことができます。Impala1.2バージョンがUDFをサポートしますが、インパラUDFはハイブよりも複雑な追加します。

インパラなぜ速いですか?

スピードのためインパラ、それは効率の詳細にたくさんの最適化を行いました。ハイブに比べ、広い意味では、インパラは、計算モデルとしてのMapReduceを使用していない、MapReduceは、偉大な発明である多くの分散コンピューティングの問題を解決しますが、残念ながら、ないSQLおよびMapReduceの設計のために。SQL MapReduceの計算プリミティブに変換すると、多くの場合、多層反復を必要とし、データは偉大な廃棄物で、その結果、より頻繁に低下する必要があります。

  • データが完了するまでにSQLクエリを落ちないようインパラはMapReduceのに比べて、メモリにキャッシュされたデータを置くために反復床設計の各ラウンドをしようと、効率が大幅に改善されました。
  • 常駐インパラプロセスはMapReduceの開始のオーバーヘッドを回避し、アドホッククエリのMapReduceタスクの起動コストは、災害でした。
  • インパラは、SQLのために特別に設計されては、反復回数を減らし、マッパーとリデューサーに毎回タスクを回避し、ソート不要なシャッフルとを避けることができます。

一方、インパラ、現代の計算フレームワークは、現代の高性能サーバをより有効に活用することができます。

  • コード実行を動的に生成LLVMとインパラ
  • インパラはSSE4.1データ等をプリフェッチする命令のセットを含む、このハードウェア構成で可能となります。
  • インパラは、全体のスループットが最大化される作り、各ディスクのスループットの制御粒度を細かくなり、自分のコーディネーションディスクIOを制御します。
  • インライン関数、速度ループの展開の技術を含む、コード効率レベルでは、C ++を使用して言語インパラは完了し、言語の詳細を追求
  • 手続きメモリ使用量は、インパラは、JVMベースの言語よりもはるかに小さく、メモリフットプリントをC ++自然の利点を使用し、コードの詳細のレベルは、データキャッシュのためのより多くのメモリを解放することが可能となり、最小限のメモリ使用量、の原則に従っています。
比べてどのようなクーズーHBaseの利点、そしてなぜ?

特定の機能にクーズーと非常によく似たHBaseのは、私たちはそれらを一緒に入れます。しかし、クーズーとHBaseの二つの異なる性質は次のように。

  • クーズーのデータモデルは、より伝統的なリレーショナルデータベースのようなものです、HBaseのが完了していない-SQLのデザイン、すべてがバイトです。
  • クーズーディスク・ストレージ・モデルでは、真の柱状ストレージ、ストレージ構造とデザインクーズーHBaseの非常に異なっています。
    クーズーのためにバインドされ全体的に、純粋にOLTP要求より適切なHBaseの、要求OLTPとOLAP。
クーズーは、純粋なメモリデータベースのですか?

クドゥ純粋ではないインメモリデータベース、データブロックがMemRowSetクドゥとDiskRowSetを分割し、ディスク上に格納されたデータのほとんど。

クーズーは独自の保存形式を持っている、またはの寄木張りのですか?

クドゥ記憶メモリは、ディスク記憶装置は、列に格納され、ラインメモリに使用され、フォーマットは寄せ木と同様であり、異なる部分は、ランダムリードをサポートし、書き込み要求します。

コンパクションは、手動で操作する必要がありますか?

コンパクションクーズーは自動的にバックグラウンドを実行するように設計されており、ブロックがゆっくりと実行され、手動操作は現在サポートされていません。

クーズーのサポートは、それを削除し、自動的に有効期限が切れますか?

サポートされていません。HBaseのは、この機能をサポートしています。

クーズーは同じローカルホットスポットやHBaseの問題を持っていますか?

モダンなデザインは、多くの場合、ストレージ・データはプライマリキー記憶装置によって順序付けされます配布されます。これは、ログリアルタイムストレージ・モデルの主キーは、常に発注時にログに書き込まれている最後の時間など、いくつかのローカライズされたホットスポットへのアクセスを、原因となります、これは中のHBaseに深刻な地域のホットスポットが発生します。クーズーも同じ問題を抱えているが、HBaseのよりもはるかに優れ、クーズーサポートハッシュフラグメント、データを書き込むまず、ハッシュに基づいて書かれた主キーと秩序を、対応するタブレットがあります。

CAP理論におけるクーズー位置?

そして、HBaseのと同様に、クーズーは、CAPのCPです。限りデータが正常にクライアントに書き込まれると、他のクライアントは、ダウンタイムが発生した場合、データは一定の遅延を書かされ、データが一致しているお読みください。

複数のインデックスが行うクーズーをサポートしていますか?

これは、クーズーのみ主キーのインデックスをサポートし、サポートしていませんが、主キーが複数の列を含むように設定されています。インデックスでの自動増加、伝統的なマルチデータベースのサポートサポート外部キーおよびその他の機能クーズーのインデックスは、設計・開発されています。

取引についてどのようにクーズーサポートしていますか?

クーズーは、複数行のトランザクション操作をサポートしていないトランザクションをロールバックサポートしていませんが、クーズーはアトミックシングルライン動作を保証することができます。

おすすめ

転載: www.cnblogs.com/maoxiangyi/p/11240263.html