Apache PredictionIOのインストール方法(バイナリディストリビューション版)

Apache PredictionIOのハウツーについては以前以下の記事でインストール方法からテンプレートを使ったレコメンドAPIのデプロイまでを紹介しました。

takezoe.hatenablog.com

当時のPredictionIOはインストールするにはソースからビルドするべしというかなりスパルタンなインストール方法だったのですが、最新のPredictionIO 0.12.0-incubatingではバイナリディストリビューションもリリースされるようになっていますので、こちらを使用したインストール方法について補足したいと思います。

まだ公式サイトのインストールガイドにはリンクがありませんが、以下からバイナリディストリビューションをダウンロードできます。

http://ftp.meisei-u.ac.jp/mirror/apache/dist/incubator/predictionio/0.12.0-incubating/apache-predictionio-0.12.0-incubating-bin.tar.gz

展開するとPredictionIO-0.12.0-incubatingというディレクトリが出てきます。

$ tar xvzf apache-predictionio-0.12.0-incubating-bin.tar.gz

展開後のディレクトリにSparkをインストールします。PredictionIOはSpark 1.6、2.0、2.1に対応していますが、バイナリディストリビューションはSpark 2.1向けにビルドされています。

$ wget https://archive.apache.org/dist/spark/spark-2.1.1/spark-2.1.1-bin-hadoop2.6.tgz
$ mkdir PredictionIO-0.12.0-incubating/vendors
$ tar zxvfC spark-2.1.1-bin-hadoop2.6.tgz PredictionIO-0.12.0-incubating/vendors

ストレージにPostgreSQLを使う場合はPostgreSQLJDBCドライバも必要です。

$ cd PredictionIO-0.12.0-incubating/lib
$ wget https://jdbc.postgresql.org/download/postgresql-42.0.0.jar

以上でインストール完了です。

バイナリディストリビューションといってもSparkやJDBCドライバを追加インストールする必要があったり、テンプレートのコンパイルにsbtをインストールしておく必要があったりするのは相変わらずですが、ソースからビルドする必要がないので少しだけ楽になっているんじゃないかと思いますw

なお、公式のものではないのですが、コミュニティで作られているDockerイメージもいくつかあるので、こちらを利用することもできます。

ロープロファイルなメカニカルキーボードを買ってみた

少し前にネット上で話題になっていたこのキーボードが気になっていたものの青軸ということで躊躇していたのですが、Amazonのレビューを見るとなかなか良さそうだし値段もそこまで高くないので試しに買ってみました。

ロープロファイル(低背)のスイッチを使っておりHHKBやこれまでのメカニカルキーボードと比べるとキーストロークがかなり浅くなっています。ノートPCなどでパンタグラフのキーボードに慣れた人でもこれなら快適にタイプできるのではないかと思います。キーストロークの浅さに加えて筐体も薄いので手首への負担も軽減できそうです。

配列はまとも(US配列のみですが)でファンクションキーやカーソルキーなどもついてるので、HHKBなどのコンパクト指向の特殊配列なキーボードと比べると若干場所は取りますが、普通に使えます。筐体やキートップにも安っぽさはありませんし、青色のバックライトも綺麗です。

一方で、やはり青軸なのでカチャカチャという音は結構しますし、青軸独特のクリック感が嫌だという人も多そうです(自分もあまり好きではありません)。ロープロファイルで茶軸や赤軸のスイッチを使った製品が出てくるといいなと思います。

ちなみに今まではThinkPadキーボードの旧モデルを使っていたのですが、MacBookをHigh Sierraにアップデートしたところセンターボタン+トラックポイントでのスクロールができなくなってしまったので、これを機にトラックポイントから卒業できないだろうかというのもこのキーボードを買った動機ですw そのためにポインティングデバイスとしてMagic Trackpad2もあわせて導入しました。

Apple Magic Trackpad 2 MJ2R2J/A

Apple Magic Trackpad 2 MJ2R2J/A

以前ロジクールの類似品を使っていたのですが、やはり操作性に雲泥の差がありますね…。先代のMagic Trackpadと比べてもめっちゃ操作しやすくなりました。

takezoe.hatenablog.com

さて、無事トラックポイントから卒業できるでしょうか…。

GitHubのスター数で見るScalaのDBアクセスライブラリ

吉田さんがこういう記事を書いていたので真似してデータベースアクセスライブラリ版を書いてみました。

xuwei-k.hatenablog.com

2009年からのグラフですが、トップ5のスター数の推移はこんな感じ。

f:id:takezoe:20171119132632p:plain

slick/slick ★1930

github.com

相変わらずの一番人気。この1年では300くらいスターが増えている。DBIOで強制モナモナやjoinしたつもりなのに何故かサブクエリになるSQLなど問題が多いのに何故こんなに人気があるのか考えさせられるものがある。クエリビルダは非常に柔軟かつ強力だけど、やはり出てくるSQLが想像もつかないのは厳しい。joinを多用するアプリケーションでは(MySQLの場合は特に)使わないほうがよいと思うし、シンプルなCRUDしかしないんだったらこんなに複雑なクエリビルダ要らないのではという気がする。

また、最近はそうでもないけどSQLだけでなく汎用的なクエリビルダを目指しておりSQL固有の機能を頑なに取り入れない方針だったのも実用性を考えるとどうなのかと思わざるを得ない。開発は活発だけどクエリビルダで組み立てたASTからSQLを生成するクエリコンパイラが死ぬほど複雑で常人はおいそれと手を出すことができない。

getquill/quill ★1077

github.com

Twitter社のエンジニアが開発しているScalaデータベースアクセスライブラリ業界の新鋭。作者の方はマーケティングにも熱心で、この1年で約900スターが増えており一気にNo.2の座に。マクロでコンパイル時にSQLを生成するというコンセプト。ちょっと試してみたところではjoinはちゃんとjoinとしてSQLが生成されており感動した。IOモナドもあるけどオプションになっているところは良心的。最近はSparkSQL対応など色気を出している。

日本だとFOLIOさんが使っているみたいで社員の方(?)がコントリビュートもしている。でもScala関西のFOLIOさんのセッションでquill微妙と言ってたのでどのへんが微妙なのか聞いてみたい。コードはちょっとしか読んでないのでよくわからないけどマクロで実装されているので拡張しづらそうだなという印象があるのと、将来的に新しいマクロシステムにちゃんと移行されるのだろうかという不安がある。

tpolecat/doobie ★973

github.com

これも新鋭でSQLを書くタイプ。1年前からは+600スター。タイプセーフじゃないけどコンパイル時やテスト時にチェックすればいいじゃんというコンセプト(らしい)。SQLを直接書くので複雑なクエリにも対応できるという安心感があるものの、動的に変わるようなSQLは書きにくい(らしい)。自分では使ったことないのでよくわからない。

IOモナド方式でもれなくScalazまたはcatsがついてくるのがちょっと微妙かもしれない。

scalikejdbc/scalikejdbc ★826

github.com

ここまでがメジャーなデータベースアクセスフレームワークの現役世代と言っていいと思う。この1年で+100スターほど。これまでと同じペースで伸びているけどquillとdoobieの伸びが大きすぎて昨年半ばの段階で順位が逆転してしまっている。

実用的なバランスがあり使いやすい。SQLを書く方式とタイプセーフなDSLの二種類の使い方があり、他のフレームワークだと大体DSLがメインで、SQL方式はDSLではできないことがある場合の回避策みたいな位置付けになっていることが多いけど(doobieは除く)、scalikejdbcは元々SQLを書く方式で後からDSLが追加されたという経緯もあり、SQLを書く方式も便利。どちらを使うべきか悩むかもしれない。

squeryl/squeryl ★493

github.com

1年で+40スターほど。最近は吉田さんがメンテを継続されている。タイプセーフなDSLタイプで結構使いやすいと思うけど内部でランタイムリフレクションが使われているのがScala界隈的には微妙なのかもしれない。今から敢えて使うかというと微妙だけど、ケースクラス作るだけでDSLが使えるのは便利(ここにリフレクションが使われている)。quillはこれをマクロで実現しているけど、slickやscalikejdbcはケースクラスと別にテーブル定義的なものが必要で、自動生成ツールがあるとはいえそもそも作らなくていいのはなんだかんだ楽。

この次にsquerylをベースにした(中身は結構変えたという話だけど)scala-activerecordが310スターで続いており、フォークして分散してしまうのは開発リソース的にもマーケティング的にももったいないなぁと思うなど。

まとめ

スター数ではslickがダントツだけど、quillとdoobieも勢いがある。でもこの3つはどれも癖が強く、汎用的に使えるとは言い難い感じ。どれを使ったらいいか判断できない場合は大人しくscalikejdbcを使っておくのが間違いなさそう。

Webフレームワークとのスターの数を比較すると、RDBScala界隈ではあまり注目を集めるトピックではないのかもしれないという気もする。でも、なんだかんだでGitHubのスターの数は外から見たときの印象や作者のモチベーションにもなるので、気に入っているライブラリがあればスターを押しておくといいと思います。

ScalaのシンプルなテスティングライブラリMinitestを使ってみる

Twitterで以下の記事を見てMonixの開発用に作られたというMinitestというテスティングライブラリの存在を知りました。

alexn.org

GitHubリポジトリはこちらです。

github.com

ScalaのテスティングライブラリというとScalaTestとSpecs2が双璧ですが、Minitestはこれらと比べると非常にシンプルなライブラリで、ScalaTestのFunSuiteからの移行がしやすいようデザインされているようです。使い方は上記の記事とGitHubのREADMEを見れば大体わかると思います。

試しに簡単なテストをMinitestで書いてみたのですが、ScalaTestのFunSuiteからであれば概ね以下のような作業で移行できそうです(FunSuiteとの互換性重視ならassertThrowsを敢えて変えなくてもよいのではという気もしますがなんで変えているのかは謎)。

  • テストケースをclassからobjectに変更し、親クラスをFunSuiteからSimpleTestSuiteに変更する
  • ScalaTestが提供する===などの比較演算子を使っている場合、通常の比較演算子に変更する
  • assertThrowsinterceptなど、一部の非互換なAPIを書き換える

assert()の第二引数にはエラー時のメッセージを指定できますが、値の比較であればassert()ではなくassertEquals()を使うと失敗したときに以下のようなメッセージを出力してくれるようなのでこちらを使ったほうがよさそうです。

- CRUD operation *** FAILED ***
  received UsersRow(1,takezoe,None) != expected UsersRow(1,takezoen,None) (SlickBlockingAPISpec.scala:33)
    minitest.api.Asserts.assertEquals(Asserts.scala:68)
    minitest.api.Asserts.assertEquals$(Asserts.scala:62)
    com.github.takezoe.slick.blocking.SlickBlockingAPISpec$.assertEquals(SlickBlockingAPISpec.scala:9)
    com.github.takezoe.slick.blocking.SlickBlockingAPISpec$.$anonfun$new$2(SlickBlockingAPISpec.scala:33)
    ...

APIはシンプルですが、Futureのアサートや、オプションでScalaCheckとの連携など、必要な機能は一通り揃っている感じです。また、Scala.jsでも使用することができます。

実際自分もScalaでテストを書くときはScalaTestでFunSuiteを使ってassert()しかしないので、Minitestのデザインはピッタリな感じがします。Specs2などはScalaの記述能力を駆使して様々な変態的な記述が可能ですが、正直機能が多すぎて覚えきれないのでこのくらいでいいんじゃないかと思いますが、assertEquals()での比較に失敗した場合のエラーメッセージなどについてはもうちょっと頑張って欲しい感があります。

IntelliJ IDEAハンズオン――基本操作からプロジェクト管理までマスター

技術評論社さんから今井さんと山本ユースケさんのIntelliJ本をお送りいただきました。ありがとうございます!ScalaIOのためしばらく留守にしていたので受け取りが遅くなってしまったのですが、この週末にざっと目を通してみました。

ページ数は200ページちょっとでスクリーンショットが多くなりがちなIDEの本としてはさほど多くないのですが、IntelliJは機能の豊富さの割に覚えることが少なくて、基本的な部分だけ押さえておけばいろんな機能を使えるという感じがあります。この本の構成や分量にもそれが現れているのではないかと思います。

全体的には入門者向けの本ではあると思うのですが、普段IntelliJを使っている自分でも知らない機能や設定、ショートカットがちょこちょこあったりして眺めているだけでも結構楽しいです。データベース機能やChrononを使用したデバッグなど、Ultimateの販促コンテンツ(?)もあります。

特に序盤の補完機能については自分もあまり使いこなせていないなぁと思いましたが、IntelliJではCTRL+SPACE(コード補完)とSHIFT×2(なんでも検索)、Command+F12(クイックアウトライン)、ALT+ENTER(クイックフィックス)くらいを覚えておけばそれなりに便利なので、細かい便利機能をなかなか覚えられないんですよねw この本でIntelliJをさらに使いこなしていきたいと思います。

Scalatra 2.6.0をリリースしました

Scala用のSinatraライクなWebフレームワークScalatraの最新バージョン2.6.0をリリースしました。

github.com

今回は新しいバリデーションフレームワークとしてscalatra-formsが追加されました。これは元々GitBucketで使用していたものをScalatra本体の1モジュールとして取り込んだものです。PlayのFormのような感じでリクエストパラメータのバリデーションとScalaオブジェクトへのマッピングを行うことができます。

また、今後のメンテナンスコスト削減のために2.5.x以前のバージョンで非推奨になっていた機能を削除するとともに、あまり使われていない機能やメンテナンスが難しい機能などを非推奨にしています。これらの機能は2.7.0で廃止される予定です。

詳細な変更内容は以下のアナウンスを参照していただければと思います。 http://scalatra.org/2017/11/11/2017-11-11-scalatra-2-6-0-released.html

今回は@magnolia-kさんにコミッタになっていただいてから初めてのリリースだったのですが、ドキュメントやサンプル、sbtプラグインの修正など、自分が見落としていた部分をかなりカバーしていただきました。また、@xuwei-kさんにも多くのプルリクエストをいただきました。ありがとうございました。

次の2.7.0では非推奨機能の廃止に加えてSwagger 3.0のサポートなどを予定しています。

次期Scalatraのバックエンドとしてのhttp4s

Scalatraの次期バックエンドをhttp4sにしようという計画は数年前からありつつ中々進んでいなかったのですが(ブランチに途中まで試みたと思われる残骸があるのですが、そもそもScalatraの開発自体が停滞しており絶賛放置されていました)、そろそろやってみようかと思いhttp4sを触り始めています。

github.com

http4sとは?

http4sはいわゆるノンブロッキングなHTTPツールキットで、今だとAkka HTTPが競合になるかと思います。http4sはAkka HTTP同様ルーティング用のDSLも備えていて単体でシンプルなWebフレームワークとして使用することもできます。

http4sの特徴の1つとして、http4s用に開発したアプリケーション(http4sではサービスと呼びます)を、サーブレットとして動かすためのアダプタが用意されているという点があります。現在ScalatraはサーブレットベースのWebフレームワークであることで、

といったメリットがあります。これらは既存のJavaベースのシステムに部分的にScalaを導入して行く際に便利なのですが、バックエンドをhttp4sに移行することでサーブレットを使うか、ハイパフォーマンスなblaze(fs2)を使うかを選択することができるようになり、Scalatraの活用の幅がより広がるのではないかと思います。

http4sを動かしてみる

http4sのサービスはこんな感じで実装します(最新のマイルストーンビルドである0.18.0-M5を使用しています)。

package com.example.http4squickstart

import cats.effect.IO
import io.circe._
import org.http4s._
import org.http4s.circe._
import org.http4s.dsl.Http4sDsl

object HelloWorldService extends Http4sDsl[IO] {
  val service = HttpService[IO] {
    case GET -> Root / "hello" / name =>
    Ok(Json.obj("message" -> Json.fromString(s"Hello, ${name}")))
  }
}

blazeで動かす場合はこんな感じ。

package com.example.http4squickstart

import cats.effect.IO
import org.http4s.dsl.Http4sDsl
import org.http4s.server.blaze.BlazeBuilder
import org.http4s.util.StreamApp

object BlazeServer extends StreamApp[IO] with Http4sDsl[IO] {
  def stream(args: List[String], requestShutdown: IO[Unit]) =
    BlazeBuilder[IO]
      .bindHttp(8080, "0.0.0.0")
      .mountService(HelloWorldService.service, "/")
      .serve
}

サーブレットで動かす場合はこんな感じのリスナーを作っておけばOKです。これをxsbt-web-pluginで実行したり、warにしてサーブレットコンテナにデプロイする感じかと思います。

package com.example.http4squickstart

import javax.servlet.annotation.WebListener
import javax.servlet.{ServletContextEvent, ServletContextListener}
import org.http4s.servlet.syntax.ServletContextSyntax

@WebListener
class Bootstrap extends ServletContextListener with ServletContextSyntax {
  override def contextInitialized(sce: ServletContextEvent) = {
    val context = sce.getServletContext
    context.mountService("helloService", HelloWorldService.service)
  }
  override def contextDestroyed(sce: ServletContextEvent) = ()
}

まだ細かいところまで見れていませんが、同じサービスがバックエンドを変えても動作することが確認できました。

http4sは国内ではだいぶマイナー感がありますが、Typelevelプロジェクトの1つ(まだIncubatorですが)ということもあり、海外ではそこそこ使われている気配があります。今のところ開発も活発ですが、Scalatraのバックエンドに採用したものの、肝心のhttp4sの開発が止まってしまうと厳しいので、そのあたりの様子も見つつ本当に移行できるかどうかを検討していきたいと思います。