Mongo DB Casual Talksに行ってきた
あんまりMongo DB Casual Talks のブログがないようなので、ざっくり書きます。
「MongoDBのアレをアレする」 by [twitter:@kuwa_tw] さん
- クラスタが遅い1
- 必要なデータを一気にインポート
- oplogが許容範囲を超えてレプリケーションが停止
- PrimaryShardにChunkが溜まってI/Oバウンドに
- 負荷が高いのでBalancerは動かない
- クラスタが遅い2
- ShardするCollectionのShard設定漏れ
- PrimaryShardでデータファイルが多くなりつづけてメモリマップドファイルのサイズをこえてI/Oバウンド
- ShardしてないのでもちろんBalancerは動かない
- 本当に突然パフォーマンスダウンする
- PrimaryShardは余裕を持たせておく
- Shard設定は定期的に確認、もしくはShardの設定を自動化する
- バックアップ
- mongos経由でAutoBalancingをoff
- 各レプリカセットにfsync lock
- 各mongodにmongodumpを実行してバックアップ取得
- 各レプリカセットにfsync unlock
- mongos経由でAutoBalancingをon
- 障害時にみるもの
- mongostat
- mongotop
- アクセスが集中しているcollectionの確認
- mongosniff
- 最後の手段のパケットキャプチャ
- mongosのアクセス状況、複雑のクエリを見る
- db.adminCommand("connPoolStats")
- Sharding環境におけるconnectionpoolの統計
- db.serverStatus()
- サーバの現在の状態の確認
恐らく国内では最大のMongoDBユーザであるCyberAgentさんの経験から得られる運用ノウハウ。
一つ一つはどこかで聞いた話ではあったが、まとめてあるとまだまだ色々問題ありますね。
カジュアルに100台運用はできません。
CAさんには、「今だからできる、MySQLを採用した場合とのコスト比較」とかやってほしい。
※ Fusion-io積んだMySQL10台でリプレイス可能とかだったら面白いのに。。
「Casual Compression on MongoDB」 by [twitter:@just_do_neet] さん
- MongoDBの欠点
- トランザクション未サポート
- Global Lock
- システムリソース(メモリ、ディスク)が肥大化
- データ圧縮未対応(通信、データストア共に)
- セキュリティ周りが弱い
- MongoDBはHBase(Snappy圧縮)の三倍強のデータサイズ
- BigDataを扱う環境にはあまり向かない
- スケールするがゆえに、下手にそれなりの規模のシステムに導入するとサーバ無限増殖の刑に。。
- フィールド名をできるだけ短く
- BSONでデータを保持しているので、1つのドキュメントの中にフィールド情報を持つ
- 複数のレコードが同一のフィールド名を持っていても、1レコード毎に情報を持つ
- 特定のデータをbinary形式で保存
- 小さい正整数の整数符号化
- 整数符号化で保存したら、Integerよりサイズが大きくなった。。
データサイズが大きくなりがちなMongoDBで、データ圧縮ができないかというアプローチ。
安定したパフォーマンスを出すために、データがメモリに乗り切る範囲で運用するというのは、
よくとられる手法なので、データ圧縮ができるとサーバが少なくてすむので貴重なお話。
最大で2/3程まで圧縮が可能であるが、圧縮したフィールドは検索に使えなくなるので、柔軟な検索が
できなくなる弊害があるなど、使用するにはアプリケーションの特性をよく見てからということですね。
「MongoさんをAWSへお迎えする」 by [twitter:@understeer] さん
- 10genがAWSでMongoDB売ってる
- ディスク性能は複数のEBSをソフトウェアRAIDすることで、ある程度いける
- インスタンスを大きくすると回線も大きくなる
- スナップショットでバックアップ
- mongodをFlush&Lock
- db.fsyncLock();
- Filesystemをfreeze
- xfs_freeze -f /path/to/mongo
- 各ボリュームのスナップショット取得
- ec2-create-snapshot -d xxx vol-xxxx
- FilesystemのunfreezeとMongodのUnlock
- xfs_freeze -u /path/to/mongo
- db.fsyncUnlock();
- mongodをFlush&Lock
- スナップショットからリストア
- 各スナップショットからボリューム作成
- ec2-create-volume-snapshot snap-xxxx
- 各ボリュームをアタッチ
- ec2-attach-volume-device /dev/sdf/vol-xxxx
- RAID、LVM復旧、MongoDB起動
- 各スナップショットからボリューム作成
MongoDBによるカジュアルなタイムラインシステムの実装 by [twitter:@hito_asa] さん
MongoDBを利用したタイムラインシステムのおはなし
タイムライン機能を作る際のフォロワーのIDを取ってきて、さらにそのフォロワーのコンテンツを
取ってくると言った処理が重いのでなんとか簡単にしたい。
- TimeLine Design
- 有限長
- 最新のみ保持
- 追記のみ
- 常に時系列での取得
- 追記、取得が早い
- ユーザ毎にCAPPED COLLECTION
- 200万コレクションの世界
- 普通では作れないので、nssizeを変更
- データベースのコレクションの上限が60万なので、上限に達したら新たなデータベースを作成
- すぐSWAPする
- mongoコンソールがsuggestで落ちる
- GLOBAL LOCKのため、コレクションの削除で止まる
- 応答時間が安定しない
- 教訓
- コレクションはたくさん作らない
- 1インスタンスでたくさんDBを作らない
- シビアな応答性能を求めない
- MongoDBをカジュアルに導入しない
個人的には一番面白かった発表。是非、この路線で突っ走って貰いたい。
CAPPED COLLECTIONは、TIMELINE機能で欲しい機能のいくつかを持っているので、うまいこと
機能拡張してくれると面白そう。
カジュアルにMongoDBのBackup機能説明 by [twitter:@matsukaz] さん
- mongexportはJSON/CSV形式でデータを出力
- 全てのデータ型をサポートしているわけではない
- data_binary
- data_date
- data_timestamp
- data_regex
- data_oid
- data_ref
- 全てのデータ型をサポートしているわけではない
- mongodumpはBSON形式でデータを出力
- データは正しい情報のまま
- Onlineでの実行も可能
- 実行中はパフォーマンスに影響あり
- ただし、小規模での利用を想定したもの
- データは一箇所に出力される
- officialなバックアップ手順
- balancerを止める
- 全PrimaryをLock
- config情報をBackup
- SecondaryのデータをBackup
- 全PrimaryをUnlock
- balancerを有効化
- 欠点として、Lock時間が長くかかる
- Lock時間を短くしたバージョン
- balancerを止める
- 全PrimaryをLock
- config情報をBackup
- Secondaryを落とす
- 全PrimaryをUnlock
- balancerを有効化
- 落としたSecondaryをBackup
- 落としたSecondaryを起動
うん。SecondaryをLockして、バックアップを取ろう。
カジュアルにソースコードリーディング by [twitter:@choplin ] さん
MongoDBソースコードリーディングの成果の発表。
- 追記型
- 更新を削除と挿入の組み合わせで実現する
- 同時制御の処理が簡潔
- データ容量が肥大
- 書き込み処理の負荷
- ガベージの発生
- In-place Update
- 既存のサイズを超えない場合、ドキュメントまるごとの追記を行わず、必要な値のみ書き換える
- Padding Factor
- In-place Updateを行うために予め、Padding領域を確保する。
- どれだけPaddingするかのfactor
- Default 1.0
- Min 1.0、Max 2.0
- Update + 0.6
- Insert / (In-place Update?) -0.01
- In-place Updateを行うために予め、Padding領域を確保する。
CasualなMongoDBのサービス運用Tips by [twitter:@nsega] さん
MongoDBを1年間運用して得たTipsを惜しまず出します。
- Tips1:定期的な計測
- Collection/Document数
- db.usercollection.find.count()
- db.usercollection.stats()
- Shardingの偏り
- printSahrdingSize()
- Disk使用状況の把握
- df -hT
- Collection/Document数
- Tips2:定期的なバックアップ
- 停止可能な場合は、データファイルをコピーすればOK
- 停止不可の場合は、Secondaryからバックアップ
- Tips3:定期的なデータ最適化
- 定期的にReparDatabaseコマンドを実施
- mongod --repair
- db.repariDatabase
- 定期的にReparDatabaseコマンドを実施
- Tips4:定期的なバージョンアップ
- 性能、機能改善
- バグfix
Casual Sucks by [twitter:@repeatedly] さん
- oplogには限界がある
- oplog collectionはcapped collectionなので、sizeの制約がある。それを超えると。。。
- マスターマスターで片方のデータが一瞬消える
- クライアントの実装アプローチが違う
mongoengineでカジュアルな有向グラフ by [twitter:@bibrost] さん
- MongoEngineを使って、カジュアルに有向グラフを扱えるPythonライブラリ作ったよ。(mongo-directedgraph)
- MongoDBはスモールデータを扱うには、よい選択。ミドルやビッグを扱うとダメ
mongodbとfluentdの素敵な関係 by [twitter:@stanaka] さん
退職しました。
正確には、2012年2月末日を持って、約2年半お世話になった会社を退職します。
現在は有給休暇消化中です。
音楽業界というかなり特殊な業界で仕事ができたこと、ドコモMUSICストアやAndoroid向けストアの立ち上げ等
非常に稀有な経験ができたと思います。(著作権のことなんかも地味に勉強になりました。)
退職する理由は色々ありますが、データ解析をやりたかったってのが一番大きな理由です。
データがあるところに行くと胸を張って言える程の経験も知識もないですが、一歩を踏み出さないと
自分の成長はないと、去年、色んな勉強会(特にMongoDB勉強会)に参加して思いました。
3月からは遅ればせながら、ソーシャル業界でお世話になります。
現職では、テクニカルな仕事よりもプロマネやアーキテクト的な仕事にウエイトを置いていましたが、
次の職場ではデータ解析基盤の構築&運用をメインにやることになっているので、Hadoop、MySQL等と
戯れることになるかと思います。(直近は引越しの手伝い?かもw)
おまけ
ソーシャル転職が最近話題ですが、私は勉強会の資料やブログを見た転職エージェントからFacebook経由で
コンタクトを頂きました。
会社に直接電話してきたヘッドハンターやLinkedin経由で連絡してきた転職エージェントも数名いましたが、
会社の代表電話に自社の社名を名乗り、何度も連絡をしてくるヘッドハンターは、迷惑以外なにものでも
ないので辞めて頂きたい。(最初は電話に出なかったのですが、さすがに3回目あたりで出ざるを得ませんでした)
しかも、「XXXXで有名な人を、G社に年俸XXX万で入社させた」など個人情報を電話口で暴露し、本人の
希望も聞かずにとにかくG社とD社に入社させようとしているエージェントも居ますので、これから転職しようと
考えている人は、まずは信用できるエージェントかどうかを確認した方がよいかと思います。
転職エージェント全てが悪いという事ではないですが、お金になる所には、当然質の悪い人(会社)も居ると
いうことを認識しておいたほうが良いかと。
(今回の転職でお世話になった方は、非常に良い方でした。)
ソーシャルメディア、ソーシャルアプリが育てたNoSQL技術に参加してきました
震災の影響で2カ月程延期されていた ソーシャルメディア、ソーシャルアプリが育てたNoSQL技術 に参加してきました。
参加者がそのままスライドした影響か、ATND上では定員を大きく上回る参加あったが、実際の参加者が少なく結構席も空いていました。
MongoDBで作るソーシャルデータ新解析基盤 [twitter:@doryokujin]
- 旧解析基盤(MongoDBとHadoopを活用)の処理フロー
- Data Gathering
- 分散するサーバから各種ログをローカルに収集
- 課金・登録情報の該当データをMySQLから取得
- ユーザゲームセーブデータをCassandraから取得
- Data Pre-processing(Hadoop)
- ログ整形
- フィルタリング
- Data Analysis(Hadoop)
- ユーザIDをキーにした各指標値を集計
- アクセスログの集計
- イベントの効果測定
- Result Data Strage(MongoDB)
- Data Mining
- Data Sharding
- 新解析基盤(MongoDB、Redis、Scribeを活用)の処理フロー
- Data Gathering(Scribe)
- 1時間毎にサーバからログファイルを転送
- Data Pre-processing
- Raw Data Strage(MongoDB)
- Shard Keyにhourを指定し、Shard0 - Shard23に1つずつ割り当てるマニュアルSharding
- Shardingの各種問題対策にもなるし、データが追加されているshardについても把握できる
- 自動Balancerも停止
- mongod1つに対し、1CPUしか使えないため、複数Shardを1台の物理サーバに同居
- 解析結果格納用のShardはSSDを使い高速にする
- Shard Keyにhourを指定し、Shard0 - Shard23に1つずつ割り当てるマニュアルSharding
- Data Analysis(MongoDB + Redis)
- Result Data Strage(MongoDB)
- Data Mining
- Data Sharding
本番で使うための"Cassandra"ガイド [twitter:@_shimada]
- 強み、弱み、落とし穴
- 勝手にシャーディング
- スケールアウトが容易
- キーの設計を間違うと、1か所にデータが集中
- 勝手にレプリケーション
- 反映に掛る時間はベストエフォート
- スレーブが反映前のデータを返すことも
- 勝手にフェイルオーバー
- 落ちたノードへの書き込みは自動的に他のノードが受け取り一時保管
- ノードが復帰したらデータが書き戻される
- スケールアウトと負荷分散
- ノードを追加すると、データが一番多いノードからデータを半分引き取る
- データの整合性
- 読み書きのパフォーマンス
- 読み出しよりも書き込みの方が早い
- コミットログ書き出し:
- 読み込み:書き込みの速度比、書き込みが8倍程早い
- 勝手にシャーディング
- まとめ
- 大量のデータを大量のサーバで捌く
- 一部で障害が起きても全体の整合性
- 書き込み速度重視
- データの整合性を犠牲にして、速度を上げることができる
"HandlerSocket": MySQLの非SQLインタフェース
- 概要
- 狙い
- mobageへの導入
- 最初の適用箇所
- 利点(libmysqlと比較して)
- CPUを食わない
- サーバ側、クライアント側のいずれも効果あり
- 特に単純なクエリで差が大きい
- ネットワークトラフィックが減らせる
- 特に単純なクエリでおおきい
- 同時接続数がほぼ無制限
- すくなくとも65000本までは可能
- 同時接続数を増やしても性能劣化がほとんどない
- CPUを食わない
- HandlerSocketに向いているケース
- データサイズが小さく十分小さくメモりに乗る
- 単純なクエリ、サーバのCPUがネック
- 単純なクエリ、トラフィックがネック
- 同時接続数が多すぎて、維持接続がつかえない
- HandlerSocketに不向きなケース
- クエリが複雑でHandlerSOcketで実現困難
- クエリ1回あたりのCPU負荷が大きい
- データサイズが大きくDisk IOがネック
- 機能(参照系)
- PKやUKを使った行取得
- 範囲取得
- SQLのINのような複数行取得
- 機能(更新系)
- libmysqlとの性能比較
- 単純な参照クエリで数倍〜10倍
- 取得する列数が多くなる場合に特に有効
- なぜ早くなるか
- 課題
第3回 MongoDB勉強会に参加&発表してきました
遅くなりましたが、第3回MongoDB勉強会に参加&発表してきました。
前回の勉強会後に、doryokujinさんが発表されたshardingについての検証記事を書いてたところ、今回の発表のお話を頂いたので、
折角なのでやらせて頂くことにしました。
次のブログのネタとして考えていた、MongoDBのクエリのチューニングのアプローチ方法は、PostgreSQLなどのRDBMSと比べて
どの程度使えるのかと言う点をまとめて発表させて頂くことにしました。
MongoDB全機能解説1 [twitter:@doryokujin]
2時間ぶっ通しでの発表。充実した内容で本当に頭が下がります。
今回は、MongoDBの全機能解説ということで、MongoDBの構成、Insertとその周辺、Query、Update 、Index 、Replicationの解説です。
- MongoDBの構成
- mongod
- m基本的にシングルスレッドしか使えず、多くのオペレーションに対してロックがかかる(v2.0〜v2.2で改善予定)
- read/writeに対してDB全体に対してロックがかかる
- Capped Collection
- 固定サイズのcollection。古いデータから自動削除されるが、パフォーマンスが良い。
- collectionを作る際にindexは自動で作成されない。
- 挿入順で取得するのがパフォーマンス的には最適
- Sharding不可
- ログやcacheなどの用途がおすすめだが、一度作成すると容量を増やすには一旦削除する必要があるので注意。
- mongod
- Insertとその周辺
- Bulk Insert
- 個々のInsertより高速
- 最適な配列サイズはデータ依存のため、環境に合わせる必要あり。大きすぎるとエラーが発生。
- デフォルトでは結果を確認していないため、全てのInsertが成功している保証はないので、getLastErrorで確認が必要。
- fsync
- メモリ上のデータをディスクに書き込む
- デフォルトでは60秒毎に実行される
- 障害発生時には、60秒間のデータロストが発生する可能性がある。
- Journaling
- write-ahead-log
- データ書き込み前に、オペレーションをjournalファイルに記述
- 障害時にはjournalファイルからオペレーションを再実行し、リカバリを行う
- journalファイルへの書き込みは100ms毎に実行されるため、100ms間のデータロストの可能性は以前残る。
- Bulk Insert
- Query
- Sub Object形式は順序依存
- Dot Notation形式のクエリが安全
- Update
- in-place-update
- オブジェクトサイズが増えない場合は、その場でupdate されるため高速
- 領域に収まらない場合は、領域が移動されるため遅くなる
- in-place-update
- Index
- B-tree indexを採用
- バックグラウンドでのindex作成が可能
- Replicationの解説
- 特徴
- Master-Slave:1master - N slaveの構成
- Replica Sets:自動フェイルオーバーなど
- masterとslaveの間は非同期通信
- Relicationの設定、管理、メンバー追加、削除は非常に簡単
- slaveからの読み出しは可能(書き込みは不可)
- Master - Slave
- 最低2台からの構成が可能
- Slaveの追加、撤退は容易
- Slaveからの読み出しは可能
- Replica Sets
- 自動フェイルオーバー
- メンバーの自動リカバリ
- 最低3台から構成可能
- Slaveからの読み出しは可能
- 特徴
「ソーシャルアプリのプロトタイプ制作にMongoDBを活用」〜PHP+Sleepy.Mongooseでお手軽永続化〜 [twitter:@bibrost]
前回に引き続きbibrostさんによる発表。
MongoDBチューニング [twitter:@matsuou1]
私の結論としては、MongoDBではRDBMSとほぼ同じチューニングのアプローチ方法が取れます。RDBMSでチューニング経験がある人は、
違和感なくやれると思います。むしろ、JOINがない分、簡単かと。ただ、バックエンドで使う分には十分な方法が提供されているが、
フロントエンドで使うには、実行回数が多い&ちょっとだけ遅いクエリを特定する方法が現状ないので、注意して見て行く必要があります。
この辺りは今後のバージョンアップに期待しましょう。(PostgreSQLでも8.4辺りからの実装でしたしね)
複合インデックス辺りをもう少し詳しく書く予定でしたが、直前に炎上中のプロジェクトごと投げられて時間が取れなかったので、
仕事が落ち着いたらブログでもう少し詳しく検証して行きたいと思います。
「MongoDBを使用したモバイルゲーム開発について」 [twitter:@ygenki]
既に定番となっているサイバーエージェント枠。
東京ガールズスナップは、勉強会殺しになりうる危険な存在。
- MongoDBでよかったこと
- 階層構造と相性が良い
- 仕様変更に対し柔軟に対応が可能
- バイナリデータの保存が可能
- 課題
- オペレーションミスでデータが消える(updateで$setをつけてないとか)
- データ型が変わる(int → double)
- ドキュメント設計
toggter [twitter:@kimukou_26]
まとめ&所感
全機能解説は本当にすばらしい。気をつける必要があるポイントが多数記載されているため、非常に有用。
Replicationについての検証は後でやってみたいと思う。そろそろ、ちゃんとした検証用サーバが欲しい・・・。
今回、初めて発表させて頂いたが、「発表するとフォロワー増えるよね。ポポポポーン」を実感しました。
まずは、情報を発信することが大事ですね。
第13回R勉強会@東京に行ってきた
前回に引き続き、第13回R勉強会@東京(#TokyoR)に参加してきました。
今回はついに60人が参加。エンジニア以外の人が多いので、いつもと違う色んな話が聞けて楽しい。
R と .NET Framework[twitter:@kos59125]
資料は こちら を参照。
- Rを.NetFrameworkから操作するためのライブラリ R.NET についてのお話。
- パッケージなんかも普通に使える。
- ユーザと開発者を募集中。
Rで学ぶロバスト推定 [twitter:@sfchaos]
- 分析データに外れ値がつきもの
- ロバスト推定とは、外れ値を除外せずに、受ける影響を小さくして頑健なモデルを推定する方法
とりあえずデータをそのまま線形回帰分析しても、望ましい結果が得られないので、何かしらの対処が必要。
Rで地理空間分析 地理データのとりあつかい@酒井
- 地理空間データマイニングのトレンド
- 分析はR
- 視覚化はOpen系のGIS Quantam GISやGoogleEarth
- 空間データの格納はPostgreSQL(PostGIS)
- 地理空間データ分析で苦労するところ
- 地物・イベントとその場所を表現したデータ
- 集めるのはたいへん
- 集めたあと視覚化するのがたいへん
- どのように視覚化するといいのか考えるのがたいへん
- 視覚化したあとの解釈がたいへん
商業施設計画に利用するモデリング技術(1998)
- 比較法
- 経験則 100%
- チェックリスト 63%
- 類推モデル 33%
- 比率分析 30%
- 予測モデル
- 重回帰モデル 42%
- 判別分析 12%
- クラスター分析 42%
- 重力モデル 37%
- 知識ベース
- エキスパートシステム 9%
- ニューラルネットワーク 14%
説明がしづらいモデルは人気がない。(意思決定者が統計に詳しい訳ではないので、直感的な分かりやすさが求められる)
- 地理空間データの特徴
- 分布そのものに何らかの意味がある
- 空間パターンのコンテキスト(文脈)を読み意思疎通をするためには「相手」と「自分」の認識の差を理解する必要がある。
- ビジネス地理空間分析の手法
- 地理的集計分析(商圏分析など)
- 点プロセス分析
- 領域最適化分析
- クラスター分析
- 空間データをdataframeみたいに・・・
- 空間データ
- Points
- Lines
- Polygons
- 地理空間データ
- 投影法
- sp packageのクラス
- SpatiaPoints
- SpatialPointsDataFrame
- 空間データ
YjdnJlpパッケージとTokyo.R翻訳プロジェクトの紹介[twitter:@yokkuns]
YjDnJlpについての発表は第2回さくテキの内容とほぼ同じ。(テキストが退職ブログになってた以外は・・・。)
形態素解析はYjdnJlpパッケージとMeCabを使用しても大きな差はでないが、特徴語抽出については、以下の2段階のフェーズで行われるため大きな差がでる。
・キーワードをカウント
・コーパス内でどれくらい使われる語かをみて、スコアを算出。
どのコーパスを使うかで、結果に大きく影響がでる。(Yahooのコーパスは不明・・・)
togetter [twitter:@kimukou_26]
まとめ
- 最近は、発表前日に資料を書くのが流行。
- CRANの読み方は、「シーラン」派と「クラン」派が壮絶な戦いを繰り広げている。迂闊な発言は危険。
- もう少しRの勉強が進んだら、パッケージ本を読みたい。Bigmemoryとか気になる。
- 地理空間を扱うのはPostGISが有名だが、MongoDBも忘れて貰ったら困るぜよ。
MongoDBのShardingを試してみた。その3 障害発生時の挙動について
今回はMongoDBのSharding環境にて、各サーバが停止した場合の挙動について検証してみたいと思います。
mongosサーバ
最初はmongosサーバです。
早速、mongosサーバを落としてみましょう。
[matsuou1@testsvr mongodb]$ kill -2 14973
次に、mongosサーバに接続してみます。
[matsuou1@testsvr mongodb]$ ./bin/mongo localhost:10000/logdb MongoDB shell version: 1.8.0 connecting to: localhost:10000/logdb Tue Apr 19 23:51:28 Error: couldn't connect to server localhost:10000 shell/mongo.js:81 exception: connect failed
当然と言えば当然ですが、mongosサーバへの接続に失敗します。
まとめ
想定通り、mongosサーバに接続できなくなりました。
各shardには問題なく接続でき、クエリの実行も可能ですが、複数shardをまたがるようなクエリの実行は出来なくなります。
下手な構成な場合は単一障害点となりうるので、基本的にはwebサーバやアプリサーバなど実際にアプリケーションが動作するサーバで
実行させて、プロセスの死活監視を行い、障害が発生したらプロセスの再起動を行う感じの運用になるのではないでしょうか。
mongosは、単なるルーティングプロセスでデータの管理はしないので、復旧時に特に気を使う必要はないかと思います。
shardサーバ
次は、3つあるshardサーバのうち1つを落としてみます。
shard3のプロセスIDを確認し、落としてみます。
[matsuou1@testsvr mongodb]$ kill -2 18436
試しにカウントを取ってみましたが、エラーとなります。
> db.logs10.count() Tue Apr 19 14:45:54 uncaught exception: count failed: { "assertion" : "DBClientBase::findOne: transport error: localhost:10003 query: { count: \"logs10\", query: {} }", "assertionCode" : 10276, "errmsg" : "db assertion failure", "ok" : 0 } > db.logs10.count() Tue Apr 19 14:45:57 uncaught exception: error { "$err" : "socket exception", "code" : 11002 }
shard keyでアクセスし、shard3以外のshardのみにアクセスする場合は、クエリ―は実行可能
> db.logs10.find({ uid : "f26AKDmNMkIXXXXt"}) { "_id" : ObjectId("4da7d407af13de0b7c6XXXX0"), "month" : "2010/02", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/02/28 16:00:51", "path" : "/?pid=P07K&sid=E74D&uid=1", "device" : "940P" } { "_id" : ObjectId("4da7d407af13de0b7c6c35cd"), "month" : "2010/02", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/02/28 16:01:12", "path" : "/", "device" : "940P" } { "_id" : ObjectId("4da7d407af13de0b7c6c369d"), "month" : "2010/02", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/02/28 16:06:06", "path" : "/index.html", "device" : "940P" } { "_id" : ObjectId("4da7d44aaf13de0b7c7aa66d"), "month" : "2010/03", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/03/31 16:51:34", "path" : "/?pid=P07K&sid=E74D&uid=1", "device" : "940P" }
障害中に実行可能なクエリのまとめ
shard環境では、targetedとglobalの2つのタイプのクエリに分けられます。
targetedは、最小限のshard(多くの場合は1つのみ)にアクセスし、globalはほぼ全てのshardにアクセスします。
つまり、このタイプの違いによって、障害中に実行可能かどうかが分かれることになります。
クエリのタイプについては、マニュアルの Operation Types を参照してください。
- targetedクエリ
- 実行可能なクエリの例
・shard keyを指定して、落ちているshard以外のshardの検索
・shard keyを指定して、落ちているshard以外のshardのアップデート
・インサート
- globalクエリ
- 実行不可能なクエリの例
・shard keyを指定して、落ちているshardのデータの検索
・shard keyを指定しない検索
まとめ
shard障害が発生すると、障害shardを参照するクエリは実行エラーとなるが、問題ないshardへのshard keyを使用したクエリは実行可能。
アプリへの影響が大きいので、基本的にはReplica set を構成し、冗長化を行うべきです。
configサーバ
最後に、configサーバが落ちた場合についてです。
先ほどと同じように、configサーバを落としてみます。
[matsuou1@testsvr mongodb]$ kill -2 27480
この状態で、以下の操作を行ってみます。
- shardの追加、削除
まずは、shard4を新たに起動します。
[matsuou1@testsvr mongodb]$ ./bin/mongod --shardsvr --port 10005 --dbpath /tmp/mongodb/shard4 --logpath /tmp/mongodb/log/shard4.log &
adminサーバより、addshardコマンドを実行します。
[matsuou1@testsvr mongodb]$ ./bin/mongo localhost:10000/admin MongoDB shell version: 1.8.0 connecting to: localhost:10000/admin > db.runCommand( { addshard : "localhost:10005" } ); Wed Apr 20 00:48:51 uncaught exception: error { "$err" : "socket exception", "code" : 11002 }
想定通りにエラーとなります。クラスタのメタデータを管理するサーバが落ちているので当然ですよね。
- 大量データロード
次に大量のデータをロードし、chunkがどのようになるか確認します。
1行のみ入れてあるcollectionに対し、100万行程のアクセスログをインポートしてみます。
logdb.logs12 chunks: shard0000 1 { "timestamp" : { $minKey : 1 } } -->> { "timestamp" : { $maxKey : 1 } } on : shard0000 { "t" : 1000, "i" : 0 }
chunkの分割や移動は行われなくなるため、色々大変となるところの検証を行うつもりでいたのですが、
shardやmongosが大量のExceptionを吐いて、mongoimportが激遅に。。。
shardのログ
Wed Apr 20 01:24:23 [initandlisten] connection accepted from 127.0.0.1:46419 #53871 Wed Apr 20 01:24:23 [conn53871] end connection 127.0.0.1:46419 Wed Apr 20 01:24:23 [initandlisten] connection accepted from 127.0.0.1:46421 #53872 Wed Apr 20 01:24:23 [conn53846] end connection 127.0.0.1:46369
mongosのログ
Wed Apr 20 01:25:57 [conn2] DBException in process: socket exception Wed Apr 20 01:25:57 [conn2] ~ScopedDBConnection: _conn != null Wed Apr 20 01:25:57 [conn2] DBException in process: socket exception Wed Apr 20 01:25:57 [conn2] ~ScopedDBConnection: _conn != null Wed Apr 20 01:25:57 [conn2] DBException in process: socket exception
わざわざ、configサーバを落とした状態でmongoimportする人はなかなかいないと思いますが、エラー吐きまくりな状態になるのでやめておいたほうが無難です。時間があったら、もう少し調査&最新版で検証してみます。
まとめ
configサーバ障害が発生すると、システムのメタデータはリードオンリーになるため、shardの追加、削除などは出来なくなります。
システムは機能し続けますが、chunkの分割や移動は行われなくなるため、このタイミングで大量のデータロードを行うとmigrateできないために、アンバランスなshardができてしまう可能性があります。(マニュアルより。。。)
また、configサーバが落ちている場合は、クラスタのメタデータが必要なためmongosサーバが起動できません。
configサーバと同時にmongosサーバも落ちた場合は、先にconfigサーバ復旧後にmongosサーバを復旧させる必要があります。
マニュアルでは、ダメージは大きくないよと記載されていますが、意外なところで思わぬバグ等を踏む可能性もあるので、可能な限り早く復旧しましょう。
全体まとめ
今回は、sharding環境構成する3つのサーバに対し、それぞれ障害が発生した場合にどういう現象が発生するか検証してみました。
障害発生時に焦るよりは、障害発生時にどのような状況になるのかを事前に把握し、速やかに復旧させたいですね。
障害が発生しない、または、きちんと冗長構成を取っておくのが良いのは、間違いないのですが。
色々、踏み込めてない気がするので、時間があれば後で追記するかもしれません。
Rで線形単回帰分析
次回のTokyo.Rの開催が近づいてきたので、前回の復習を兼ねてRで回帰分析をやってみます。
今回は最も単純な線形単回帰分析を行います。
回帰式を求める意義があるか検討
無相関なデータに対しても、数学的には回帰式が求められるため、検討しておくことは重要です。
データはマンガでわかる統計学 回帰分析編のデータを使用してみます。
ある喫茶店のアイスティーの売り上げとその日の最高気温についてのデータです。
> norns temperture icetea 8/22 29 77 8/23 28 62 8/24 34 93 8/25 31 84 8/26 25 59 8/27 29 64 8/28 32 80 8/29 31 75 8/30 24 58 8/31 33 91 9/01 25 51 9/02 31 73 9/03 26 65 9/04 30 84
回帰分析
ここまでデータについて確認してきましたが、回帰分析をやる意味がありそうなので、早速回帰分析をやってみましょう。
回帰分析は、lm関数を使うことで簡単にできます。
まずは、lm関数の書式を確認します。
lm関数
- 書式
lm(formula, data, subset, weights, na.action,method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE,singular.ok = TRUE, contrasts = NULL, offset, ...
- 引数
引数名 | 必須 | 説明 |
---|---|---|
formula | ○ | 当てはめられるモデルのシンボリックな記述式 |
data | ○ | モデル中の変数を含むオプションのデータフレーム |
subset | 当てはめ過程で使われる観測値の部分集合を指定 | |
weights | 当てはめ過程で使われるオプションの重みベクトル | |
na.action | データが NA を含むときそれを処理する関数 | |
method | 使われるメソッド | |
model | x, y, qr 論理値.もし TRUE なら当てはめの成分 (モデルフレーム,モデル行列,目的変数,分解) が返される | |
singular.ok | 論理値. もし FALSE なら特異な当てはめはエラーとされる | |
contrasts | オプションのリスト | |
offset | これは当てはめの途中で,線形予測子に含められるべきことが事前に知られている成分を指定するのに使える |
- formulaの書式について
- y~x
- y~x-1
1は、通常の線形単回帰分析で使用するが、2は定数項がない場合に使用する。
自動車のガソリンの消費量と走行距離など、説明変数が0の場合、目的変数が必ず0になる強い仮定がある場合にのみ使用する。
- 戻り値
戻り値名 | 説明 |
---|---|
coefficients | 係数の名前付きベクトル |
residuals | 残差,つまり目的変数から当てはめ値を引いたもの |
fitted.values | 当てはめられた平均値 |
rank | 当てはめ線形モデルの数値計算によるランク |
weights | (重みつき当てはめだけに該当) 指定された重み |
df.residual | 残差自由度 |
call | 呼出し式 |
terms | 使われた terms オブジェクト |
contrasts | (関係するときだけ) 使われた対比 |
xlevels | (関係するときだけ) 当てはめで使われた因子の水準の記録 |
y | もし要求されたなら使われた目的変 |
x | もし要求されたなら使われたモデル行列 |
model | もし要求されたなら (既定),使われたモデルフレーム |
実行結果
では、実際にlm関数を使って、回帰分析をやってみます。
> norns.lm <- lm(icetea~temperture , data=norns) > summary(norns.lm) Call: lm(formula = icetea ~ temperture, data = norns) Residuals: Min 1Q Median 3Q Max -8.037 -5.693 2.094 4.409 8.225 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -36.3612 14.6873 -2.476 0.0292 * temperture 3.7379 0.5012 7.457 7.66e-06 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 5.709 on 12 degrees of freedom Multiple R-squared: 0.8225, Adjusted R-squared: 0.8077 F-statistic: 55.61 on 1 and 12 DF, p-value: 7.661e-06
コード自体は2行しかないので、実行は超簡単です。
分析結果のサマリは、summary関数で見ることができます。
以下、summaryの各項目について見て行きましょう。
Residuals
残差の四分位数
(四分位数とは、分布の左側からの相対頻度の合計値(累積相対頻度)が 25%、50%、75% になる値のこと)
Min 1Q Median 3Q Max -8.037 -5.693 2.094 4.409 8.225
Coefficients
Estimate Std. Error t value Pr(>|t|) (Intercept) -36.3612 14.6873 -2.476 0.0292 * temperture 3.7379 0.5012 7.457 7.66e-06 ***
Estimate:係数
Std.Error:標準誤差
t value:t値
pr(>|t|):p値
回帰分析においては y=a+bx において b=0 となることはあってならず、b=0となると y=a となり、x は y に影響を与えないことになってしまいます。
それでは回帰分析が成立しないので(ここでいう b=0 のことを帰無仮説とよぶ)、b=0となることを棄却できるかどうか考えなくてはなりません。
そこで p値を見ます。p値は帰無仮説が発生する確率なので、0.01以下ならばその推定値は99%の有意水準、0.1以下ならば90%の有意水準ということになります。
また、有意であるならば横に *(星)がつきます。何パーセントかは
Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1
をみればわかります。
つまり、星は'***'で、p値が小さければ小さいほど良いということです。
Multiple R-squared , Adjusted R-squared
Multiple R-squared: 0.8225, Adjusted R-squared: 0.8077
Multiple R-squared:寄与率、決定係数
Adjusted R-squared:調整済み寄与率、調整済み決定係数
寄与率には説明変数が多くなる程、値が大きくなる欠点があるので、自由度調整済み寄与率を使用する。
(線形単回帰分析では、そんなに気にする必要はないが、重回帰分析では意識して扱う必要がある。)
これは1に近いほど予測値と観測値が近くなることを表し、モデルの正確性を表す。
値に対する基準はないが、「0.5以上」を一つの目安として扱う。
回帰式
上記結果から以下の回帰式が得られる。
y = 3.7379x -36.3612
plotしてみると、こんな感じになる。
> plot(norns) > abline(norns.lm , lwd=1 , col="blue")
予測値
回帰式で計算される値を予測値(推測値)は、summary関数では返却されない。
予測値を返すためには、predict関数を用い算出する。
> norns.predict <- predict(norns.lm) # 予測値 > norns.residuals <- residuals(norns.lm) # 残差 > data.frame(norns, norns.predict , norns.residuals) temperture icetea norns.predict norns.residuals 8/22 29 77 72.03744 4.962555 8/23 28 62 68.29956 -6.299559 8/24 34 93 90.72687 2.273128 8/25 31 84 79.51322 4.486784 8/26 25 59 57.08590 1.914097 8/27 29 64 72.03744 -8.037445 8/28 32 80 83.25110 -3.251101 8/29 31 75 79.51322 -4.513216 8/30 24 58 53.34802 4.651982 8/31 33 91 86.98899 4.011013 9/01 25 51 57.08590 -6.085903 9/02 31 73 79.51322 -6.513216 9/03 26 65 60.82379 4.176211 9/04 30 84 75.77533 8.224670
得られた回帰式の妥当性の検証
残差を視覚的に分析するために、回帰診断図を表示してみます。
回帰診断図は、回帰分析結果をplotすることで表示できます。
> par(mfrow=c(2,2)) > plot(norns.lm)
以下に、それぞれのグラフが何を示しているかを確認しましょう。
残差とフィット値のプロット(左上)
横軸が予測値、縦軸が残差。
残差の全体像を概観するために使用する。
残差の正規Q-Qプロット(右上)
データの正規性考察するために使用する。
データが正規分布に従っている場合は、直線上に並ぶ。
残差と影響力プロット(梃子値とクック距離)(右下)
1つのデータがモデルの当てはまりへの影響力を測るために使用する。
クックの距離が0.5を超えると影響力あり、1を超えると特異に大きい。
横軸は梃子値で、縦軸は標準化した残差。点線でクックの距離0.5を示している。
信頼区間と予測区間を求める
信頼区間は、predict関数にinterval="confidence"を指定することで求められる。
> norns.con <- predict(norns.lm , interval="confidence") > plot(x.plot , norns.con[,1] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="") > par(new=T) > plot(x.plot , norns.con[,2] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="red") > par(new=T) > plot(x.plot , norns.con[,3] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="blue") > par(new=T) > plot(norns$temperture , norns$icetea , type="p",xlim=c(23,35),ylim=c(40,110),ylab="icetea" ,xlab="temperture")
この結果からいえることは、例えば、同じやり方で気温が32度の日のアイスティー売り上げの平均値を見てみると、95%の確率で78.69 〜 87.81の間に収まりますということになります。
予測区間は、predict関数にinterval="prediction"を指定することで求められる。
> new <- data.frame(temperture= seq(23 , 35 , 1 )) > norns.pre <- predict(norns.lm , new , interval="prediction") > plot(x.plot , norns.pre[,1] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="") > par(new=T) > plot(x.plot , norns.pre[,2] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="red") > par(new=T) > plot(x.plot , norns.pre[,3] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="blue") > par(new=T) > plot(norns$temperture , norns$icetea , type="p",xlim=c(23,35),ylim=c(40,110),ylab="icetea" ,xlab="temperture")
この結果から言えることは、例えば、気温が32度の日のアイスティー売り上げは、95%の確率で70.00 〜 96.49の間に収まりますということになります。
単位根検定
ランダムウォーク(単位根過程)同士を回帰分析すると、見せかけの回帰が発生するため、単位根検定を行い、変数が単位根でないかどうか確認しておく。
使用するのはPhillips-Perron検定。
> PP.test(norns2[,1]) Phillips-Perron Unit Root Test data: norns2[, 1] Dickey-Fuller = -8.0442, Truncation lag parameter = 2, p-value = 0.01 > PP.test(norns2[,2]) Phillips-Perron Unit Root Test data: norns2[, 2] Dickey-Fuller = -6.0224, Truncation lag parameter = 2, p-value = 0.01
それぞれのp-valueが0に近いため単位根過程ではなく、問題なさそう。
回帰式から定数項をはずした場合
次に、回帰式から定数項をはずした場合についても、やってみます。
formulaで指定する式を代えるだけなので簡単です。
> norns2.lm <- lm(icetea~temperture - 1 , data=norns) > summary(norns2.lm) Call: lm(formula = icetea ~ temperture - 1, data = norns) Residuals: Min 1Q Median 3Q Max -11.591 -4.358 -1.103 5.888 8.890 Coefficients: Estimate Std. Error t value Pr(>|t|) temperture 2.50366 0.06149 40.72 4.26e-15 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 6.742 on 13 degrees of freedom Multiple R-squared: 0.9922, Adjusted R-squared: 0.9916 F-statistic: 1658 on 1 and 13 DF, p-value: 4.263e-15
サマリを確認してみても、定数項は表示されいないです。
得られる回帰式は以下の通り。
y = 2.50366x
注意点
定数項をはずした場合(formula=y~x-1)の寄与率が、定数項を含んだ場合(formula=y~x)の寄与率より
高くなる場合もあるが、ある場合とない場合で計算方法が違っているので比較はできない。
実際に今回の場合は、前者の寄与率が0.9916、後者の寄与率0.8077がとなっているが、Residualsを見ても
散布図+回帰式を見ても後者の方が精度が高い。
Min 1Q Median 3Q Max -8.037 -5.693 2.094 4.409 8.225 (formula=y~x-1) -11.591 -4.358 -1.103 5.888 8.890 (formula=y~x)
参考文献
- 作者: 金明哲
- 出版社/メーカー: 森北出版
- 発売日: 2007/10/01
- メディア: 単行本(ソフトカバー)
- 購入: 36人 クリック: 694回
- この商品を含むブログ (64件) を見る
- 作者: 高橋信,井上いろは,トレンドプロ
- 出版社/メーカー: オーム社
- 発売日: 2005/09/01
- メディア: 単行本
- 購入: 42人 クリック: 186回
- この商品を含むブログ (101件) を見る
まとめ&所感
今回は、Rで線形単回帰分析を定数項がある場合とない場合でやってみました。
教科書通りといえばその通りなのですが、手順として正しいのか、他のステップが抜けてたりしないのか等はよく分かってないのが実情です。
(我ながら怪しいなぁと思いながら記述してるところも・・・)
こんな感じでlm関数使えますのではなく、実際の業務としてどこまでやるべきか、どこまで求められるかをきちんと押さえたいところです。
Web系の業界では、あんまりそこまで求められないのか・・・?
間違いや不足などがありましたら、ご指摘頂けると助かります。
Tokyo.R#13までに、重回帰分析、非線形回帰分析まで復習したいが、果たして・・・。