fluent+dstat+kibana4でのサーバリソース可視化

コメントいただいた id:a3no さんの記事のほうが良いので、そちらを参照しましょう。a3no.hatenablog.com



普段はmuninやzabbixのグラフでまあいいかというサーバリソースグラフが、秒単位で見たいというケースがあって色々試行錯誤してできたもの。
rrdtoolで1秒を対応するグラフを作るという手もあるのだけど、なかなか秒単位にいじれるフロントエンドツールが無くて Elasticsearch 触ったこと無かったしで、Web記事を参考にして作ってみることにしました。

参考URL

dstatをkibanaで可視化+3.0.0milestone5新機能 - ほわいとぼーど
curator で Kibana 用の elasticsearch のインデックスを定期的に削除する - Qiita
Use relative paths instead of absolute · Issue #1630 · elastic/kibana · GitHub
Elasticsearch Kibana beta behind Apache Proxy - mmbash.de

作った時期が比較的最近で、fluentdやkibanaのバージョンが違っててなんかWeb上の設定から色々変わってて、これでいいのか?という設定になったけどまあ動いてるのでとりあえずメモということで。

バージョン

OS:CentOS 6.6
elasticsearch-1.6.0
td-agent-2.2.0-0
kibana-4.0.3

注意点とか考慮点(殆ど fluentd )

  • fluent-plugin-map の設定記述方法が fluentd の v1config と合わないパターンがあるので注意
  • elasticsearch 側でデータ型自動判別が上手くいくように fluent-plugin-typecast でデータ型変更
  • elasticsearch に入れる時点で、@timestamp を予め付与してデータのタイムスタンプはなるべく正確に
  • elasticsearch に入れる時点で、ホスト名を予め付与して elasticsearch 側でホスト名フィルタを使えるように
  • kibana の設定で reverse proxy 経由アクセスを予定して elasticsearch_url の書き換えを行う
  • dstat取得ノードから直接 ES に入れることも考えたけど、テキストログの集約保存もしたかったため結局一旦 ES ホスト上の fluentd に集めてから ES に入れる方向に

インストール手順

※なるべく外に取りに行かずにできるように予めパッケージ類落としてきて入れようとしました…が、curator 忘れてて結局外部見にいってしまっていますorz 普通に使う分にはyumとか適当に使えばいいと思います!

elasticsearch

alternatives でjavaシンボリックリンク切り替えていますが、java環境の整え方はお好みでしょう。

yum install java-1.8.0-openjdk.x86_64
alternatives --display java
rpm -ivh elasticsearch-1.6.0.noarch.rpm
chkconfig --add elasticsearch
td-agent

td-agent の設定は後述します。

rpm -ivh td-agent-2.2.0-0.x86_64.rpm
chkconfig td-agent on
/opt/td-agent/embedded/bin/fluent-gem install *.gem
cd /var/log/td-agent/
cp -pr buffer/ arch
cp -pr buffer/ pos
vi /etc/td-agent/td-agent.conf

※入れたプラグインリスト:irc通知とか色々見越した余計なプラグインが入ってます
fluent-plugin-slack-0.6.1.gem
fluent-plugin-typecast-0.2.0.gem いる
fluent-plugin-dstat-0.2.5.gem いる
fluent-plugin-forest-0.3.0.gem いる
fluent-plugin-parser-0.5.0.gem
fluent-plugin-config-expander-0.1.5.gem いる
fluent-plugin-numeric-counter-0.2.2.gem
fluent-plugin-map-0.0.4.gem いる
fluent-plugin-ikachan-0.2.6.gem
fluent-plugin-snmptrap-0.0.1.gem
fluent-plugin-record-reformer-0.6.3.gem いる
fluent-plugin-notifier-0.2.3.gem
fluent-plugin-elasticsearch-0.9.0.gem いる
fluent-plugin-irc-0.0.7.gem
fluent-mixin-rewrite-tag-name-0.1.0.gem
kibana4

先の注意点に書いていますが kibana.yml で elasticsearch_url をデフォルトの localhost から変更します。
詳しい理屈と原因は追っていませんが、そうしないと reverse proxy apache からアクセスした際に上手くいきませんでした。

cd
tar xzf kibana-4.0.3-linux-x64.tar.gz
chown -R root:root kibana-4.0.3-linux-x64/
cd kibana-4.0.3-linux-x64/config
vi kibana.yml
==
elasticsearch_url: "http://[elasticsearch server ip(not localhost)]:9200"
===
curator

後付で入れたので外に取りに行ってしまった残念?なもの。

wget --no-check-certificate https://raw.github.com/pypa/pip/master/contrib/get-pip.py
python get-pip.py
pip install elasticsearch-curator
curator --version
curator show dstat*

ホストリソース取得ノードの td-agent 設定

<source>
  type config_expander
  <config>
    type dstat
    tag host.dstat.__HOSTNAME__
    option  -tclmsr -dD sda --disk-util -nN bond0,bond1
    delay 5
  </config>
</source>

<match host.**>
  type forward
  send_timeout 60s
  recover_wait 10s
  heartbeat_type tcp
  heartbeat_interval 1s
  phi_threshold 16
  hard_timeout 60s

  <server>
    name es-host
    host [fluent server]
    port 24224
    weight 60
  </server>
</match>

ホストリソース取得ノードの td-agent 設定

<source>
  type forward
  port 24224
</source>

<match host.dstat.*>
  type copy
  <store>
    type forest
    subtype file
    <template>
      time_slice_format  %Y%m%d
      append true
      buffer_type file
      buffer_chunk_limit 100m
      flush_interval 30s
    </template>
    <case **>
      path /var/log/td-agent/arch/__TAG__
      symlink_path /var/log/td-agent/arch/__TAG__.log
      buffer_path /var/log/td-agent/buffer/__TAG__/
    </case>
  </store>
  <store>
    type map
    map '["map." + tag + ".cpu_idl", time , "cpu_idl" => record["dstat"]["total cpu usage"]["idl"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".loadavg_1m", time , "loadavg_1m" => record["dstat"]["load avg"]["1m"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".mem_free", time , "mem_free" => record["dstat"]["memory usage"]["free"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".swap_used", time , "swap_used" => record["dstat"]["swap"]["used"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".io_sda_read", time , "io_sda_read" => record["dstat"]["io/sda"]["read"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".io_sda_write", time , "io_sda_write" => record["dstat"]["io/sda"]["writ"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".dsk_sda_read", time , "dsk_sda_read" => record["dstat"]["dsk/sda"]["read"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".dsk_sda_write", time , "dsk_sda_write" => record["dstat"]["dsk/sda"]["writ"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".sda_util", time , "sda_util" => record["dstat"]["sda"]["util"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".net_bond0_recv", time , "net_bond0_recv" => record["dstat"]["net/bond0"]["recv"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".net_bond0_send", time , "net_bond0_send" => record["dstat"]["net/bond0"]["send"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".net_bond1_recv", time , "net_bond1_recv" => record["dstat"]["net/bond1"]["recv"]]'
  </store>
  <store>
    type map
    map '["map." + tag + ".net_bond1_send", time , "net_bond1_send" => record["dstat"]["net/bond1"]["send"]]'
  </store>
</match>

<match map.host.dstat.**>
  type record_reformer
  enable_ruby true
  tag  timeadd.map.host.dstat
  <record>
    hostname ${tag_parts[3]}
    @timestamp ${time.strftime('%Y-%m-%dT%H:%M:%S%z')}
  </record>
</match>

<match timeadd.map.host.dstat.**>
  type typecast
  item_types cpu_idl:float,loadavg_1m:integer,mem_free:integer,swap_used:integer,io_sda_read:integer,io_sda_write:integer,dsk_sda_read:integer,dsk_sda_write:integer,sda_util:float,net_bond0_recv:integer,net_bond0_send:integer,net_bond1_recv:integer,net_bond1_send:integer
  tag  typecast.timeadd.map.host.dstat
</match>

<match typecast.timeadd.map.host.dstat.**>
  type copy
#  <store>
#    type stdout
#  </store>
  <store>
    type elasticsearch
    type_name       dstat
    host            localhost
    port            9200
    logstash_format true
    logstash_prefix dstat
    flush_interval  3s
  </store>
</match>

ちなみにelasticsearchに入るデータ構造はこんな感じ

2015-06-20 11:21:24 +0900 typecast.timeadd.map.host.dstat: {"sda_util":2.18,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:24+0900"}
2015-06-20 11:21:29 +0900 typecast.timeadd.map.host.dstat: {"sda_util":0.72,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:29+0900"}
2015-06-20 11:21:34 +0900 typecast.timeadd.map.host.dstat: {"sda_util":0.3,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:34+0900"}
2015-06-20 11:21:39 +0900 typecast.timeadd.map.host.dstat: {"sda_util":0.08,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:39+0900"}
2015-06-20 11:21:44 +0900 typecast.timeadd.map.host.dstat: {"sda_util":0.06,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:44+0900"}
2015-06-20 11:21:49 +0900 typecast.timeadd.map.host.dstat: {"sda_util":1.84,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:49+0900"}
2015-06-20 11:21:54 +0900 typecast.timeadd.map.host.dstat: {"sda_util":2.26,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:54+0900"}
2015-06-20 11:21:59 +0900 typecast.timeadd.map.host.dstat: {"sda_util":0.06,"hostname":"dstathost","@timestamp":"2015-06-20T11:21:59+0900"}
2015-06-20 11:22:04 +0900 typecast.timeadd.map.host.dstat: {"sda_util":0.32,"hostname":"dstathost","@timestamp":"2015-06-20T11:22:04+0900"}
2015-06-20 11:22:09 +0900 typecast.timeadd.map.host.dstat: {"sda_util":1.42,"hostname":"dstathost","@timestamp":"2015-06-20T11:22:09+0900"}
2015-06-20 11:22:14 +0900 typecast.timeadd.map.host.dstat: {"sda_util":1.32,"hostname":"dstathost","@timestamp":"2015-06-20T11:22:14+0900"}
2015-06-20 11:22:19 +0900 typecast.timeadd.map.host.dstat: {"sda_util":0.12,"hostname":"dstathost","@timestamp":"2015-06-20T11:22:19+0900"}
2015-06-20 11:22:24 +0900 typecast.timeadd.map.host.dstat: {"sda_util":1.72,"hostname":"dstathost","@timestamp":"2015-06-20T11:22:24+0900"}

elasticsearchのインデックス定義

name 	type 	analyzed  	indexed  	
------------------------------------
_index  	string	false	false	
loadavg_1m  	number	false	true	
hostname  	string	true	true	
cpu_idl  	number	false	true	
swap_used  	number	false	true	
io_sda_write  	number	false	true	
_type  	string	false	true	
io_sda_read  	number	false	true	
dsk_sda_read  	number	false	true	
dsk_sda_write  	number	false	true	
@timestamp   	date	false	true	
mem_free  	number	false	true	
_source  	string	false	false	
_id  	string	false	false	
sda_util  	number	false	true	
net_bond0_recv  	number	false	true	
net_bond1_send  	number	false	true	
net_bond0_send  	number	false	true	
net_bond1_recv  	number	false	true

kibana4設定

画像かき集めて無いので無し

kibanaアクセスのためのReverseProxy?定義

nginx
 location ~* /kb4/.* {
       rewrite ^/kb4/(.*) /$1 break;
           proxy_pass http://[kibana server]:5601;
           proxy_set_header Host $host;
           proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_send_timeout 600s;
       proxy_read_timeout 600s;
 }
apache
ProxyRequests On
ProxyPreserveHost On
ProxyPass               /       http://[kibana server]:5601/
ProxyPassReverse        /       http://[kibana server]:5601/
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule .* http://[kibana server]:5601%{REQUEST_URI} [P,QSA]

作ってみて

dstat + fluentd + Graphite + Grafana でサーバモニタリングする - blog.nomadscafe.jp の記事にありますが、ESのCPU使用率がきついです。
あと、dstat 5秒間隔取得データで、ES のヒープ 2G で 20日データ保存が安定稼動ラインで、それを超えるとメモリ不足や search の queue size エラーが出はじめます。ES のチューニングやトラブル対応のネタ的にはいいのですが、予想以上にデータ溜められないかもな…という印象。とりあえず数日の可視化はできているので、目標的にはOK。ES の調整は30日までは頑張って、後は fluentd で集めたテキストログ見ればいいやという割り切りでしばらく使うことに。

「Fluentd Meetup 2015 夏」参加メモ

Fluentd Meetup 2015 夏 - 2015/06/01(月) - dots.[ドッツ]に参加してきたのでメモです。
ねんがんのFluentdステッカーを手に入れたぞ!
Fluent-bitは聞くのに精一杯でメモる余裕は無かったし、LTはざーっと聞くほうに倒してたのでいい加減です。
詳しいメモはmuziyoshizさんのブログ方が正確で詳しいのでそちらを見たほうがたぶんいいです。Fluentd Meetup 2015 夏の参加レポート - 無印吉澤@HatenaBlog
あと、Gloopsさんの会場良かったなあ。

  • 『Fluentd v0.12完全解説』@repeatedly

http://www.slideshare.net/repeatedly/fluentd-v012-master-guide
 大きな4つの追加
 v1config
 イベントハンドリング(フィルタとか)
 at-least-once
 HTTP-RPC
 
 v1config
  フォーマット自由度が上がった
  若干非互換部分があるがドキュメント読んでね
  Hash/Array型の追加
  RubyCodeも入れれる(環境変数とかを使ったりしやすく)
  :secretオプション
   プラグイン側の対応が必要
   起動時の設定ファイルのダンプとかの設定ファイルでマスクしたい設定をすることができるようになる
 Filter
  matchと同レベルでfilterが使えるようになって、filter専用プラグインで処理
  旧バージョンだとOutput単位でトランザクションしていたため、多段Outputの際に欠損する可能性があったが
  v0.12ではfilterを通すと1トランザクションで処理できるので欠損を減らせる
  デフォルトで stdout/grep/record_transformer が同梱
  実装する場合はfilter/filter_streamメソッド追加
  Label
   イベントのグルーピング機構
   複数ソースをまとめるようなシーンで使える…はず
   label対応する場合は、route.emit
   エラーレコードのみ抽出するemit_error_eventというAPIもあり(@ERRORラベルがつく)
 At-least-once
  エラーったら送り返す(重複する可能性あり)
  require_ack_reponse を設定追加すればOK
  al-most-onceがデフォルト挙動で、エラーったらロストの可能性あり
 HTTP-RPC
  HTTPベースのAPI提供
  SlackのAPIスタイルを参考にして実装
 
 Webのdocsは既にv0.12ベース
 Td-agentも現在はv0.12ベース

  • 『fluentdで本番環境を再現する』@toyama0919

http://toyama0919.bitbucket.org/fluentd_shadow.html#/

 Shadow Proxy
  productionのhttpリクエストを複製してバックエンドに送信するproxy
  OSSのその他の実装ではkageなどもある
  ユーザに近いフロントエンドにミドルウェアをあまり入れたくなく、安全にやりたい
 fluent-plugin-http_shadow
  http requestを復元
  Apache/Nginxログ想定だが、独自ログでのpostも可能
  パラメータ
   rate
    本番と同様のスペックをそろえられない場合のためのパラメータ
    1%くらいから始めて徐々にあげていくスタイル
   timeout
    fluentd の buffer が溜まるのでそのためのパラメータ
   並列数
    負荷調整用
  注意点
   config_paramにHASHが使えないものだと使えない
 ユースケース
  バグ発見器
  ミドルウェアのアップデート検証用
 まとめと感想
  完全なShadow環境は難しい
   POSTはログに無いと再現できない
   クライアントブラウザじゃない

  • 『fluent-bit』Eduardo Silva氏

http://fluentbit.io
https://github.com/fluent/fluent-bit
http://qiita.com/ksoeda@github/items/47fe5732637a923e5ed6

  • 『fluentd対応MIDIキーボードを作ってみた』@kazunori_279

http://qiita.com/kazunori279/items/208e1526367426b39bbb

  • 『Docker and Fluentd』@tagomoris

http://www.slideshare.net/tagomoris/docker-and-fluentd

  • 『fluentdによる大規模キュー設計』@edvakf

https://speakerdeck.com/edvakf/fluentdniyoruda-gui-mo-kiyushe-ji

  • 『大量のログをBigQueryに送ってみた』@catatsuy

https://speakerdeck.com/catatsuy/send-a-log-to-bigquery-with-fluentd

  • 所感

v0.12での変更点が綺麗にまとまっていて非常に助かりました。
v1configやFilter、LABELでプラグイン側での対応が必要だったりする箇所もあり、移行時に参考にする予定。
ロードマップ的には0.14がもう予定されているのでもうちょっと待ってv0.10→v0.14という方向もあるとは思うのですが、個人的には先日v1configが絡む微妙な動きも経験したこともあり、v0.12を1回でもいいから経験をしておいたほうが良いように感じます。
前作ったOracleのログかき集めがv0.10ベース…だと思うので、とりあえずそれをv0.12で作り直しかなあ。

Cloudera Manager API で Cloudera Manager Admin Console の TLS 化する備忘録

Configuring TLS Encryption for Cloudera Manager Admin Consoleの"Step 2: Enable TLS encryption and specify Server keystore properties."を、Cloudera Manager API で変更するメモ。
デフォルトポートの7180がアクセス制限されてるので、初期インストール後、許可されてるポートにとりあえず変えたいみたいなそんな時用。

メモ

キーストア作ったり、再起動部分は省略

設定見て
curl -X GET -u "admin:xxxxx" -i http://localhost:7180/api/v1/cm/config
curl -X GET -u "admin:xxxxx" -i http://localhost:7180/api/v1/cm/config?view=full

設定入れ
curl -X PUT -H "Content-Type:application/json" -u admin:xxxxx -d '{ "items": [
{ "name" : "HTTPS_PORT", "value" : "8443" },
{ "name" : "HTTP_PORT", "value" : "8080" },
{ "name" : "WEB_TLS", "value" : "true" },
{ "name" : "KEYSTORE_PATH", "value" : "/etc/cloudera-scm-server/sslkeystore" },
{ "name" : "KEYSTORE_PASSWORD", "value" : "xxxxxxxxxx" }
] }' 'http://localhost:7180/api/v1/cm/config'

注意点とか

  • ポートは1024以上にしておかないとjettyがポート取れずに起動しなくなる
2015-04-04 11:56:04,828  INFO [WebServerImpl:mortbay.log@67] jetty-6.1.26.cloudera.4
2015-04-04 11:56:04,835  WARN [WebServerImpl:mortbay.log@76] failed SslSocketConnector@0.0.0.0:443: java.net.BindException: Permission denied
2015-04-04 11:56:04,835  WARN [WebServerImpl:mortbay.log@76] failed SelectChannelConnector@0.0.0.0:80: java.net.SocketException: Permission denied
2015-04-04 11:56:04,836  WARN [WebServerImpl:mortbay.log@76] failed Server@5e04d6b0: org.mortbay.util.MultiException[java.net.BindException: Permission denied, java.net.SocketException: Permission denied]
  • API v1 ~ v9くらいまであるっぽいけど、v9だと情報取れなかった。CDHバージョンとAPIバージョンのサポートマトリクスってどっかに無いんだろうか。

Cloudera Manager API v1
Cloudera Manager API v9

  • cm_apipython も入れたけど、CLIでさらっと再起動かけれるのでこれもこれで結構嬉しい

cloudera/cm_api · GitHub

五番煎じくらいの fluentd+dstat+growthforecast で起きたことのメモ

※2015/02/23 時点の状況で、後日解消する可能性が高いため一時的な状況だと思われます。

ちょっと性能系のリソースグラフ作成で fluentd+dstat+growthforecast を組んだことが無かったので、組んでみたら思いのほか色々あったのでメモです。
@repeatedly さんから直接ヒント頂いて解決できました。ありがとうございます。
Mr. Fiber on Twitter: "@mhnsr ふーむ. http://t.co/1orfk0ymIi この手のサンプルにあるやつはちゃんと動くんですけどねぇ…"

起きたこと

こちらの方と同じ事象になりました。
https://groups.google.com/forum/#!searchin/fluentd/map/fluentd/T3O4YDk7_Xc/_TDbLd6G5TwJ
ざっくりまとめると v1-config で、且つ mapプラグインの map を使わずに record オプションを使うと起動時に設定ファイル読み込み時に parse_error が発生しました

回避策

とりあえず2つあります。
・v0-config で起動する
・fix_493 で出ている literal_parser.rbの変更を適用して、mapプラグインの定義を record を使わず map 側で行う
 (※変更内容は→remove multilined JSON array/hash parser · 40072fc · fluent/fluentd · GitHub

バージョン組み合わせ

td-agent-2.1.4-0.x86_64
fluent-plugin-dstat (0.2.5)
fluent-plugin-growthforecast (0.2.8)
fluent-plugin-map (0.0.4)

JPOUG> SET EVENTS 20140907参加メモ

JPOUG> SET EVENTS 20140907 | Japan Oracle User Group (JPOUG)に参加させて頂きました。
ので、typo沢山ありそうなのですが、そのメモはりつけ。
企画運営の皆様、会場のIIJ様ありがとうございました。
12cは触ってないので知らないことだらけ、ターミナルの件はbashあんまり使いこなしてないのでその辺、MySQLはロック周りの挙動を改めて勉強し直しとどれもとても勉強になる話ばかりでとても満足。

知られざる Oracle Database 12c の新機能

スライドは後日公開できるようになったら公開したいとのこと。

・列データ型の制限拡張
 varchar/rawが32kまで拡張
 char系は2000バイト制限のまま
 標準では無効なので、設定変更必要で変更したら戻せない
 実態はインライン格納のBLOB
  物理フォーマットは初期化パラメータdb_securefileと表領域タイプで変わる
 インデックス張れる
  制限とか
   ファンクションインデックス
   列サイズが「ブロックサイズ×75% - オーバーヘッド」の制限はそのままで引っかかりやすくなる
 LOB使わないやり方
  後から列のmodifyで増やす
  初期化パラメータ:_scalar_type_lob_storage_threshold でのLOBしきい値の調整
 
・Identify列
 テーブルの列に一意な値を自動設定する機能
 自動採番された値をユーザが更新できるかどうか、を設定できる
 実態は自動生成されるSEQUENCEとデフォルトの組み合わせ
  シーケンスの制限がそのまま適用される
 自動生成されたシーケンスは ALTER SEQUENCE はエラーになる
  ALTER TABLE で調整
  でもnextvalはできる
 列のデフォルト値でシーケンスを指定することもできるようになった
  この場合は依存関係をチェックされていないので、シーケンスだけ削除することができてしまう

・fetch n rows only
 これまでは row_number,rownumでやってた
 12cではoffset / fetch next / only などを使って簡単にかけるようになった
 他にあまりないのはパーセント指定、同値の値を出す機構など
 実行計画見ると、row_numberとサブクエリ、caseでの書き換えをして実行されている
 制限
  下記あたりと一緒には使えない
   for update
   シーケンス

・In-Database Arvhiving
 レコードの有効・無効フラグを自動判定させる機構
 テーブルの設定で row archival 属性設定
  all_tab_colsで見えるけど、all_tab_columnsでは見えない列
 ora_archive_state 列を 0(0x30) 以外に設定した行はwhereをつけなくても勝手に見えなくなる
 alter session set row archival visibility=ALL で制御を無効化もできる
 実行計画見ると勝手にwhereをつけた動きをしている
 注意点
  制約は有効なので、一意制約とか注意
  列が勝手に追加されているので、列数maxが減る
  属性を消すときは大量のI/Oが起きちゃうので大規模テーブルは注意

・SEQUENCEの拡張
 セッションという属性ができた
 セッション単位で初期化されるシーケンス
 永続化されていない様子
 KEEP/Partitionという属性があるがこれは不明

・非表示列
 select * での表示列を見えなくするだけで、列指定すれば見える
 desc も見えなくなる
 visibleで属性設定するが、有効・無効を変更するとdescで見たときに末尾につく

・オンライン操作
 ONLINE指定できるDDLが増えた
 データファイルの移動がオンラインでできるようになった(オフライン化不要)
 セグメントの移動(パーティションの表領域移動など)
  ADO(データライフサイクルの機能)あたりはこの辺の恩恵でできるようになった

・マルチスレッドインスタンス
 バックグラウンドプロセスのスレッド化
  threaded_execution
  インスタンスを6プロセスくらいに集約
 サーバプロセスのスレッド化
  listener.ora DEDICATED_THROUGH_BROKER_〜をon
 DB接続時に / as sysdba とかがNGに
 共有メモリ使用は変わらず

PGA制限
 pga_aggregate_limitで制限値が設定できるように
  設定すると一番メモリ使っているプロセスが勝手に切られる

・unified auditing
 標準、SYS、ファイングレインを統合
 create audito policyで設定する感じ
 標準で有効になっている
 11gからの監査も有効なままなので、二重監査状態なので設定注意

・パッチセット12.1.0.2
 大量に新機能追加
 初期化パラメータも増減、デフォルト値変更あり
  ドキュメントは最新を見ること

とあるDBAの黒い画面(ターミナル)II ~端末作業を快適にするヒント、お届けします(その2)~

JPOUG> SET EVENTS 20140907 で話してきました - Keep It Simple, Stupid

三種の神器:vim/zsh/screen

・SQLplus
 ユーザプロファイル
  SQLPATH/login.sql
 プロンプトの調整
  事前定義変数を使ってもうちょっと見やすく
  set time on で時刻表時
  事前変数以外も変数設定可能
  ただ、50文字くらいまでぽい
 SQLバッファ
  _editorを設定するとエディタを指定できる
  define _editor=vim 

・リファレンス
 吉川さんツールgithub
  yoshikaw/oracle-cui-reference · GitHub
 生成するコマンドをたたいたターミナルの幅に合わせて生成されるのと、EUCでできあがる
 ローカルにおいておくと便利

・シェル機能を使いこなす
 Ctrl/Esc 経由での操作が可能
 移動 Ctrl-a/e
 切り取り Ctrl-k/u/w/y
 ヒストリ検索 Ctrl-r/s
 ヒストリ利用 !!/!$
 ヒストリの置換 ^xxx^yyy もしくは !!:gs/xxx/yyy
  置換してすぐ実行されるので注意ではある
 ``の代わりに$()
 cd - で、1つ前のディレクトリと行ったり来たり

・rlwrap
 epelでぶち込みできる
 rlwap sqlplus でいい感じに
 保管用辞書使って、さらに便利に〜

・三種の神器
 時間無くてskip

MySQLのロックについて

スライド手直し中とのことで、出たら更新 → 更新されました
MySQLのロックについて - SH2の日記

MySQL デフォルトのトランザクション分離レベルである REPEATABLE READ が、InnoDB でどう振る舞うのかというお話をギャップロック、ネクストキーロック周りの挙動をとても分かりやすくまとめられていました
内容はスライドを見れば分かるので、ひたすら聞く方に集中してメモ取らず
InnoDBのロックのかかり方はSQLから想像するのが難しいので、何回聞いても勉強になります
平塚さんは READ COMMITTED で良いんじゃ…とのことで、今日の挙動を聞くと確かに…と感じました(笑
あと直前までツールデバッグで忘れてたというurandomの件はたぶんこの件
LinuxサーバからOracle JDBC接続するとEnd of TNS data channelやConnection resetが発生する場合の対処法 - けみかるはてな

LT

●LT:MySQLユーザから見た「ここが{ヘンだ,スゴい}よOracle Database」
 YahooのDB管理
  11g EE 200DB/ExaFullとかも
  MySQL 300DBとか他チームのものもある
 
 変なところ
  Webに情報無い、ソースが見れない
  sqlplus貧弱
  「データベース」がスキーマじゃない
  レプリケーションが脇役

 ここがすごい
  DBAという存在が明確に組み込まれていること
  データが消えないのが当たり前
  パラレルクエリ
  RACでの書き込みのスケール

 まとめ
  同じRDBMSでも結構違う
  複数勉強すると理解が深まる
  適材適所で選定できるように

●LT:WindowsでもChefしたい!
JPOUG> SET EVENTS 20140907で、LTしました:記憶に頼るんじゃない、記録するんだ:So-netブログ
 Chef-soloで作る
 C:¥opscode のPATHでインストールが必須
 knife-solo は個別インストール
  no-user-install
  もう1個 ignore〜 があったけどメモるのが間に合わず
 Berkshelf
  コミュニティのcookbook管理ツール
 後はお料理

●LT:安くて速くて安心な構成を目指して
 DBサーバ、ストレージの冗長化
  RAC/ASM
 NWの冗長化
  Bonding/Multipath
  Interconnectはact/actで帯域稼ぎ

 高速化
  InfiniBand
  ストレージ層ではiSer使用
  HDD&10Gからのメリット
   速い
   値段もあまり変わらず
   RDMA通信の考慮が必要

 Q&A:ASMの冗長化数はいくつ?
  標準冗長が多い、3コピーは議論にはなるけど今はあまり

●LT:続・IIJもデータベースのサービスやっています
 Hadoop連携できるカラムナーなDWHも追加
 リソース占有型のRACサービスもある


●聞けなかったもののスライドなど
http://www.slideshare.net/kitayamat/20140907-jpoug-myoldmemoriesofdatabase

MySQL Cluster Casual Talks #2参加メモ

とりあえず

MySQLClusterCasualTalksに参加させて頂いたので今更ですが個人メモのまとめです。パラメータ名はきっとtypoがありそうで、かつ後半になるといい加減になっていくのもいつもの通り。はー、仕事でMySQL Cluster作りたい。
 http://atnd.org/events/50736

ちなみに、id:garage-kid さんの方が奇麗にまとまっていますのでそちらを読む方がオススメです。
 http://garagekidztweetz.hatenablog.com/entry/mysql-cluster-casual-talks2

とても参考になる会でした。参加させて頂いてありがとうございました!

MySQL運用話

 http://www.slideshare.net/hiroi10/mcct2-pub

構成

 LVS、WEB/SQLノード20〜30台、管理ノード2台、データノード3、4台
  ※NWは10GE?

データノードパラメータ

 MaxNoOfExecutionThreads
  ndbmtdのみパラメータ
  スレッド系のパラメータ→CPUコアと同じ数くらいが良さそう
   ThreadConfigでより詳細に設定できるが、ここまでのパラメータはまだ使っていない
 Numa
 ODirect
 TransactionDeadlockDetectionTimeout
  ms単位のタイムアウト
  クエリ実行で待てる時間
 MaxNoOfConcurrentScans
  スキャン系での並列実行数
  データノード単位での設定
 MaxNoOfConcurrentTransactions
  デフォルト小さすぎ
  データノード全体で同時実行可能なトランザクション
   1トランザクションで1消費とは限らないので、デフォルトの4096だと小さい
 NoOfFragmentLogFiles
  redoログ、これ関連のパラメータ

SQLノードパラメータ

 connection-pool
  コネクションプール数
  ノードIDが消費されるので増やしすぎるとよろしくない
  実運用では2
 クエリキャッシュは無効

サービスインしてから発生した障害と対応

 序盤の半年くらい
  SQLノードのエラーログに too many active scans タイムアウト小さくしつつ、アプリでリトライ
  データノードのログに LongMessageBufferが枯渇
   昔のデフォルトは4Mで、7.3ではデフォルトが64Mに…
  ndbd から ndbmtd への移行
   mysqldumpで吸って戻せるかでテスト
    リストア中にエラー
    NoOfFragmentLogFilesを増やす
    TimeBetweenLocalCheckpoints を6以下でリストア成功
     20Gくらいのデータ
  ndbmtdがcronタイミングで落ちる
   スワップ使ってた
    cronいくつかoff
    TimeBetweenWatchDogCheckに引っかかって停止
    vm.swappiness = 0 (Cent5系)

監視

 データノードはCPUコア毎の状況を見た方がよい
 ldmスレッド数+1,2くらいのロードアベレージに落ち着く
 NWトラフィック監視
  基本トラフィックが流れているので、逆にトラフィックが流れていない状態は異常
   大体100kbpsくらいは常時流れている
 管理ノードでDataMemory,IndexMemoryの監視
 SQLノードは死活監視
  CPU使用率SQLノードの方が割と使う
 単キー更新系で6,7万qpsとか出せる
 パケドロとスワップ
  NICのリングバッファを最大に

まとめ

 最新バージョンを使いましょう
 JOINで30倍くらい早くなったクエリがあった
 レンジ系、セカンダリインデックスまわりが苦手

mac minimysql cluster

 http://www.slideshare.net/cyberweb1/mac-minimysql-cluster

OpenPNE2の開発してる
42Uラックが事務所兼自宅においてて1G×7本
電気代で20万くらい
SSDで構成、Macのthunderbolt2接続で1G越えでのIO帯域、25万IOPSくらい
その上にVirtualBOXUbuntu
WordpressのためのMySQLCluster環境
 WordPressはデフォルトテーブルを明示的にndbへ変更をかける
 100万記事くらい入れても平気
OpenPNEでも対応させる方向で実験中
Macmini向けのthunderboltを使ったPCI拡張カード

HPさん

 http://h50146.www5.hp.com/services/ci/opensource/pdfs/HP_OpenServices.pdf

管理ノード2、データノード2、SQLノード2、10GE接続、データノードにioDrive

パラメータチューニングの確認
データノードでのioDrive効果
 ディスクテーブルにioDriveを使う
デフォルトではMaxNoofExecutionThreadsネックになってノード増やしてもスケールしない
MaxNoofExecutionThreadsを16に増やした
 2台に増やしたときに1.7倍くらいにスケール
ThreadConfigでいじるとスケールがリニアな2倍まで到達
 データノードのCPUは、40%くらい。SQLノードのCPUネック(おそらくNW部分)になった
connection-pool設定すると1台あたりの性能が2倍になったため、最初の4倍くらいまで来た
 データノードのCPUが60%くらいで、SQLノードのsysも減ってCPUの使われ方がいい感じに
Elaps
 チューニングするとelapsも短くなっている
ディスクテーブルのioDrive化
 ext4
 DiskPageBufferMemory でキャッシュを意図的に少なく
  スループットが1/3のレイテンシが1.5倍くらい
 NWは4Gbpsくらいは出ちゃう

データノードでメモリテーブルで台数が必要なケースについて、ディスクテーブルを使うことでデータノード数を削減できればラッキー 
ndbmtdを使う

Cent6系でmOTPを使ってみる

概要

 sshの2段階認証できないかなーとちょっと試したメモです。
 ぐぐるGoogle Authenticator 例が多いのですが、Mobile-OTP を今回は試してみました。
 なるべく設定量は少なくするのが希望。

確認環境

 CentOS6.5
 ※SELinux は落としました。
 (Mobile-OTP が /var/cache/motp を使うのですがそこの権限付与が必要となるのですが、そこにちょっと手が回らなかったので)
 

パターン1:OTPでもパスワードでも可

/etc/ssh/sshd_config(authentication method: passwordで処理)

PasswordAuthentication yes
ChallengeResponseAuthentication no

/etc/pam.d/sshd

先頭に以下を追加
auth     sufficient pam_mobile_otp.so not_set_pass debug
account  required   pam_mobile_otp.so debug
password required   pam_mobile_otp.so debug
パターン2:OTPとパスワード両方必要(authentication method: keyboard-interactiveで処理)

/etc/ssh/sshd_config

PasswordAuthentication yes ※ここはnoでも可Challengeが重要
ChallengeResponseAuthentication yes

/etc/pam.d/sshd

先頭に以下を追加
auth     required  pam_mobile_otp.so not_set_pass debug
account  required  pam_mobile_otp.so debug
password required  pam_mobile_otp.so debug
番外:OTPと鍵認証が必要

パターン1,2に合わせて RequiredAuthentications2 での制御を追加
/etc/ssh/sshd_config

※パターン1用
RequiredAuthentications2 publickey,password
※パターン2用
RequiredAuthentications2 publickey,keyboard-interactive
※Match を使って特定アドレスからのみOTPを要求する形
Match Address *,!127.0.0.1
  RequiredAuthentications2 publickey,password

できてないこと

SELinux有効化状態のまま運用すること。
 →/var/cache/motp を扱えるように設定できればたぶん通せるはず。
pam での接続元による OTP Only等の細かい制御の確認
 →設定方法を調査しきれず一旦保留扱い。pam から勉強になりそう…。