hack/hhvmの最新事情とメイン言語に採用した理由
TRANSCRIPT
Hack/HHVMの最新事情と
メイン言語に採用した理由
株式会社スカイディスク CTO
大谷祐司
2017/6/10 @ PHPカンファンレンス福岡
自己紹介
・株式会社スカイディスク CTO
・山口県下関出身
・今年から福岡に移住してIoTやってます
・技術が大好きなエンジニア
マンガになりました。 雑誌に寄稿しました。
検索:大人になったらエンジニア大谷
スカイディスクについて
IoTサービスを展開している福岡のスタートアップ。
2013年の創業で社員は約20名です。
ハードウェア、Webサービス、機械学習など、
IoTに必要なことを幅広くやっている会社です。
センサーデバイス
ゲートウェイ DB
IoTサービスのプラットフォーム
NW/APP
IoTダッシュボード
データ分析基盤
今年「Scalable」「適材適所」をキーワードに、
全面的に技術の見直しを行いました。
スカイディスクの開発言語
昨年まではPythonのみで開発していました。
今年から、用途に応じて3つの言語を使います。
分析や機械学習
・豊富な分析系ライブラリ。
・AIフレームワークのデファクトスタンダード。
Webサービス開発
・PHPの拡張言語で、高いパフォーマンス。
・福岡にPHP人口が多い。
・日本語の情報が多く、スムーズに開発できる。
バッチ、APIのバックエンド
・非常に高いパフォーマンス。
・カチッとした言語仕様。
・並列処理が簡単に行える。
おまけ:データベース
質問①
Hack/HHVMを使ったことがあるかた
質問②
PHP5系→7系に移行検討中のかた
Hack/HHVMもぜひご検討ください。
・PHP5系/7系に設定の変更が可能。(ini ”hhvm.php7.all = 1”)
・静的解析ツール(hh_client)でソースチェック。
・ライブラリはC++で記述→hphpize
HHVMのPHP7関連設定
Hack/HHVMについて
基本的な解説
・Facebookの作ったPHP実行環境。
・PHPをバイトコードに変換して高速化。
・JavaでいうJVMのような役割。
HHVMとは
・Facebookによって開発された言語
・PHPと互換性を持っている
・HHVMという仮想マシン上で動作する
・高いパフォーマンスと独自の言語仕様
Hackとは
・バグのないコードを迅速に書けるようになる
・エンジニアがコーディング体験を楽しめる
・「高速な動作」「大規模開発向きの仕様」
Hackの思想
Hackの特徴
コーディング体験を楽しめる!!
ソース初めの宣言を「<?php」→「<?hh」と変更
→Hackのソースとして認識されます。
(PHPとHackからお互いに呼び出し可能です)
HHVMにおけるHack or PHPの指定
HHVMはC++で書かれている(PHPはC)
→簡潔に実装でき、機能の強化や安定性を実現。
PHPとの大きな違い
Hack言語の採用
スカイディスクでの利用状況
・IoTダッシュボードで採用
・フレームワークはFuelPHP
・テンプレートエンジンは未使用
(xhpを一部導入)
・エディタはNuclideを推奨
・コードフォーマットはPHP_CodeSnifferを利用
→hhvmでキックすればそのまま利用可能
(PSR-2を採用)
・CentOS7をDocker(開発) / AWS(本番) で採用。
スカイディスクでの利用状況
活用しているライブラリ
・MySQL / Redisは標準で利用可能。
・MongoDBはComposerを利用。
→HHVMのライブラリが公開されている。
・LevelDBのアクセスはGoを呼び出す。
(HNIで実装予定)
PHP7がリリースされて、Hackの特徴が
いくつも盛り込まれています。
大幅な高速化!!
Hackの特徴もたくさん実装されています。
・スカラ型のタイプヒンティング
・返り値のタイプヒンティング
・配列で使うメモリが少ない
・AST(抽象構文木)を使ったコンパイル
しかし、PHP7が出たから
Hack/HHVMは不要というのは誤解。
それぞれに特徴があります。
PHP7の採用も検討しましたが、
・拡大するサービスをかっちり作る
・パフォーマンスの高いサービスを素早く作る
という観点から、Hack/HHVMを選びました。
ポイント①
強力なタイプヒンティング
タイプヒンティングとは?
functionの引数/戻り値がどの種別かを指定できます。
Class Sample {
public static function sampleFunc(int $a):
string{
return "OK";
}
}
//OK
Sample::sampleFunc (1);
//Fatal Error
Sample::sampleFunc ("a");
タイプヒンティングの仕様は、
HackとPHP7で大きく異なります。
タイプヒンティング/PHP7
2つのタイプが存在。
・弱い型指定→自動的な型キャスト。
・強い型指定→型まで厳密に判別。
<?php
Class Sample {
public static function sampleFunc(int $a): string{
return "OK";
}
}
//どちらのタイプでもOK
Sample::sampleFunc(1);
//「弱い型指定」のみOK
Sample::sampleFunc("1");
タイプヒンティング/PHP7
・デフォルトは「弱い型指定」
・「強い型指定」には、ファイルの最初で宣言が必要。
・ファイル単位でのみ「強い型指定」が設定可能。
→iniファイル等での指定は不可能。
<?php
//ファイルに「強い型指定」が有効になる。
declare(strict_types=1);
タイプヒンティング/Hack
・PHP7の「強い型指定」のみが存在。
・mixedを使うことで、nullを含むあらゆる型を許容できる。
<?hh
Class Sample {
public static function sampleFunc(mixed $a): string{
return "OK";
}
}
//OK
Sample::sampleFunc(null);
Sample::sampleFunc(1);
Sample::sampleFunc(”a");
タイプヒンティング/Hack
・配列のKey, Valueに型指定できる。
<?hh
Class Sample {
public static function sampleFunc(array<int, string> $a):
string{
return "OK";
}
}
//OK
Sample::sampleFunc(array(1 => "a", 2 => "b"));
Sample::sampleFunc(array(1 => 1, 2 => null));
タイプヒンティング
「強い型指定」が基本。
型をきちんと意識した、
大規模サービス向けの仕様。
「弱い型指定」が基本。
型を意識せず実装できる、
開発速度を重視の仕様。
ポイント②
専用のコレクション
PHPの配列とは
・配列と連想配列を同じものとして扱える。
・配列に入れる型は何でもOK。
・キーは整数または文字列。
・何をキーにしても、値は入れた順番に取り出される。
<?php
//実行するとabと表示される。$arr = array(1 => ”a", 0 => ”b");
foreach($arr as $value ) {
print($value);
}
コレクション/Hack
・独自のコレクションが利用可能(Vector/Map/Set/Pair)
→宣言時に型を指定できる
<?hh
$a = new Map<string, string>;
//OK
$a->set("key1", "value1");
//OK
$a->set("key2", 2);
//OK
$a->set(3, array());
49
Map
キーと値をセットで格納。
B
A
D
EC
50
Vector
順番に値を保持する純粋な配列。
21 4 53
51
Set
値の集合で、中身の重複が認められない。
BA D EC
52
Pair
2つの値をセットにして保持。
配列/コレクション
・4つの独自コレクション。
・コレクションに型を指定可能。
配列の用途を意識して、
かっちり利用できる。
・”何でも入る”配列のみ利用可能。
・配列の種類、型は意識しない。
連想配列に何でも突っ込める、
開発速度を重視の仕様。
ポイント③
コードの効率化に役立つ
独自の言語仕様
独自の言語仕様
・Lambdas (ラムダ式)
・Generics (ジェネリクス)
・Enum (列挙型)
・Tuples (複数の要素を持つ配列)
・Shapes (複数の要素を持つマップ)
Enum(値の列挙)
<?hh
enum Size: int {
SMALL = 0;
MEDIUM = 1;
LARGE = 2;
X_LARGE = 3;
}
型を指定した値を宣言できる
Tuples(複数型の配列)
<?hh
list($a, $b) = testFunc();
public function testFunc() : (string, int) {
return tuple(“OK”, 1);
}
functionから複数の値を戻せる
and, or, endforeach, goto, globals, break N
などを非推奨にしています。
PHPソース中にHTMLを書くのもNGです。
(ファイルが<?hhから始まらなければエラー)
非推奨の構文
ポイント④
並列実行のサポート
並列実行
Async/Awaitという独自の関数を利用して、
並列処理を実行することができます。
マルチスレッドではなく非同期で処理を実行。
活用することで処理を高速化できます。
並列実行
ポイント⑤
静的解析ツール
静的解析ツール
hh_clientにより、コードの静的解析が可能。
構文エラーや型の不整合など実行前に潰せます。
厳密な型制約を持つHackで利用することで、
バグの少ないコードを実現できます。
実行前に構文チェックを行えます。
・コンパイルエラー
・引数/戻り値の型チェック
・非推奨の構文
・型の不適切な変換
etc
静的解析ツール/Hack(HHVM)
ポイント⑥
大規模サービスでの採用実績
Wikipediaを編集する際の速度が2倍に!!
https://www.box.com/blog/going-forward-faster-hhvm/
Webレスポンスを1/3に短縮!!
https://slack.engineering/taking-php-seriously-cf7a60065329
パフォーマンス向上のためPHPをHHVMに移行
これらのポイントに魅力を感じ、
HHVM/Hackを採用することにしました。
素敵なHack/HHVMですが、
覚悟が必要な点もあります
リリースサイクルがとても早い
Hack(HHVM)
・8週ごとにリリース。
・3バージョン毎のLTSを1年間のサポート。
PHP
・リリースサイクル1年
・ライフサイクル3年(バグ2年/セキュリティ1年)
LTSを約1年間サポート。
サポートについて/Hack
ググラビリティが非常に低い。
問題点
フレームワーク対応状況
・以前はフレームワークの対応状況を公開。
・現在は自分たちでテストの実行が必要。
最近の動向
Hack/HHVMの進化は早く、
最近もたくさんの動きがありました。
Nuclideリリース(2015/03)
Nuclideについて
・Facebook製のAtomプラグイン
・Hack / js / Reactなどに対応。
・サーバのソースをリモート編集できる。
NuclideのHackサポート
・コードの静的チェック
・オートコンプリート
・定義へのジャンプ
・コードフォーマット
HHVMのPHP7対応(2015年4月)
PHP7に対応した設定項目がver3.11より追加される
ソースコードフォーマット(2017/04)
hackfmtでソースコードをフォーマットできる。
ただしPSR2などは指定できず、おそらく
Facebook内部で利用されている規約のみ利用可能。
Windowsサポート終了
ユーザは少かったのかもしれませんが、
サポート終了。。
Arm hardware対応
2017年3月に、Armハードウェアの対応をしていくこ
とがアナウンスされる。
まとめ
このようにHack/HHVMの動きは非常に早く、
継続的に進化し続けています。
今後の技術選定において、
Hack/HHVMを選択肢に入れてみては
いかがでしょうか。
募集してます
Webエンジニアを募集しています。
最新技術に積極的に挑戦できます!
興味あるかたは気軽にお声がけください。
ご静聴ありがとうございました。