Go:2年間の生産

Iron.ioの制作に2年間Goを使用した経験を共有したいと思います。 私たちは、負荷の高いサービスでGo(golang)を使用した最初の企業の1つです。 Iron.ioがこの言語を使用することを決定したとき、長期的には何を期待すべきかわかりませんでしたが、これまでのところすべてが順調に進んでいます。



これについては、Go with Rubyへの切り替えに関する以前の投稿ですでに少し書いています。 しかし今、私はこの言語を愛している特定のことについて話したいと思います。 。 ここでは、それらはランダムな順序です。







性能



Iron.ioで使用する言語を最初に決定したとき、最初にいくつかの調査を行い、製品(メッセージキュー)のテストを作成しました。 既存のクライアントを使用してテストできるように、beanstalkdプロトコルを使用する部分的なbeanstalkdクローンをGoで作成しました。 テストのパフォーマンスは高く、Cの公式バージョンとほとんど同じでした。しかし、すばらしい追加として、Goで驚くほど簡単に書くことができました。



Computer Language Benchmarks GameでGoを他の言語と比較するための基準を見つけることができます。 以下のグラフでは、Javaと比較しています(Goがなければ、おそらくこれが使用される言語になります)。







このグラフは、Goの方が若干速い場合もありますが、通常はJavaに負けていることを示しています。 ただし、これはほんの数年前の言語にとってそれほど悪くはありません。 彼がしばらくして競合他社に追いつくことは間違いありません。 また、使用されるメモリの量がはるかに少ないことがわかります。



楽しみのために、以下のGoとRubyの違いを比較してください。 Goは、パフォーマンスとメモリ使用量においてRubyよりも優れています。





2年間、Goは当社製品のボトルネックではなく、常にデータベースでした。



記憶


Goには仮想マシンやインタープリターがないため、すぐに起動し、少量のメモリを使用します。 IronMQは、構成の読み込み、接続の作成などを含む約6.5 KBの常駐メモリで動作を開始します。 しばらく動作した後、主にキャッシュによりメモリ消費が増加します。 現在、実稼働サーバーは約400 MBで実行されています(この比較は、アプリケーションのコンテキストでは適切でない可能性があることを理解しています)。



2年間で、メモリリークやメモリの問題は発生していません。



並列計算



並行性はGoの非常に重要な部分であり、さまざまな高レベルの抽象化により簡単に使用できます。 私は長年Javaを使用しており、java.util.concurrencyパッケージに非常に満足していました。このパッケージは、非常に優れた並列化ツールのセットを提供しますが、Goの基本的な実装の容易さはまったく同じではありません。 Goには、並列操作とそれらの間の通信チャネル用のゴルーチンがあります。 ゴルーチンは特に興味深いです:



「ゴルーチンは同時実行を容易にするための一部です。 長い間存在してきたアイデアは、多くのスレッドで独立して実行されるコルーチン関数のセットです。 たとえば、ブロッキングシステムコールの呼び出しを通じてコルーチンがブロックされると、ランタイムは同じオペレーティングシステムスレッド内の他のコルーチンを別の実行中のスレッドに自動的に移動し、ブロックされないようにします。 プログラマーはこれを見ることはありません。これは明らかな利点です。 その結果、ゴルーチンを取得します。 これらは軽量であり、長いシステムコールに大きな時間コストがかからないため、数キロバイトにしか収まらないスタックにはもう少しメモリがかかります。 スタックを小さく保つために、Goは実行時にセグメント化されたスタックを使用します。 新しく作成されたゴルーチンには数キロバイトが割り当てられますが、これはほとんどの場合十分です。 それ以外の場合、ランタイムはセグメントを自動的に展開します。 オーバーヘッドには、関数呼び出しごとに平均約3つの単純な命令がかかります。 同じアドレス空間に数十万のゴルーチンを作成することをお勧めします。 ゴルーチンが単なるスレッドである場合、システムリソースははるかに速く枯渇します。 「 ソース



私たちがしなければならなかった重要なことは、ピーク負荷時にデータベースやシステムの他の部分を過負荷にしないために、並行性を制限することでした。 Goチャネルを使用した単純なセマフォでこれを実装しました。



信頼性



信頼性を定量化することは困難ですが、最終的に、Goアプリは非常に堅牢であると結論付けました。 外部の問題(データベース、サードパーティライブラリのエラー)に関係のない障害やエラーがあったとは思いません。 一般に、オープンソースのGoのライブラリは非常に高品質のライブラリです。 メインライブラリにメモリリークや重大なエラーは見つかりませんでした。



また、Goで記述されているからこそ、コードの品質が向上すると考えがちです。 正確な理由を言うことはできませんが、IronMQコードを見ると、「暖かくて塊っぽい」ように見えます。 おそらく、インポートと未使用の変数を強制的に削除するのは非常に厳密なコンパイラです。 おそらくこれは、大きなタスクを解決するために小さなコードを書くだけで十分な場合があるためです。 おそらく、ここで何が重要かをすぐに理解し、詳細を聴衆と共有するでしょう。



展開



Goは、単一の静的バイナリにコンパイルします。 展開とは、単にファイルをサーバーにアップロードして起動することです。 追加の依存関係は必要ありません。 プログラムのランタイム環境はありません(サーバーにGoをインストールする必要はありません)。 実行可能ファイルは小さく、IronMQのサイズは〜6 Mbです。



ロールバック


展開後に問題が発生し、ロールバックが必要な場合は、いつでも実行可能ファイルを停止して、以前のファイルと置き換えることができます。 プログラム全体が単一のバイナリファイルにコンパイルされるため、依存関係について心配する必要はありません。



才能のある専門家



2年前、Goを選択する大きなリスクがありました。その言語を知っている人はほとんどいませんでした。 私たちはgolangメーリングリストに最初に求人を掲載した会社であり、回答者の資格に困惑していました。 最高のテクノロジー企業から豊富な経験を持つ開発者からアプリケーションを受け取り、博士号を取得した開発者や、本格的なプロジェクトに取り組んだ開発者もいました。 彼らのほとんどはフルタイムのGo開発者ではありませんでしたが、経験と知識を共有したいという欲求を得るために彼と十分に協力しました。 私たちが作成しようとしているものが重要なのか、それとも単にGoで作業したかったのかはわかりません。



Golangの最初のGoプログラマであるEvan Shawは 、現在も一緒に働いており、Golangの開発者の1人です。



おわりに



Goで2年間働いた後、私たちは正しい選択をしたと自信を持って言えますか。 今日Iron.ioを開始した場合、とにかくGoの方が良いオプションです。 GoogleやHerokuなど、他の多くの企業が現在使用しています。 同様のビューは、Goの作成者の1人である+ Rob Pikeによって表されます。



「Googleで構築したソフトウェアは、利用可能な言語で常に十分に機能するとは限らないことに気付きました。 Robert Griesemer、Ken Thompson、私は、Googleで開発するプログラムを書くのに最適な言語にすることを決めました。」



Apceraの創設者であるDerek Collisonは 、最近Wiredの記事で次のように述べています。



「クラウドサービスの機能を確保するために、最新テクノロジーのどのコントロールレイヤーとインフラストラクチャレイヤーが使用されますか? 2年以内に、それらのほとんどはGoで記述されます。」



Goは私たちが待ち望んでいた次世代の言語です。 おそらく、このようなカテゴリーの声明はまだ早すぎますが、これは確かに良い出発点です。



All Articles