UI 作業を簡素化し、運用および保守担当者により柔軟なリソース クエリ方法を提供するために、ZStack はバージョン 2.6 で最初の IaaS 指向クエリ言語である ZStack クエリ言語 (ZQL) を導入しました。
背景 IaaS は膨大な量のデータセンター リソースを管理します。これらのリソースを柔軟かつ迅速にクエリする方法は、運用および保守担当者が直面する困難な問題です。以前の IaaS ソフトウェアでは、単一リソースの特定のフィールドに対してのみ、限定された API クエリ サポートが提供されていました。たとえば、仮想マシンの IP フィールドを介してクエリを実行することは可能でしたが、これは不十分で柔軟性に欠けていました。複雑なクエリを実行する場合、運用および保守担当者は IaaS ソフトウェアをバイパスし、バックエンド データベースに直接クエリを実行する必要があることがよくあります。これにより、運用・保守担当者は IaaS リソースの内部関係を理解する必要があり、データベースの誤操作のリスクが生じます。 ZStack の最初の公式リリース バージョンである ZStack 0.6 以来、私たちは API レベルでデータベース レベルのクエリ機能を提供することに取り組んできました。 ZStack の各リソースにはクエリ API が含まれており、リソース独自のフィールドとリソースに関連付けられたリソース フィールドを通じてクエリを実行できます。例えば: QueryVmInstance 名~=web-vm 状態=実行中 ここでは、名前に文字列 web-vm が含まれる実行中のすべての VM をクエリします。別の例: クエリVmInstance vmNics.eip.vip.ip='22.22.22.22' EIP は仮想マシンに関連付けられたリソースです。ここで、ネットワーク カードは EIP 22.22.22.22 の仮想マシンにバインドされています。 クエリ API は強力です: ユーザーは、SQL select count(*); と同様に、count パラメータを使用して、クエリ条件を満たすリソースの数を返すことができます。 返されるフィールドは、SQL select uuid,name from; と同様に、fields パラメータを通じて指定されます。 SQL の order by と同様に、sortBy および sortDirection パラメータを使用して、並べ替えフィールドと方向を指定します。 ページネーション クエリは、SQL の limit と offset に似た start および limit パラメータを通じて実装されます。 クエリ API は使いやすいだけでなく、定義も簡単です。プログラマーが ZStack に新しいリソースを追加した後は、コード内で次のクラスを定義するだけで済みます。 @AutoQuery(応答クラス = APIQueryVmInstanceReply.class、インベントリクラス = VmInstanceInventory.class) パブリッククラス APIQueryVmInstanceMsg は APIQueryMessage を拡張します { } 実装を記述する必要はありません。対応するリソースにはクエリ API があります。 ZStack には、すべてのリソースのクエリ API を処理し、それらを対応する SQL ステートメントに変換し、クエリ条件に関連リソース条件が含まれている場合に対応する結合句を生成するクエリ サービスが含まれています。 クエリ API に基づいて、ZStack 0.6 バージョンには 400 万を超える単一クエリ条件が含まれており、組み合わせたクエリ条件の数は 400 万の階乗になります。操作と保守、複雑な UI の設計が大幅に容易になります。しかし、Query API にはまだいくつかの欠陥があります。 Ø クエリ条件は AND ロジックのみ可能で、OR ロジックは実行できません。複雑な論理的組み合わせを実現するために条件間に括弧を追加することはできません。 Ø SQLと同様のサブクエリ句をサポートしていません Ø 1 つの API でクエリできるのは 1 つのリソースのみです。複数のリソースをクエリするには、複数の API を呼び出す必要があります。 Ø 監視システムのクエリ言語との統合をサポートしていない ZStack UI のシナリオがますます多様化するにつれて、クエリ API の制限により UI 側の作業がますます増加します。多くのシナリオでは、データを結合するためにクエリ API を複数回呼び出す必要があります。たとえば、Top 5 ページ (CPU、メモリ、ディスク、ネットワークなど、システム内の上位 5 つのリソースを検出するために使用されるページ) を監視する場合、最初にクエリ API を使用して仮想マシン、物理マシン、およびその他のリソース情報を照会し、次に監視システム ZWatch の API を呼び出して、対応する監視データを照会する必要があります。 クエリ API は将来の ZStack バージョンでも保持および保守され、そのバックエンド実装は元のクエリ サービスから ZQL に置き換えられました。 ZStack クエリ言語 有名な問題管理システム JIRA を使用したことがある開発者は、高度な検索を実行するときに JIRA がクエリ言語 JQL (JIRA Query Language) を提供していることを知っています。 SQL のような DSL (ドメイン固有言語) を使用して、JIRA のチケットのさまざまなフィールドを効率的にクエリできます。 ZQL は JQL に似ており、SQL に似た DSL でもあります。例を見てみましょう: name='webvm' または vmnics.ip='192.168.0.10' または (vmnics.eip = '172.20.100.100' かつ (cpuNum >= 8 または clusterUuid in ('fe13b725c80e45709f0414c266a80239','73ca1ca7603d454f8fa7f3bb57097f80')) の場合、vminstance をクエリします。 この単純な例では、and/or 条件、括弧、>=/in 演算子など、多くの一般的な SQL 要素を見ることができます。ZQL は、SQL のサブセットと、ZStack が独自のニーズに基づいて作成した拡張クエリ言語を組み合わせたものと考えることができます。基本的な構造は次のとおりです。 QUERY クエリターゲット (WHERE 条件+)?制限によって?戻り値?グループ化?順序は?制限?オフセット?フィルター?名前付きAs? クエリキーワード ZQL ステートメントは通常、query キーワードで始まり、queryTarget はクエリの対象となるリソースまたはリソース フィールドのコレクションを示します。前の例では、vminstance は仮想マシンを表し、host は物理マシンを表し、zone はゾーンを表します。クエリされたすべてのリソースには独自の名前があります。リソースのすべてのフィールドを返すのではなく、リソースの 1 つ以上のフィールドのみを取得する場合は、SQL の select uuid,name from ... に似た関数を実装できます。リソース名の後にフィールド名を指定し、複数のフィールド名をコンマで区切ることができます。次に例を示します。 vminstance.uuid、名前、cpuNum をクエリします。 このクエリは、すべての仮想マシンの UUID、名前、CPU 数を返します。 クエリ キーワードに加えて、クエリは count キーワードと sum キーワードで開始することもできます。前者はクエリ条件を満たすリソースの合計数を返し、後者はリソースのフィールドを合計することができます。例えば: cpuNum > 8 の vminstance をカウントします。 システム内の 8 個を超える CPU コアを持つ仮想マシンの合計数を返します。 cpuNum > 8 の場合、名前ごとに vminstance.memorySize を合計します。 仮想マシン名を使用して、8 個を超える CPU コアを持つ仮想マシンをグループ化し、それらの memorySize フィールドを合計します。システムに 10CPU8G の仮想マシンが 2 台あり、どちらも webvm という名前である場合、合計後に返される webvm 仮想マシンの合計メモリ使用量は 16G になります。 SQL に翻訳すると: cpuNum > 8 の vminstance から sum(memorySize) を選択し、名前でグループ化します。 WHERE句 ZQL の WHERE 句は SQL の句と似ており、論理演算子と括弧の組み合わせをサポートしています。条件の比較演算子は、=、!=、>、>=、<、<=、like、not like、is null、is not null、in、not in をサポートします。クエリ条件名は、リソースのフィールド名です。 SQL とは異なり、ZQL のクエリ条件は関連リソースのフィールドになる場合があります。次に例を示します。 vmNics.eip.vip.ip='22.22.22.22' の vminstance をクエリします。 クエリ vminstance によってクエリ対象のリソースがすでに制限されているため、where 句の前に SQL のように from xx 句を記述する必要がないことに注意してください。 ここで、vip は eip に関連付けられ、eip は vmnic に関連付けられ、vmnic は vminstance に関連付けられます。次に、クエリ条件として VIP の IP を指定できます。これが ZQL の力です。複数の関連リソースに対するクエリの場合、アプリケーション側でデータを結合するために複数の API を呼び出す必要はなく、SQL のような複雑な結合句を記述する必要もありません。プログラミングのようにドット (.) を使用して別のリソースを参照するだけです。 ZQL トランスレータは、リソース間の参照を対応する SQL 結合句に自動的に変換します。 WHERE 句には、SQL のサブクエリ機能に似たサブクエリを含めることができます。次に例を示します。 vmNics.l3NetworkUuid が ipRanges.networkCidr='10.1.0.0/24' であるクエリ vminstance ここでは、CIRD 10.1.0.0/24 のレイヤー 3 ネットワーク上で実行されているすべての仮想マシンが見つかります。 上記の例は、より簡単な方法で実装することもできます: query vminstance where vmNics.l3network.ipRanges.networkCidr='10.1.0.0/24'。これは、サブクエリ機能を示すためのものです。 GROUP BY、ORDER BY、LIMIT、OFFSET 句 SQL と同様に、ZQL はグループ化、並べ替え、ページング機能を実装するための GROUP BY、ORDER BY、LIMIT、OFFSET キーワードをサポートしています。 グループ化: VM はリージョン UUID とクラスター UUID 別にグループ化され、各リージョンの各クラスター内の VM の数をカウントします。 zoneUuid、clusterUuid で vminstance グループをカウントします。 注文方法: すべての仮想マシンをクエリし、cpuNum フィールドを使用して降順で並べ替えます。 1. cpuNum desc による vminstance の順序をクエリする 制限、オフセット: ページングを実装するには、limit と offset を使用します。 クエリ vminstance 制限 100 オフセット 10 複数のリソースクエリ 複数のリソースをクエリするには、セミコロンで区切られた複数のクエリ ステートメントを使用できます。次に例を示します。 name = 'my-vm' の vminstance をクエリします。 cpuNum > 10 のホストをクエリします。 クエリゾーン; すると、1 回の呼び出しで 3 つのリソースのクエリ結果を返すことができます。返される結果はマップ JSON 構造であるため、対応するステートメントのクエリ結果を簡単に取得するには、named as キーワードを使用してクエリ ステートメントに名前を付けることができます。次に例を示します。 name = 'my-vm'、named as 'vm' の vminstance をクエリします。 cpuNum > 10 で 'host' という名前のホストをクエリします。 'zone' という名前のクエリ ゾーン。 返された JSON マップでは、vm、host、zone をキーとして使用して、対応するステートメントのクエリ結果を取得できます。 監視クエリをマージする(句付きで返す) ZStack では、メタデータを保存するためのリレーショナル データベースと監視データを保存するための時系列データベースの 2 種類のデータベースが使用されます。データベースによってクエリ方法が異なるため、ZQL が登場する前は、ユーザーがリソースの監視データをクエリする場合、まずクエリ API を通じてリソースのメタデータを取得し、次に ZWatch クエリ API を通じて監視データを取得する必要がありました。たとえば、webvm という名前の仮想マシンの CPU 使用率監視データを照会するには、次の API を実行します。 QueryVmInstance フィールド = uuid 名前 = webvm GetMetricData namespace=ZStack/VM metricName=CPUUsedUtilization labels=VMUuid=QueryVmInstance によって返された UUID offsetAheadOfCurrentTime=60 ZQL は return with 句を通じてこの問題を解決します。 Return with は、サブシステムがプラグインを通じて独自のクエリ条件を ZQL に挿入できるようにするプラグイン メカニズムです。 ZQL は、まずリレーショナル データベース クエリを実行し、条件を満たすリソースの元のデータをクエリし、次にリソースの主キーを入力条件として使用して、return with 句を実装するプラグインを呼び出し、最後にプラグインのクエリ結果を ZQL の呼び出し元に返します。 仮想マシン監視データをクエリするための上記の要件は、ZQL ステートメントを通じて実現できます。 vminstance.hostUuid,uuid をクエリし、name = 'webvm' を返す (zwatch{resultName='webvm-cpu',metricName='CPUAllUsedUtilization',offsetAheadOfCurrentTime=60}) 戻る: { "結果": [ { 「在庫」: [ { "ホストUuid": "f8271f58468b4281a212a43e530b5535", "UUID": "05781209d24341ac84fc055ae71820ac" } ]、 "returnWith": { "webvm-cpu": [ { 「ラベル」: { "VMUuid": "05781209d24341ac84fc055ae71820ac" }, 「時間」: 1533280402, 「値」: 0.8 }, { 「ラベル」: { "VMUuid": "05781209d24341ac84fc055ae71820ac" }, 「時間」: 1533280462, 「値」: 0.8 } ] } } ]、 「成功」: 真 } ここでは、ZQL ステートメントを使用して、関心のあるメタデータ フィールド (uuid と hostUuid) を返し、仮想マシンの監視データも返します。注意深い読者は、ZWatch クエリ フィールドにパラメーター resultName='webvm-cpu' を指定し、返された JSON マップ内の監視データのキーも webvm-cpu であることに気付いたでしょう。 named as キーワードと同様に、これは複数の ZWatch クエリ句を実行するときに返された結果を取得するのに便利です。 ZStack UI は非常に複雑な ZQL クエリ ステートメントを使用します。たとえば、TOP 5 ページでは、ZQL クエリに最大 13 個の ZWatch クエリが含まれます。 ZQLQuery zql="query vmInstance.uuid,name where zoneUuid='89e148fb667c404dbc5309a2e956fa28' and hypervisorType='KVM' and type='UserVm' and state='Running' return with (zwatch{resultName='CPUAllUsedUtilization',metricName='CPUAllUsedUtilization',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\" VMUuid\")',functions='top(num=5)'},zwatch{resultName='MemoryUsedInPercent',metricName='MemoryUsedInPercent',offsetAheadOfCurrentTime=60,period=6, functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='MemoryFreeInPercent',metricName='MemoryFreeInPercent',offsetAh eadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='DiskAllReadOps',metricName='DiskAllReadOps',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid\")',functions='top(num=5)'},zwatch{resultName='DiskAllWriteOp s'、metricName='DiskAllWriteOps'、offsetAheadOfCurrentTime=60、period=6、functions='average(groupBy=\"VMUuid\")'、functions='top(num=5)'}、zwatch{resultName='DiskAllReadBytes'、metricName='DiskAllReadBytes'、offsetAheadOfCurrentTime=60、period=6、functions='average(groupBy=\"VMUuid\")'、functions='to p(num=5)'}、zwatch{resultName='DiskAllWriteBytes'、metricName='DiskAllWriteBytes'、offsetAheadOfCurrentTime=60、period=6、functions='average(groupBy=\ "VMUuid\")',functions='top(num=5)'},zwatch{resultName='NetworkOutBytes',metricName='NetworkOutBytes',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'},zwatch{resultName='NetworkInBytes',metricName='NetworkInBytes',offsetAheadOfCurrentTime=60,period=6,functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")',functions='top(num=5)'},zwatch{resultName='NetworkOu tPackets'、metricName='NetworkOutPackets'、offsetAheadOfCurrentTime=60、period=6、functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")'、functions='top(num=5)'}、zwatch{resultName='NetworkInPackets'、metricName='NetworkInPackets'、offsetAheadOfCurrentTime=60、period=6、functions='average(group By=\"VMUuid,NetworkDeviceLetter\")'、functions='top(num=5)'}、zwatch{resultName='NetworkOutErrors'、metricName='NetworkOutErrors'、offsetAheadOfCurre ntTime=60、period=6、functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")'、functions='top(num=5)'}、zwatch{resultName='NetworkInErrors'、metric Name='NetworkInErrors'、offsetAheadOfCurrentTime=60、period=6、functions='average(groupBy=\"VMUuid,NetworkDeviceLetter\")'、functions='top(num=5)'})" 上記の例は、引用符をエスケープするために \ を使用して ZStack CLI で実行されます。 リソースが大量にある場合、時系列データベースのクエリ パフォーマンスが複数の ZWatch クエリのパフォーマンス ボトルネックになる可能性があるため、 return with は、デフォルトの同時実行数 10 でプラグインを同時に実行します。たとえば、上記の例の 13 個の ZWatch クエリは、10 個のスレッドで同時に実行されます。ユーザーは、グローバル構成zql.returnWith.concurrencyを通じて同時実行性を変更できます。たとえば、 UpdateGlobalConfig カテゴリ=クエリ名=zql.returnWith.concurrency 値=15 クエリを制限する (句による制限) ZStack のエンタープライズ管理モジュールには、管理者を特定の領域にバインドして、管理者がその領域内のリソースのみを管理できるようにする機能が含まれています。これには、管理者に対する ZQL クエリ要求が、管理者にバインドされた領域内のリソースのみを返すことが必要です。 仮想マシンなどのリソースの場合、そのメタデータ自体にゾーンを識別するための zoneUuid フィールドが含まれています。ただし、EIP などのリソースの場合、メタデータ内に地域属性を示すフィールドはありません。地域属性は、それが配置されている 3 層ネットワークまたはバインドされた仮想マシンによって決まります。たとえば、特定のエリアの eip を照会するには、次のようにします。 # 仮想マシンとのバインド関係によるクエリ vmNic.vmInstance.zoneUuid = '52fdad0a2c0d4131a6c0fc6c1b7141a6' の eip をクエリします。 または # 3層ネットワークで決定 vip.l3Network.zoneUuid = '52fdad0a2c0d4131a6c0fc6c1b7141a6' の eip をクエリします。 方法に関係なく、呼び出し元は eip とゾーンの関係を理解する必要があり、API ユーザーに対して非常に厳しい要件が課せられます。 ZQL は、制限による句を通じてこの問題を解決します。 return with 句と同様に、restrict by もプラグイン フレームワークであり、これにより他のサービスがプラグインを通じて restrict by 句で指定された条件を解釈し、生成された SQL に追加の条件を挿入できるようになります。たとえば、上記の eip の例は、restrict by 句を使用して次のように記述できます。 (zone.uuid='52fdad0a2c0d4131a6c0fc6c1b7141a6') による eip 制限のクエリ ここで、呼び出し側は eip と zone 間の論理的な関係を知る必要はありません。パスによる制限プラグインは、2 つの間の論理関係を自動的に計算し、対応する SQL 結合句を生成します。ここで、eip は第 3 層ネットワークまたはバインドされた仮想マシンを介してリージョンとの関係を決定できます。プラグインはパスの重みを自動的に計算し、重みが最も高いパスを使用して SQL ステートメントを生成します。 eip の例では、プラグインは 3 層ネットワークを通じて関係を選択し、SQL ステートメントを生成します。 eip は仮想マシンにバインドされていない場合がありますが、特定の 3 層ネットワーク内にある必要があるため、3 層ネットワーク パスの重みが高くなります。 restrict by は、カンマで区切られた複数の条件をサポートし、複数の条件は AND 関係になります。 ZQL 呼び出し元で使用されることに加えて、プラグインによる制限は、ZStack 内の他のサービスでも広く使用されています。たとえば、通常のアカウントが ZQL を呼び出すと、アカウント システムはプラグインを通じてアカウントに関連付けられた SQL ステートメントを挿入し、通常のアカウントはアカウントに属するリソースのみをクエリできるようにします。たとえば、SNS サービスはプラグインを通じてステートメントを挿入し、ZQL がシステム タイプ以外のレシーバーのみをクエリできるようにします。 未来 ZQL は、SQL に似た IaaS クエリ言語を ZStack に提供し、プラグイン フレームワークを介して他の非リレーショナル データベース システムと統合できます。今後のバージョンでも引き続き機能を充実させてまいります。現在、2つの方向があります。 句でフィルタリング return with の ZWatch プラグインを使用すると、リソース メタデータとその監視データを同時にクエリできますが、監視データをメタデータ クエリ条件として使用することはできません。たとえば、CPU 使用率が 90% を超えるクラスター内のすべての仮想マシンを ZQL でクエリすることは不可能です。これは、filter by 句を介して将来のバージョンで実装されます。例: clusterUuid = '33e26bd547d149fbb190436cc9aca824' の vminstance をクエリし、(zwatch{metricName='CPUAAllUsedUtilization', offsetAheadOfCurrentTime=60, threshold>90}) でフィルターします。 同様に、filter by 句は、非リレーショナル データベースのクエリ条件を統合するために、return with に似たプラグイン フレームワークとして実装されます。 スマートCLI ZQL には多数の句があり、各 ZStack には多数のクエリ可能なフィールドがあります。現在、ZStack CLI はクエリ API のクエリ可能なフィールドを完了できますが、ZQL は当面それらを完了できません。将来のバージョンでは、すべてのクエリ条件に対してプロンプトと補完を提供できるように CLI を拡張する予定です。 |
<<: 1 つの記事で理解する: 「エッジ コンピューティング」とは正確には何ですか?なぜその可能性は無限なのでしょうか?
>>: 3つのレベルでのクラウドコンピューティングストレージ仮想化技術の実装
1月21日、新浪微博は違法マーケティングアカウントを定義し、要件を満たすアカウントを主要な監視範囲に...
現在、多くのブロガーはブログ投稿のトピックを選ぶのが難しすぎると感じており、「ブログに書く内容が見つ...
最近、ジェーン・オースティンの「分別と多感」という本を読みました。この本では、世の中の人は感性と合理...
HostingInside は、2004 年に IRC と仮想ホスティング サービスを提供する会社と...
ユーザーによっては、調和化などさまざまな理由で VPS の IPv4 を変更する必要がある場合があり...
おそらく、私と同じように、誰もが、短期間でウェブサイトをホームページにランク付けしたり、1 位にした...
パブリック クラウドに一夜にして移行することはできません。そのため、ハイブリッド クラウドは企業にと...
OpenVirtuals は 2016 年に設立されましたが、自社の機器を運用および管理しています。...
以前の記事のいくつかで、著者はサイトの重さに影響を与えるいくつかの要因について簡単に触れました。内部...
theonionhost は 2009 年に設立されたオフショア サーバー プロバイダーで、著作権フ...
優れたデザインとは、デザインそのものを目的とするものではなく、全体的なユーザー エクスペリエンスを追...
「外部リンクこそが王様」という言葉は、SEO 従事者が常に主張してきた言葉ですが、外部リンクがあらゆ...
Sharknodeは、新たに40%オフの生涯割引WHT40を開始しました。XEN PVに基づくすべて...
インターナショナル・データ・コーポレーションは、デジタル変革への世界の支出は2022年までに約2兆ド...
[51CTO.com からのオリジナル記事] パブリック クラウドは、その弾力性と拡張性により、多く...