taki

C#でリモートのMySQLやSSH接続をやってみた


こんにちは、大阪スタジオ ソフトウェアエンジニアの滝です。
今回のお話は、C#でMySQLに接続してデータを取得したり、SSH接続でコマンドの送信をやってみたお話になります。

きっかけは、業務で集計ツールを作成する機会があり、その要件は、Windows環境からターミナルを使わずに、データベース及びログサーバーからデータ集計を行い、その結果をExcelファイルに出力するというものです。
実現には様々な方法が考えられますが、今回はWindows環境から行いたいということだったため、デスクトップクライアントを作成し、アプリケーションを実行することで集計処理を自動で行ない、結果をExcelファイルに出力するようなツールを作成することにしました。
要件を満たすために、C#でMySQLに接続してデータを取得したり、SSH接続でコマンドの送信を行う必要があり、どのように実現したかを簡単なサンプルコードと共に紹介させていただきます。

プロジェクトはコンソールアプリでもフォームアプリでもどちらでも動作します。
対応プラットフォームなど、詳しい情報は以下のリンクから確認できます。

 

今回使うライブラリ

・SSH.NET (github)
https://github.com/sshnet/SSH.NET

・MySQL(github)
https://dev.mysql.com/doc/connector-net/en/

 

SSH接続のやりかた

  • 必要なもの
    • SSH接続が可能なリモート環境(物理マシンでもVMでもOK)
      • 記事内で使用している環境はLinux CentOS 6.9(VirtualBox使用)
    • VisualStudio(どのエディションでも可)
      • 記事内で使用している開発環境はVisualStudio2017
  1. 新しいプロジェクトを作成または既存のプロジェクトを読み込む
    このサンプルではConnectSSHというプロジェクトをコンソールプロジェクトで作成しました。
    既存のプロジェクトでテストしていただいても問題ありませんが、できれば新規作成をおすすめします。

  2. NuGetからSSH.NETの追加
    図のように、ソリューションエクスプローラー内で1で作成したプロジェクト名の項目を右クリックし、NuGetパッケージの管理をクリックします。参照タブをクリックし、検索フォームに「SSH.NET」と入力し検索します。Renci製のSSH.NETをプロジェクトにインストールします

  3. とりあえず接続してみる
    以下にサンプルコードを記載します。コードの説明はコメントに書いております。

    using System;
    using Renci.SshNet;
    
    namespace RemoteServerConnect
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    // 接続先のホスト名またはIPアドレス
                    var hostNameOrIpAddr = "192.168.xxx.xxx";
    
                    // 接続先のポート番号
                    var portNo = 22;
    
                    // ログインユーザー名
                    var userName = "taki";
    
                    // ログインパスワード
                    var passWord = "xxxxxxxxxx";
    
                    // コネクション情報
                    ConnectionInfo info = new ConnectionInfo(hostNameOrIpAddr, portNo, userName,
                        new AuthenticationMethod[] {
                            new PasswordAuthenticationMethod(userName, passWord)
                            /* PrivateKeyAuthenticationMethod("キーの場所")を指定することでssh-key認証にも対応しています */
                        }
                    );
    
                    // クライアント作成
                    SshClient ssh = new SshClient(info);
    
                    // 接続開始
                    ssh.Connect();
    
                    if(ssh.IsConnected)
                    {
                        // 接続に成功した(接続状態である)
                        Console.WriteLine("[OK] SSH Connection succeeded!!");
                    }
                    else
                    {
                        // 接続に失敗した(未接続状態である)
                        Console.WriteLine("[NG] SSH Connection failed!!");
                        return;
                    }
    
                    // 接続終了
                    ssh.Disconnect();
                }
                catch(Exception ex)
                {
                    // エラー発生時
                    Console.WriteLine(ex);
                    throw ex;
                }
                
            }
        }
    }
    

    パスワード認証でSSH接続をしてみた例になります。
    接続できない場合は、ファイアウォールやポートフォワーディング設定など、ネットワーク接続自体に問題がないかを確認してみてください。

  4. コマンドを送信してみる(リモートマシンの時間を取得)
    using System;
    using Renci.SshNet;
    
    namespace RemoteServerConnect
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    // 接続先のホスト名またはIPアドレス
                    var hostNameOrIpAddr = "192.168.xxx.xxx";
    
                    // 接続先のポート番号
                    var portNo = 22;
    
                    // ログインユーザー名
                    var userName = "taki";
    
                    // ログインパスワード
                    var passWord = "xxxxxxxxxxxxxx";
    
                    // コネクション情報
                    ConnectionInfo info = new ConnectionInfo(hostNameOrIpAddr, portNo, userName,
                        new AuthenticationMethod[] {
                            new PasswordAuthenticationMethod(userName, passWord)
                            /* PrivateKeyAuthenticationMethod("キーの場所")を指定することでssh-key認証にも対応しています */
                        }
                    );
    
                    // クライアント作成
                    SshClient ssh = new SshClient(info);
    
                    // 接続開始
                    ssh.Connect();
    
                    if(ssh.IsConnected)
                    {
                        // 接続に成功した(接続状態である)
                        Console.WriteLine("[OK] SSH Connection succeeded!!");
                    }
                    else
                    {
                        // 接続に失敗した(未接続状態である)
                        Console.WriteLine("[NG] SSH Connection failed!!");
                        return;
                    }
    
                    // 送信したいコマンドを変数に入れる
                    var commandString = "date";
    
                    // コマンドを作成する
                    SshCommand cmd = ssh.CreateCommand(commandString);
    
                    // コマンドを実行する
                    Console.WriteLine("[CMD] {0}", commandString);
                    cmd.Execute();
    
                    // 結果を変数に入れる
                    var stdOut = cmd.Result;
                    var stdErr = cmd.Error;
    
                    // 終了コードを表示する
                    Console.WriteLine("終了コード:{0}", cmd.ExitStatus);
    
                    // 標準出力を表示する
                    if (stdOut != string.Empty)
                    {
                        Console.WriteLine("標準出力:");
                        Console.WriteLine(stdOut);
                        Console.WriteLine("---------");
                    }
    
                    // エラー出力を表示する
                    if (cmd.ExitStatus != 0 && stdErr != string.Empty)
                    {
                        Console.WriteLine("標準エラー出力:");
                        Console.WriteLine(stdErr);
                        Console.WriteLine("----------------");
                    }
    
                    // 接続終了
                    ssh.Disconnect();
                }
                catch(Exception ex)
                {
                    // エラー発生時
                    Console.WriteLine(ex);
                    throw ex;
                }           
            }
        }
    }
    

    今回はサンプルとして、リモート側の時間を取得してコンソールに表示するサンプルを作ってみました。

  5. こんなことに使えます
    SSHをターミナル以外のWindowsクライアントから送信するという事自体が滅多にないことだとは思いますが
    Webクライアントが使えない環境や、サーバーへのSSHアクセスはさせたいがコマンドをテンプレート化して使用させるなどの制限をしたい場合などに使えるかもしれません。
    もちろん、このライブラリを使ってターミナルクライアントを作ることも可能だと思います。

MySQL接続のやりかた

  • 必要なもの
    • MySQLサーバーが起動していて接続が可能なリモート環境(物理マシンでもVMでもOK)
      • 記事内で使用している環境はLinux CentOS 6.9 / MySQL5.5.50(VirtualBox使用)
    • VisualStudio(どのエディションでも可)
      • 記事内で使用している開発環境はVisualStudio2017
  1. 新しいプロジェクトを作成または既存のプロジェクトを読み込む
    このサンプルではConnectMysqlというプロジェクトをコンソールプロジェクトで作成しました。
    既存のプロジェクトでテストしていただいても問題ありませんが、できれば新規作成をおすすめします。

  2. NuGetからMysql.Dataの追加
    図のように、ソリューションエクスプローラー内で1で作成したプロジェクト名の項目を右クリックし、NuGetパッケージの管理をクリックします。参照タブをクリックし、検索フォームに「Mysql」と入力し検索します。
    Oracle製のMysql.Dataをプロジェクトにインストールします。

  3. とりあえず接続してみる
    以下にサンプルコードを記載します。コードの説明はコメントに書いております。

    using System;
    using MySql.Data.MySqlClient;
    
    namespace ConnectMysql
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 接続に必要なパラメータ文字列を生成する
                var connectionParams = string.Format(
                    "host={0}; userid={1}; password={2}; database={3}; charset={4}",
                    "192.168.xxx.xxx",
                    "taki",
                    "xxxxxxxxxxxx",
                    "sample_db",
                    "utf8"
                );
    
                // コネクターを作成
                var mysql = new MySqlConnection(connectionParams);
    
                try
                {
                    // 接続開始
                    mysql.Open();
                }
                catch (MySqlException ex)
                {
                    // 何らかの理由で接続に失敗した
                    Console.WriteLine(ex);
                    throw ex;
                }
            }
        }
    }
    

    リモートにインストールされたMySQLサーバーにアクセスする例になります。
    接続できない場合は、MySQLユーザーのアクセス権、ファイアウォールやポートフォワーディング設定など、設定に問題がないかを確認してみてください。

  4. insertとselectをしてみる
    using System;
    using MySql.Data.MySqlClient;
    
    namespace ConnectMysql
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 接続に必要なパラメータ文字列を生成する
                var connectionParams = string.Format(
                    "host={0}; userid={1}; password={2}; database={3}; charset={4}",
                    "192.168.xxx.xxx",
                    "taki",
                    "xxxxxxxxxxx",
                    "sample_db",
                    "utf8"
                );
    
                // コネクターを作成
                var mysql = new MySqlConnection(connectionParams);
    
                try
                {
                    // 接続開始
                    mysql.Open();
                }
                catch (MySqlException ex)
                {
                    // 何らかの理由で接続に失敗した
                    Console.WriteLine(ex);
                    throw ex;
                }
    
                // サンプルではこういうテーブルにアクセスしている
                // CREATE TABLE shoplineup(ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY, Name VARCHAR(16) NOT NULL, Price INT NOT NULL);
    
                // コマンド文字列用変数
                string cmd = "";
    
                // insertしてみる
                cmd = @"INSERT INTO shoplineup SET Name='Sword', Price=100;";
    
                // コマンドコンポーネント作成
                var insertCmd = new MySqlCommand(cmd, mysql);
    
                // 実行
                MySqlDataReader insertResult = insertCmd.ExecuteReader();
    
                // 変更を与えた件数を表示してみる
                Console.WriteLine("{0}row affected", insertResult.RecordsAffected);
    
                // 結果を閉じる
                insertResult.Close();
    
                // selectしてみる
                cmd = @"SELECT * FROM shoplineup;";
    
                
    
                // コマンドコンポーネント作成
                var selectCmd = new MySqlCommand(cmd, mysql);
    
                // 実行
                MySqlDataReader selectResult = selectCmd.ExecuteReader();
    
                // MySqlDataReaderというクラスに結果が入っている
                // Read()を呼ぶことで次の行にアクセスする
    
                while(selectResult.Read())
                {
                    var id = selectResult.GetInt32("ID");  // フィールド名でのアクセス
                    var name = selectResult.GetString(1);  // カラムインデックスでのアクセス
                    var price = selectResult.GetUInt32(2); // 同上
    
                    Console.WriteLine("ID:{0} Name:{1} Price:{2}", id, name, price);
                }
    
                // 結果を閉じる
                selectResult.Close();
    
                // Mysql接続終了
                mysql.Close();
            }
        }
    }
    

    今回はサンプルとして、sample_dbというデータベースにあるshoplineupテーブルに対してinsertおよびselectをする例を作ってみました。

  5. DataTableで欲しい場合

    var datatable = new DataTable();
    var adapter = new MySqlDataAdapter(query, mysql);
    adapter.Fill(datatable);
    return datatable;

    このようにして、クエリを実行する部分にMySqlDataAdapterを使用することで結果をDataTableで得ることも出来ます。

  6. こんなことに使えます
    MySQLターミナルクライアントを作ることも出来ますし、機能をテンプレート化してデータの集計用クライアントとしても使うことが出来ます。

まとめ

SSH接続及びMySQL接続をC#でやってみるというチャレンジでしたが、いかがでしたでしょうか?
パッケージのおかげで誰でも簡単に実装出来るので、アイディア次第ではとても便利なアプリを作ることが出来ると思います。
C#でSSH接続やMySQL接続をやってみたいという方のお役に立てれば幸いです。


yuemori

Rails Developers Meetup 2018に進行協力・登壇しました


こんにちは。大阪スタジオの植森です。

Ruby on Rails の “現場の知見”に触れる Meetup

Rails Developers Meetup 2018が3/24(土)、3/25(日)の二日間に渡り開催されました。

Rails Developers Meetup 2018: Day 1

Rails Developers Meetup 2018: Day 2

弊社Aimingからは黒木(が発表、私植森(@wakaba260yen)がDay2の司会進行とPRスポンサー発表として参加しました。

二人とも大阪スタジオ所属で、このために東京まで足を運びましたが、それだけの価値のあるイベントでした。こうしたイベントに発表・運営協力の両面で参加できて非常に良かったと思います。

大阪中継会場の提供

弊社大阪スタジオを会場提供し、大阪へのLive中継も行われました。

当日はYoutubeでのLive配信があったのですが、大阪中継にも人が集まり、このイベントへの関心の高さが伺えます。

今回はRails Developers Meetup通じて初めてのAトラック・Bトラック同時開催だったのですが、大阪でも2トラック同時中継を試みました。中継をどうするかについては相談していましたが、やはり2トラックどちらも中継することでLive感を大事にしたいという気持ちもあり、こういった形での会場提供とさせていただきました。

手を貸してくれた社員と、こちら側の要望に応えて中継の手配をしてくれたオーガナイザーの方々のおかげで実現できましたが、結果として大阪会場に来ていただいた参加者の皆様にもご満足いただけたなら嬉しいです。

冴えてるRailsエンジニアの育て方

黒木()による、弊社で行っているRailsエンジニアの採用・教育の取り組みについての発表でした。

当日は私が司会を担当しているBトラックでの発表だったのですが、他のセッションに比べてもなお盛況だった印象です。

大阪会場のスタッフから話を聞いたところ、大阪側もほぼ満席だったとのことで、教育・採用に対しての関心の高さが伝わってきました。

弊社では採用の際にゲームプレイヒアリングシートというものに今までプレイしたゲームとそれに対する簡単な感想を書いて提出してもらっています。そうした取組みを紹介しつつ、教育の際に考えていることなどをお話させていただきました。

twitterでも弊社のゲーム会社らしい採用の目線や、ペアプロ、教育の取り組みなどに良い反響を頂けたと思います。

 

サービスクラス、その前に

PRセッションは、私植森(@wakaba260yen)の方よりサービスクラスの前に知っておきたいことをテーマに話をさせていただきました。

会社の方から「最後にPRしてもらえればなんでもいいよ」と言われていたので、PRセッションというよりもLTに近い雰囲気で話をしようと思い、こういう話になりました。

Day2はチームビルディングの話が多く、他のセッションが心に響く内容ばかりで、自分の話が皆さんの心に届くだけのパワーがあったかどうかは自信がありませんが、少しでも感じるものがあったら嬉しいです。

仰っていることは完全に同意で、「オブジェクト指向実践ガイド」の話をしながらのRubyでオブジェクト指向や設計についての話も本当はしたかったのですが、今回はちょっとエモい話をしたかったのでカットしました。

いつか機会があったらそういう話もしたいと思っています。

Rails Developers Meetup2018の司会を通じて

私はいつもは大阪側で中継スタッフをしていますが、今回は司会というポジションで参加しました。

司会についての感想は同じ日に別トラックで司会をされていた、みんなのウェディングの櫻井さんが熱い記事を上げられているので是非そちらを見てください。

オーガナイザーである平野さん(@yoshi_hirano )は、以前フリーランスとして大阪スタジオで働かれていたことがあり、その時のご縁もあってRails Developers Meetupのスタッフの一人として参加させてもらっています。

平野さんは本当にパワーのある人で、Rails Developers Meetupの初回からずっと走り続けて、一年もしないうちにこんなに大きなイベントにされてしまうなんて想像もしていませんでした。

Day2のセッションでしなもんさん( )によるバス因子の素晴らしい発表があったのですが、Rails Developers Meetupのバス因子は平野さんだと思います。平野さんの代わりなんてとんでもない、とは思いますが、進行や準備の協力など少しでも平野さんの負担を減らせられたら良かったと思います。

まあ、司会が終わった今となっては「楽しかったので是非次回もやらせてください」という気持ちなのですが。

まとめ

発表者の方々、ボランティアスタッフの方々、オーガナイザーの平野さん・秒速さん、そして参加者の皆様。

皆様のお陰であの楽しい二日間があったと思います。ありがとうございました。

We Are Hiring!

Aimingではエンジニアを募集しています。

セッションやこの記事を見て興味をもっていただけたなら、是非エントリーください!

https://aiming-inc.com/ja/jobs/


s-kuroki

Code Review Meetup #2に会場を提供しました&発表しました #codereviewmeetup


大阪スタジオのwebエンジニアの黒木です。

3/9(金)に開催されたCode Review Meetup #2に大阪スタジオのセミナールームを提供しました。

その名の通りコードレビューの話をする勉強会で、前回(東京開催)と今回はコードレビュー自動化サービスのSideCIさんが主催されました。(誰が主催しても良いというスタンスだとおっしゃられてました)

SideCI 角さんの発表

最初に行われたのは、SideCIのFounderの角さんの発表です。

角さんがSideCIを立ち上げるに至った経緯から、コードレビューサービスを運営しているからこそ見える、いろんな企業さんのコードレビューのあり方についてのお話で、非常に興味深く聞かせてもらいました。

LT

LTでは、Aimingから3名に加えて、飛び入りで1名、計4名が発表しました。

伝わるコードレビューのために(黒木)

焼肉とレビューの関係 〜難しいコードレビューのコツ〜

Qiitaにスライドが上がっています

oznor

ダブルレビューをやってみて

oznor

飛び入りの @whosaysni さんの発表

発表内容は公開されないということでしたので具体的な内容は控えさせてもらいますが、職場でレビュー文化を根付かせようと奮闘されているお話で、いろんなあるあるに共感しつつ聞かせてもらいました。

パネルディスカッション

角さんとLTの参加者で短めのパネルディスカッションを行いました。
参加者の皆さんからいろんな質問が出ました。皆さん、コードレビューの勉強会に来られるだけあって、コードレビューをチームに導入しようとしていて悩まれていたりしていて、非常に温度の高い話になっていたかなと思います。

まとめ

コードレビューの勉強会と聞くとニッチな感じもしましたが、チームで開発をやっていくには欠かせない重要な要素ですし、いろんなところでチーム開発に奮闘されている方が参加されていた、良い勉強会だったと思います。
また、出席率が100%だったそうで、その高さにSideCIの皆さんも驚かれていました。それだけ皆さん温度が高かったのだと思います。

宣伝

Rails Developers Meeting 2018でも会場提供&発表します!

来る3/24,25に開催されるRails Developers Meeting 2018でも、Aiming大阪スタジオで中継を行います。
中継会場の参加枠(1日目2日目)にはまだ空きがありますので、興味のある方は是非ご参加いただければと思います。
私も2日目に「冴えてるRailsエンジニアの育て方」というタイトルでお話させてもらいます。

Aimingは各種勉強会への会場提供をしています

東京本社大阪スタジオで勉強会に会場を提供しています。お気軽にご連絡ください。


Unityのバージョンをなるべく最新にする試み


こんにちは。エンジニアの鈴木聡です。

現在開発中のプロジェクトでは、Unityの新機能をできるだけ使えるようにしています。そのためには、Unityのバージョンを最新のものにしていくことが重要です。

今回は、実際に使用を始めている機能や、苦労した点について書こうと思います。

新しい機能のプロジェクトでの使用

現在、プロジェクトにおいて、以下の新しい機能が使用されております。

Timeline(2017.1.0から)は演出の一部で使用が開始されていて、そのままリリースに取り込まれる方向で開発が進められています。

TestRunnerのPlayMode(5.6.0から)についても、EditModeと共にCIの流れに組み込まれており、全てのPullRequestに対してテストが走るようになっています。

最新を追い求めるが故の不具合との向き合い

Unity2017.3.0f3にバージョンアップを行なった際に、以下のような不具合が発生して、苦労することになりました。

  1. iOSでアプリを動作させると高確率でアプリがクラッシュしてしまう
  2. UnityUI(uGUI)でApplyした時にレイアウトが崩れてしまう
  3. TestRunnerが実行時に硬直を起こすようになった

これらについては、プロジェクト側での対応では難しいものについては、パッチリリースを待つことになります。

上記不具合については、Unity2017.3.1p1において1および2が解決された模様です。Unity開発チームの迅速な対応に感謝です。

(その後、RectTransformをスクリプトで更新した時の挙動が少し変わっていて少し苦労するのですが、それはまた別の話)

最新を追い求めるが故のAPI置き換えとの戦い

Unityのバージョンをアップデートすると、新しいAPIへの差し替えを促進するために、古いAPIにObsolete属性が置かれることがあります。

完全に古いAPIが消されるまでは、ある程度の時間的猶予があることが多いですが、それでも古いAPIを新しいものに置き換えていく作業もそれなりの手間がかかります。

プロジェクト内で使用しているAPIについては、その都度対応するという方向で問題ないのですが、外部アセットを使用している場合は、そのアップデートを待って忘れずに更新を入れる必要があります。

さらに、外部アセットがサポート終了になっている場合は、アセットの更新が行われませんので、プロジェクト内でアセットを解読してパッチを当てていくことになります。地道な戦いが続きます。

リリース後のアップデートはどうするのか?

リリース後のアプリについては、アプリの安定性がとても重要になります。アプリのクラッシュなどは確実に避けなければなりません。

バージョンアップについては、アプリ全体の動作について、品質保証チームの助力を仰ぐなど、十分な動作確認を行う必要があるでしょう。

最後に

Unityのバージョンを最新に保っていくことには、それなりの苦労が発生するとは思いますが、最新の機能が使えるようになるというメリットは大きいと思います。これからも可能な限り新バージョンを追い求めていければと思います。


DB負荷試験をやった話


こんにちは!インフラチームの川田です。

業務では社内ネットワーク構築・運用やツールの検証などしています。
本記事では、1月末から2月初頭にかけて行ったDB検証のベンチマーク結果をまとめたいと思います。

試験環境

今回は以下4つの環境を対象にMySQL 5.7互換のあるDBを構築し、ベンチマークを測りました。

  • Google Compute Engine (以下GCE)
  • Google CloudSQL
  • Amazon EC2
  • Amazon Aurora

サービス概要

GCE及びEC2は、仮想マシンを構築することができるサービスです。
CloudSQLとAuroraは、フルマネージド型DBサービスです。どちらも簡単なので、とりあえずDB構築してみたいという初心者にオススメです。
CloudSQLはチューニング項目はありませんが、AuroraではMySQLのmy.cnfで設定できる項目の一部を変更できます。

インスタンス概要

GCPで使用したマシンスペックは次の表の通りです。

GCEでのディスク容量は500GB SSD永続ディスク、CloudSQLは2TB SSDとしました。はじめにデフォルト要領で計測を行っていましたが、GCPではディスクサイズによってIOPSとスループットが向上するため、本記事ではディスク容量を多めに取った状態での結果を記載しています。
また、CloudSQLへの接続方法は外部IPアドレスを直接指定するか、proxyを経由するかの2通りがあります。2通りで検証を行ったところ、外部IPで接続した方が1.3倍ほど良い性能が得られました。本記事内の結果は外部IPで接続したときのものです。

AWSで使用したマシンスペックは次の表の通りです。

EC2のディスク容量はデフォルトの10GB 汎用SSDとしました。
RDSでは設定項目をパラメータグループとして扱います。
今回のAuroraでの検証パラメータグループはデフォルトを使用しています。

試験内容

使用したベンチマークツールはtpcc-mysqlとsysbenchです。
tpcc-mysqlはTPC-Cの仕様に沿ったベンチマークツールです。
今回のベンチマークで使用したパラメータは以下の通りです。

  • warehouse: 5
  • warmup time: 10
  • bench time: 180
  • connection: 64

試行回数は各環境で3回ずつ、結果は1分間に処理したトランザクション数です。
CPUが2,4,8コアのインスタンスを対象に検証を行いました。
tpcc-mysqlはGCEもしくは、EC2の8コアインスタンス上で実行しました。

sysbenchは、Luaスクリプトによってシナリオを変更することができます。
今回のベンチマークで使用したLuaスクリプトは以下の8つです

  • bulk_insert.lua
  • oltp_insert.lua
  • oltp_point_select.lua
  • oltp_read_write.lua
  • oltp_update_index.lua
  • oltp_write_only.lua
  • select_random_points.lua
  • select_random_ranges.lua

パラメータは次の通りです。

  • thread: 256
  • bench time: 180

試行回数は各環境1回ずつ、結果は1秒間に処理したトランザクション数です。
マシンスペックは全環境で8コアのインスタンスを使用しました。
sysbenchもGCEもしくは、EC2の8コアインスタンス上で実行しました。

また、今回の検証では2月7日に正式リリースされたばかりAurora MySQL 5.7互換を早速使ってみました。
tpcc-mysqlとsysbenchでの試験はMySQL5.7互換での結果を出していますが、最後にMySQL5.6互換のAuroraとの比較も行いました。
手順はこちらを参考に、ベンチマーク用AMIに同梱されているsysbenchを用いて検証を行いました。使用したシナリオは次の通りです。

  • oltp
  • readonly
  • readwrite
  • selectonly
  • writeonly

ベンチマーク結果

まずはtpcc-mysqlの結果です。
CPUのコア数が2, 4, 8のインスタンスで検証を行いました。
GCEとEC2上で構築したMySQLはチューニング前後共に計測しています。
チューニング前後ではinnodb_buffer_pool_sizeなどを変更しています。


続いて、sysbenchの結果です。








最後にAurora 5.6と5.7の比較です。





まとめ

tpcc-mysqlの結果から、GCE, EC2インスタンスのチューニング後の性能が非常に良いことがわかります。GCEとEC2ではチューニング前後共にGCEの方が性能が高くなっています。性能差が大きく開いているため今後機会があれば、もう少し調べてみたいと思います。
また、sysbenchのoltp_write_only.luaとoltp_read_write.luaの結果を見るとCloudSQLとAuroraのwrite性能が他よりも低いことがわかります。

Auroraはデフォルトのパラメータグループでベンチマークを取っているので、チューニング次第ではさらに良い性能が見込めるのではないでしょうか。また、Amazonが提供するAurora負荷テスト用AMIでのsysbench検証結果では、とても良い性能が出ています。32コアインスタンスを使用していることや専用sysbenchのため、他のsysbench結果と単純比較は出来ませんが、スケールアップすることで順当に性能向上が見込めます。そして、AuroraのMySQL5.6互換、5.7互換の比較については、readonlyとselectonlyの性能が圧倒的に高くなっています。

CloudSQLについては、tpcc-mysqlではスケールアップした場合に他と比べて性能向上しませんでした。しかし、sysbenchのbulk_insertの結果が他より高い値が計測できました。並行処理が少なく、一度の書き込み量が多い環境では良い性能が出ると考えられます。

これらの結果から、Auroraはread性能が強い傾向が現れていたので、Webサイトなどに向いていると思います。write性能が求められる環境では、素のMySQLをチューニングしていくと良いのではないかと思います。

最後に

本番環境を想定したシナリオで測定するのがベストですが、これらの計測結果が誰かのDB選定の参考になれば幸いです。

また、Aimingではインフラエンジニアを絶賛募集中です!
ご興味のある方がいましたら、是非ご応募ください!


平井 佑樹

さくゲーコンテストを行いました!


こんにちは、新卒エンジニアの平井です。

今年、Aiming では「さくゲーコンテスト」というイベントを行いました。

さくゲーコンテストとは

プロジェクト業務を行っているだけでは、なかなか新しいゲームエンジンなり技術に触れる機会って少なくなると思います。 また、人事や企画や運営やデザイナーなど、非エンジニアの方がゲーム開発の経験があるとすごく相互理解が深まったりしますけど、実際のところ普段の会社生活の上でそういうことができる機会ってなかなか無かったりします。 それらを踏まえて Aiming では、ゲームコンテストを定期的に行うことで、ゲーム開発する機会を積極的に作るようにしています。

前回の様子

第4回Aimingクソゲー開発コンテストを行いました!

今回のゲームコンテストはさくっとゲームを作ってもらうためさくゲーコンテストと題し行いました。テーマは「」です!
こちら大阪スタジオのみ行い、11チームの発表がありました!

会場の様子

応募作品


インクを飛ばし地面に塗り合うゲーム
某インクを塗りあうゲームを理解しようとして開発されたとのこと
通信機能により二人対戦出来るようになっています!
こちら新卒エンジニアが作成しました!


ラブレターを紙飛行機にしてそれを操作しながら女の子に届けるゲーム
Spineの勉強を兼ねてデザイナーが1人で作った作品です!
Unityでプログラミングをするのは初めてというとても開発意欲の高い方でした!

~プレイ画面~


ジャンプして相手を踏んづけた方が勝ちのゲーム
Web上で2人から遊べるようサーバを構築したとのこと
こちらWebエンジニアが1人で作成しました。


社長の椎葉をボールの魔の手から守るゲーム
守りたい人とは何かと考えたとき社長の椎葉が浮かんだとのこと
社長の椎葉の3Dモデルがとても忠実に再現されていましたw

~クリア画面~


画像認識システムを使ってUnityちゃんを守るゲーム
プレイヤーの腕を使って上から落ちてくる赤いオブジェクトをUnityちゃんにぶつからないようにするという発想がとてもユニークな作品でした!
こちら、2018年度の新卒内定者が作成しました


マイクに声をかけて手紙をポストに運ぶゲーム
発表中なかなかポストに入らず、歓声が上がるたびに軌道がずれたりなどとても盛り上がりました!
こちらも内定者が作成しました


結婚式にタイミングよく突撃することで花嫁の心を奪うゲーム
リア充を爆発させつつ自分たちはリア充になれるとのこと
花嫁をさらうのが難しくて発表者もなかなかうまくいきませんでしたw
こちらも内定者が作成しました


Aimingのキャラクターを積み上げていき、落とした人が負けとなるゲーム
最近、流行りのゲームを見習って作ったそうでサーバからすべて自作したとのこと
どこかで見たようなゲームでしたw

 

 

 

 

 

 

 

 

地獄に落ちるネコに魚を当てて天国に送り出すゲーム
おじさんに魚を当ててしまうとゲームオーバーになります
こちらも内定者が制作したのですが
実はこのチームにエンジニアがいなくて
Unityのサンプル2Dシューティングゲームをもとに作ったとのこと
とてもキャラクターが可愛らしい作品でした!


社員を札束でビンタすることでモチベーションを向上させていき資金を増やしていくゲーム
愛社精神をもとに会社をリスペクトして作ったとのこと
こちら私が作成しました
社長の椎葉から狂気に満ちたゲームだと言われましたw

 


こちらチワワが他のチワワと会話して奥に進んでいくゲーム
人事の方が作成しました、なんとその人事の方は社内ゲームコンテストに参加するのは3回目とのこと!
開発意欲がとても高く雰囲気がよく出来ています!

まとめ

今回、新人研修の一環としてさくゲーコンテスト運営をさせていただきました。
難題もありましたが、結果的にエントリー数も上々で意欲作が多かったです。
当日もとても盛り上がり、良いイベントにすることが出来たと思います!

さくゲーコンテストいかがだったでしょうか?
Aimingでは不定期に勉強会やゲーム開発コンテストを行っています。
今回はエンジニアだけではなくプランナー、デザイナーや人事が参加するなど敷居は低くかなり自由な会になりました。応募された作品はどれも個性的なゲームが多く、とても賑わっていました!

以上、さくゲーコンテスト報告でした。

最後に社長賞としてなんと焼肉をごちそうしてくれました!
社長と受賞者で美味しくいただきました!


平井 佑樹

ログレスマップエディタのパフォーマンスを改善したお話


はじめまして、17年度新卒エンジニアの平井です。

今回、新卒エンジニアの平井と西田の二人がパフォーマンス向上のため新たにUnityでマップエディタを開発しました。
その際に改善した点や苦労した点を紹介しようと思います。

マップエディタとは

弊社の「剣と魔法のログレス いにしえの女神」及び「ブラウザ版 剣と魔法のログレス」では、自社GUIツールを使用してマップデータを制作しています。地面タイルの配置や噴水などのオブジェクトを配置するだけでなく、キャラクターが移動できない位置の指定や影の設定など、マップ処理に関する様々な設定も可能です。

~新マップエディタ画面~

ログレスの旧マップエディタは、Adobe AIRで作られています。これは、先に開発されたブラウザ版ログレスがFlashで作られているため、マップ上に配置されたオブジェクトを表示したりアニメーションをしたりするためのコンポーネント群を、ゲームクライアントとマップエディターとで共有ができ、開発効率が高いためです。

旧マップエディタの問題点

旧マップエディタは以下の問題がありました。

  • ファイル読み込みに時間がかかる
  • 描画速度が遅い
  • 弊社でAdobe AIRを使えるエンジニアが少なくメンテナンス性が低い

新マップエディタでは、これらの問題を改善することが目標となります。

Unityで開発した理由

  • 弊社には Unity を使えるエンジニアが多くメンテナンス性が向上できる
  • 弊社が Unity を使った開発を活発に行なっており、情報収集が容易かつノウハウを蓄積できる
  • 新卒エンジニアとして Unity を覚えて基本的な開発方法を知っておきたい、使えるようになっておきたい

今回、Unityのエディタ拡張は行わずツールアプリとして運用します。
Unityのエディタ拡張を使わない理由は、マップデザイナーが新マップエディタを使う際に
旧マップエディタと同じ操作感に近づけるためです。

目標

  • 旧マップエディタの機能を再現
  • パフォーマンス改善

これらの目標を達成するために苦労した部分や工夫した部分を解説していきたいと思います。

旧マップエディタの機能を再現

基本的な配置機能は問題なく実現できました。
しかし、旧マップエディタはFlash固有の機能を使って表現している部分があり、Unityのスプライト標準機能では表現できませんでした。

これを解決するためにUnityのシェーダー機能を使って表現しました。

~マスクブレンド~

~カラーブレンド~

ここまでは順調に開発できましたが、Unityで開発していくにあたってパフォーマンス周りの問題が発生しました。

パフォーマンス改善

  • マップファイルの読み込みに時間がかかる

ログレスの標準のマップは平均で10万個のチップやオブジェクトが配置されています。新マップエディタではUnityのGameObjectを10万個作成すると処理が重くなるため、カメラに映し出される箇所のGameObjectのみ生成し、それ以外はデータだけ保持するようにしました。それにより従来6分かかったマップを1分足らずで展開することが出来ました。

  • 描画速度が遅い

マップを読み込み時にチップやオブジェクト(GameObject)をインスタンス化した際にマテリアルも複製されていたためドローコールが増えていました。そのため、インスタンス化する際、1つのマテリアルでチップやオブジェクトを生成して、そのマテリアルのテクスチャを差し替えることで800ぐらいあったドローコールを20~30にまで削減しました。
さらに、カメラに映し出される部分のみチップを生成し、画面スクロールした際、そのチップのテクスチャのみ変更して最小限のGameObjectで描画できるようにしました。その結果、マップ読み込み時のチップ生成速度や描画速度が向上し、スムーズな視点移動が出来るようになりました。

結果

旧マップエディタでも上記の最適化は行われていましたが、平均で20~30FPSしか出ませんでした。しかし、新マップエディタでは常時60FPSを維持することが出来、描画速度の改善を達成できました。

~カメラに映る画面~

~カメラの範囲外のオブジェクト~

まとめ

旧マップエディタと比べてパフォーマンスが向上し、より快適にマップ制作が出来るようになったと思います。Unityで制作したため今後のメンテナンス性はAdobe AIRと比べてかなり上がり、今後の要望にも迅速に対応できるようになりました。

振り返り

Unityを使ったことによりプロトタイプを早く作成することが出来ました。
処理の最適化をする際にとても苦労しましたが、今思えばどうすれば処理を軽くできるかを試行錯誤して、とても良い経験になったと思います。
マップエディタを作るにあたり、どうすれば使いやすいのかを、もう一人の新卒メンバーの西田さんや先輩と話し合いながら取り組みました。
新マップエディタの制作で得た経験を、今後の業務に活かしていきたいと思っています。

ありがとうございました。


神﨑 拓人

Rails Developers Meetup 2017 で大阪会場の提供を行いました


こんにちは! Aiming ソフトウェアエンジニアの神﨑です。

Aiming は去る12月9日に東京で開催された Rails Developers Meetup 2017 のスタッフ協力及び、弊社エンジニア植森の登壇、そして弊社の大阪スタジオの一部を Rails Developers Meetup 2017 大阪会場 として提供させていただきました。

Rails Developers Meetup とは

Rails Developers Metetup (以下 Railsdm) は「第一線で活躍する開発者・導入企業から、RubyやRailsに関する発想・アプローチ・成功体験・失敗体験を学ぶ非営利勉強会」で、普段は月1回ほどのペースで平日の夜に行われています。

しかし今回の Railsdm は「2017年の最後を締めくくる超拡大版」として、休日の13時から18時までぶっ続けで、 Rails 界隈で有名な方々の発表を聞けるという非常に濃い時間を過ごせる貴重な機会でした。

大阪会場について

今回私は大阪会場の設営と当日のお手伝いをさせていただきました。大阪会場は東京の本会場で行われている発表の中継映像を視聴するもので、いわゆる「ライブビューイング」の形で行っています。こういった有名な方がたくさん登壇されるような勉強会が開催されるのは東京のほうが圧倒的に多いので、中継であってもそういった方々の発表を大阪に居ながらにして聞くことができるのは非常にありがたいことです。

また今回はセッション終了後に大阪会場で懇親会も行いました。東京に比べると小規模なものでしたが、その分参加者の方と密度の高いお話をすることができて非常に面白かったです。

さいごに

今回 Railsdm で発表に登壇していただいた方々、また主催者である平野さんをはじめ、東京・大阪会場のスタッフの方々には貴重なお話を聞ける機会を作っていただきありがとうございました。

Aiming では、新宿駅に近い東京本社及び、大阪駅直結の大阪スタジオの部屋を勉強会会場として積極的に提供を行っていますので、お知り合いの弊社スタッフか弊社公式サイトのお問い合わせまでお気軽に問い合わせください。


菅野 明洋

第4回 Game Gatling LTに登壇してきました!


はじめに

初めての人は初めまして、前回の記事(社内でエンジニア読書会をやってみた!)見てくれてる人こんにちは!
大阪スタジオ インフラチームの菅野明洋です。
業務では、大阪スタジオのサービスインフラを担当させていただいております。

今回は、2017年12月9日の土曜日に大阪で開催されました第4回 Game Gatling LTにて、スピーカーとして私と藤井が登壇させていただきましたので、レポートとしてまとめました。

GGLTとは

関西でゲーム開発に携わるエンジニア、デザイナー、プランナー等の人が集まり、ライトニングトークを行うイベントになります。

今回発表させていただいた内容について

今回の発表は、ミドルウェアの性能試験などの話になります。

■菅野明洋:我流ミドルウェア性能・障害試験の心得

■藤井章暢:仕事以外でプログラミングのモチベを上げる方法

私の発表ではミドルウェアの性能試験を中心に発表しました。今回は後進向けの教育を想定した作りにしております。
プロジェクトでミドルウェアを選定する場合、枯れていないミドルウェアを用いると情報が少ないケースが非常に多いと思います。その中で、少しでも多くのノウハウを積むための考えみたいな物をまとめてみました。ミドルウェアを適切に選定や使用できなかった場合は単純に開発・検証する以上のコストがかかるケースが多いため、きちんと精査していきたいと思います。

藤井の発表では、業務外でのプログラミング活動についての話を発表しました。
日々の情報収集などをどのように行うか、通勤途中の時間や休日をどう活かすかなどの実例の紹介になります。業務上で知識を得るのも重要ですが、課外活動や日々の行動改善で知見を得るのも重要かなと思います。
詳しくはスライドをご覧ください。

■発表中の様子

発表中の菅野

発表中の藤井

感想

今回は、登壇だけでは無く運営の参加にも挑戦してみました。
業務を行いながら並行で準備するのは大変でしたが、勉強会の裏側が見れて良い経験ができたと思います。

また、登壇については、やや時間配分を間違えて残りのページを話しきれなかったのが残念でした。次回はそのようなミスが無いようにしていきたいと思います。

最後に

GGLT運営の皆様、会場に来場した方々、登壇の機会を頂きありがとうございました。色々と面白い活動の話や、明日から実践してみようと思えるような話等が聞けて良かったです。
今後も皆様とこのような場で情報交換できると幸いです。


いますぐデュアルキーボードを始めるべき7つの理由と3つの注意点


こんにちは、エンジニアの佐藤です。

突然ですが、みなさんは分割キーボードをご存知でしょうか。
キーボードが真ん中で左右に分かれており、左右のそれぞれの腕に対して自然な位置・角度に設置できるキーボードのことです。

エルゴノミクスの観点からも人気の高い分割キーボードですが、高価であることや種類の少なさなどから導入ハードルは低くありません。

そんな分割キーボードの代替手段としてあるのがデュアルキーボードです。
デュアルキーボードとは、2台のキーボードを左右に並べ、左手で左のキーボード、右手で右のキーボードをタイプするスタイルのことです。

本記事では、弊社でも多くのメンバーが採用しているデュアルキーボードの魅力についてお伝えしたいと思います。

デュアルキーボードの7つの魅力

身体にやさしい

なんといっても分割キーボード自体の魅力である、自然な腕の角度でタイピングできることが最大の利点でしょう。

初期投資がいらない

必要なハードウェアはたったの2つ、キーボードと、キーボードです。

会社に勤めている方なら、デスクには会社支給のキーボードと、私物のキーボードが備わっていることでしょう。
したがって、ハードウェアには一切お金をかけずに始められるということです。


^ 筆者は会社支給の apple wireless keyboard と私物の Majestouch2 という異色の組み合わせだが、問題なく使えている

好きなキーボードでできる

分割キーボードはまだまだ多くの種類が市場に出回っているとは言い難い状況です。
しかしデュアルキーボードなら好みの配列、キースイッチで同等の恩恵を享受できます。


^ ThinkPad キーボード愛用者である山納のデスクには、当然のごとく2台の ThinkPad キーボードが配置されている

設定が簡単である

macOS をお使いの場合、必要なアプリケーションは Karabiner-Elements のみです。
(キーボードを跨いでの修飾キーとの同時押しに必要です)

Windows の場合は、なんと設定は不要です。

スペースバーが2つになる

現実的にどちらの指でも押せる唯一のキー、それがスペースバーです。
リマップによって、左右いずれかのキーボードのスペースバーには違う役割を持たせることも可能になります。

割る必要がない

信じがたいことですが、世の中には自分でキーボードを割って分割キーボードを実現する方もいらっしゃるようです。
そのような手間とリスクをかけなくとも、デュアルキーボードならすぐに分割キーボード同等の環境を手に入れられます。


^ 栗本は薄いキーボードが好きで、市場に出回っている分割キーボードでは要求を満たせないため、デュアルキーボードにしたという

いつでも元に戻せる

もしどうしても慣れないときは、片方のキーボードを脇に寄せるだけで元の環境に戻せます。

デュアルキーボードを始めるときに注意するべき3つのこと

スペースを取る

やはり通常の2倍の面積がキーボードに占領されてしまうことには気をつけないといけません。


^ 根占は片手ゲーミングキーボードとの組み合わせで、1.5倍の面積で実現している

普通のキーボードでタイピングしづらくなる

オープンで自然なスタイルでのタイピングに慣れてしまうと、どうしても普通のキーボードでのタイピングは窮屈に感じてしまいます。

ラップトップで作業することが多い人は、知らない方が幸せな世界かもしれません。

好奇の目で見られがち

市民権を得つつあるデュアルキーボードも、まだ一般的とは言えないのが実情です。
2台のキーボードを同時にタイピングしているようにも見える姿は、同僚からの好奇の眼差しに晒されるかもしれません。

(しかしあなたは、デュアルキーボードがいかに優れているかをその同僚に対して説くべきです!)

さいごに

デュアルキーボードの魅力と注意点について述べてきました。

すでにおわかりのように、導入コストが低く、メリットが大きいのがデュアルキーボードです。
この記事が快適なタイピングのためのヒントになれば、幸いです。

あわせて読みたい: あなたの知らないキーボード拡張の世界