Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

"Reactive Streams" の実装はどうなっているの?

こんにちは。@です。
夏の日差しが日に日に増し、セミも盛んに鳴きはじめましたが、皆さん夏バテなどされていませんか?

さて、今回の内容は、非同期ストリーム処理界隈で注目の「Reactive Streams」です。

先月のJJUGナイトセミナーでも取り上げられており、私は残念ながら参加はできなかったのですが
後から資料を読んで勉強させていただきました。jjug.doorkeeper.jp

1. Reactive Streamsとは何か?

Reactive Streamsとは、JVM 上でのノンブロッキングなバックプレッシャーを持つ非同期ストリーム処理の標準」で、
様々な非同期ストリーム処理のインタフェースを共通化して標準的に扱えるようにしようというものです。

分散環境での非同期ストリーム処理においては、
「上流のコンポーネント群の方が処理能力が高く、下流のコンポーネント群が処理しきれずに溢れる」というのは
既存の非同期ストリーム処理でかなり頻発する事象でした。
こうなるとネットワーク/システム全体に影響して、システム停止に繋がってしまいます。
私もStormを触っている中で、この問題にかなり悩まされました。


このような中でReactive Streamsが注目され、標準化につながったのだと思います。

なお、Reactive Streamsについては下記の解説記事がとても詳しいです。

okapies.hateblo.jp

okapies.hateblo.jp

takezoe.hatenablog.com

さて今回は、実際にReactive Streamsを実現しているプロダクトを動かしてみたいと思います。

2. 実際にReactive Streamsを実現しているプロダクトは?

実際にReactive Streamsを実現している代表的なプロダクトには下記があります。

というわけで? これらを実際に動かしてみましょう。
今回はAkka Streamsを用いて、RabbitMQをバックエンドとするScalaConsultants/reactive-rabbit · GitHubを用いて試してみます。

3. まずは動かしてみると・・?

というわけで、RabbitMQをローカルマシンにインストールし、reactive-rabbitを動かしてみたのですが、
RabbitMQに対しては何のメッセージの送受信も行われず、以下のコードで「invoices」というキューを作成して
メッセージを投入してみたのですが、やはり何もおきませんでした・・・

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
import io.scalac.amqp.Connection


// streaming invoices to Accounting Department
val connection = Connection()
val queue = connection.consume(queue = "invoices")
val exchange = connection.publish(exchange = "accounting_department",
  routingKey = "invoices")

implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()

Source(queue).map(_.message).to(Sink(exchange)).run()

中身を追っていきたい気持ちもありますが、
今回の記事の目的はまず動かすことなので、まずは動かすことを優先します(^^;

4. reactive-rabbitを利用するプロダクトを探してみる

というわけで、更に「reactive-rabbit」を使っているプロダクトを探してみました。
そうすると、Akka-Streamでreactive-rabbitを使っているサンプルがあったため、そちらを見てみました。
Processing RabbitMQ messages using Akka Streams - Typesafe Activator | @typesafe | Typesafe

ただ、こちらはこちらでReactive Streams 0.4.0準拠で、
APIが更新されたReactive Streams 1.0.0では動作しないという状況!

あちこち探してみたのですが、良いサンプルが見つからなかったため、
rabbitmq-akka-streamをReactive Streams 1.0.0準拠するバージョンに更新してみました。

ソースは下記になります。
kimutansk/reactive-streams-example · GitHub

で、実行してみると下記の結果になりました。

[DEBUG] [07/14/2015 05:07:00.259] [main] [EventStream(akka://rabbit-akka-stream)] logger log1-Logging$DefaultLogger started
[DEBUG] [07/14/2015 05:07:00.261] [main] [EventStream(akka://rabbit-akka-stream)] Default Loggers started
05:07:00.686 [rabbit-akka-stream-akka.actor.default-dispatcher-5] INFO  c.g.kimutansk.reactive.ConsumerApp$ - Exchanges, queues and bindings declared successfully.
05:07:00.833 [rabbit-akka-stream-akka.actor.default-dispatcher-5] INFO  c.g.kimutansk.reactive.ConsumerApp$ - Starting the flow
05:07:00.945 [rabbit-akka-stream-akka.actor.default-dispatcher-5] INFO  c.g.kimutansk.reactive.ConsumerApp$ - Starting the trial run
05:07:01.018 [rabbit-akka-stream-akka.actor.default-dispatcher-5] DEBUG c.g.k.reactive.DomainService$ - message: 'message 1'  will be held for 2558 ms
05:07:03.580 [rabbit-akka-stream-akka.actor.default-dispatcher-4] DEBUG c.g.k.reactive.DomainService$ - message: 'message 2'  will be held for 1873 ms
05:07:03.585 [rabbit-akka-stream-akka.actor.default-dispatcher-3] DEBUG c.g.k.reactive.DomainService$ - message classified as 'safe'
05:07:03.599 [rabbit-akka-stream-akka.actor.default-dispatcher-7] INFO  c.g.kimutansk.reactive.ConsumerApp$ - 'message 1 [message processed]' delivered to censorship.ok.queue
05:07:05.454 [rabbit-akka-stream-akka.actor.default-dispatcher-6] DEBUG c.g.k.reactive.DomainService$ - message classified as 'safe'
05:07:05.454 [rabbit-akka-stream-akka.actor.default-dispatcher-4] DEBUG c.g.k.reactive.DomainService$ - message: 'message 3'  will be held for 1915 ms
05:07:05.458 [rabbit-akka-stream-akka.actor.default-dispatcher-7] INFO  c.g.kimutansk.reactive.ConsumerApp$ - 'message 2 [message processed]' delivered to censorship.ok.queue
05:07:07.371 [rabbit-akka-stream-akka.actor.default-dispatcher-4] DEBUG c.g.k.reactive.DomainService$ - message classified as 'safe'
05:07:07.372 [rabbit-akka-stream-akka.actor.default-dispatcher-6] DEBUG c.g.k.reactive.DomainService$ - message: 'message 4'  will be held for 1364 ms
05:07:07.374 [rabbit-akka-stream-akka.actor.default-dispatcher-9] INFO  c.g.kimutansk.reactive.ConsumerApp$ - 'message 3 [message processed]' delivered to censorship.ok.queue
05:07:08.737 [rabbit-akka-stream-akka.actor.default-dispatcher-6] DEBUG c.g.k.reactive.DomainService$ - message: 'message 5'  will be held for 1125 ms
05:07:08.737 [rabbit-akka-stream-akka.actor.default-dispatcher-9] DEBUG c.g.k.reactive.DomainService$ - message classified as 'safe'
05:07:08.740 [rabbit-akka-stream-akka.actor.default-dispatcher-9] INFO  c.g.kimutansk.reactive.ConsumerApp$ - 'message 4 [message processed]' delivered to censorship.ok.queue
05:07:09.862 [rabbit-akka-stream-akka.actor.default-dispatcher-6] DEBUG c.g.k.reactive.DomainService$ - message classified as 'safe'
05:07:09.865 [rabbit-akka-stream-akka.actor.default-dispatcher-5] INFO  c.g.kimutansk.reactive.ConsumerApp$ - 'message 5 [message processed]' delivered to censorship.ok.queue
05:07:09.865 [rabbit-akka-stream-akka.actor.default-dispatcher-5] INFO  c.g.kimutansk.reactive.ConsumerApp$ - Trial run finished. You can now go to http://localhost:15672/ and try publishing messages manually.

どうやら、RabbitMQに対してメッセージの投入と取得、処理が行われたようです。
実際にRabbitMQの管理画面からもメッセージが送受信された旨が表示され、キューが作られていることがわかります。

f:id:acro-engineer:20150623064313j:plain
f:id:acro-engineer:20150623064515j:plain

また、RabbitMQの「censorship.inbound.queue」というキューにメッセージを投入してみると、
下記のように処理した旨のメッセージも表示されました。

05:07:53.525 [rabbit-akka-stream-akka.actor.default-dispatcher-7] DEBUG c.g.k.reactive.DomainService$ - message: 'Test Input Manual Message'  will be held for 1380 ms
05:07:54.906 [rabbit-akka-stream-akka.actor.default-dispatcher-10] DEBUG c.g.k.reactive.DomainService$ - message classified as 'safe'

というわけで、とりあえずサンプルを動かしてみることは出来ました。
ですが、これだけだと中身でどんな事が行われているかは分かりませんし、
バックプレッシャーを体感することもできません。

なので、次回以降は実際に中身を追っていこうと思います。

Acroquest Technologyでは、キャリア採用を行っています。


  • 日頃勉強している成果を、Hadoop、Storm、NoSQL、HTML5/CSS3/JavaScriptといった最新の技術を使ったプロジェクトで発揮したい。
  • 社会貢献性の高いプロジェクトに提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や対外的な勉強会の開催を通した技術の発信や、社内勉強会での技術情報共有により、技術的に成長したい。
  • OSSの開発に携わりたい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
 キャリア採用ページ

MQTT Broker比較~性能比較編

こんにちは、ツカノ(@)です。

MQTT Broker 比較の第二弾です。

前回は、機能の比較を行いました。


実際のシステムへの適応を考えると、性能は特に気になるところ。
ということで、今回は性能比較を行ってみました。
ベンチマークは環境や測定方法、バージョンによっても大きく異なりますので、
あくまで一例として参考にしてもらえればと思います。

f:id:acro-engineer:20150618200645p:plain

ベンチマークに利用したプログラムは、Goで開発された以下の MQTT-Bench を利用しています。


ベンチマークの条件は以下の通りです。

  • 構成、メッセージ長
    • MQTT Broker に対して、500connections で同時処理
    • 1つのメッセージ長は 1024byte
  • マシンスペック
    • OS: CentOS 6.5 (64bit)
    • CPU: Intel(R) Core(TM) i7-2700K CPU @ 3.50GHz (4コア HT有効)
    • メモリ: 32GB
    • NIC: 1Gbps
  • MQTT Broker のバージョン
    • Mosquitto(1.4.2)
    • Apollo(1.7.1)
    • RabbitMQ(3.5.3)
    • Mosca(0.29.0)
    • eMQTTD(0.8.6-beta) クラスタに対応しているが、1プロセスで処理
    • VerneMQ(0.9.4) クラスタに対応しているが、1プロセスで処理

計測内容

計測は、以下のパターンで行っています。

  1. Publish(Retainなし)
    • MQTT Broker に対して、クライアントからメッセージを送信する処理になります。Retainなしの場合は、最後にPublishされたメッセージをBrokerが保持しません。
  2. Publish(Retainあり)
    • MQTT Broker に対して、クライアントからメッセージを送信する処理になります。Retainありの場合は、最後にPublishされたメッセージをBrokerが保持します。
  3. Subscribe
    • MQTT Broker から、クライアントがメッセージを受信する処理になります。MQTTの特性として、接続されているときのみメッセージを受信するため、Subscribeしている間、それとは別プロセスでPublish(Retainなし)の処理を行っています。

計測結果は、以下のグラフになりますが、グラフの縦軸は、「処理したメッセージ数/秒」です。
また、機能的に対応していない箇所はグラフを記載していません。

※RabbitMQ のQoS=1の場合のSubscribeの処理は、Publishされたメッセージが内部のキューを介するようで、今回のSubscribeの計測方法では、性能があまり出なかったため、計測結果からは除いています。

Publish性能(retain=false)

f:id:acro-engineer:20150626061010p:plain

Publish性能(retain=true)

f:id:acro-engineer:20150626061220p:plain

Subscribe性能

f:id:acro-engineer:20150626061250p:plain

結果

  • 全体として、Mosquitto/Apollo/VerneMQの性能が良いです。
  • 以前は、Mosquittoの性能はいまひとつ、という話がありましが、現在のバージョンでは、他と比べてもトップレベルの性能になっているようです。
  • VerneMQ は、Retainありの場合は性能が低くなる傾向がありますが、1プロセスでもトップレベルの性能になっています。クラスタ構成を組むことで、分散して処理することができるため、さらに性能を向上できる可能性があります(クラスタ構成での性能は、今回未計測です)。


さて、2回に分けて、MQTT Brokerの機能比較と性能比較を行ってきましたが、
この1~2ヶ月の間にも、MQTT Brokerがバージョンアップされて機能や性能が改善したり、
VerneMQのような新しいプロダクトがリリースされたりと、動きが大きい分野だと感じています。


これからも、IoTとともにMQTT Brokerは要注目、ですね!

Acroquest Technologyでは、キャリア採用を行っています。


  • 日頃勉強している成果を、Hadoop、Storm、NoSQL、HTML5/CSS3/JavaScriptといった最新の技術を使ったプロジェクトで発揮したい。
  • 社会貢献性の高いプロジェクトに提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や対外的な勉強会の開催を通した技術の発信や、社内勉強会での技術情報共有により、技術的に成長したい。
  • OSSの開発に携わりたい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
 キャリア採用ページ

MQTT Broker比較~機能比較編

こんにちは、ツカノ(@)です。

このところ IoT(Internet of Things)関連のニュースを目にすることが増えました。
最近であればPepper君の一般販売などが大きなニュースでしたが、
システムの足回りが大好きな自分としては、IoTと言えば、そう、MQTTですね!(強引!)
f:id:acro-engineer:20150618200645p:plain

Googleトレンドで調べてみたら、こんな感じでした。ここ1-2年で急速に伸びていますね。
f:id:acro-engineer:20150619070315p:plain

MQTTは、Message Queue Telemetry Transport の略ですが、Pub/Sub型モデルのメッセージキュー"プロトコル"であり、MQ(Message Queue)と言いつつ、メッセージを蓄積はしないんですよね。よく勘違いされる点なので、注意が必要です。

MQTTの詳しい説明は、以下のサイトが参考になります。


さて、そんなMQTTですが、メッセージをやり取りするには、仲介役となる MQTT Broker が必要になります。
OSSの MQTT Broker も多く登場してきているのですが、それぞれ実装されている仕様も異なっているため、利用時には注意が必要です。

そこで、自分としてもどのような差分があるのか知りたくなり、代表的なOSSの MQTT Broker について調査してみました。

MQTTの参照実装と言われる Mosquitto をはじめとして、利用されるケースが多い、Apollo、RabbitMQ、eMQTTD、Mosca について機能比較を行いました。


その結果が以下の表です(○:対応あり、×:対応なし)。

Broker(version) 開発言語 対応しているMQTT version QoSレベル Retain Will WebSocket UI 冗長化
Mosquitto(1.4.2) C MQTT 3.1/3.1.1 0,1,2 × ×
Apollo(1.7.1) Java MQTT 3.1 0,1,2 ×
RabbitMQ(3.5.3) Erlang MQTT 3.1 0,1 × ×
Mosca(0.29.0) Node.js MQTT 3.1 0,1 × × ×
eMQTTD(0.8.6-beta) Erlang MQTT 3.1/3.1.1 0,1,2 ×
VerneMQ(0.9.4) Erlang MQTT 3.1/3.1.1 0,1,2 ×

Brokerのversionは調査時のものです。


以下、今回比較した観点について、簡単に説明します。

  • MQTT 3.1と3.1.1の違いは以下に解説されています。3.1.1では、曖昧な点の仕様を明確にしたり、Client IDのサイズ拡張等が行われています。
  • QoS(Quality of Service)はメッセージ配信に関する品質保証のレベルで、以下の3段階存在します。
    • QoS 0: At most once - 最高1回配信します。(1回も配信されない可能性があります)
    • QoS 1: At least once - 少なくとも一回配信します。(2回以上配信される可能性があります)
    • QoS 2: Exactly once - 正確に一回配信します。
  • Retainに対応していると、トピックにSubscribeしたときに、最新のメッセージが配信されます。
  • Willは「Last Will and Testament」のことで、Publisherが切断した際に予め決めておいたメッセージを、Subscriberに配信する流す仕組みがあります。
  • WebSocketは、MQTTのメッセージをWebSocketのプロトコルを使って配信できるかどうかです。
  • UIは、Brokerの管理画面などがUIで提供されているかどうか表します。Webブラウザを使って管理できると便利ですよね。


各Brokerに対して寸評を書くと。。。

  • Mosquitto
    • 冗長化が無いものの(MQTTの仕様上は、冗長化は必要ありません)、参照実装だけあって、QoSやretain等の仕様は全て対応されています。
  • Apollo
    • 機能的には良いのですが、動作をさせてみたところ、MQTTのメッセージのヘッダが標準と多少異なるようで、MQTTクライアントのAPIの種類によっては、Subscribeできないケースがありました。
  • RabbitMQ
    • 以前から普通のMQとして利用することも多かったので、期待していたのですが、未だに、QoS=2に対応していなかったり、retainに対応していなかったり(開発は進んでおり、v3.6.0で対応する予定があるようです)する点は、残念な状況です。
  • Mosca
    • MQTTとしての機能は不足している感じがします。ただし、MoscaはStandaloneでもEmbedded(他アプリ内で動作する)でも動作する、という特徴があります。
  • eMQTTD
    • クラスタ構成を組むことができるため、冗長化にも対応しており、機能的には良いですね。現在、バージョンアップも頻繁に行われています。
    • ただ、次回紹介しますが、性能が他Brokerに追いついていないところがあり、そこは今後に期待ですね。
  • VerneMQ
    • 直近の2015年5月に、最初のリリースが行われましたが、MQTTの仕様も網羅されている上に、クラスタ構成にも対応しているため、OSSのMQTT Brokerとしてはかなり有力候補となるプロダクトですね。
    • ドキュメントも充実して分かりやすいです。


また、今回はそのままインストールして利用するのではないため、比較の対象からは外していますが、750,000 Messages/sec を達成したという、Goで実装された SugeMQ (MQTT Broker/Client ライブラリ、という位置づけ)なんかもあったりします。


バージョンが変わると、また状況は変わってくるかもしれませんが、MQTT Broker を利用する際の参考なれば、と思います。
#できれば、商用の MQTT Broker も対象にしたかったのですが、それはまた今度の機会に。

次回はこれらの MQTT Broker に対して、皆さん気になるベンチマークした結果を紹介したいと思います!


2015/06/26 更新
MQTT Brokerの動きも早く、短期間の内にバージョンアップされていたり、新しいBrokerが登場していました。
それらに関してコメントを頂いたため、内容を更新しました。

  • 調査対象のバージョンを、2016/06/26時点で最新のものに更新しました。
  • Will、WebSocket の項目を追加しました。
  • 調査対象にVerneMQを追加しました。

Acroquest Technologyでは、キャリア採用を行っています。


  • 日頃勉強している成果を、Hadoop、Storm、NoSQL、HTML5/CSS3/JavaScriptといった最新の技術を使ったプロジェクトで発揮したい。
  • 社会貢献性の高いプロジェクトに提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や対外的な勉強会の開催を通した技術の発信や、社内勉強会での技術情報共有により、技術的に成長したい。
  • OSSの開発に携わりたい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
 キャリア採用ページ

JJUG主催Pepperハッカソンに参加してきました!

Java Developerの皆さん、こんにちは。
ボクの名前は @IPアドレスは192.168.254.254

・・・というPepperのモノマネはさておき、@です。

6月6日にPepperハッカソンに参加してきました!
【東京】JJUG主催Pepperハッカソン ( https://jjug.doorkeeper.jp/events/25442 )

Pepperハッカソンって?

Pepperハッカソンは、あのヒューマノイドロボットPepperを使って、実際にプログラムを組んで動かしてみようというイベントです。
今回のイベントはPepperJava NAOqi SDKで開発できるようになることを記念されて開催されたものです。
Java NAOqi SDK ( http://doc.aldebaran.com/2-1/dev/java/index_java.html )

そう、JavaPepperのプログラミングができる! というわけですね。

自分のプログラムで動かせると考えると、最初は気味悪かったPepper君の顔も心なしか可愛く見えます。
f:id:acro-engineer:20150609070309j:plain

ハッカソンのようす

さて、会場の風景を・・・といっても、当日はひたすらPepper君をハックしていたのみのため、
Pepper君の雄姿ばかりになりますが、紹介させてもらいますね。

Pepper君達
f:id:acro-engineer:20150609070318j:plain
・兄のNAOと並んだPepper
f:id:acro-engineer:20150609070327j:plain

ハッカソンということもあり、皆さん黙々と開発を進めていました。
ただ、Pepper君が動作確認の時にしゃべるので、それがきっかけで笑いが起こることが多いという、謎な雰囲気でした^^;

イベントの最後には、自分たちで作ったプログラムの発表が行われました。





また、このTwitterの中にはないのですが、JJUGの槙さんによる、SpringBootで作ったPepperの管理画面などは、とても興味深かったです。


え、、、私が作ったもの・・・?
私はPepperのロボットとしての機能(センサー、カメラ、ポーズ、移動など)を駆使して
癒し系のマスコットのようなものを作りたかったのですが、
SDKのドキュメントに無い個所を試しながら掘り下げていって時間切れ。

癒しではない、うざいPepper君になってしまいました^^;

PepperJava SDKはどうだったのか?

今回、参加した理由として、ハッカソンとしてものづくりを楽しみたかった一方で、
PepperJava SDKがどれぐらい使えるのかを知りたいという目的もありました。

実際に使ってみたJava SDKですが、正直なところ、やや使いづらい印象でした。

  1. ドキュメント、サンプルが無い。
    • いまのところ「どんな機能があるのか?」について分かるドキュメントがありません。
    • JavaDocはあるのですが、ほとんど自動生成されたJavaDocのみで、パラメータの意味などもわからないものでした。
    • 分からないからってデコンパイルに走る猛者も
    • ドキュメントはこれから充実すると思いますし、利用者によるブログやまとめも増えそうですよね。
  2. 数百ものイベント検知を1つ1つ設定する必要がある。
    • Pepperには数百ものイベント(頭に触られた、人間が近づいた)があるのですが、それを検知するためには1イベントごとに検知するコードを書く必要があります。
    • イベントは「EngagementZone/PersonEngage」のように階層構造になっているので、MQTTのようにTopicにワイルドカード指定をする形でSubscribe出来ると使いやすくなると思います。
  3. コールバックの型がイベントごとに異なり、扱いにくい。
    • 上記のイベント検知のハンドリングにはコールバックを使用するのですが、そのコールバックの引数型がイベントごとに異なるため、共通的なコールバックのクラス階層を作りにくいです。
    • 今はお試しレベルなのでそう大きな問題にならないのですが、大きなアプリケーションを作る場合にはコードの統制がとりにくいAPIでした。

なんかちょっと細かいところまで書いてしまいましたが。
ただ、ハッカソン後のイベントでスタッフの方と話したところ、
現状のJavaAPIはあくまでβ版であり、今回のイベントでのコメントを受けてブラッシュアップしていくという強い意志を感じました。

何より、これまでのJavaの開発資産を用いることで、
外部サービスとの連携等が容易になるということは、非常に大きな進展だと思います。
その証拠に皆さん、とにかくtwitter4jを使っていましたし(笑)

また今回のような機会があれば是非参加して、PepperJavaで何ができるか、考えながら手を動してみたいと思います。

おまけ

・イベントが終了し、お休みのPepper君達
f:id:acro-engineer:20150609070341j:plain

Pepperステッカー
f:id:acro-engineer:20150609070356j:plain

皆さんも、ぜひPepperJava SDK、試してみてください!

Acroquest Technologyでは、キャリア採用を行っています。


  • 日頃勉強している成果を、Hadoop、Storm、NoSQL、HTML5/CSS3/JavaScriptといった最新の技術を使ったプロジェクトで発揮したい。
  • 社会貢献性の高いプロジェクトに提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や対外的な勉強会の開催を通した技術の発信や、社内勉強会での技術情報共有により、技術的に成長したい。
  • OSSの開発に携わりたい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
 キャリア採用ページ

オライリー「Javaパフォーマンス」増刷決定! 記念に書評まとめ。

Hello, world! Java界のアイドル CEROMETAL こと、@ DEATH!!
はい、雪が解けても僕の滑りは止まりません!

さて、Acroquestが監訳に協力した「Javaパフォーマンス」ですが、この度めでたく増刷が決定しました!
それもこれも購入して頂いた皆さんのおかげです。そして、まだの方は、ぜひこの機会にご購入ください!

Javaパフォーマンス

Javaパフォーマンス

さて、発売してから2か月弱が経ち、その間にブログに書評なども書いていただきました。
今回はそれらをご紹介したいと思います。

「Java パフォーマンス」を読みました - sos の 作業メモ

著者は、15年間サンマイクロシステムズとオラクルにおいてJavaのパフォーマンスに携わってきた方で、 なかなか読み応えのある内容。 きちんとJavaの流行を追っかけてる人にとっては当たり前のことなのかもしれませんが、Java6の時代でほぼ止まっている私のような 人間にとって、改めて勉強になることが多い本でした。

「Java パフォーマンス」を読みました - sos の 作業メモ

各章について、サマリ・ポイントを掲載してくださっています。
目次だけでは分かりにくかった方にも、本書の内容が掴めると思います。

Javaパフォーマンス - 響雲

性能問題は最後の最後に苦労する事が多いと思います。
経験と知識から事前によけていけるものですが、落とし穴はあるものです。
言語知識だけでは太刀打ち出来ない場面も多く、いろいろな知識が求められます。
本書籍はJavaJVMを主人公に説明されている書籍です。

Javaパフォーマンス - 響雲

ひとつの読み進め方として、1〜3章を前提知識として抑えておき、それ以降は好きなところから読むという流れを紹介されています。僕もその読み方が良いと思います。

書籍「Javaパフォーマンス」を読んで - 見習いプログラミング日記

本書 Javaパフォーマンス のスコープは非常に広く、上記のようなJVMJava SE APIJava EEの広い範囲の性能課題について触れています。本書のような内容が日本語では今までなかったため、トラブル時にはJava SeriesのJava Performanceで苦戦しながら調べていましたが、本書も机の上に置いておこうと思います。

書籍「Javaパフォーマンス」を読んで - 見習いプログラミング日記

仕事としてJavaトラブルシューティングをなさっている @ さんによる書評です。
JITGCログ、解析ツールの解説が嬉しいというあたり、完全に同業者感があります(笑)

「Java パフォーマンス」感想 - sugarlife's blog

今現在 Java で開発している人、特に運用者や試験者は間違いなく買っておくべき本です。Javaに限らない一般的なパフォーマンスチューニングの考え方・観点から、Java アプリケーションにおいてボトルネックになりやすい GCJIT の詳細な確認方法からチューニング方法が解説されている。特にすごいのが Java の世界のみならず、OS の世界まで触れている点。流石に OS の世界はここに書かれているのが全てではないけれど、Java アプリに関わる部分で問題になりやすい点は割と触れている。

JDK8 にも対応しており、今現在手に入る情報としては一番頼もしいと思う。4000 円程度でこの知識量が手に入るなら非常に安い。

「Java パフォーマンス」感想 - sugarlife's blog

OpenJDKコミッタでもある @ さんによる書評です。
1〜3章の後、さらにどこの章を読むと良いか詳しく書かれています。

また、誤訳の訂正もしていただき、これは第二刷に反映させています。ありがとうございます!

Javaでのnullチェックのパフォーマンス - きしだのはてな

こういった最適化の話は、最近出たJavaパフォーマンスに載っています。Javaで書いたプログラムを実行させる人は一度読んでおくといいと思います。

Javaでのnullチェックのパフォーマンス - きしだのはてな

最後は @ さんのエントリー。
nullチェックの話からのJavaパフォーマンス本の紹介、ありがとうございます!w


もし他にも「私も書評を書いてるよ!」という方がいらっしゃれば、ぜひお知らせください。

そして繰り返しになりますが、まだの方は、ぜひこの機会にご購入ください!!
大事なことは2回言う、マニュアル通りの @ でした!

OpenDaylight Helium SR3を試してみた 【OpenDaylight 「Helium」でSDNを構築してみよう】

こんにちは、 miyakeです :-)

ちょっと先の話ですが、来月6月は幕張でINTEROPが開催されます :-)
ネットワーク機器からSDN、NFVのデモや展示が行われる、ネットワークに関する大きなイベントです。
今年はIoT関係の展示も増えているそうなので、見に行こうと思っています。

http://www.opendaylight.org/sites/all/themes/opendaylight/ixm/images/logo_opendaylight.png

前々回:OpenDaylight 「Helium」 概要編
 前回:OpenDaylight 「Helium」をインストールしてみよう
 今回:OpenDaylight 「Helium」でSDNを構築してみよう < イマココ

そんな訳で最終回の今回は、前回インストールを行った環境でSDNを構築します。

今回構築するネットワークのイメージは以下の図のようになります。

f:id:acro-engineer:20150524164551p:plain

open vSwitchでOpenFlow Switchを3つ(ofbr0~ofbr2)作成して、SwitchごとにNodeを4つずつ接続した構成となります。
このNodeをKVMなどの仮想マシンで構築するのはCPUやメモリなどの確保が困難なので、今回はNetwork Namespaceを使って疑似的にNodeを作成します。
Network Namespaceを使うと、一つのホスト内で独立したネットワーク環境を複数作成することが出来るようになります。この機能を使うことで、疑似的なNodeを作成することができます。
Dockerは、このNetwork Namespaceを使ってコンテナ内に独立したネットワーク環境を作っていたりします :-)

それではこれから、順番に環境を構築していきます。

OpenFlow Switchの作成

まずは図にあるOpenFlow Switch(ofbr0~ofbr2)を、以下のコマンドを実行して作成します。
なおこれらのコマンドはroot権限がないと実行できないものなので、rootで行ってください。

# ovs-vsctl add-br ofbr0
# ovs-vsctl add-br ofbr1
# ovs-vsctl add-br ofbr2

# ovs-vsctl set bridge ofbr0 protocols=OpenFlow13
# ovs-vsctl set bridge ofbr1 protocols=OpenFlow13
# ovs-vsctl set bridge ofbr2 protocols=OpenFlow13

# ovs-vsctl set-controller ofbr0 tcp:[OpenDaylightをインストールしたマシンのIPアドレス]
# ovs-vsctl set-controller ofbr1 tcp:[OpenDaylightをインストールしたマシンのIPアドレス]
# ovs-vsctl set-controller ofbr2 tcp:[OpenDaylightをインストールしたマシンのIPアドレス]

# ovs-vsctl set bridge ofbr0 other-config:datapath-id=0000000000000011
# ovs-vsctl set bridge ofbr1 other-config:datapath-id=0000000000000012
# ovs-vsctl set bridge ofbr2 other-config:datapath-id=0000000000000013

"ovs-vsctl"はopen vSwitchのコマンドです。

"ovs-vsctl add-br"で、open vSwitchのブリッジを作成しています。
"ovs-vsctl set bridge xxx protocols=OpenFlow13"は、ブリッジをOpenFlow1.3に対応したSwitchとなるように設定しています。
"ovs-vsctl set-controller xxx tcp:"は、SDNコントローラであるOpenDaylightに接続するための接続先IPアドレスを設定しています。
"ovs-vsctl set bridge ofbr0 other-config:datapath-id"は、OpenFlow Switchを識別するためのIDを設定しています。このIDは16進数で設定します。

実際に作成された内容は、"ovs-vsctl show"で確認することができます。

# ovs-vsctl show
e4b90a1e-584c-4de2-983d-c814e27581e4
    Bridge "ofbr1"
        Controller "tcp:192.48.128.40"
        Port "ofbr1"
            Interface "ofbr1"
                type: internal
    Bridge "ofbr2"
        Controller "tcp:192.48.128.40"
        Port "ofbr2"
            Interface "ofbr2"
                type: internal
    Bridge "ofbr0"
        Controller "tcp:192.48.128.40"
        Port "ofbr0"
            Interface "ofbr0"
                type: internal
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
    ovs_version: "2.3.1"

OpenFlow Switch間の接続

次は、図にあるOpenFlow Switch間の接続(青い線)を、以下のコマンドを実行して作成します。

# ovs-vsctl add-port ofbr0 ofbr0_ofbr1 -- set interface ofbr0_ofbr1 type=patch options:peer=ofbr1_ofbr0
# ovs-vsctl add-port ofbr1 ofbr1_ofbr0 -- set interface ofbr1_ofbr0 type=patch options:peer=ofbr0_ofbr1

# ovs-vsctl add-port ofbr1 ofbr1_ofbr2 -- set interface ofbr1_ofbr2 type=patch options:peer=ofbr2_ofbr1
# ovs-vsctl add-port ofbr2 ofbr2_ofbr1 -- set interface ofbr2_ofbr1 type=patch options:peer=ofbr1_ofbr2

ここでは、OpenFlow Switch間を接続するための仮想インタフェースと、そのインタフェース間を接続する定義を行っています。
ポートは双方に接続する必要があるので、図の青い線1つに対して2つのコマンドを実行しています。

"ofbr1_ofbr0"としているのが、仮想インタフェースの名称になります。

"ovs-vsctl show"で結果を確認すると、以下のようになっているはずです。

# ovs-vsctl show
e4b90a1e-584c-4de2-983d-c814e27581e4
    Bridge "ofbr1"
        Controller "tcp:192.48.128.40"
        Port "ofbr1"
            Interface "ofbr1"
                type: internal
        Port "ofbr1_ofbr0"
            Interface "ofbr1_ofbr0"
                type: patch
                options: {peer="ofbr0_ofbr1"}
        Port "ofbr1_ofbr2"
            Interface "ofbr1_ofbr2"
                type: patch
                options: {peer="ofbr2_ofbr1"}
    Bridge "ofbr2"
        Controller "tcp:192.48.128.40"
        Port "ofbr2"
            Interface "ofbr2"
                type: internal
        Port "ofbr2_ofbr1"
            Interface "ofbr2_ofbr1"
                type: patch
                options: {peer="ofbr1_ofbr2"}
    Bridge "ofbr0"
        Controller "tcp:192.48.128.40"
        Port "ofbr0"
            Interface "ofbr0"
                type: internal
        Port "ofbr0_ofbr1"
            Interface "ofbr0_ofbr1"
                type: patch
                options: {peer="ofbr1_ofbr0"}
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
    ovs_version: "2.3.1"

ブリッジごとに、仮想インタフェースがポートとして接続されています。
peer=で表示されているのが、対向として接続されている仮想インタフェースになります。

Nodeの生成

最後に、Network Namespaceを使用して疑似的なNodeを生成します。

まず先に、ブリッジとNode間を接続するためのveth peerを生成します。
veth peerとは、ホスト内に生成された2つの仮想インタフェースと、そのインタフェース間を接続した仮想ケーブルのセットだと考えてください。
図にある、OpenFlow SwitchとNode間のオレンジの線が、veth peerになります。

このveth peerの生成には、ipコマンドを使用します。

# ip link add name veth1 type veth peer name veth1_ovs

このコマンドで、veth1、veth1_ovsという名称の仮想インタフェースを持つveth peerが出来上がります。
"ip link"とコマンドを実行すると、この2つの仮想インタフェースが表示されます。

次に、Nodeに相当するNetwork Namespaceを生成して、上で作成したveth peerでOpenFlow Switchと接続します。

1)veth1_nodeという名前のNamespaceを生成
# ip netns add veth1_node

2)veth1_nodeに、veth peerの仮想インタフェースveth1を接続
# ip link set veth1 netns veth1_node

3)仮想インタフェースveth1にIPアドレスを定義
# ip netns exec veth1_node ip addr add 10.0.0.1/24 dev veth1

4)OpenFlow Switchであるofbr0に、veth peerの仮想インタフェースveth1_ovsを接続
# ovs-vsctl add-port ofbr0 veth1_ovs

"ip netns"が、Network Namespaceに対する操作を行う際のコマンドだと思ってください。
"ip netns exec veth1_node..."は、Network Namespace上でコマンドを実行する際に使用します。
上の例では、Network Namespace上でipコマンドを実行して、veth1にIPアドレスを設定しています。

最後にveth peerの仮想インタフェースをLink Upにして完了です。

# ip netns exec veth1_node ip link set veth1 up
# ip link set veth1_ovs up

以上でNodeの生成は完了ですが、図にあるものを手で打つのも大変なので、以下のシェルスクリプトを実行すると、図にあるNodeが生成することが出来ます。

#!/bin/bash

#
# Network Name Space とOVS間のPeer生成
#
create_ovs_veth ()
{
    veth_ovs="veth"${2}"_ovs"
    veth="veth"${2}
    veth_node="veth"${2}"_node"
    ip_addr="10.0.0."${2}"/24"
    brg_name=${1}

    echo "veth_ovs=${veth_ovs} veth=${veth} veth_node=${veth_node} ip_addr=${ip_addr} brg_name=${brg_name}"

    # delete
    ovs-vsctl del-port $brg_name $veth_ovs
    ip netns del $veth_node
    ip link del $veth_ovs

    # add
    ip link add name $veth type veth peer name $veth_ovs
    ip netns add $veth_node
    ip link set $veth netns $veth_node
    ip netns exec $veth_node ip addr add $ip_addr dev $veth

    ovs-vsctl add-port $brg_name $veth_ovs
    ip netns exec $veth_node ip link set $veth up
    ip link set $veth_ovs up

    ip netns exec $veth_node ip addr
}

# ofbr0にNode生成
array0=("1" "2" "3" "4")

for elem in "${array0[@]}"
do
    create_ovs_veth "ofbr0" $elem
done

# ofbr1にNode生成
array1=("11" "12" "13" "14")

for elem in "${array1[@]}"
do
    create_ovs_veth "ofbr1" $elem
done

# ofbr2にNode生成
array2=("21" "22" "23" "24")

for elem in "${array2[@]}"
do
    create_ovs_veth "ofbr2" $elem
done

シェルを実行するための手順は、以下の通りです。

# vi veth_setup.sh

上記の内容を入力して実行します。

# chmod a+x veth_setup.sh
# ./veth_setup.sh

このシェルによって、SDN内に10.0.0.*/24のIPアドレスを持つ疑似的なNodeが生成されます。

生成されているNetwork Namespace一覧を確認したい場合は、"ip netns"と実行します。

# ip netns
veth24_node
veth23_node
veth22_node
veth21_node
veth14_node
veth13_node
veth12_node
veth11_node
veth4_node
veth3_node
veth2_node
veth1_node

IPアドレスは、Network Namespace名称"veth**_node"の**部分が、10.0.0.**となるように設定されます。
例えば"veth14_node"の場合、"10.0.0.14"となります。
まぁ、シェルを修正すれば、好きなIPアドレスに変更することもできるので、色々いじってみてください :-)

ちなみに、生成したNetwork Namespaceのネットワーク設定の確認は、以下のように行います。
Network Namespaceに、どのIPアドレスが割り当てられているかを確認したい場合は、このコマンドを実行してみてください。

# ip netns exec veth1_node ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
57: veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 9a:3e:45:e4:9f:e2 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::983e:45ff:fee4:9fe2/64 scope link
       valid_lft forever preferred_lft forever

【ちょっと補足】
今回、ipアドレスやLinkUpの設定にifconfigコマンドを使用せず、すべてipコマンドで行っています。
知っている方もいると思いますが、RHEL7/CentOS7ではnet-toolsそのものが廃止予定となっていて、iproute2パッケージに含まれているipコマンドやssコマンドに移行することが推奨されています。
実際RHEL7では標準でnet-toolsがインストールされていないため、ifconfigコマンドが使えない環境に当たることもあります...
そういう背景もあり、今回は明示的にifconfigコマンドを使用していません。
遅かれ早かれifconfigコマンドは使えなくなるので、早いうちにipコマンドに慣れておきましょう...

OpenDaylightを起動して実際にネットワークを見てみよう

前回のOpenDaylight 「Helium」をインストールしてみようの最後にある方法にしたがってOpenDaylightを起動し、画面を開いてみてください。
SDNの作成に成功していれば、ログイン後に以下のように3つのOpenFlow Switchが表示されます。

f:id:acro-engineer:20150524201120p:plain

Switchの下にopenflow:17と表示されているので、OpenFlow Switchとして認識されていることがわかります。
ちなみに17という数字は、OpenFlow Switchの作成時に16進数で設定したIDが10進数で表示されたものです。
この値で、どのSwitchなのかを区別します。

Switchが表示されているけど、Nodeが表示されていません...
これはまだ、NodeからMACアドレス解決のため通信が行われていないため、Switch側でNodeがどこに接続されているのかを認識できていないためです。
通常この認識は、APRによるMAC解決のパケットを利用しています。
OpenFlowでは、このARPパケットをコントローラ側に送ることで、SwitchのどのポートにどのNodeが接続されているかを関連付ける仕組みになっています。
これをよく「ポート学習」などと言っています。

それでは実際にpingを実行してARPによるMAC解決のための通信を行ってみましょう。
SDNとして正常に機能していれば、pingが通ります :-)

Nodeに対してpingを打ってみる

今回、NodeはNetwork Namespaceで疑似的に作成したので、pingはNetwork Namespace上で実行する必要があるので、以下のようにipコマンドを使って実行します。

# ip netns exec veth1_node ping 10.0.0.11
PING 10.0.0.11 (10.0.0.11) 56(84) bytes of data.
64 bytes from 10.0.0.11: icmp_seq=1 ttl=64 time=0.521 ms
64 bytes from 10.0.0.11: icmp_seq=2 ttl=64 time=0.200 ms
64 bytes from 10.0.0.11: icmp_seq=3 ttl=64 time=0.046 ms
64 bytes from 10.0.0.11: icmp_seq=4 ttl=64 time=0.037 ms
64 bytes from 10.0.0.11: icmp_seq=5 ttl=64 time=0.036 ms
...

この例では、veth1_node上で、10.0.0.11にpingを打っています。
ちゃんとpingが届いて、応答が返ってきているので、SDNの構築は成功です :-)

"ip netns exec [Namespace名] [Namespace上で実行するコマンド]"というパターンでpingを打つことで、OpenFlow Switchを通して、他のNamespace上の仮想インタフェースに対してpingが行われます。
このpingをすべてのNodeに対して行ったのち、先ほどの画面の「Reload」ボタンを押下すると、以下の画面のようにすべてのNodeが表示されるようになります。

f:id:acro-engineer:20150524203828p:plain

Switchの情報を確認してみよう

画面の「Nodes」タブを選択すると、接続されているSwitchの一覧が表示されます。

f:id:acro-engineer:20150524205643p:plain

この一覧の右側にある"Node Connectors"を選択すると、Switchのポート情報が表示されます。

f:id:acro-engineer:20150524210238p:plain

見てもらうとわかりますが、ポートごとのパケット量やエラーパケット数、ドロップパケット数が表示されているので、ある程度のネットワークの状況であれば、この画面で確認することが出来そうです :-)

OpenFlowのフローエントリを確認する方法

open vSwitchのコマンドを使って、OpenFlow Switchに設定されているOpenFlowのフローエントリを確認してみましょう。
設定されているフローエントリを見ることで、どのような制御が行われているのかを確認することができます :-)

# ovs-ofctl dump-flows ofbr0 --protocol=OpenFlow13
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x2a00000000000001, duration=5.648s, table=0, n_packets=5, n_bytes=490, idle_timeout=1800, hard_timeout=3600, priority=10,dl_src=ae:8a:bd:a4:7e:f7,dl_dst=7a:9c:01:d3:a1:46 actions=output:2
cookie=0x2a00000000000000, duration=5.648s, table=0, n_packets=5, n_bytes=490, idle_timeout=1800, hard_timeout=3600, priority=10,dl_src=7a:9c:01:d3:a1:46,dl_dst=ae:8a:bd:a4:7e:f7 actions=output:1
cookie=0x2b0000000000000d, duration=51.144s, table=0, n_packets=0, n_bytes=0, priority=2,in_port=3 actions=output:1,output:7,output:2,output:4,CONTROLLER:65535
cookie=0x2b0000000000000c, duration=51.145s, table=0, n_packets=0, n_bytes=0, priority=2,in_port=7 actions=output:1,output:3,output:2,output:4
cookie=0x2b0000000000000b, duration=51.146s, table=0, n_packets=7, n_bytes=574, priority=2,in_port=1 actions=output:7,output:3,output:2,output:4,CONTROLLER:65535
cookie=0x2b0000000000000f, duration=51.144s, table=0, n_packets=0, n_bytes=0, priority=2,in_port=4 actions=output:1,output:7,output:3,output:2,CONTROLLER:65535
cookie=0x2b0000000000000e, duration=51.144s, table=0, n_packets=7, n_bytes=574, priority=2,in_port=2 actions=output:1,output:7,output:3,output:4,CONTROLLER:65535
cookie=0x2b00000000000004, duration=56.289s, table=0, n_packets=12, n_bytes=1044, priority=100,dl_type=0x88cc actions=CONTROLLER:65535

この内容を見る限り、"CONTROLLER:65535"によってポート学習用のパケットがコントローラに送られており、dl_src、dl_dstのMACアドレスのパケットが届いた場合に特定のポートに転送するフローエントリーが登録されていました。これはOpenFlowでL2スイッチを実現するための定番の動作です。
ここからも、正常にSDNとして機能していることが確認できました :-)


そんなわけで、3回に分けて「OpenDaylight Heliumを試してみました」をやってみましたが、いかがだったでしようか?
昨今、NFVに注目が集まってきており、今まで物理マシンで実現していたネットワーク機器にまでも仮想化の波が押し寄せるようになってきました。
このNFVの制御部分にSDNコントローラが使われるケースも出てきており、Open Platform for NFV (OPNFV)ではOpenDaylightが使用されています。

今回のブログをきっかけに、仮想ネットワークやSDNに興味を持ってもらえれば幸いです :-)

それではまたの機会に~~

Acroquest Technologyでは、キャリア採用を行っています。


  • 日頃勉強している成果を、Hadoop、Storm、NoSQL、HTML5/CSS3/JavaScriptといった最新の技術を使ったプロジェクトで発揮したい。
  • 社会貢献性の高いプロジェクトに提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や対外的な勉強会の開催を通した技術の発信や、社内勉強会での技術情報共有により、技術的に成長したい。
  • OSSの開発に携わりたい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
 キャリア採用ページ

OpenDaylight Helium SR3を試してみた 【OpenDaylight 「Helium」をインストールしてみよう】

こんにちは、こんばんは miyakeです :-)
GW開け早々、まだ5月なのに台風が来たり、真夏のような暑さになったりしているなか、いかがお過ごしでしょうか...

今回は「OpenDaylight Helium SR3を試してみた」の2回目、「OpenDaylight 「Helium」をインストールしてみよう」です。

http://www.opendaylight.org/sites/all/themes/opendaylight/ixm/images/logo_opendaylight.png

 前回:OpenDaylight 「Helium」 概要編
 今回:OpenDaylight 「Helium」をインストールしてみよう < イマココ
 次回:OpenDaylight 「Helium」でSDNを構築してみよう

インストール環境の準備

今回、OpenDaylight 「Helium」はCentOS7にインストールします。
DebianUbuntuの方は....ごめんなさい...
あと、最新のFedoraではOpenJDK1.7のパッケージが用意されていなかったので、出来るだけCentOS7にしてください。
試してはいませんが、CentOS6.5以降でも動作するはずです。

なお、ここではCentOS7のインストール手順は説明しませんので、WebからOSのインストール手順を調べて、VirtualBoxなどを使って仮想マシンを構築してCentOS7をインストールしてください。
CentOS7をインストールする際に出てくる「ソフトウェアの選択」の設定は、”最小限のインストール”のままでOKです。
ネットワークインタフェース(NIC)については1つで十分ですが、インターネットに接続できるようIPアドレスGatewayDNSの設定をしておいてください。

それから、OpenDaylightを実行するためのユーザを追加しておいてください。
rootユーザでもOpenDaylightを実行出来ますが、root権限でアプリケーションを実行するのも気持ち悪いので...

OSの準備ができたら、以下の手順でOpenDaylight をインストールするための準備を行います。
なお、以下の手順はyumでパッケージのインストールなどを行うので、root権限で実行してください。

yum update

まずはOSを最新の状態に更新します。

# yum -y update

SELinuxの無効化

open vSwitchのデータベースデーモン(ovsdb-server)との接続などに影響するので、SELinuxを無効化します。
完全に停止(Disabled)するのも抵抗があるので、ここではPermissiveに設定します。

まずはコマンドでPermissiveに設定します。

# setenforce 0
# getenforce
Permissive

OS再起動後もPermissiveになるよう、/etc/selinux/configの設定項目、SELINUXを、enforcingからpermissiveに変更します。

# vi /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=permissive <-- ここを変更する

...

OpenJDK、Mavenインストール

OpenDaylightはJavaで開発されているので、JDKのインストールが必要になります。
前回のブログにも書いていますが、OpenDaylightがまだJava8に対応できていないため、OpenJDK 7をインストールします。

インストールは以下のように行います。

# yum install java-1.7.0-openjdk

OpenJDKのインストールが終わったら、次はMavenのインストールです。
OpenDaylightインストールのところで説明するプラグイン(Feature)のインストールでは、裏でMavenが使用されているので、事前にMavenをインストールします。

# yum install maven

※会社など、Proxy経由でインターネットにアクセスしている環境では、MavenのProxy設定を行っていないと、OpenDaylightのプラグインインストールが出来ないので注意してください。

open vSwitchインストール

次回のSDN構築用に、事前にopen vSwitchをインストールしておきます :-)
通常、open vSwitchはリポジトリに含まれていないので、ソースコードからrpmパッケージをビルドしてインストールするのですが、ちょっと面倒なので、RDOリポジトリに登録されているopen vSwitchパッケージをインストールします。

[補足]
いきなり出てきたRDOですが、これはRedHat主体で運営している、RedHatディストリビューション用OpenStackコミュニティです。
OpenStackの仮想ネットワークの下回りはopen vSwitchがほぼ標準になっているので、RDOのリポジトリ(まぁ、厳密にはFedoraの下にあるのですが...)にパッケージとして登録されています。
※本気でOpenStackをサービスで使い始めると、open vSwitchでは性能が出ないので、他の手段を使う様になるんですけどね...

インストールは以下のように、RDOのリポジトリ情報を登録してから、open vSwitchのインストールを行います。

# yum install https://repos.fedorapeople.org/repos/openstack/openstack-juno/rdo-release-juno-1.noarch.rpm
# yum install openvswitch

インストールが完了したら、open vSwitchサービスの有効化と、起動を行います。

# systemctl enable openvswitch.service
# systemctl start openvswitch.service

open vSwitchサービスが正しく起動しているかどうかは、statusで確認します。

#  systemctl status openvswitch.service
openvswitch.service - Open vSwitch
   Loaded: loaded (/usr/lib/systemd/system/openvswitch.service; enabled)
   Active: active (exited) since 日 2015-05-17 16:55:09 JST; 2min 23s ago
  Process: 1555 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 1555 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/openvswitch.service

5月 17 16:55:09 ******.localdomain systemd[1]: Starting Open vSwitch...
5月 17 16:55:09 ******.localdomain systemd[1]: Started Open vSwitch.

ここで使っているsystemctlコマンドですが、CentOS6.x以前(RHEL6以前)を使用している人には馴染みがないかもしれませんが、CentOS7(RHEL7)からサービスの管理するシステムがSystemdに変更されたことに伴い、サービス管理コマンドがsystemctlに変更されています。
RHEL系で仕事をしていると、遅かれ早かれSystemdの洗礼を受けることになるので、今のうちに慣れておきましょう。

それでは以下のコマンドで、インストールされたopen vSwitchのバージョンを確認します。

# ovs-vsctl -V
ovs-vsctl (Open vSwitch) 2.3.1
Compiled Dec 26 2014 15:35:14
DB Schema 7.6.2

2.3.1は、最新のバージョン(http://openvswitch.org/releases/)をベースにビルドされているもののようなので、問題なさそうです :-)

OpenDaylight 「Helium」インストール

それではこれから、本命のOpenDaylight 「Helium」をインストールします。
なおOpenDaylightのインストールは、OpenDaylightを実行するユーザで行ってください。
※プロンプトが"#"から"$"になっていることに注意してください...

JAVA_HOMEの設定

OpenDaylightは、環境変数JAVA_HOMEで指定されているJavaJVM)を使用して起動します。
このため環境変数JAVA_HOMEを設定します。

$ export JAVA_HOME=/etc/alternatives/jre_1.7.0_openjdk

環境変数JAVA_HOMEの設定を、.bashrcに追加しておきます。

$ vi .bashrc

# .bashrc
....
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
export JAVA_HOME=/etc/alternatives/jre_1.7.0_openjdk  <-- 追加
....

OpenDaylightインストール

それではこれから、OpenDaylight「Helium」SR3をインストールします :-)

まずはOpenDaylightのサイトからイメージファイル(zip)をダウンロードしてから解凍します。
※ここではホームディレクトリに解凍していますが、ホームディレクトリ配下であれば、どこに解凍してもOKです

$ wget https://nexus.opendaylight.org/content/groups/public/org/opendaylight/integration/distribution-karaf/0.2.3-Helium-SR3/distribution-karaf-0.2.3-Helium-SR3.zip
$ unzip distribution-karaf-0.2.3-Helium-SR3.zip
$ mv distribution-karaf-0.2.3-Helium-SR3 opendaylight 

これでOpenDaylight本体のインストールは完了です :-)
あとは、OpenDaylightを起動させて、SDNコントローラとしての基本的なプラグイン(Feature)のインストールを行います。
まずはOpenDaylightの起動です。

$ cd opendaylight
$ ./bin/karaf

    ________                       ________                .__  .__       .__     __
    \_____  \ ______   ____   ____ \______ \ _____  ___.__.|  | |__| ____ |  |___/  |_
     /   |   \\____ \_/ __ \ /    \ |    |  \\__  \<   |  ||  | |  |/ ___\|  |  \   __\
    /    |    \  |_> >  ___/|   |  \|    `   \/ __ \\___  ||  |_|  / /_/  >   Y  \  |
    \_______  /   __/ \___  >___|  /_______  (____  / ____||____/__\___  /|___|  /__|
            \/|__|        \/     \/        \/     \/\/            /_____/      \/


Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown OpenDaylight.

opendaylight-user@root>

OpenDaylightの起動が完了すると、"opendaylight-user@root"というプロンプトが表示されます。
インストール直後の起動時は、初期化などが行われるため、起動か完了するまで数分かかることがあります。

OpenDaylightを終了させる場合は、「Ctrl+d」と押下するか、logoutとコマンドを実行します。

それでは、次に基本的なプラグイン(Feature)をインストールします。
まずは初期段階にインストールされているFeatureを、"feature:list -i"を実行して確認してみます。

opendaylight-user@root>feature:list -i
Name       | Version | Installed | Repository     | Description
------------------------------------------------------------------------------------------------------
standard   | 3.0.1   | x         | standard-3.0.1 | Karaf standard feature
config     | 3.0.1   | x         | standard-3.0.1 | Provide OSGi ConfigAdmin support
package    | 3.0.1   | x         | standard-3.0.1 | Package commands and mbeans
kar        | 3.0.1   | x         | standard-3.0.1 | Provide KAR (KARaf archive) support
ssh        | 3.0.1   | x         | standard-3.0.1 | Provide a SSHd server on Karaf
management | 3.0.1   | x         | standard-3.0.1 | Provide a JMX MBeanServer and a set of MBeans in K
opendaylight-user@root>

これだけではSDNコントローラとして機能しないので、OpenFlowPluginやGUIのDLUX、L2Switchとして動作させるためのFeatureをインストールします。

opendaylight-user@root>feature:install odl-dlux-core odl-restconf odl-mdsal-apidocs odl-l2switch-switch
....

opendaylight-user@root>

これで、依存する他のFeatureを含めてインストールが完了します。
実際にどのようなFeatureがインストールされているか確認しましょう。

opendaylight-user@root>feature:list -i
Name                             | Version          | Installed | Repository                              | Description                          
--------------------------------------------------------------------------------------------------------------------------------------------------------------
....
odl-aaa-authn                    | 0.1.3-Helium-SR3 | x         | odl-aaa-0.1.3-Helium-SR3                | OpenDaylight :: AAA :: Authentication
odl-l2switch-switch              | 0.1.3-Helium-SR3 | x         | l2switch-0.1.3-Helium-SR3               | OpenDaylight :: L2Switch :: Switch   
odl-l2switch-hosttracker         | 0.1.3-Helium-SR3 | x         | l2switch-0.1.3-Helium-SR3               | OpenDaylight :: L2Switch :: HostTracker
odl-l2switch-addresstracker      | 0.1.3-Helium-SR3 | x         | l2switch-0.1.3-Helium-SR3               | OpenDaylight :: L2Switch :: AddressTracker
odl-l2switch-arphandler          | 0.1.3-Helium-SR3 | x         | l2switch-0.1.3-Helium-SR3               | OpenDaylight :: L2Switch :: ArpHandler
odl-l2switch-loopremover         | 0.1.3-Helium-SR3 | x         | l2switch-0.1.3-Helium-SR3               | OpenDaylight :: L2Switch :: LoopRemover
odl-l2switch-packethandler       | 0.1.3-Helium-SR3 | x         | l2switch-0.1.3-Helium-SR3               | OpenDaylight :: L2Switch :: PacketHandler
odl-mdsal-common                 | 1.1.3-Helium-SR3 | x         | odl-config-0.2.8-Helium-SR3             | OpenDaylight :: Config :: All        
odl-config-api                   | 0.2.8-Helium-SR3 | x         | odl-config-0.2.8-Helium-SR3             | OpenDaylight :: Config :: API        
odl-config-netty-config-api      | 0.2.8-Helium-SR3 | x         | odl-config-0.2.8-Helium-SR3             | OpenDaylight :: Config :: Netty Config API
odl-config-core                  | 0.2.8-Helium-SR3 | x         | odl-config-0.2.8-Helium-SR3             | OpenDaylight :: Config :: Core       
odl-config-manager               | 0.2.8-Helium-SR3 | x         | odl-config-0.2.8-Helium-SR3             | OpenDaylight :: Config :: Manager    
odl-config-netty                 | 0.2.8-Helium-SR3 | x         | odl-config-persister-0.2.8-Helium-SR3   | OpenDaylight :: Config-Netty         
odl-mdsal-broker                 | 1.1.3-Helium-SR3 | x         | odl-mdsal-1.1.3-Helium-SR3              | OpenDaylight :: MDSAL :: Broker      
odl-flow-model                   | 1.1.3-Helium-SR3 | x         | odl-flow-1.1.3-Helium-SR3               | OpenDaylight :: Flow :: Model        
odl-flow-services                | 1.1.3-Helium-SR3 | x         | odl-flow-1.1.3-Helium-SR3               | OpenDaylight :: Flow :: Services     
odl-openflowjava-protocol        | 0.5.3-Helium-SR3 | x         | odl-openflowjava-0.5.3-Helium-SR3       | OpenDaylight :: Openflow Java :: Protocol
odl-config-persister             | 0.2.8-Helium-SR3 | x         | odl-config-persister-0.2.8-Helium-SR3   | OpenDaylight :: Config Persister     
odl-config-startup               | 0.2.8-Helium-SR3 | x         | odl-config-persister-0.2.8-Helium-SR3   | OpenDaylight :: Config Persister:: Config Startup
odl-restconf                     | 1.1.3-Helium-SR3 | x         | odl-controller-1.1.3-Helium-SR3         | OpenDaylight :: Restconf             
odl-restconf-noauth              | 1.1.3-Helium-SR3 | x         | odl-controller-1.1.3-Helium-SR3         | OpenDaylight :: Restconf             
odl-mdsal-apidocs                | 1.1.3-Helium-SR3 | x         | odl-controller-1.1.3-Helium-SR3         | OpenDaylight :: MDSAL :: APIDOCS     
odl-protocol-framework           | 0.5.3-Helium-SR3 | x         | odl-protocol-framework-0.5.3-Helium-SR3 | OpenDaylight :: Protocol Framework   
odl-yangtools-models             | 0.6.5-Helium-SR3 | x         | odl-yangtools-0.6.5-Helium-SR3          | OpenDaylight :: Yangtools :: Models  
odl-yangtools-data-binding       | 0.6.5-Helium-SR3 | x         | odl-yangtools-0.6.5-Helium-SR3          | OpenDaylight :: Yangtools :: Data Binding
odl-yangtools-binding            | 0.6.5-Helium-SR3 | x         | odl-yangtools-0.6.5-Helium-SR3          | OpenDaylight :: Yangtools :: Binding 
odl-yangtools-common             | 0.6.5-Helium-SR3 | x         | odl-yangtools-0.6.5-Helium-SR3          | OpenDaylight :: Yangtools :: Common  
odl-yangtools-binding-generator  | 0.6.5-Helium-SR3 | x         | odl-yangtools-0.6.5-Helium-SR3          | OpenDaylight :: Yangtools :: Binding Generator
odl-dlux-core                    | 0.1.3-Helium-SR3 | x         | odl-dlux-0.1.3-Helium-SR3               |                                      
odl-netconf-api                  | 0.2.8-Helium-SR3 | x         | odl-netconf-0.2.8-Helium-SR3            | OpenDaylight :: Netconf :: API       
odl-netconf-mapping-api          | 0.2.8-Helium-SR3 | x         | odl-netconf-0.2.8-Helium-SR3            | OpenDaylight :: Netconf :: Mapping API
odl-netconf-util                 | 0.2.8-Helium-SR3 | x         | odl-netconf-0.2.8-Helium-SR3            |                                      
odl-netconf-impl                 | 0.2.8-Helium-SR3 | x         | odl-netconf-0.2.8-Helium-SR3            | OpenDaylight :: Netconf :: Impl      
odl-config-netconf-connector     | 0.2.8-Helium-SR3 | x         | odl-netconf-0.2.8-Helium-SR3            | OpenDaylight :: Netconf :: Connector 
odl-netconf-netty-util           | 0.2.8-Helium-SR3 | x         | odl-netconf-0.2.8-Helium-SR3            | OpenDaylight :: Netconf :: Netty Util
odl-netconf-monitoring           | 0.2.8-Helium-SR3 | x         | odl-netconf-0.2.8-Helium-SR3            | OpenDaylight :: Netconf :: Monitoring
pax-jetty                        | 8.1.14.v20131031 | x         | org.ops4j.pax.web-3.1.0                 | Provide Jetty engine support         
pax-http                         | 3.1.0            | x         | org.ops4j.pax.web-3.1.0                 | Implementation of the OSGI HTTP Service
pax-http-whiteboard              | 3.1.0            | x         | org.ops4j.pax.web-3.1.0                 | Provide HTTP Whiteboard pattern support
pax-war                          | 3.1.0            | x         | org.ops4j.pax.web-3.1.0                 | Provide support of a full WebContainer
odl-openflowplugin-southbound    | 0.0.6-Helium-SR3 | x         | openflowplugin-0.0.6-Helium-SR3         | OpenDaylight :: Openflow Plugin :: SouthBound
odl-openflowplugin-flow-services | 0.0.6-Helium-SR3 | x         | openflowplugin-0.0.6-Helium-SR3         | OpenDaylight :: Openflow Plugin :: Flow Services
opendaylight-user@root>

依存関係のあるものを含めて、かなりの数のFeatureがインストールされました。
これで、次回のSDN構築に必要なFeatureのインストールが完了しました。

それでは実際に、OpenDaylightのGUI画面を開いてみましょう。

まず、Webブラウザから以下のURLにアクセスします。

http://[OpenDaylightをインストールしたマシンのIPアドレス]:8181/dlux/index.html

Featureのインストールが成功していれば、以下のログイン画面が表示されます。

f:id:acro-engineer:20150517183735j:plain

Usernameに"admin"、Passwordに"admin"と入力してLoginボタンを押すと、ログインに成功して以下のトポロジ画面が開きます。

f:id:acro-engineer:20150517184408j:plain


まだopen vSwitchの設定などを行っていないので、何も表示されていませんが、これでOpenDaylight 「Helium」のインストールは完了です :-)
ここまで来たらもう一息。
次回に紹介するSDN構築が成功すると、以下のようなトポロジが表示されるようになります。
f:id:acro-engineer:20150506184659j:plain

それでは、また次回をよろしくお願いします~

Acroquest Technologyでは、キャリア採用を行っています。


  • 日頃勉強している成果を、Hadoop、Storm、NoSQL、HTML5/CSS3/JavaScriptといった最新の技術を使ったプロジェクトで発揮したい。
  • 社会貢献性の高いプロジェクトに提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や対外的な勉強会の開催を通した技術の発信や、社内勉強会での技術情報共有により、技術的に成長したい。
  • OSSの開発に携わりたい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
 キャリア採用ページ