Top Banner
クリスマスを支える 俺たちとJava 阪田 浩一 フリュー株式会社 関西Javaエンジニアの会 1
181

クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

Jul 15, 2015

Download

Technology

jyukutyo
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

クリスマスを支える  俺たちとJava

阪田  浩一  フリュー株式会社  

関西Javaエンジニアの会

1

Page 2: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

22

@jyukutyo

著書 3冊

関西Javaエンジニアの会 (関ジャバ) 中の人・発起人

blog:Fight the Future http://jyukutyo.hatenablog.com/

フリュー株式会社 所属

エンジニア歴12年 36歳SI業界での客先常駐 9年 Web系? 3年

文学部哲学科卒

塾講師アルバイト

阪田 浩一

Page 3: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

要約

3

普通のエンジニアたちが

Page 4: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

要約

4

いろんな  技術的課題、  

プロセスの課題、  チームの課題に

Page 5: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

要約

5

ぶつかりつつも  サービスを開発、運用  しているお話です

Page 6: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

6

扱えないこと:  大規模サービスを  

運用する  ベストな方法

Page 7: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

目次

7

• 対象となるアプリケーションについて  • わき上がる課題とその対処  • RDBMS編  • JVM編  • サーバ編  

• まとめ

Page 8: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

要約

8

本題へ

Page 9: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

9

僕たちのアプリケーションは  クリスマスの負荷に  耐えられずにいた

Photo by Yuichi Sakuraba https://flic.kr/p/9JYRSQ

Page 10: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

10

そう、クリスマスは  1年で最もアクセスが  

ある日

Photo by Yuichi Sakuraba https://flic.kr/p/9JYRSQ

Page 11: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

11

恋人たちがみんな  撮影をする日だからだ

Photo by Yuichi Sakuraba https://flic.kr/p/9JYRSQ

Page 12: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

12

撮影?  そう、プリントシール機  

での撮影…

Page 13: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

プリントシール機とは

13

Page 14: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

14

弊社フリュー株式会社は  プリントシール機の  トップメーカーです

Page 15: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

15

全国の機械の  半分以上がフリューです

Page 16: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

16

なのですが、  今回はこの筐体の  実装ではなく

Page 17: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

簡単な図

17

ここの詳細に  ついてです

Internet

Page 18: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

Webとの関係は?

18

撮影した画像は  Webサイト/アプリから  

取得できます

Page 19: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

19

アプリを除く  Webシステム部分  (サイト、API、DB、  ファイルサーバなど)  について話します

Page 20: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

20

会員数1000万人:  10代から20代の女性  

(女子高生は  クラスほぼ全員が会員)

Page 21: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

サービスの概要

21

サービス名 ピクトリンク

会員数1000万人  

(有料会員数は秘密…)

主な機能プリントシール機で  撮影した画像を  取得できる

提供Webサイト  iOSアプリ  

Androidアプリ

課金携帯電話キャリア課金  

(月額制)

PV 数百万PV/日

Page 22: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

会員数の推移

22

Page 23: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

23

画像は10億枚弱  (うかつにcount(*)も  

できない)

Page 24: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

24

大規模と思っています

Page 25: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

25

現システムは  4年前に構築  

(前身サービスは  2003年に開始)

Page 26: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

私の立ち位置

26

私は3年前にJoinし、  今サイト開発のリーダ  

という立場です  (つまりリリース後参画)

Page 27: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

開発チーム

27

アプリ開発  (ネイティブ/API)  

7名

サイト開発  7名

インフラ  (サーバ/NW/DBA)  開発部門全体2名  チーム内2名  

ログ分析  2名

HTML/CSS  2名

Page 28: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

28

リリース後1,2年は  クリスマスに  

サービスが瀕死

Photo by Yuichi Sakuraba https://flic.kr/p/9JYRSQ

Page 29: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

29

なぜか?

Page 30: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

30

まず、Webサーバの  ロードアベレージが  非常に高かった

Page 31: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

31

平日は数百万PV/日  だが  

クリスマスはその4倍

Photo by Yuichi Sakuraba https://flic.kr/p/9JYRSQ

Page 32: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

32

夕食の時間「前後」に  とくに集中する  (ピークタイムが  

数時間単位となる)

Photo by Yuichi Sakuraba https://flic.kr/p/9JYRSQ

Page 33: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

33

リクエストが  さばけていない

Page 34: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

34

プリントシール機で  撮影した画像(プリ画像)  を保存する処理なので  軽い処理ではない

Page 35: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

35

ここでサーバ構成を  紹介

Page 36: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

現在のサーバ構成

36台数は概数です

ユーザが保存処理を実行するまでの1週間分のみ  

Page 37: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

37

ちょっと横道へ

Page 38: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

38

MogileFSとは:  分散ファイルシステム  

(OSS)

Page 39: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

MogileFSとは

39

tracker:  管理サーバ。  

クライアントとやり取りする。

storage:  ファイル保存  サーバ。  

同一ファイルを  複数台で保持。  

ファイルにはHTTP  でアクセスできる。

metadata:  RDBMS。  

ファイル情報や  全体の設定を  保存する。

Page 40: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

40

ストレージノードが  数十台  

(まだ増え続ける…)

Page 41: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

41

ここまで大きな問題は  出ていない

Page 42: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

42

ファイルやノードを  管理するMySQLが  ボトルネックとなる  かもしれない

Page 43: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

43

ストレージノードは  現実的には何台まで  

いけるのかわからないので、だんだん怖くなっている

Page 44: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

44

リクエストが  さばけていない件

Page 45: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

45

対応:Webサーバを  台数追加した

Page 46: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

46

教訓:お金を払おう

Page 47: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

47

解決(えっ

Page 48: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

48

サーバは  増やせば対応できたが

Page 49: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

49

今度は  RDBMSが  

ネックとなってくる

Page 50: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

50

next:RDBMS編

Page 51: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

51

ここでアーキテクチャを  紹介

Page 52: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

アーキテクチャ

52

JavaフレームワークSeasarファミリー  

(Cubby/S2Dao  etc)

ファイルシステム  (画像ファイル保存)

MogileFS

RDBMS Oracle  11g(メイン)  MySQL  5.6

Webサーバ/  サーブレットコンテナ

Apache/  Tomcat

Javaバージョン 6  -­>  8

Page 53: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

53

• 近い将来メモリが不足する予測ができた  

• IO性能が悪かった  • レコード件数が多い  • (テーブル設計もベストではないが)

Page 54: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

54

クエリやインデックスを  変更してコストを削減、  

でどうにかなる  レベルではなかった

Page 55: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

55

RDBMSの移行

Page 56: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

56

変更前 Oracle  Database  11g    Standard  Edition 1台

変更後Oracle  Database  11g    Real  Application  Clusters(RAC)

複数台

Page 57: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

57

RACとは:  ロードバランス型の  

Oracleクラスタリング構成

Page 58: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

58

Copyright© 2011, Oracle. All rights reserved.

5.7

RACのスケーラビリティRACの特長

11

OracleInstance

OracleInstance

OracleInstance

• RACは、全ノードがデータベースの全データにアクセスでき、Active-Activeの構成をとることが可能

• RACは、ノード追加によるスケールアウトで性能向上

processprocess

processprocess

processprocess

「実践!高可用性システム構築  〜~RAC基本編〜~」より引用

Page 59: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

59

全ノードが全データに  アクセスできる  

Acitve-­Active構成  となる

Page 60: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

60

さらに  ハードウェアも変更した

Page 61: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

61

パフォーマンスは  劇的に改善した

Page 62: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

62

解決(えっ

Page 63: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

63

教訓:お金を払おう

Page 64: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

64

ただ、そうした増強分も  使い果たしつつある

Page 65: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

65

レコードが増えたことで  見えていなかった問題が  

浮き彫りになる

Page 66: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

66

DBAが来るまで、  DBサーバのOS、  Oracleとも  

適切にパラメータが  設定されていなかった

Page 67: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

67

そうしたパラメータを  1つずつ精査しつつ…

Page 68: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

68

クエリのコストや  実行回数を  調査すると…

Page 69: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

69

DBA「夜間バッチの  1クエリがコスト  500万です!」

Page 70: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

70

理由:テーブルを  フルスキャンしている

Page 71: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

71

テーブルに  インデックスは…

Page 72: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

72

貼られている!

Page 73: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

73

クエリもインデックスを  使ったカラムを  where句で  指定している

Page 74: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

74

ログに出したSQL文を  SQLDeveloperで  

実行してもすぐ終わる。  実行計画でも  

インデックスを使っている

Page 75: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

75

しかし実環境では  DATE型カラムへの  インデックスが  使われていない。

Page 76: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

76

???

Page 77: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

77

Oracleを見てみる

Page 78: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

78

SELECT SA.SQL_ID, NAME, WAS_CAPTURED, BC.LAST_CAPTURED, VALUE_STRING, anydata.accesstimestamp(value_anydata), datatype_string, sql_text FROM GV$SQL_BIND_CAPTURE BC, GV$SQLAREA SA   WHERE BC.HASH_VALUE = SA.HASH_VALUE AND SA.SQL_ID = 'hoge'   ORDER BY LAST_CAPTURED DESC;

Page 79: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

79

datatype_string -> TIMESTAMP

Page 80: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

80

バインド変数の  値の型(Oracle上)が  

TIMESTAMPと  なっている!

Page 81: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

81

Javaアプリケーションでの型 java.util.Date

永続化ライブラリでの型 java.sql.Timestamp

JDBCでセットする時の型 java.sql.Types.Timestamp

Oracleでの型 TIMESTAMP

Page 82: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結論:

82

OracleのDATEは  ANSI定義と異なり  時間の情報を持つ

Page 83: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結論:

83

Types.Timestampとすることで  時間情報も保持していた  

が、そのために  OracleでTIMESTAMPとなり  インデックスが使われなかった

Page 84: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結論:

84

対応:Oracle独自の  PreparedStetementを  

使うことにした

Page 85: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

対応:

85

if (ps instanceof OraclePreparedStatement){ OraclePreparedStatement ops =

(OraclePreparedStatement) ps; // Oracle JDBCドライバ独自のメソッド、引数の型を利用する

ops.setDATE(index, new oracle.sql.DATE(new java.sql.Timestamp(toDate(value).getTime())));

} else { ps.setDate(index, toSqlDate(value)); }

Page 86: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

86

コスト:  500万  -­>  8万

Page 87: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

87

大勝利

Page 88: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

88

ってか何年間も  誰も気づかなかったのか

Page 89: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

89

教訓:実行計画を  SQLクライアントで  見るだけでなく  

実環境の実行コストも  見よう

Page 90: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

90

RDBMS関連だと  こんな問題も  ありました

Page 91: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

91

企画「アプリでiOSの  絵文字を使えるように  

したい!」

Page 92: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

92

お、Unicodeで  定義された  絵文字だな

Page 93: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

93

SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER=‘NLS_CHARACTERSET'; !-> JA16SJISTILDE

Page 94: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

94

Shift_JISェ…

Page 95: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

95

「NVARCHAR2に  カラムの型を  

変更すればいける!」

Page 96: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

96

JDBCでNVARCHAR2列  に絵文字を入れる場合、  

JVMパラメータに  「-Doracle.jdbc.defaultNChar=true」  を追加する必要がある

http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/java.102/B19275-03/global.htm

Page 97: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

97

先にJVMパラメータだけ  つけてアプリケーション  

起動しておくか  (ステージングでは  

問題なし)

Page 98: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

98

そう、あのときの  俺たちには  何の疑念も  

なかったんだ…

Page 99: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

99

再起動した瞬間に  全ユーザが  

ログインできなくなる  (正確にはものすごく遅い)

Page 100: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

100

理由:テーブルを  フルスキャンしている

Page 101: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

101

defaultNChar=true すると、VARCHAR2カラム  

のバインド変数に  SYS_OP_C2C関数が  

適用される

Page 102: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

102

とあるテーブルのカラムhogeが  VARCHAR2型のとき、  

defaultNChar=trueがあると…

PreparedStetemetの  SQL

where hoge = ?

Oracleで実行される  SQL

where hoge = SYS_OP_C2C(:1)

Page 103: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

103

hogeへの  インデックスが  使われない

Page 104: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

対応:

104

SYS_OP_C2C関数を  使った  

関数インデックスを  すべて作成した

Page 105: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

105

教訓:実行計画を  SQLクライアントで  見るだけでなく  

実環境の実行コストも  見よう

Page 106: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

将来:

106

UTF-­8への移行を  計画中

Page 107: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

将来:

107

next:JVM編

Page 108: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

108

ある日、  JVMオプションがほとんど  

設定されていないことに気づく  (XmxとPermGenくらい)

Page 109: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

109

僕「GCログ出してみよう。」  -Xloggc:gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=10M

Page 110: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

110

数日後

Page 111: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

111

Page 112: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

112

僕「なんてこった…」

Page 113: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

113

確保しているヒープ:  最大3.2GB  

フルGC時間:  最大0.9秒/回

Page 114: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

114

こんなにヒープ領域  使うほどのシステムでは  

ないような…  これかなりSTWしてるよね

Page 115: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

115

対応:GCアルゴリズムを  CMSにしよう!  

※CMS  =  Concurrent  Mark  &  Sweep  !-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSClassUnloadingEnabled

Page 116: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

詳細:

116

GCアルゴリズムの変更前後

変更前Parallel GC【デフォルトGC】 (マイナーGCのみをパラレルで)

変更後

CMS GC【J2SE 1.4から】 ご存じない方は、ぜひsugarlife's blogさんの

ブログエントリ「CMS GC おさらい」を! http://cco.hatenablog.jp/entry/2014/12/01/162240

Page 117: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

117

確保した  最大ヒープ領域

STW時間

変更前 3.2GB 最大 0.9秒/平均0.5秒

変更後 1.2GB 最大0.23秒/平均0.2秒

0

1

2

3

4

変更前 変更後

1.2

3.2

0

0.225

0.45

0.675

0.9

変更前 変更後

0.23

0.9

Page 118: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

118

大幅改善!

Page 119: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

119

Page 120: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

120

ただし、CMSは  CPUリソースを使うので、  スループットが低下する  

恐れがある

Page 121: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

121

僕らの場合、  スループットが1%低下し  

CPUの負荷も  やや上がった

Page 122: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

122

教訓:JVMは  デフォルトでも  かなりいける  (人類の叡智)

Page 123: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

123

教訓:ただし、  測定はしておき、  増加傾向が出たら  対処していく  

(最初から考えすぎない)

Page 124: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

124

ある日、  アクセスの少ない夜中に  OutOfMemoryError  

が発生し、  再起動する

Page 125: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

125

「-­XX:+HeapDumpOnOutOfMemoryError」  しているので  

ダンプファイルがある

Page 126: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

126

java_pid<9999>.hprof  4.3GB…

Page 127: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

127

このダンプファイル  どうしたらいいんだっけ?

Page 128: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

128

Eclipse  Memory  Analyzer(mat)  

を使う

https://eclipse.org/mat/

Page 129: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

インストール方法

129

• Eclipseプラグインとして     Update  Managerからインストール  • スタンドアローン版をダウンロード

Page 130: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

130

いろいろな方法で  可視化してくれた

Page 131: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

131

Page 132: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

132

ふむ…

Page 133: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

133

Page 134: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

134

Page 135: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

135

Page 136: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

136

うん…

Page 137: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

137

Page 138: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

138

ん!?

Page 139: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

139

net.rubyeye.xmemcached.impl.MemcachedTCPSession

のインスタンスが  ヒープの85.28%を  

占めてる!

Page 140: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

140

1インスタンスが200MB  とか…

Page 141: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

141

対応:このライブラリの  バージョンを上げよう!

Page 142: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

142

教訓:  「-­XX:+HeapDumpOnOutOfMemoryError」  

ほんとに役立つ!  (これまで本番で  

OOME出たことなかった)

Page 143: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

143

ある日、Java  SE  8が  リリースされる

Page 144: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

144

もう6から8に  したくてしょうがなくなる

Page 145: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

145

まずTomcatの  起動VMを6から8に  

してみた

Page 146: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

146

結果:何も問題  なかった

Page 147: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

147

プロジェクトのJDKを  6から8にしてみた

Page 148: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

148

結果:ユニットテストが  ほとんど全部エラーになる

Page 149: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

149

Caused  by:  java.lang.ArrayIndexOutOfBoundsException:  31038     at  org.objectweb.asm.ClassReader.<init>(Unknown  Source)  

  at  org.objectweb.asm.ClassReader.<init>(Unknown  Source)  

  at  org.objectweb.asm.ClassReader.<init>(Unknown  Source)  

  at  org.objectweb.asm.ClassReader.<init>(Unknown  Source)  

  at  jp.co.dgic.testing.common.AsmClassModifier.getModifiedClass(AsmClassModifier.java:49)  

Page 150: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

150

JUnit  +  djUnit…

Page 151: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

151

indyが入ったことで  djUnitが依存している  ASMがエラーとなる

Page 152: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

152

ASMを最新にすると  APIが変わり  

djUnitがエラーとなる

Page 153: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

153

うーん…

Page 154: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

154

djUnitを止め、  違うモックライブラリを  

使うことにする

Page 155: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

155

対応:jMockitにして  テストケースを  すべて書き直す

Page 156: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

156

jMockitにした理由:  djUnitにある機能が  

すべてそろっていたから  (意味を考えずに  置換できる)

Page 157: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

157

その他対応:  Javassistでエラーが  出たりしたので、  これもバージョンを  

上げた

Page 158: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

結果:

158

教訓:  Java  SE  8を  導入しよう  

(せめて実行環境  からでも!)

Page 159: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

159

next:サーバ編

Page 160: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

160

そうこうしている間に  サーバ台数が  増えてきた

Page 161: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

161

再起動時に  各サーバのログ見るの  

面倒だなあ

Page 162: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

162

全台SSHで  tail  -­f  

(less  +Fも僕してたよ!)

Page 163: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

163

見てられん…

Page 164: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

164

ログ収集:  fluentd  +  Elasticsearch  

+  Kibana  で見るのが楽になった

Page 165: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

165

Page 166: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

166

fluentdでサーバ全台の  ログを集め、  

それ1つを見るだけで  済む

Page 167: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

167

さらに

Page 168: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

168

Page 169: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

169

Kibanaで可視化  される

Page 170: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

170

教訓:  「ログの可視化は  

エンジニアの責任」

Page 171: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

171

ログはHDFSにも  入れているので  将来的に利用する  

予定だ

Page 172: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

172

話は変わり、  継続的に  

サーバが追加される状況

Page 173: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

173

サーバ追加で  いちいちインストール  

してられん…

Page 174: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

174

サーバ構築:  Ansible化を  進めている

Page 175: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

175

結局、去年は  クリスマスに  

何も起こりませんでした

Photo by Yuichi Sakuraba https://flic.kr/p/9JYRSQ

Page 176: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

176

今日の教訓のまとめ  • お金を払おう  • 実行計画をSQLクライアントで見るだけでなく実環境

の実行コストも見よう  • JVMはデフォルトでもかなりいける(人類の叡智)  • ただし、測定はしておき、増加傾向が出たら対処し

ていく(最初から考えすぎない)  • Java  SE  8を導入しよう(せめて実行環境からでも!)  • ログの可視化はエンジニアの責任

Page 177: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

まとめ

177

スーパーエンジニアが  いるわけじゃない

Page 178: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

まとめ

178

普通のエンジニアたちが  悪戦苦闘しながら  運用してるよ

Page 179: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

まとめ

179

かっこいい方法じゃ  ない部分もあるけど、  

運用できてる!

Page 180: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

まとめ

180

また  こうやって得たものを  発信したいです!

Page 181: クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)

181

ご清聴  ありがとうございました