免責事項 †
概要 †
目次 †疑問 †
基本構成 †
用語 †
一般的なクラウドサービスの知識 †
サービス †L7リバースプロキシ †dispatch.yaml や dispatch.xml はGoogle App Engine(以下GAE)のFrontendでルールベースでL7 HTTP Reverse Proxyしてくれるものです。 これはMicroservicesをやる上では大変便利なものになっています。 L7リバースプロキシなので、全てのサービスが立ち上がっている状態じゃないとデプロイできない(してもいいけどない) Google App Engine †
Task Queue †Task QueueはCloud TasksとPub/Subの中間みたいなもの。PushQueue?とPullQueue?という2種類のキューがあって、使い分ける感じ。 To use the push Task Queue service outside of the first generation standard environment, you can use Cloud Tasks. In many cases where you might use pull queues, such as queuing up tasks or messages that will be pulled and processed by separate workers, Cloud Pub/Sub can be a good alternative as it offers similar functionality and delivery guarantees. デフォでdefaultのqueueがあるらしい。これは5/s rateのPush queue。Push quueeとかでも、最大レートやリトライ回数などを細かく指定し、名前を浸かるためのものがquuee.yaml(GAE Standardのみ) Memstore †Redis an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. 基本的なデータ構造を扱えるNoSQL データベース セッション管理・カウント・ランキングなどの実装に使うのがよい。RedisはI/Oの速さが長所で、消失してもダメージが少ないが、大量アクセスが見込まれるような、ゲームコンテンツなどで使用すると、高い効果を発揮できると思います。 あと、パブサブ・メッセージキュー・ロックとしても使うことができるらしい。すごい メモリ上に全部データを乗せるかなりドラスティックなデータベース スナップショットというものがあって、これを使うと非同期でRDBダンプによってディスクに書き込まれる 2秒おきにデータをファイルシステムに書き込むようになっているので、必要であれば安全なオプションを利用可能。 何がmemcachedと違うのかというと、データを2通りの方法でディスクに書き出せるというところ。 SQLと違ってシングルスレッドに限定されているので自動的に排他的(memcachedはマルチスレッドで処理可能) メモリを使い果たしたら、LRUなどのルールから削除していく。注意点としては、Radisの設定を「データ削除しない」にしておくと、メモリが足りなくなったときに削除せずに、書き込みエラーになる Radisで落ちてほしくないならばちゃんとメモリ増設をする。本当にmaxmemoryもttlも設定していないと、OOMで殺されるので注意 古いVerは爆弾を抱えていることもあるので、理由もなく使い続けるのはやめよう。 ログとかも、新しいVerの方が色々吐いてくれたりするので、 問題発生時の原因特定がしやすい。 maxmemoryと書いてあるけど、これはevictする閾値なので、これ以上のメモリを消費することもある。なので、メモリ性費用を厳密に制限することはできない。2~3倍メモリを消費することくらい全然ありえる。 イメージバックアップは10000回keyの書き換えが会ったら60秒後にディスクに保存するみたいなやつ まずoutput-bufferってなんやねん、という話から。 output-bufferはRedisがメモリ上に確保するバッファの一種。 レプリケーション環境で運用してる際、slaveはmasterのコピーであるので、 keyの削除時には「このkey消しといてー」とslaveに通知する必要がある。 その情報はoutput bufferにため込んで、まとめて送信される。 あまりに削除するkeyが多かったり、masterが抱えるslaveがたくさんあったりすると、 output bufferの分だけ、メモリを大量に消費してしまう。 そうすると、通信がいつまで経っても終わらなくなって、しかし削除要求は増え続け、 slaveの更新ができないまま、メモリ消費量だけ肥大化する。 こうなると非常に危険で、色々な問題を誘発することがある。 空きメモリが無くなって、HTTPが死んだり、前述のBGSAVEプロセス作成に失敗して スナップショットが長期間保存されない状況になったりする。 Radisはバージョンを上げるのはマジで大切。あとRadisは一つに丸投げするのではなく、インスタンスを風数に分ける必要がある。 appendfsync everysecというのがあって、これをonにしておくと書き込み操作のたびにfsyncする。ちなみにeverysecではなくalwaysというのがあり、これが一番安全 client-output-buffer-limitは所定の容量をbufferが超えたら、 クライアントとの通信を強制的に切断するという設定。 これはこれで問題があるけど、メモリが枯渇するよりはマシかもしれない。 masterから見たクライアントというのは、slaveのことなので、 仮にbufferのピーク容量が500MBで、slaveが4台繋がってたら、 最大で2GBぐらい消費することになる。 実際は詰まり始めたらどんどん消費してしまうので、「最大で」とか「最悪でも」なんて 想定をしても、あまり意味はないかもしれない。 ただ、output-bufferの危険性を認識しておくのは非常に大事。 最終的にはサーバ内のディスクにデータが保存されますが、保存直後はメモリに一時保存されるため、データ揮発の可能性はゼロではありません。 バックグラウンド書き込み用のメモリをどれくらい確保すればよいかと言うと、2.8.22 以降の場合は 25 (25 パーセント) に設定、それ以前なら50%にする必要がある active deflagという機能が4.0から提供されていてこれを使うと効率的にメモリを使えるようになる(が完全な解決ではない) Dialogflow †言語解析エンジン 音声入力で問題となりやすい自然言語の解析を簡単にやってくれる機能。 これを挟むことで言語解析のややこしいところを大幅に削減できる。 Google Compute Engine (GCE) †GCEのホストマシンが死んだりメンテに入った場合(プリエンプティぶも含む) gcloud compute instances set-schedulingによって他のマシンに移したり、終了したりする。普通にサービす稼働させたいものをterminateでデプロイしない!(リファレンスのアドレス好き) https://cloud.google.com/sdk/gcloud/reference/compute/instances/set-scheduling managed instance-groupにはautohealingという機能がある。 文字通り、ヘルスチェックの結果によってインスタンスを自動修復(再作成)する機能だ。 負荷分散におけるヘルスチェックは、ロードバランサの振り先がHEALTHYかどうかを見るだけで、インスタンスの再作成は行わないが、マネージドインスタンスグループに適用されるヘルスチェックはインスタンスがUNHEALTHYになったら、削除して再作成する。 GCF †
Datastore †
射影クエリ 要するにSQLのselectで一部だけ撮ってくるみたいなやつ エンティティの特定のプロパティだけにアクセスする場合は、射影クエリを使用します。射影クエリでは、エンティティ全体を取得する場合よりも低いレイテンシとコストで結果が返されます。 多くの場合、アプリケーションが必要とするのはエンティティのプロパティの一部分だけです。 射影クエリを使用すると、エンティティのプロパティの中で本当に必要なものだけをクエリできるため、エンティティ全体を取得する場合よりもレイテンシとコストを低く抑えられます。 射影クエリで指定するプロパティには、インデックスが必要です。 カーソル、制限、オフセット クエリに対して制限を指定することで、1 バッチで返される結果の最大数を制御できます。次の例では、最大で 5 つの Task エンティティを取得します。 これによって、100万人のうち200000-2000100人を撮ってくる、みたいな処理をオーバヘッドなしでおこなえる。課金もされない。 同じような機能をオフセットで行うことができるが、計算量的に悪いし遅いし課金される。Datastore モードのデータベースでは整数のオフセットをサポートしていますが、使用は避けてください。その代わりにカーソルを使用します。オフセットを使用するとスキップされたエンティティがアプリケーションに返されなくなりますが、そのようなエンティティも内部的には引き続き取得されています。スキップされたエンティティはクエリのレイテンシに影響するだけでなく、そのようなエンティティの取得に必要な読み取りオペレーションに対してアプリケーションが課金されます。このようなコストは、オフセットの代わりにカーソルを使用することですべて回避できます。 この記事がめちゃくちゃ面白い https://cloud.google.com/datastore/docs/articles/fast-and-reliable-ranking-in-datastore/#olog-n- これがめちゃくちゃよいエンティティグループの解説。結局のところ、やっぱり連結されていれば全部強整合性を保つため、1op/sの制限がかかってかなりヤバい。組織全体で木にするというよりは、本当に強性合成が必要だと思ったところだけを木にして連結させるという発想のほうが良い。安心(強整合性)は高いということを知れ。 https://cloud.google.com/datastore/docs/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/ 重要な問題の 1 つは、各エンティティ グループに更新(またはトランザクション)の回数を保管するようにシステムを設計する必要があることです。エンティティ グループごとに 1 秒間に 1 回の更新に制限されます[2]。 更新の回数がこの制限を超える必要がある場合、そのエンティティ グループはパフォーマンスのボトルネックとなるおそれがあります。 上記の例では、各組織内のどの人のレコードも更新が必要になる可能性があります。「ateam」内に 1,000 人含まれていて、それぞれの人物のいずれかのプロパティを 1 秒間に 1 回更新する可能性があるとします。その結果、このエンティティ グループでは 1 秒間に最大 1,000 回の更新がありえますが、これは更新の制限により実現できません。これにより、パフォーマンス要件を考慮した適切なエンティティ グループの設計の選択が重要であることがわかります。これは、結果整合性と強整合性の最適なバランスを求める際の課題の 1 つです。 読み取り、書き込み、削除には、単一のオペレーションではなくバッチ オペレーションを使用します。バッチ オペレーションでは、単一オペレーションと同じオーバーヘッドで複数のオペレーションが実行されるため効率的です。 トランザクションが失敗した場合はロールバックを試行してください。ロールバックを使用すると、トランザクション内で同じリソースを使用する別のリクエストの再試行レイテンシが最小限に抑えられます。ロールバック自体が失敗する可能性もあるため、ロールバックはベスト エフォート型の試行である点に注意してください。 可能な場合は、同期呼び出しではなく非同期呼び出しを使用します。非同期呼び出しでは、レイテンシの影響が最小限に抑えられます。たとえば、同期 lookup() の結果とクエリの結果に従ってレスポンスをレンダリングするアプリケーションについて考えてみましょう。lookup() とクエリにデータの依存関係がない場合、lookup() が完了するまでクエリの開始を同期的に待機する必要はありません。 Datastoreのデータ構造。森がある。全ての頂点には必ず、キーと呼ばれる数字もしくは文字列が書き込まれおり、何らかの色が塗られている。各頂点には、数字もしくは文字列の任意長のタプルが書かれている。以下のクエリを高速に行え。 (1) 色を一つ選んで、同じ色のものを全列挙する (2) 頂点を一つ選んで、その頂点を根とする部分木に含まれる頂点を全列挙する https://cloud.google.com/appengine/docs/standard/python/datastore/transactions Databaseでキーをランダムではなく文字列で管理している場合、同じ文字列 ID を持つエンティティを別のユーザーが作成または更新しようとする状況を処理するには、前の例と同様、ここでもトランザクションが必要です。トランザクションを使用しない場合は、エンティティがまだ存在していない時点で 2 人のユーザーが同時にこれを作成しようとすると、1 人目のユーザーが知らないうちに 2 人目のユーザーが作成したエンティティが 1 人目のエンティティを上書きしてしまいます。 トランザクションのもう 1 つの一般的な用法は、名前付きキーによってエンティティを取得することです。名前付きキーがまだ存在しない場合は、新規に作成します。 実はキーに対応する実態がなくても大丈夫(Noteに人のIDを突っ込んでputしていないし、実際にconsoleでみるとそれはないみたいな) HTTPリクエストから来ているやつらは基本的に文字列だから注意!!!Keyはnameだったりidだったりするので、とくにidの場合キャストせずに突っ込むとまずい。 ndbのkeyを作るときは、kindを文字列としても渡しても良いし、ndbのEntityのクラスを渡してもよいらしい。 sandy_key = ndb.Key(Account, 'sandy@example.com') ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1') Keyを得るためには、これは本当に(S, S cup N)+の配列なので、自分で構築してしまったほうが早い。Keyはちゃんと設計して自分で作るもの。Entityから得るものというよりは。なのでfrom_pathを使っている時点でなんかおかしいと思ったほうが良さそう。 Dialogflow †Dialogflow 言語解析エンジン 音声入力で問題となりやすい自然言語の解析を簡単にやってくれる機能。 これを挟むことで言語解析のややこしいところを大幅に削減できる。 Cloud Storage †
Object split / compose splitコマンドで分解したファイルをあとでcomposeするのは非常によくやられる方法。GCS上ではgcloud compose part-* resultの形で行うことができるらしい。 catした結果をパイプで繋いでgsutilに渡す。 cat files.txt | gsutil -m cp -I gs://my_bucket →リストに書いてあるファイルが全てコピーされる gsutil -mでマルチスレッドコピーができる。他にも並列化されるものはある? gsutilにはトップレベルオプションとそうでないオプションがある gsutil -DD cp src dstのようにすると、-DDはトップレベルオプションでコマンドの詳細情報が得られる。 Google Cloud SQL †
gcloud sql instances create myinstance2-replica2 --master-instance-name=myinstance2 を走らせた後にctrl-Cを押してもインスタンス作成はキャンセルされずに作られる。 SQLはstart timeというコンフィグが会って、 start of a 4-hour backup windowでバックアップが取られる。そのためコネクションが4時間に一回増える。 リードレプリカは全然削除を気軽にしても大丈夫。なぜならリードレプリカだから。最悪管理コマンドで消しても作り直せばよいし、再起動くらいなら全然やってよい。 MySQLの MySQL 5.6以降ではデフォルトでONに設定されるようになったパフォーマンススキーマですが、MySQL 5.5時代をご存知の方は明示的にOFFにしているかも知れません(MySQL 5.5のパフォーマンススキーマはパフォーマンスへのオーバーヘッドが非常に大きかった上に、大量にメモリーを利用した)。最近のパフォーマンススキーマはON/OFFに再起動が必要な点こそ変わりませんが、パフォーマンスオーバーヘッド、メモリー使用量ともに大幅に改善されています。また、取得できる情報も「ステートメント(ダイジェスト)単位での各種待ち状態の統計」、「各ステージでの経過時間」、「トランザクション単位での統計」などが追加され、さらに「スキーマ単位、テーブル単位で記録するか否か」、「ユーザー単位、ホスト単位で記録するか否か」を設定できるようになっています。 A cascading failure is a failure that grows over time as a result of positive feedback. It can occur when a portion of an overall system fails, increasing the probability that other portions of the system fail. For example, a single replica for a service can fail due to overload, increasing load on remaining replicas and thereby increasing their probability of failing, causing a domino effect until all the replicas for a service are down. Dataflow †裏でオープンソースのものを使っているので難しい HiveやPigでTezを使うのはすごく簡単です。 Hiveの場合、 set hive.execution.engine=tez; など、hive.execution.engine変数にtezという値を入れてやります。 Pigの場合も起動時に $ pig -x tez set exectype=tez; HiveはSQLっぽくHadoopのmap reduceパイプラインを作るためのツール。もともとはFacebookが作った。 他の言語としては以下がある Cloudera Impala -- allows you to query Hadoop data using SQL, but does not utilize Mapreduce under the hood so can run faster. i.e. more similar to Dremel in architecture. See https://vision.cloudera.com/impala-v-hive/. IBM BigSQL HAWQ Hadapt Apache Pig -- new language for specifying a Mapreduce against Hadoop data. Simpler than writing Java code. Originally created by Yahoo. HBaseはこのHDFS上に構築するデータベースです。HBaseとHadoop(HDFS)の関係を図4に示します。なお、HBaseの構築にYARNとMapReduce?は必須ではありませんが、MapReduce?を使用するとHBaseのデータ格納/参照を高速に行えるため、YARNとMapReduce?も同時にインストールすることを推奨します。 NoSQL RDDとは、以前にも書きましたが「不変(イミュータブル)で並列実行可能な(分割された)コレクション」 RDD(A Resilient Distributed Dataset (RDD),)に保持したデータを操作するメソッドは大きく分けて2つに分類されます。「Transformations」と「Actions」です。「Transformations」はRDDを操作し、結果を新しいRDDとして返します。「Transformations」の代表的なメソッドは、mapやfilterです。「Actions」はRDDのデータを操作し、結果をRDD以外の形式で返すか保存を行います。大雑把に言えば、RDDを返すのが「Transformations」、そうではないものが「Actions」であると言えると思います。 得意 Hadoopで加工したのちのドリルダウン分析 TB級までのデータを扱うシステム サンプリングが有効でないロングテールのデータ分析 数秒~数分程度のHadoopよりも短いレスポンスが必要な処理 不得意 クラスタ全体のメモリに乗りきらない巨大なデータ処理(TB以上) 大きなデータセットを少しずつ更新する処理 秒以下の時に短いレスポンスが必要な処理 Hadoopの欠点と言われていたのが主に以下の三つ 個々のメモリを活用できる設計でなかった(タスクごとにデータをディスク読み込み&書き込みしなきゃいけないのがボトルネック) 同じ処理を複数行う際に、その都度データアクセスが発生 同じデータでもなんども使うものは使う際に無駄にアクセスがいっぱい発生 この課題を解決するのがRDD(Resilient Distributed Datasets)というSparkの分散共有メモリの仕組みです。 すごくざっくり言うと、Hadoopでは毎回ストレージにアクセスしたりしていたのがインメモリで実行できるのでいいこといっぱいあるよねって感じだと解釈しました。 YARNとHDFSって何 (*1)HDFS:MapReduce?で処理するデータを扱う、分散ストレージとして複数のマシンを一つのストレージとして扱うことができる。 HDFSは管理するファイルのI/Oを高速化するため大きなファイルを一定の大きさ(初期設定では64MB)のブロックに分割して、複数の記憶装置に分散して保存、I/Oを記憶装置の台数だけ並列に実行できるようにしている。 HDFSは並列でよめるファイルシステム。Hadoop Distributed File System Sparkはインメモリにすると早いよねなので、クラスタのメモリがなくなると当然弱い(遅延評価しているとはいえ)。 データをインメモリにロードする部分はSparkContext?と呼ばれるtextFileのようなファイルシステムからダウンロードしてくるような関数が提供されている。一方で、parallelizeという関数があってこれはプリミティブなデータ構造(配列とか)をRDDにするための関数。 RDDはデータそのものではなく、「RDDsを構築するためにデータに対して行った変換」を記録することで効率的な耐障害性を実現している。 もしRDDの中の一部分がロストした場合、RDDはそのデータが他のRDDからどのように変換されて生じたデータかを保持しているため、コストの大きなレプリケーション(*5)なしに迅速に再計算/復旧させることができる。 . 系譜のステージへの分割 DAGSchedulerが、系譜をスケジュールに分割する ステージは系譜中で狭い依存関係が連続して発生する範囲(依存関係の種類は変換の種類できまる) 系譜中で広い依存関係が発生する変換関数を処理する場合はエグゼキュータ間でシャッフルと呼ばれる多数対多数の通信が発生する。 この分割は、パーティションごとに一つのエグゼキュータがまとめて計算できる変換の範囲を決めるため なので、sparkの実装にdataflowを使いたくなるのはすごく気持ちがわかるねという感じ RDDは静的なので静的なデータの変換を行うために、関数型で物体そのものを定義するというのは妥当な感じがする YARN は、以下の図に示す次世代の Hadoop 計算プラットフォームです。イメージクラスタのマスターがYARN masterでworkerがYARN slaveと呼ばれるっぽい。YARN slaveはMapreduce マスタ・スレーブをコンテナとして起動する感じになる。 プログラマブルでやれることがちょっと限られているdataflowみたいな感じかな Cloud Dataproc service – receives job requests from the user and submits the request to the dataproc agent dataproc agent – runs on the VM, receives job requests from the Cloud Dataproc service, and spawns driver driver – runs customer-supplied code, such as Hadoop jar, spark-submit, beeline, and pig applications Dataprocではselectorというのがあって、これはクラスタを冗長化してジョブをランダムにクラスタアサインする Jobが失敗したら全てのジョブがキャンセルされて今後のものもキャンセルされる。 Cloud Launcher †https://qiita.com/NagaokaKenichi/items/41ee9d8ba40555eaf2b7 Cloud Launcherというサービスがあって、これをつかうとpredefinedのjenkinsなどをGCE上に立ち上げることができる。 BigTable? †HBase BigTable?のapache版。こっちからBigTable?に移行したい、あるいはベンダーロックを嫌うためにHBaseっぽいクライアントライブラリが提供されている(ちょっとの差はあるけど) com.google.cloud.bigtable.hbase.BigtableConfiguration?が全てのhaddp系と全く同じインターフェースの関数群を提供しており、それから先はほぼhadoop.hbaseと同じように操作できるよ!という感じ。 このナレッジベースがかなりよいので一読の価値がある 数については知らないのでページの機能をいい感じに実装するのは厳しそう Filter filter = new PageFilter?(pageSize); BTでもない BigTable? Cloud Bigtable は行をアトミックに読み取ります。このため、一回の更新が1行で収まるようにする努力が大切で、1 行に格納するデータ量の合計を制限することは非常に重要です。1 つのセルに格納するデータを 10 MB 以下にし、1 行のデータを 100 MB 以下にするのがベスト プラクティスです。 BigTable?は二次主キーを作ることができないが、列ファミリーをいくつか作ってその中では辞書順ソートされるようにできる。 Java+BigTable? githubのcloud-bigtable-examples/java/hello-worldのgithub上のREADMEに従ったら一瞬でできた。mavenを一から書くにはたいへんだな… put.addColumnみたいなのをやると、Bigtableの各列はector<map<string, multiset<string>>>みたいなものなので、その列ファミリーが指定するsetにappendされる mvn package mvn exec:java -Dbigtable.projectID=wakataberyo-sandbox2 -Dbigtable.instanceID=bigtable-test BigTable?の列ファミリーって何 BigQuery? †
# 半角数値 x を全角文字列に変換する関数 CREATE TEMP FUNCTION TO_MULTI_BYTE(x INT64) AS ( CODE_POINTS_TO_STRING(array(select c + 65248 from UNNEST(TO_CODE_POINTS(CAST(x as STRING))) as c)) ); # 全角文字列 x を半角数値に変換する関数 CREATE TEMP FUNCTION TO_SINGLE_BYTE(x STRING) AS ( CAST(CODE_POINTS_TO_STRING(array(select c - 65248 from UNNEST(TO_CODE_POINTS(x)) as c)) as INT64) ); BQの配列アクセスarr[1]は arr[OFFSET(1)] BQの一時テーブル作成において、以下のようにすると楽。 FROM UNNEST([1, 2, 3, 4, 5]) AS numbers; To convert an ARRAY into a set of rows, also known as "flattening," use the UNNEST operator. UNNEST takes an ARRAY and returns a table Pub/Sub †
Dataproc †
Kubernetes †https://knowledge.sakura.ad.jp/16082/ GKEを理解したい Docker: コンテナとイメージというのがあって、イメージからコンテナを作る感じ。コンテナをイメージにするコマンドもあるし、どのようにそのコンテナを作ったかを記録しておいてそれをスクリプト的に走らせて再現性高くコンテナを作ることもできる(Dockerfile)。DockerではDockerネットワークという仮想的なコンテナ間通信を行うことができる。 複数ホストでコンテナを起動して、コンテナ間通信するには、今回説明したことの他にも必要な設定があります。そこで活躍するのが、KubernetesやDocker Swarmなどのコンテナオーケストレーションツールになります(今はKubernetesがデファクトスタンダードとなっています)。 k8sはこれがわかりやすかった https://news.mynavi.jp/itsearch/article/devsoft/4097 1つ目は高い抽象度です。Dockerコンテナは通常一台のサーバ内に閉じて構築されます。複数台のサーバにまたがるコンテナ環境を構築するためには、ネットワークにおけるNAT設定など、さまざまな設定が必要になります。 こういった問題にアプローチするのがKubernetesです。Kubernetesを使うとコンテナのクラスタ化が容易になります。クラスタはサーバ単位でコンテナを管理するPodと、サーバをまたがるPodを管理するReplicaSet?の組み合わせで構築されます。 2つ目は高い信頼性・回復性です。セルフヒーリングと呼ばれ、障害により設定された台数を下回った場合には、自動的にコンテナが再起動されます。これにより、ゼロダウンタイムを実現します。 3つ目は中立性です。Kubernetesを実現するサービスはGoogle Cloud PlatformやOpenStack?などさまざまに存在します。CNCF(Cloud Native Computing Foundation)により標準化されており、Kubernetesが各クラウドを抽象化する層を担うことで、ベンダーロックインを防ぎます。 ハイパバイザ 従来のホストOS型は、HW->OS->仮想化->ゲストOS ハイパバイ座敷は、HW->ハイパバイザ仮想化->ゲストOSとなっている。 ハイパバイザの一つの例としては、Linux自体をハイパバイザにしたQEMUというのが有名(発表して二週間でLinuxにマージされたので)。これはLinuxだからホスト型じゃない?と思うかも知れないけど、ハイパバイザの上で通常のプロセスを走らせることなく、ゲストOSをのせるという点で少し異なる 技術的な差異は主に3つある。(1) 仮想化支援機能を有するCPUを前提としていること。通常ソフトだけで仮想化してx86の上でarmなどの違うアーキテクチャを動かすとその計算のエミュレートが大変だったのだが、CPUがその機能を提供するようなCPUが販売されるようになったので、パフォーマンスがよくなった(CPUを限定してゲストOS側を最適化・改造が必要な準仮想化に比べると遅いけど)。(2) KVMは独自にハイパバイザを開発するのではなく、Linuixのデバドラを流用できるのでハードウェア対応が容易 (3) KVMでのゲストOSはプロセスとして管理される(!)ので、killとかCtrl-CによるゲストOSの削除が可能になる KVMは完全仮想化に際して仮想化支援機能を有するCPUを要求する(HWに対する制約がある)。使用している機器にCPUの仮想化支援機能があるかどうか分からない場合は、/proc/cpuinfoを見てみるとよいでしょう。Intel VTの場合はvmxが、AMD-Vの場合はsvmがあるか否かが1つの判断基準となります。 apt-get install kvm bridge-utilsみたいなやつをやって、kvm-img create -fとかいうかなりお手軽間を醸し出していることをすることによってkvmがインストールできたりOSがインストールできたりしてすごい KVMはただでさえ仮想化していて物理的なサーバの位置がよくわからないのに、物理サーバの位置が多くなってくると本当にわけわからなくなってしまう。なので、こういうときに使うためのKVM運用ツールoVirtというものがある。 Cloud tasks †HTTP PUTを定期的に投げるだけのサービス(タスク:このHTTPリクエストをここに投げといてという依頼) 「POSTを積む、POSTを投げる」 投げる先はオンプレでもGCEでもApp Engineでもありえる。Google内部だといろいろ楽なので楽(例としてHTTPリクエストを…と言ったときにターゲットがApp Engineだったらprojectからの相対パスで指定できるので)。 ターゲットはPOSTに対して200台を返す義務がある。返さないとリトライとかされる。 Cloud Tasksからのリクエストには、どのキューからPOSTされたのかなどのヘッダーが書かれている。 こういうタスク系は非常に重くて特殊なものを使いがちだと思うので、GAEではなくGCEがそれを受けるというのが現実的になりそう 数百万または数十億のような多数のタスクを追加する必要がある場合、二重注入パターンが便利です。1 つのジョブからタスクを作成する代わりに、インジェクタ キューを使用します。 このTask Queueには、キューに追加した処理がGAEにより自動実行されない Pull Queue という種類があり、これを使うとGAEではない外部のプラットフォームからキューに入っている処理を引き出す事ができます。 StandardはTask queue, FlexはCloud tasks/PubSub?を使うべき(本当?StandardもCloud tasksのほうが良くない?) 言語 †Java †JavaでLocalをチェックするための方法として、以下のものがある。要するに、環境変数的な感じでSystemからappengine.appid private static final String APP_ID = System.getProperty("appengine.appId"); private static final String APP_VERSION = System.getProperty("appengine.version"); private static final boolean LOCAL_TEST = null == APP_ID || null == APP_VERSION; app.yamlにそうとうするものは、javaのばあいsrc/main/webapp/WEB-INF/appengine-web.xmlになっているっぽい。ここの部分でランタイムをxmlとして入力し、 Javaのweb-??.xmlみたいなやつ(app.yamlのJava ver)では、serviceが何故かmoduleという表現になっている あと、appIdって見たらプロジェクトIDのことだと思う必要がある インスタンス設定 †
デプロイ †
初期設定 †
curl https://sdk.cloud.google.com | bash exec -l $SHELL gcloud init # ちゃんとログインページに飛ばしてくれないので、リンクを手でコピペする ssh †gcloud compute ssh instance-1 --zone us-central1-c GCPでコマンドが無い時に自動終了するスクリプト †https://twitter.com/imos/status/923551881166602240 月2ドルとかで超安くサーバが使えるように鳴るらしい Googleクラウド お金がクレジットある状態だと不明瞭なのまじね。試しに使って見て、これくらいかーとなるもんじゃないの Logging †Stackdriver Logging †
Stackdriver Trace †https://cloudplatform-jp.googleblog.com/2018/05/viewing-trace-spans-and-request-logs-in-multi-project-deployments.html また、トレースの一部となっている全プロジェクトからのリクエストに関するログ エントリの表示も可能です。これには関連するプロジェクト側に “logging.logEntries.list” の権限が必要で、ログを Stackdriver Logging に書き込む際は、“projects/[PROJECT-ID]/traces/[TRACE-ID]” というフォーマットで LogEntry? オブジェクトの trace フィールドを設定する必要があります。LogEntry? の span_id フィールドを、16 文字の 16 進数でエンコードされたスパン ID として設定し、ログを特定のトレース スパンと関連づけることも可能です。詳細はこちらのドキュメントを参照してください。 Fluentd を介して Google Kubernetes Engine もしくは Stackdriver Logging エージェントを利用する場合は、“logging.googleapis.com/trace” や “logging.googleapis.com/span_id” というキーを使って構造化ログを書き込むことで、LogEntry? オブジェクトの trace や span_id フィールドを設定できます。詳細はこちらのドキュメントを参照してください。 トレース スパンに関連づけられたログ エントリを表示するには、“Show logs” をクリックしてください。 ということは、これはStackdriver Traceと同等の機能なのか。 Cloud Activity †パーミッションチェンジみたいなやつは、Cloud Activityで得ることができる。Cloud ActivityはもともとStackdriverのAdmin操作のみを取り出したもので、 Cloud Activity (Home > My Activity) of your "snap-crackle-proxy" project and then filter for resources "GCS bucket". gcloud †gcloud app logs read gcloud app logs tail Appengineのstackdriver logging的なものが得られる。各サービス、HTTPリクエスト、loggingが割と読みやすい形式で撮ってくれる。 結構遅延がある (30分) 言語別比較 †
|