Java8 lambda式の復習
桜庭祐一さん(@skrb)のlambda式 ハンズオンの復習を兼ねてまとめ。
ハンズオンの教材:
skrb/LambdaDojo · GitHub
lambda式を使うメリット
lambda式を使用する意味は、処理のパラレル化。
処理を複数CPUで並列に処理することで、高速化を図る事が出来る。
Functional Interface
lambda式はfunctionを書くもの。
stream apiはiteratorを書くもの。
lambda式は、Functional Interfaceのメソッドをimplementsする。
Interface | method |
---|---|
Runnable | void run() |
Callable |
T call() |
Comparator |
boolean compare(T t1, T t2) |
メソッド名を覚えておく必要はあまりなく、引数と戻り値さえ覚えておけばOK。
他にも、java.util.function packageに色々ある。
Functinal Interfaceを自作する場合は、@FunctionalInterfaceアノテーションを付与すると、コンパイラがFunctionalなInterfaceになっているかをチェックしてくれる。
演習
Functional Interfaceの実装
基本的なlambda式の書き方から。
Comparator<Integer> comparator1 = new Comparator<Integer>() { @Override public int compare(Integer x, Integer y) { return x - y; } };
ComparatorはFunctinal Interface。
このComparatorの無名クラスの定義は以下のように書き換えられる。
Comparator<Integer> comparator1 = (x, y) -> x - y;
なお、引数の型省略は、片方のみ(例えば(x, Integer y)のような)は出来ない。型省略時は両方の引数の型を省略する。
余談として、Intellijでは、特に操作しなくてもラムダ式に書き換えられる。
引数がない場合のlambda式の記述方法。引数指定がない場合でも()は省略不可。
Callable<Date> callable1 = () -> new Date();
下記のような記載も可。(コンストラクタリファレンス)
Callable<Date> callable2 = Date::new;
ループ処理
List<String> strings = Arrays.asList("a", "b", "c", "d", "e"); StringBuilder builder = new StringBuilder(); for (String s: strings) { builder.append(s); }
forループは、forEachメソッドでのループに置き換える。
List<String> strings = Arrays.asList("a", "b", "c", "d", "e"); StringBuilder builder3 = new StringBuilder(); strings.forEach(t -> builder3.append(t));
メソッドコールをメソッドリファレンスの形式にすると、引数の記載も不要。
List<String> strings = Arrays.asList("a", "b", "c", "d", "e"); StringBuilder builder4 = new StringBuilder(); strings.forEach(builder4::append);
filterメソッド
List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); for (Integer x : numbers) { if (x % 2 == 0) { System.out.print(x); } } System.out.println();
forはforEachに、elseを持たないifはfilterに置き換え。
numbers.stream(). filter(x -> x % 2 == 0). forEach(System.out::print); System.out.println();
数値計算
List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); double ave = 0.0; for (Integer x : numbers) { ave += x; } System.out.println(ave / numbers.size());
forEachメソッドを使用して置き換え。
なお、無名クラスと同様に、finalでないローカル変数にはラムダ式からはアクセス出来ない。ave2変数はクラス変数とする必要がある。
// ave2はクラス変数 numbers.forEach(x -> ave2 += x); System.out.println(ave2 / numbers.size());
数値の合算をreduceメソッドに置き換え。(reduceは値を集約するメソッド。第一引数に初期値、第二引数に値集約を行うラムダ式を指定する)
int ave3 = numbers.stream() .reduce(0, (x, y) -> x + y); System.out.println(ave3 / numbers.size());
Integer<->intのオートボクシング回数を削減するため、mapToIntでintに置き換えを行い、Integerへのオートボクシングを抑止。
int ave4 = numbers.stream() .mapToInt(x -> x) .reduce(0, (x, y) -> x + y); System.out.println(ave4 / numbers.size());
単純な合計値計算は、sumメソッドで出来る。
int ave5 = numbers.stream() .mapToInt(x -> x) .sum(); System.out.println(ave5 / numbers.size());
指定回数分の実行
// 乱数のリストを作成 Random random = new Random(); List<Double> numbers = new ArrayList<>(); for (int i = 0; i < 100; i++) { numbers.add(random.nextDouble()); }
forループをIntStream.range関数に置き換え。range関数は、指定した数値の範囲(回数)だけ処理を行う。
List<Double> numbers2 = new ArrayList<>(); IntStream.range(0, 100) .forEach(i -> numbers2.add(random.nextDouble()));
予め空リストを作って値を追加しくていくのではなく、collectメソッドでコレクションに変換する。collectメソッドの引数にList変換関数を指定する事で、Listへの変換を行う。
List<Double> numbers3 = IntStream.range(0, 100) .mapToObj(i -> random.nextDouble()) .collect(Collectors.toList());
桜庭さんのIT Proの連載。
Java技術最前線 - Java技術最前線:ITpro
Pacemaker+Heartbeatを試してみる(起動編)
Pacemaker+Heartbeatを試してみる(インストール編)の続き。
サーバの構成は以下。
ノード名 | 外向けIPアドレス | インターコネクト1 | インターコネクト2 |
---|---|---|---|
ha1.localdomain | 192.168.56.10(eth1) | 172.35.10.10(eth2) | 172.40.20.10(eth3) |
ha2.localdomain | 192.168.56.20(eth3) | 172.35.10.20(eth4) | 172.40.20.20(eth5) |
それぞれのサーバでha.cfを設定。
ha.cfは雛形になるファイルがあるので、そのファイルをコピーして使用する。
必要な部分のみコメントアウトを外していく。
ucast、nodeは環境に合わせて設定。nodeは、uname -nで出力される名前を指定する。
auto_failbackはoffに変更した。(系切替後に故障サーバが復旧したとき、自動で切り戻る事を防止する)
「pacemaker on」は自分で追加。
両方のサーバの違いはucastの指定部分のみ。
[root@ha1 /]# cp -p /usr/share/doc/heartbeat-3.0.5/ha.cf /etc/ha.d/ha.cf [root@ha1 /]# vi /etc/ha.d/ha.cf [root@ha1 /]# cat /etc/ha.d/ha.cf | egrep -v '^#' | egrep -v '^$' debugfile /var/log/ha-debug logfile /var/log/ha-log logfacility local0 keepalive 2 deadtime 30 warntime 10 initdead 120 udpport 694 ucast eth2 172.35.10.20 ucast eth3 172.40.20.20 auto_failback off node ha1.localdomain node ha2.localdomain pacemaker on
[root@ha2 /]# cp -p /usr/share/doc/heartbeat-3.0.5/ha.cf /etc/ha.d/ha.cf [root@ha2 /]# vi /etc/ha.d/ha.cf [root@ha2 /]# cat //etc/ha.d/ha.cf | egrep -v '^#' | egrep -v '^$' debugfile /var/log/ha-debug logfile /var/log/ha-log logfacility local0 keepalive 2 deadtime 30 warntime 10 initdead 120 udpport 694 ucast eth4 172.35.10.10 ucast eth5 172.40.20.10 auto_failback off node ha1.localdomain node ha2.localdomain pacemaker on
authkeysの設定。こちらは両方のサーバで共通。
コピー後にファイルの権限変更が必要なので注意。
今回はsha1アルゴリズムを使用している。
# cp -p /usr/share/doc/heartbeat-3.0.5/authkeys /etc/ha.d/authkeys # chown root:root /etc/ha.d/authkeys # chmod 600 /etc/ha.d/authkeys # vi /etc/ha.d/authkeys # cat //etc/ha.d/authkeys | egrep -v '^#' | egrep -v '^$' auth 2 2 sha1 secret
両系でheartbeatを起動してみる。
# service heartbeat start
で、起動してみたが、crm_monがいつまでも接続できない。
/var/log/ha-logを見ると、以下のようなエラーが。
Oct 07 17:23:52 ha1.localdomain heartbeat: [5107]: ERROR: glib: ucast: error binding socket. Retrying: Permission denied Oct 7 17:23:52 ha1 heartbeat: [5107]: ERROR: glib: ucast: error binding socket. Retrying: Permission denied Oct 07 17:23:53 ha1.localdomain heartbeat: [5107]: ERROR: glib: ucast: error binding socket. Retrying: Permission denied Oct 7 17:23:53 ha1 heartbeat: [5107]: ERROR: glib: ucast: error binding socket. Retrying: Permission denied Oct 07 17:23:54 ha1.localdomain heartbeat: [5107]: ERROR: glib: ucast: unable to bind socket. Giving up: Permission denied Oct 07 17:23:54 ha1.localdomain heartbeat: [5107]: ERROR: make_io_childpair: cannot open ucast eth2 Oct 7 17:23:54 ha1 heartbeat: [5107]: ERROR: glib: ucast: unable to bind socket. Giving up: Permission denied Oct 7 17:23:54 ha1 heartbeat: [5107]: ERROR: make_io_childpair: cannot open ucast eth2 Oct 07 17:23:55 ha1.localdomain heartbeat: [5111]: CRIT: Emergency Shutdown: Master Control process died. Oct 07 17:23:55 ha1.localdomain heartbeat: [5111]: CRIT: Killing pid 5107 with SIGTERM Oct 07 17:23:55 ha1.localdomain heartbeat: [5111]: CRIT: Emergency Shutdown(MCP dead): Killing ourselves. Oct 7 17:23:55 ha1 heartbeat: [5111]: CRIT: Emergency Shutdown: Master Control process died. Oct 7 17:23:55 ha1 heartbeat: [5111]: CRIT: Killing pid 5107 with SIGTERM Oct 7 17:23:55 ha1 heartbeat: [5111]: CRIT: Emergency Shutdown(MCP dead): Killing ourselves. Oct 7 17:26:59 ha1 heartbeat: [5179]: info: Pacemaker support: on
SELinuxが悪さをしているという情報があった。SELinux、iptablesを無効にしてみる。
# getenforce Enforcing # setenforce 0 # getenforce Permissive # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT icmp -- anywhere anywhere ACCEPT all -- anywhere anywhere ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT all -- anywhere anywhere reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) target prot opt source destination # service iptables stop
再度チャレンジ。
両方のサーバでheartbeatを起動。
# service heartbeat start
crm_monの内容を確認。
# crm_mon -1r ============ Last updated: Tue Oct 7 18:09:46 2014 Stack: Heartbeat Current DC: ha2.localdomain (8b5fa310-2ad6-6504-5874-35e498f88c61) - partition with quorum Version: 1.0.13-30bb726 2 Nodes configured, unknown expected votes 0 Resources configured. ============ Online: [ ha1.localdomain ha2.localdomain ] Full list of resources:
サーバ2台がOnlineになった。起動出来たっぽい。
SELinuxは特に要らないので、iptablesともどもOFFにする。
# vi /etc/selinux/config SELINUX=enforcing ↓ SELINUX=permissive
# chkconfig iptables off # chkconfig --list iptables iptables 0:off 1:off 2:off 3:off 4:off 5:off 6:off
(追記)
/etc/ha.d/ha.cfの内容を変更してpacemaker再起動を繰り返すと、crm_monの結果に
Node ha1.localdomain (994f9fdb-49d2-458f-a26f-3d7ace82063b): UNCLEAN (offline) Node ha2.localdomain (701f93e2-b2e2-4c22-b5e7-57f88fd864b6): UNCLEAN (offline)
のような出力が現れる。
これを削除するには、crm configure edit でcrm設定を開き、該当のnode定義を削除する必要がある。
参考:
OSごとコピーしてLinux-HA環境作りTai! « Linux-HA Japan
crm resource migrateの罠
Pacemakerのクラスタ切替方法調べててハマったのでメモ。
crm resource helpに以下の記載があるのを見つけた。
migrate,move migrate a resource to another node
unmigrate,unmove unmigrate a resource to another node
migrateならクラスタ切替出来るな、と思ったのが罠。
早速コマンドを実行。
# crm resource move vip WARNING: Creating rsc_location constraint 'cli-standby-vip' with a score of -INFINITY for resource vip on host1 This will prevent vip from running on host1 until the constraint is removed using the 'crm_resource -U' command or manually with cibadmin This will be the case even if 0270-host1 is the last node in the cluster This message can be disabled with -Q
WARNINGが出たが、目論見通り系切替が出来た。
(今見ると、このWARNINGの内容をちゃんと読んでおくべきだった。。)
が、その後、vipと同一グループのリソースにエラーが起きても、クラスタ切替が走らなくなった。
なぜだと思って色々調べていたら、crm configure showで見慣れない定義が追加されてたのを見つけた。
location cli-standby-vip vip \ rule $id="cli-standby-rule-vip" -inf: #uname eq host1
この定義がある限り、vipはhost1には絶対に切り替わらない。(-infは"絶対に〜してはならない"という定義)
いつ追加された定義かを確認したら、crm resource moveを実行した時に追加されたことが分かった。
対処として
# crm resource unmigrate vip
を実行することで、上記のlocation定義は消えた。
(ちなみに、moveとmigrate、unmoveとunmigrateはそれぞれ同じ動作をするオプションになる)
とは言え、unmigrateをクラスタ切替後に実行したかは、crm_monの結果からは確認出来ないので、実行忘れが怖い。毎回crm configure showするのも非現実的だし。
クラスタ切替は
# crm node standby host1 # crm node online host1
という手順で、ACT側のノードを一旦standbyにすることでリソースを反対のサーバに移動させて、その後、standbyのノードをonlineにすることで実施することにした。
もう少し綺麗なクラスタ切替の方法はないんかなぁ。。
minttyをインストールしてみた
Windows標準のコマンドプロンプトが使いづらくて何か代替手段ないかと思って探してたら、minttyがいいという情報があったのでインストールしてみた。
環境はWindows7 Professional。
参考:
http://tanakh.jp/posts/2011-11-15-windows-terminal.html
http://dogmap.jp/2011/11/15/mintty/
MinGW/MSYSのインストール
以下のURLからinstallerをダウンロードして実行。
http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/
インストール後、MinGW Installation Manager起動。
All Packages->MSYS->MSYS Base Systemを選択して、msys-baseを右クリックし、Mark for Installationを選択。
要るのか分からなかったけど、All Packages->MinGW->MinGW Base Systemのmingw32-baseも選択した。
メニューのInstallation->Apply Changesを選択してパッケージインストール。
minttyのインストール
C:\MinGW\msys\1.0\msys.bat を起動し、起動したウィンドウで以下を実行
$ mingw-get mintty
これでminttyのインストールは出来た。
mintty起動用のショートカット作成
Windowsの右クリックメニューより、ショートカットを作成。
以下のコマンドパスを設定する。
起動後の設定
ウィンドウのカスタマイズ
mintty起動したら、ウィンドウの右クリック->optionsから好みの設定が出来る。
自分が設定したのは以下。後はお好みで。
- Looks -> Colours (文字色、背景色)
- Looks -> Transparency (ウィンドウの透過度)
- Text -> Font (フォント)
- Window -> Default Size (起動時のウィンドウサイズ)
Text -> Localeの設定をja_JP, SJISに設定しても日本語が使えなかった(lsで日本語名のファイルが表示できなかった)のは謎。
何か他に設定やら追加パッケージが居るんかな?
Agile Japan 2014 仙台サテライト に行ってきました(基調講演)
2014/6/27(金)のAgile Japan 2014の仙台サテライトのレポート。
当日のTogetter
本家のTogetter
仙台サテライトのTogetter
基調講演
日産でGT-R開発の総責任者を務めていた水野和敏さんによる基調講演。
この人のインタビューは日経ビジネスで何回か見たことがあって、そのインタビューの歯に衣着せぬ物言いが面白かったので楽しみにしてたけど、期待に違わない面白さでございました。
あまり"Agile Japan"の講演ではなかったけど。。
以下、内容と感想など。
企画も開発も生産も実験も販売もサービスも品質保証も一体になるのが日本人のすばらしさ。なぜこれが出来るかというと、大多数の日本人は共通の価値観を持ってるから。
日本語は、考えなければ、相手を洞察しなければ、喋れない言葉。
英語は何も考えなくても喋れる言葉。だから世界の公用語になった。言葉に感性のない国のブランドは失われている。グローバル競争が始まったら、アメリカはDiscount Valueの消費立国にしかならなかった。
ヨーロッパは単一民族国家、共通の価値観を持った集団がブランド形成している。
全ての会社がブランド形成に成功しているわけではない。アメリカの資本とマネジメントを取り入れた会社が、ドイツの文化や技術を理解せずにモノ作りを始めたら、Discount Valueの世界になってしまった。
最初から飛ばしてきたー。
日本ってアメリカに押されっぱなしで、仕事のやり方もアメリカに倣おうとしてるように感じるけど、自分たちの強みは知っておかないといけないんだろね。
レースは1年前に終っていなければいけない。サーキットに出てレースをやってるようではいけない。
自分がレースの仕事に入って、最初にやったことはビッグデータベース作り。
データ計測する人間を雇って、周りのライバル社の全ての車のデータを集める。そのデータを徹底的に分析し、来年勝つためにはタイムをどれくらい短くすれば勝てるか計算し、車の改良で何秒速くする、ドライバーが何秒速くする、メカニックがピットワークで何秒速くする、といった個々の目標を決め、裁量権を与える。
ここで与える目標は曖昧ではいけない。みんなが納得できるものでなければいけない。だからビッグデータを使う。
データは集めるだけではダメで思考しなければいけない。
この講演で衝撃受けたところ。
チームで目標を具体化して共有するのは、開発仕事の度に出来なくて悩むところ。
今は根性論でチームにハッパかけて仕事やらせてる部分があるけど、こういう所に力入れるのがリーダーの役目なんだろうなと痛感。
効率を追いかけるなら、"What is race"で考える。
車が速ければいい、ドライバが速ければいいというのは"How to race"。バクチ。
レースはサーキットでやるものではなく、ホームワークでやるもの。だから全戦全勝できる。
プログラマ的には「どう作るか?」ではなく「何を作るのか?」。これは本当に大事。
最近の仕事で「設計書通りに作りました。どう使うのかは知らないので誰かに決めてもらって下さい」と言われて衝撃を受けたことを思い出した。。
トライ&エラーなんてやってはいけない。特に車はエラーがあると人が死ぬ。予測してOKな事しかやってはいけない。
ただし、「予測してOK」な事を求めると過去の例に戻ってしまう。これをやると商品が時代遅れに戻ってしまう。未来の目標をどう共有させるかが、チームの最高の仕事。
ソフトなのでとりあえず作って動かしてみて、はよくやる。ここはソフトと車の違いかな、と思った。
しかし、予測OKなもので、しかも新しいもの、ってハードルが高い。
不景気というのは、お金持ちがお金の使い道に困って、たっぷり蓄えていて、普通の人にお金がいかなくなった状態。
ちょっとつつけばお金持ちからお金は出てくる。
不景気だから会社が儲からないのではなく、新聞の記事を読んで経営して会社を儲からなくしてるのが経営者。リーマン・ショック後、NYでは高い価値を持つもの(金、絵画、アパートメント等)の値段は上がった。BMW、ベンツ、ポルシェの高級車も飛ぶ様に売れた。日本は高級車として売れる車がなく、東南アジアに行って安車を売るという戦略を取ってしまった。
「不景気だから安くしなきゃダメなんだ」と考えてたけど、こういう視点もあるんだな。
GT-Rがスーパーカーに見えるか? むしろセダンに見えるでしょ?
でも、スーパーカーに見えない車がスーパーカー抜いていったら相手は度肝抜かれる。普通の人が不可能と思ってることをやるのが日本人。トランクに荷物が積める。退職したおっさんが片手ハンドルで300km出せる。4輪駆動で雨の日も雪の日も走れる。300km走行中にバーストしても普通に走ってディーラーにタイヤ交換行ける。こういう車を作れるのが日本人。日本人のおもてなしの心。
これが日本人がスーパーカーを作って世に問う意味。フェラーリより良いフェラーリを作ったってしょうがない。そこには創造性がない。
以前にフランスに留学してた人から、向こうで不便な所をちょっと工夫するだけでみんなから驚かれたという話を聞いたことを思い出した。この「便利さ」を自然と追求出来るのは日本人の強みなんだろうなと思った。
技術の進化は値段を下げる。技術の進化は付加価値を上げるとみんな思っているが、それは勘違い。
これは実感として分かる。何でも最初に出た時が一番高くて、後は下がってくだけだし。
とは言っても、進化していかないと、買ってすらもらえなくなる。。
原価を下げる方法として、2つの道がある。技術の進化で原価と小型化を行うことで原価を下げるか、技術開発を止めて安い所を使って賃金格差で原価を下げるか。
技術開発を止めると、低いレベルに合わせた技術と作りになる。今まで誤差±0.3で作ってたものを、誤差±0.5で作ってもOKと言ったりする。これを100箇所集めたら車はどうなる? これを日本の会社の商品として売ることは長い目で見ていってどうなのか?安い車で海外展開を行ったメーカーは3月決算でほとんど利益出ていない。
日本のものづくりにこだわった自動車メーカーは利益が出ている。特にTOYOTAは震災後、岩手にAQUAの工場を作って、震災復興と日本の技術の復興の両方を行った。こういう事をやると従業員もやる気が出る。
ソフト開発も全く同じ道を歩んでるのでよく分かる。
なぜものが見えなくなるか?それは会社という枠の中でモノを見ているから。ニュートラルに見れなくなるから。
野生の動物を檻の中に入れると、最初は野生に戻ろうと暴れるが、1周間もすると暴れるのを止める。居心地が良くなってしまうから。
みんな最初は社会的使命で職業を選んだはず。そのときはフィルターはなかったので社会が見えてた。会社に入ると居心地が良くなり最初の使命を忘れてしまう。情報が見えなくしてるのは自分自信。
会社は実現の手段であり人生に取ってHow Toでしかなく、職業の選択がWhat、Whyだったはず。
会社に入って居心地が良いと、How Toだったはずの会社がWhat、Whyに変わってしまう。これで商品開発やっても客は永遠に見えない。
これは耳が痛いです。。。
物事の開発の上流はプログラマーや設計ではない。
一番えらいのは現場。現場が作れない設計を出しても認められない。現場が作れるもの以外、図面は書いてはいけない。現場が最上流。
現場の技術開発と設計の開発がパラで動くのが日本のものづくりのはず。
今の日本は、設計が言ったから、設計が言ったから、設計が言ったから...
日本人の良さは、新しい精度や技術に挑戦する現場のものづくりと、その現場の腕を活かそうとする設計が組み合わさったものが本来の日本のものづくり。ここにはトライ&エラーという無駄なものはない。現場の技術を疎かにしたメーカーは今後、永遠にディスカウント合戦とクレーム対応から逃れられなくなる。
なぜなら、設計者は現場の技術以上の図面が描けないから。
「現場の技術を疎かにしたメーカーは今後、永遠にディスカウント合戦とクレーム対応から逃れられなくなる。」は刺さった。
オフショア開発の品質が..というのははよく聞く話だし、オフショアでなくても、安くするために単金の安い協力会社に発注してそれなりのものを作るというのもよくある話。
あと、個人的には、モノを作らない設計者が、現場の技術に着いて行けなくなってるのも怖かったりする。
本当のグローバルはその先にある。
今は日本人が日本の価値観でブランド作ってるが、価値観や概念まで含めて多様化していったとき、日本人の想像力は世界的にもっと力を持てるはず。
エアバスは、デザインはフランス人、質実剛健な構造はドイツ人、質感の高い所はイギリス人がやってる。民族が結集して、それぞれの良さをアセンブリしている。海外化とはこういう事だと思う。
互いの強さを合わせながら新しいものを作り出す。そういう開発やってみたい。
未来は言葉にならない。未来や夢は画像で考えてるはず。未来は言葉では表現できない。
言葉はコミュニケーションツールであって、過去の表現にしかならない。
新しい事をやるときに討論してはいけない。まず一人で考えること。
考えた結果を言葉や画像で見せて、チームでイメージを共有する。
GT-Rを作ったときは「リタイヤした夫婦2人が1週間分の荷物をトランクに詰めて、、ドイツのアウトバーンを走って、、、『こんな時代が来るなんて』と会話してる」こういう車を作ろうぜ、と言った。
「最高速何kmで、ベンチマーク幾つで、、」のような画像にできないものでは目標にならない。
これはなるほどなー、と思った。
最近「これからどうするか?」という討論をやった時に、討論を詰めていっても、現状の問題の反転としての未来(今こういう問題があるから、こう改善されてればいい)しか出てこなかった事を思い出した。
リーダーになって、チーム員と本当に仕事したかったら、会社からもらった権限を忘れること。
今からやる事はかつて世界中で誰もやったことがない仕事なんだ、この人たちは必ず失敗するんだ、失敗を最大限リカバー出来るようにに自分はどんな責任の範囲を貰えばよいか、それだけを考える。
自分はまだここまで腹くくってリーダー出来てないです。確かにこういうリーダーの下だったらみんな全力で作業するよな。
趣味で仕事するからチームがバラバラになる。趣味というのは自分のため。これを「自分らしさ」と勘違いしてる。
「人の喜び」というキーワードがあって、チームで物事が共有できる。
「自分は何やろうか?」と考えてもアイデアは出てこないが、「人のために何をやろうか?」と考えるとアイデアは無限に出てくる。
キーワードは「人の喜び」。「どういうお客さんをどう喜ばせるか」に徹底的に時間を掛けて、具体的な支援に落としこむ。How Toは一番最後に考える。
これは納得。アジャイル開発にも通じる話。
アジャイル開発に通じる話もあったけど、それ以上に、水野さんの仕事への情熱に当てられた2時間でした。水野さん熱かったなー。
公演中に度々紹介されてたスライド。
『時を超える技術』 水野和敏氏 ―あなたと部下を最高の結果に導く極意とは?― - YouTube
午後の部に続く。
DevLOVE関西×仙台 泥臭い受託開発を語り合う に行ってきました
5/17に仙台で開催されたDevLove仙台✕関西に参加してきた。久しぶりのITイベント参加。
当日にまとめてたnemorineさんblogの二番煎じの感はあるけど、出てた内容のまとめ。
今回は勉強会の写真と音声録音からまとめてみたけど、まとめるのに時間かかり過ぎ。次回はPC持って参加する。
炎上プロジェクトの経験を前向きに学ぶ(村上さん) #DevSen
村上さんは現在プロジェクトマネージャ(火元w)。
炎上あるある
- 要件が毎日変わる
- 終わらないレビュー 4回やったら元に戻る。メビウスレビューw
- 赤字覚悟の案件受注 仕様は前と同じでいいよ→前のシステム作られたの10年前→よく見ると新しい機能が追加されてる。。
炎上の対策として管理強化
- プロジェクトマネージメント強化
- PMO取ってみた
- ISO取ってみた
その結果は?
- 手続きが増えた
- 工数が増えた(管理作業のため)
- でも品質は上がらなかった...
何が問題なのか?
みんなの話を聞かない人がいると、そこで情報が止まって、先に進まなくなる。
現場の話が上に報告されず、適切な対応が取られない。
当人は問題意識はなし。
こういう人の特徴
- 積み重ねの概念がない。昨日の結果と今日の結果に連続性がないことが気にならない。
- 連続性がないので何が起きてもずっと正解。悪いのは自分以外のどこか。
- 認めないので反省する事もない。常に自信満々。
- よそから持ってきた対策ばかり。自分で考えてない。
「自信満々」な人への対策
- プロジェクトを進める仲間を増やして、進める話をする。
- 組織やチームの垣根を超えて、情報を伝播していく。
- 真ん中辺りの話は真ん中でやってもらって、実作業は周りで回す。
- 報告はするけど、要求されたところだけ報告する。
- 現場に影響を与えないように無力化する。
- うまくいったら周りに感謝する。
受託だからといって受け身である必要はない (大友さん) #DevKan
お客さんを満足させつつ、楽しく開発するためにやっていたこと。
大友さんは炊事、洗濯、育児をこなすフルスタックエンジニアを目指してるそうw
下請けからみて誰がお客さんか?
一番の発注元を満足させる必要がある。
「誰が何のために」をとことん聞く。本当に要求を持っている人(ドメインを理解している人)にしか答えられない。ここを確認しないまま進めると、ちゃぶ台をひっくり返される。ウォーターフォールでもアジャイルでも関係ない。
受け身じゃないポイント① 本当の要求を持っているユーザまでたどり着く
どうやってお客さんの要求を引き出すか?
質問が違えば当然答えも変わる。時間も掛けられない。
手っ取り早くお客さんの考えを知るにはどうすればよいか?
n次受けに話が来る時は、予算も納期も、問題の解決策も決まってることが多い。
これが弊害になる。「こうなっちゃてるんで...」と言われる。
「念のため教えてください。予算獲得時の資料はありますでしょうか?」と確認。
プロジェクトが発足した当時の資料を見れるように頑張る。
「念のため」は相手の事を思っていますよ、という謙虚な感じが出るので便利。
受け身じゃないポイント② ユーザのコンセプト資料を手に入れる
プロジェクト発足時のユーザの熱い想いが書かれている。
n次受けに来る数ヶ月の間には、ユーザが想いを忘れてることがある。
資料を元に要求分析を作成する。
「なぜなら~だからだ」は必須。
受け身じゃないポイント③ たとえ不要と言われても、要求には「なぜなら」を書く
これがないと言った言わないになる。
開発チームの認識合わせのためにも必須。
開発チームがプロジェクト内で意見を交わすとき、これがないと憶測になる。憶測でケンカまで始める。
「なぜなら」があると、プロジェクトの会話の質が上がる。
楽しく開発するためにやってきたこと
受け身じゃないポイント④ チームが形成される仕組みを積極的に組み入れる
いっぱい話せる仕組みを取り入れる。
朝ミ、夕ミ、ランチ、飲み会、お菓子など。
チーム形成は勝手にはできない。チーム形成のための仕組みを意図的に用意する必要がある。
ほっといてもチームが出来るのであれば、それは優秀な人ばかりだったということ。
普段からどうでもいい事を話していないのに、大事なことを話してくれる訳がない。
受け身じゃないポイント⑤ 良いプロダクトを作る機会では社外もチームととらえ積極的に会話する
社外のチームとも楽しく開発をするためには?
毎日数分のWeb会議を設定してチームの顔を見せる。
週一で直接会って話す。
「我々はチームなので何でも共有します」と宣言する。
これを言っておくと、状況が変わった時に連絡もらえたりする。
泥臭い場所(瑕疵対応とか)とそうでない場所は明確に分けて対応する。
言葉を選ぶことは、時としてコミュニケーションの量よりも重要。
会話の量は仕組みで増やせるが、会話の質は個人に依存するので要注意。
例えば、いつも否定から入る人が「何でも相談して」と言ったところで、そんな人には相談したくない。
「泥臭くない」受託開発なんてない。あるいはTDD/DDDのすすめ(井上さん)#DevSen
SIer勤務。3月に会社を辞めてフリーに。
泥臭い受託開発とは?
SIer辞めたら本当に泥臭くなくなるのか?そうであれば泥臭い受託開発って何だろう?
お客さんが求めるシステムはお客さん毎に全て異なる。
ある技術やプロセスを適用すれば必ずうまくいく、なんてことはない。正解はない。
Why,What,Howを常に探求し続ける必要がある。
レベルの違いはあっても、全ての現場で泥臭くやってるのではないか?
SIer時代について
課題に当たっても最初は力も技術力もない。
歯車感。病みそうになる。
プロジェクトを変わって楽しい仕事に。
テスト駆動開発、XPなど新しいことにチャレンジできた。
周りに意識高い人が多かった。
何よりも、お客さんに良い物を作る事に注力できた。
コードを重要視していた現場だったので、コードを書くのが楽しかった。
悩む日々
- プロセスはウォーターフォール。
- 中間管理職のような立ち位置で、パートナーの管理、書面書きに追われる日々。
- 「決定したことをいかにそのままやるか」という立場になり、コードが書けない!
- 低品質なコードに悩む。リファクタリングは井上さんが忙しくなると回らなくなる。
- システムのWhy、Whatに注意を払う人がいなかった
TDDの良さに改めて気づく。
自分が満足するシステム構築が出来たシステム、井上さん在籍期間バグ0!
問題山積みプロジェクトに...
- 仕様が伝言ゲーム Whyがない
- 終盤ではコストカットで出張禁止 顧客と会うのが年1回ペース
- 仕様が曖昧 ドキュメントとコードが一致しない
- 品質悪(コピペの嵐) リリース後の障害が日常茶飯事
- リファクタリングしても、修正量<追加量で改善が追いつかない。
- スピード感がない
- チーム全体に覇気がない
まとめ
- 全ての「受託開発」は「泥臭い」
- 受託開発の本質は顧客の望むものを一緒に作り上げること
- 自分を変えるのと比較して、周り(チーム/組織/顧客)を変えるのは難しい
- (少なくとも)自分が変わらないと周りは変わらない
- 自分の強みを持ちましょう
- TDD/DDDがおすすめ
自分の力をつけないと、そもそも選択肢がありません!
「私がモテないのはどう考えても受託開発が悪い!」なんてことはない (横山さん) #DevKan
受託開発あるあるチェック
- 要件定義が長引き開発の費用や時間が大幅に減った
- 作ったものが期待するレスポンスで動かない (作り直し)
- 外注したら絶望的な品質の何かが届いた (やっぱり作り直し)
- そういえば今日はメールとExcelしか使っていない
- お客さんからモーニングコールがかかってきた (夜間バッチ障害)
終わらない開発
- 仕様が確定しない
- お客さんの要求が変わる
「こうして欲しいという」要求のなぜ?やそもそもを十分に把握せずに対処してたのが問題。
真意が分からないので、提案や交渉が出来ない。
チームのスキルを無視した技術の採用
- 背伸びしたツールやプロセスの導入
- 要求を実現する方法の調査コスト大
個人の力技で解決
- 技術力を磨く
- 生産性を上げる(ひたすら頑張る)
特定のキーマンがそのプロジェクトの命運を握る。
→いつまで経ってもその人は楽にならない。
受託から自社製品開発に
受託開発でなければ上手くいくかと思い、自社製品の開発を始めてみた。
仕様を自分たちで決められる 要件の認識違いは発生しない。
自分たちで考えた機能をお客さんに褒めてもらえる。
が、売れなかった...
売上に繋がらなくて焦る日々
→お客さんが欲しいものとのギャップが?
→ギャップを埋めるために製品をカスタマイズする
→要件を聞いて希望の納期までに…
どこかで聞いたような、、、
仕事のやり方見直し
知識やスキルは前提条件。
技術力は必要だが、上手く進めるための事前準備でしかない、と自覚する。
プロジェクトは未知への挑戦。
未知の領域に既知が通用するとは限らない。
やるべきことはやる
- 見積もりはしっかりする
- 顧客の真の要求(そもそも)を把握する
- 顧客と交渉する(逃げない)
- 進捗や課題の見える化
- チームのスキルに合わせた技術選定
- チームでの会話を重視する(雑談も)
- チームメンバーの適材適所な役割分担
チームがうまく機能すれば、プロジェクトは劇的によくなると実感。
受託開発の難しさって何だ?
- 複数の会社と連携することの難しさ
- 常に仕事を取るための営業と内部リソースの調整
- 技術スキルのマッチングと社員の育成
受託開発のいいところ
- 色んな技術を習得できるチャンスがある
- お客さんと直に接することが出来る
- お客さんの望んでるものに対して自分達の最高を届ける
どうすれば受託開発が上手く行くのか?
受託開発の難しさは進め方の問題よりも組織やビジネス的な課題の方が大きい。
- 経営上の課題を解決する
- お客さんとしっかり信頼関係を作る
- 現場が正しいと思うことを出来るようにする
サービス企業だけど結構色々あるんですよ (半谷さん) #DevSen
Hadoopで2PBのデータ分析やってます。
対立
本社と開発部隊で対立。各部門間で対立。本社vs地方、ビジネスvsプロデューサー、システムvsプロデューサー、プロデューサーvsエンジニア等。
本社のエンジニアは運用第一 止める/止めないが大事。
地方は新しい技術使いたい。
お互いに対立(3年くらい前)。あいつら全然分かってねぇ。
とは言え悔しいので成果を出そうと頑張った
老朽化したDWHを使ってとにかくSQLを書いた。
老朽化したDWHをHadoopに移行。
374本くらいのSQLをHadoopで動くようにガシガシ書き換え。
震災2ヶ月後にリリース。
こういう事を繰り返して成果を出していった
次第に本社に評価されるようになった。
転機
2011の年末に3ヶ月くらい本社にいて激論交わした。
飲みにも行った。毎週毎月。
本社サービス視点で色々な事を考えてるということが分かった。
本社への態度が軟化していった。
「こういう事をやりたい」と言うと「いいんじゃないの」と言われるようになった。
「心の友よ!」みたいな関係になった。(言われてはいないw)
まとめ
- Face To Faceでやりとりが出来ない環境では、お互いに対する信頼関係、愛が大事
- お互いに対する愛
- プロダクションに対する愛
- お客様、利用者に対する愛
- 嫌とか嫌いとか言うのではなく、受け入れて、やる
- 楽しくやることが重要。笑いながら仕事をする
- あとは酒。酒があれば大抵大丈夫w
ダイアログ
テーマ毎に4グループに分かれて討論。
自分が入ったのは、グループ3:チーム形成のコミュニケーション。
話しやすい場を作るには?という所をメインに話をした。
出た意見としては、
- 朝/夕ミーティング
- 飲み会
- ランチミーティング
- おみやげを取っ掛かりに話をする
- 自分のキャラを立てる(ツッコまれやすくする)
- 相手の良いところを探して褒める
- 接点になる趣味を見つける
- 雑談する(隠し事をしない・させない)
といったところ。
他にチーム作りをどうするか? コミュニケーションが取れない人はどうするか?という話も少ししていたが、こっちはあまりまとまらず。
他チームの意見。前半のはメモし損ねたので、残ってたものだけ。
受け身にならないようにするには
- 「~でいいですか?」ではなく「~でいいですね?」と自分で咀嚼したものを確認する。自分もその決定に対して責任を持つ。
- 相手から言われたことをやるだけでなく、自分たちで受けた話に対して もっとこうすればどうか?ということを確認する。
自分たちが受け身にならないためには
- クオリティ感覚を持つ こうします、品質はこれくらいを保ちますという宣言をする。
- 残業することが受け身 仕事を自分でコントロール出来る人は受け身にならず、自分の時間もコントロール出来るのでは?
- 会社から言われて仕事をするのではなく、自分が会社をこう動かそうと考える。
相手が受け身にならないためには
- プロジェクトと見積りの情報を与える あなたにはこれくらいのお金が掛かってますよ
- 視野が狭いと受け身になる 情報を与えることで受け身にならない
ビアバッシュ
プロジェクトを進めるための方策、XX駆動開発などなど、文書に起こせない話題が色々と。。
感想
チーム、コミュニケーションについての内容で刺さるものが色々あった。
今の仕事で苦労しているが、チーム作りが出来ていなかったことがその一因だという事に気付かされた。
個人の忙しさにかまけて、チームに向き合う時間が取れていなかったので、時間の管理方法が自分の直近の課題。
毎日のミーティングやるようにしてもチームとしての一体感出る感じがなかったので、コミュニケーションの方法ももう少し改善を考える必要あるな。
あと、自分含めて後ろ向きな気持ちで作業してるチームをどうやって前向きにさせるかというのも個人的課題。
チーム作りって本当に難しい。
ヒントを色々貰ったのでまた考えてみる。
主催者の皆さん、会場を提供して頂いた楽天様、参加者の皆様、ありがとうございました。
会場を提供して頂いた楽天さんからもらったノベルティのシール。
Pacemaker+Heartbeatを試してみる(インストール編)
CentOS6でPacemaker、Heartbeatをインストールした時のメモ。
OSデフォルトのものではなく、Linux-HAのサイトからダウンロードしたパッケージを使用する。
RHEL6用リポジトリパッケージからリポジトリパッケージをダウンロードし、/tmpに展開。
展開先は必ず/tmpにする必要があるっぽい。
[root@cent6 ~]# cd /tmp [root@cent6 tmp]# tar xvzf ~/pacemaker-1.0.13-1.2.el6.x86_64.repo.tar.gz
[root@cent6 tmp]# cd pacemaker-1.0.13-1.2.el6.x86_64.repo/ [root@cent6 pacemaker-1.0.13-1.2.el6.x86_64.repo]# yum -c pacemaker.repo install \ pacemaker pm_crmgen pm_diskd pm_logconv-hb pm_extras base | 3.7 kB 00:00 base/primary_db | 4.4 MB 00:08 epel/metalink | 4.9 kB 00:00 epel | 4.4 kB 00:00 epel/primary_db | 6.0 MB 00:11 extras | 3.4 kB 00:00 extras/primary_db | 19 kB 00:00 pacemaker | 2.9 kB 00:00 ... pacemaker/primary_db | 25 kB 00:00 ... pgdg92 | 3.7 kB 00:00 pgdg92/primary_db | 102 kB 00:00 updates | 3.4 kB 00:00 updates/primary_db | 2.6 MB 00:04 Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package pacemaker.x86_64 0:1.1.10-14.el6_5.2 will be installed --> Processing Dependency: pacemaker-libs = 1.1.10-14.el6_5.2 for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: pacemaker-cluster-libs = 1.1.10-14.el6_5.2 for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: pacemaker-cli = 1.1.10-14.el6_5.2 for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libtransitioner.so.2()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libstonithd.so.2()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libpengine.so.4()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libpe_status.so.4()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: liblrmd.so.1()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libcrmservice.so.1()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libcrmcommon.so.3()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libcrmcluster.so.4()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 --> Processing Dependency: libcib.so.3()(64bit) for package: pacemaker-1.1.10-14.el6_5.2.x86_64 ---> Package pm_crmgen.noarch 0:1.4-1.el6 will be installed ---> Package pm_diskd.x86_64 0:1.3-1.el6 will be installed --> Processing Dependency: heartbeat >= 3.0.3 for package: pm_diskd-1.3-1.el6.x86_64 --> Processing Dependency: cluster-glue >= 1.0.6 for package: pm_diskd-1.3-1.el6.x86_64 --> Processing Dependency: libplumb.so.2()(64bit) for package: pm_diskd-1.3-1.el6.x86_64 --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pm_diskd-1.3-1.el6.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pm_diskd-1.3-1.el6.x86_64 ---> Package pm_extras.x86_64 0:1.4-1.el6 will be installed --> Processing Dependency: libhbclient.so.1()(64bit) for package: pm_extras-1.4-1.el6.x86_64 --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pm_extras-1.4-1.el6.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pm_extras-1.4-1.el6.x86_64 --> Processing Dependency: libcib.so.1()(64bit) for package: pm_extras-1.4-1.el6.x86_64 ---> Package pm_logconv-hb.noarch 0:1.3-1.el6 will be installed --> Processing Dependency: pacemaker < 1.1 for package: pm_logconv-hb-1.3-1.el6.noarch --> Running transaction check ---> Package cluster-glue.x86_64 0:1.0.11-1.el6 will be installed --> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 --> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 --> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 --> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 ---> Package cluster-glue-libs.x86_64 0:1.0.11-1.el6 will be installed ---> Package heartbeat.x86_64 0:3.0.5-1.1.el6 will be installed ---> Package heartbeat-libs.x86_64 0:3.0.5-1.1.el6 will be installed ---> Package pacemaker-cli.x86_64 0:1.1.10-14.el6_5.2 will be installed ---> Package pacemaker-cluster-libs.x86_64 0:1.1.10-14.el6_5.2 will be installed ---> Package pacemaker-libs.x86_64 0:1.1.10-14.el6_5.2 will be installed ---> Package pm_diskd.x86_64 0:1.3-1.el6 will be installed --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pm_diskd-1.3-1.el6.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pm_diskd-1.3-1.el6.x86_64 ---> Package pm_extras.x86_64 0:1.4-1.el6 will be installed --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pm_extras-1.4-1.el6.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pm_extras-1.4-1.el6.x86_64 --> Processing Dependency: libcib.so.1()(64bit) for package: pm_extras-1.4-1.el6.x86_64 ---> Package pm_logconv-hb.noarch 0:1.3-1.el6 will be installed --> Processing Dependency: pacemaker < 1.1 for package: pm_logconv-hb-1.3-1.el6.noarch --> Running transaction check ---> Package OpenIPMI-libs.x86_64 0:2.0.16-14.el6 will be installed ---> Package openhpi-libs.x86_64 0:2.14.1-6.el6 will be installed ---> Package pm_diskd.x86_64 0:1.3-1.el6 will be installed --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pm_diskd-1.3-1.el6.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pm_diskd-1.3-1.el6.x86_64 ---> Package pm_extras.x86_64 0:1.4-1.el6 will be installed --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pm_extras-1.4-1.el6.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pm_extras-1.4-1.el6.x86_64 --> Processing Dependency: libcib.so.1()(64bit) for package: pm_extras-1.4-1.el6.x86_64 ---> Package pm_logconv-hb.noarch 0:1.3-1.el6 will be installed --> Processing Dependency: pacemaker < 1.1 for package: pm_logconv-hb-1.3-1.el6.noarch --> Finished Dependency Resolution Error: Package: pm_extras-1.4-1.el6.x86_64 (pacemaker) Requires: libcrmcommon.so.2()(64bit) Available: pacemaker-libs-1.0.13-1.el6.x86_64 (pacemaker) libcrmcommon.so.2()(64bit) Available: pacemaker-libs-1.1.10-14.el6.i686 (base) Not found Available: pacemaker-libs-1.1.10-14.el6_5.1.i686 (updates) Not found Available: pacemaker-libs-1.1.10-14.el6_5.2.i686 (updates) Not found Error: Package: pm_logconv-hb-1.3-1.el6.noarch (pacemaker) Requires: pacemaker < 1.1 Available: pacemaker-1.0.13-1.el6.x86_64 (pacemaker) pacemaker = 1.0.13-1.el6 Available: pacemaker-1.1.10-14.el6.x86_64 (base) pacemaker = 1.1.10-14.el6 Available: pacemaker-1.1.10-14.el6_5.1.x86_64 (updates) pacemaker = 1.1.10-14.el6_5.1 Installing: pacemaker-1.1.10-14.el6_5.2.x86_64 (updates) pacemaker = 1.1.10-14.el6_5.2 Error: Package: pm_diskd-1.3-1.el6.x86_64 (pacemaker) Requires: libcrmcommon.so.2()(64bit) Available: pacemaker-libs-1.0.13-1.el6.x86_64 (pacemaker) libcrmcommon.so.2()(64bit) Available: pacemaker-libs-1.1.10-14.el6.i686 (base) Not found Available: pacemaker-libs-1.1.10-14.el6_5.1.i686 (updates) Not found Available: pacemaker-libs-1.1.10-14.el6_5.2.i686 (updates) Not found Error: Package: pm_extras-1.4-1.el6.x86_64 (pacemaker) Requires: libcib.so.1()(64bit) Available: pacemaker-libs-1.0.13-1.el6.x86_64 (pacemaker) libcib.so.1()(64bit) Available: pacemaker-libs-1.1.10-14.el6.i686 (base) Not found Available: pacemaker-libs-1.1.10-14.el6_5.1.i686 (updates) Not found Available: pacemaker-libs-1.1.10-14.el6_5.2.i686 (updates) Not found Error: Package: pm_diskd-1.3-1.el6.x86_64 (pacemaker) Requires: libcrmcluster.so.1()(64bit) Available: pacemaker-libs-1.0.13-1.el6.x86_64 (pacemaker) libcrmcluster.so.1()(64bit) Available: pacemaker-libs-1.1.10-14.el6.i686 (base) Not found Available: pacemaker-libs-1.1.10-14.el6_5.1.i686 (updates) Not found Available: pacemaker-libs-1.1.10-14.el6_5.2.i686 (updates) Not found Error: Package: pm_extras-1.4-1.el6.x86_64 (pacemaker) Requires: libcrmcluster.so.1()(64bit) Available: pacemaker-libs-1.0.13-1.el6.x86_64 (pacemaker) libcrmcluster.so.1()(64bit) Available: pacemaker-libs-1.1.10-14.el6.i686 (base) Not found Available: pacemaker-libs-1.1.10-14.el6_5.1.i686 (updates) Not found Available: pacemaker-libs-1.1.10-14.el6_5.2.i686 (updates) Not found You could try using --skip-broken to work around the problem You could try running: rpm -Va --nofiles --nodigest
何だか大量のエラーが出る。。
Linux-HAのサイトの説明を読むと、OS同梱のpacemakerが展開されないように、pacemakerはバージョン指定でインストールする必要があるっぽい。
念のため、heartbeatもリポジトリ同梱バージョン指定で一緒にインストール。
[root@cent6 pacemaker-1.0.13-1.2.el6.x86_64.repo]# yum -c pacemaker.repo install \ pacemaker-1.0.13 heartbeat-3.0.5 pm_crmgen pm_diskd pm_logconv-hb pm_extras Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package heartbeat.x86_64 0:3.0.5-1.1.el6 will be installed --> Processing Dependency: heartbeat-libs = 3.0.5-1.1.el6 for package: heartbeat-3.0.5-1.1.el6.x86_64 --> Processing Dependency: cluster-glue-libs for package: heartbeat-3.0.5-1.1.el6.x86_64 --> Processing Dependency: cluster-glue for package: heartbeat-3.0.5-1.1.el6.x86_64 --> Processing Dependency: libplumb.so.2()(64bit) for package: heartbeat-3.0.5-1.1.el6.x86_64 --> Processing Dependency: libhbclient.so.1()(64bit) for package: heartbeat-3.0.5-1.1.el6.x86_64 --> Processing Dependency: libapphb.so.2()(64bit) for package: heartbeat-3.0.5-1.1.el6.x86_64 ---> Package pacemaker.x86_64 0:1.0.13-1.el6 will be installed --> Processing Dependency: pacemaker-libs = 1.0.13-1.el6 for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libstonithd.so.0()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libpe_status.so.2()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libesmtp.so.5()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 --> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.0.13-1.el6.x86_64 ---> Package pm_crmgen.noarch 0:1.4-1.el6 will be installed ---> Package pm_diskd.x86_64 0:1.3-1.el6 will be installed ---> Package pm_extras.x86_64 0:1.4-1.el6 will be installed ---> Package pm_logconv-hb.noarch 0:1.3-1.el6 will be installed --> Running transaction check ---> Package cluster-glue.x86_64 0:1.0.11-1.el6 will be installed --> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 --> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 --> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 --> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.11-1.el6.x86_64 ---> Package cluster-glue-libs.x86_64 0:1.0.11-1.el6 will be installed ---> Package heartbeat-libs.x86_64 0:3.0.5-1.1.el6 will be installed ---> Package libesmtp.x86_64 0:1.0.4-16.el6 will be installed ---> Package pacemaker-libs.x86_64 0:1.0.13-1.el6 will be installed --> Running transaction check ---> Package OpenIPMI-libs.x86_64 0:2.0.16-14.el6 will be installed ---> Package openhpi-libs.x86_64 0:2.14.1-6.el6 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================= Package Arch Version Repository Size ============================================================================= Installing: heartbeat x86_64 3.0.5-1.1.el6 pacemaker 162 k pacemaker x86_64 1.0.13-1.el6 pacemaker 5.6 M pm_crmgen noarch 1.4-1.el6 pacemaker 47 k pm_diskd x86_64 1.3-1.el6 pacemaker 13 k pm_extras x86_64 1.4-1.el6 pacemaker 25 k pm_logconv-hb noarch 1.3-1.el6 pacemaker 31 k Installing for dependencies: OpenIPMI-libs x86_64 2.0.16-14.el6 base 473 k cluster-glue x86_64 1.0.11-1.el6 pacemaker 261 k cluster-glue-libs x86_64 1.0.11-1.el6 pacemaker 110 k heartbeat-libs x86_64 3.0.5-1.1.el6 pacemaker 263 k libesmtp x86_64 1.0.4-16.el6 pacemaker 57 k openhpi-libs x86_64 2.14.1-6.el6 base 135 k pacemaker-libs x86_64 1.0.13-1.el6 pacemaker 262 k Transaction Summary ============================================================================= Install 13 Package(s) Total download size: 7.4 M Installed size: 14 M Is this ok [y/N]: y Downloading Packages: (1/13): OpenIPMI-libs-2.0.16-14.el6.x86_64.rpm | 473 kB 00:01 (7/13): openhpi-libs-2.14.1-6.el6.x86_64.rpm | 135 kB 00:00 ----------------------------------------------------------------------------- Total 3.0 MB/s | 7.4 MB 00:02 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : cluster-glue-libs-1.0.11-1.el6.x86_64 1/13 Installing : heartbeat-libs-3.0.5-1.1.el6.x86_64 2/13 Installing : pacemaker-libs-1.0.13-1.el6.x86_64 3/13 Installing : OpenIPMI-libs-2.0.16-14.el6.x86_64 4/13 Installing : openhpi-libs-2.14.1-6.el6.x86_64 5/13 Installing : cluster-glue-1.0.11-1.el6.x86_64 6/13 Installing : heartbeat-3.0.5-1.1.el6.x86_64 7/13 Installing : libesmtp-1.0.4-16.el6.x86_64 8/13 Installing : pacemaker-1.0.13-1.el6.x86_64 9/13 Installing : pm_diskd-1.3-1.el6.x86_64 10/13 Installing : pm_logconv-hb-1.3-1.el6.noarch 11/13 Installing : pm_extras-1.4-1.el6.x86_64 12/13 Installing : pm_crmgen-1.4-1.el6.noarch 13/13 Verifying : libesmtp-1.0.4-16.el6.x86_64 1/13 Verifying : pacemaker-libs-1.0.13-1.el6.x86_64 2/13 Verifying : pm_diskd-1.3-1.el6.x86_64 3/13 Verifying : cluster-glue-1.0.11-1.el6.x86_64 4/13 Verifying : openhpi-libs-2.14.1-6.el6.x86_64 5/13 Verifying : OpenIPMI-libs-2.0.16-14.el6.x86_64 6/13 Verifying : pm_logconv-hb-1.3-1.el6.noarch 7/13 Verifying : pm_crmgen-1.4-1.el6.noarch 8/13 Verifying : heartbeat-3.0.5-1.1.el6.x86_64 9/13 Verifying : heartbeat-libs-3.0.5-1.1.el6.x86_64 10/13 Verifying : cluster-glue-libs-1.0.11-1.el6.x86_64 11/13 Verifying : pm_extras-1.4-1.el6.x86_64 12/13 Verifying : pacemaker-1.0.13-1.el6.x86_64 13/13 Installed: heartbeat.x86_64 0:3.0.5-1.1.el6 pacemaker.x86_64 0:1.0.13-1.el6 pm_crmgen.noarch 0:1.4-1.el6 pm_diskd.x86_64 0:1.3-1.el6 pm_extras.x86_64 0:1.4-1.el6 pm_logconv-hb.noarch 0:1.3-1.el6 Dependency Installed: OpenIPMI-libs.x86_64 0:2.0.16-14.el6 cluster-glue.x86_64 0:1.0.11-1.el6 cluster-glue-libs.x86_64 0:1.0.11-1.el6 heartbeat-libs.x86_64 0:3.0.5-1.1.el6 libesmtp.x86_64 0:1.0.4-16.el6 openhpi-libs.x86_64 0:2.14.1-6.el6 pacemaker-libs.x86_64 0:1.0.13-1.el6 Complete!
インストール成功。
(追記)
ネットワーク接続できない環境でpacemakerをインストールする時のコマンド。
[root@cent6 pacemaker-1.0.13-1.2.el6.x86_64.repo]# yum -c pacemaker.repo --disablerepo='*' --enablerepo=pacemaker \ install pacemaker-1.0.13 heartbeat-3.0.5 pm_crmgen pm_diskd pm_logconv-hb pm_extr
CentOSデフォルトのPacemakerがインストール済みの環境だとインストールに失敗するため、アンインストールしてからインストールする。
# rpm -aq|grep pacemaker pacemaker-cluster-libs-1.1.7-6.el6.x86_64 pacemaker-cli-1.1.7-6.el6.x86_64 pacemaker-libs-1.1.7-6.el6.x86_64 pacemaker-1.1.7-6.el6.x86_64 # rpm -e pacemaker pacemaker-cluster-libs pacemaker-cli pacemaker-libs pm_extras