b.l0g.jp     About     Archive     Feed

MyNA会2013年9月 メモ

 

MyNA(日本MySQLユーザ会)会 2013年9月

先週のMySQL Cluster Casual Talksに続いて、週末にかけて行われたMySQL Connectで発表された最新情報を聞けるということで、MyNA会に参加してきた。基調講演の内容は既に報道されていたので(Publickey (1), (2), (3))ある程度分かっていたが、一番うれしかったのはMySQL Fabricのデモが見られたこと。MySQL Utilitiesの機能でシャーディングができるようになるということでどんな感じか見てみたかったので、(ラボ版で一部動かないところがまだあるということだったが)興味深かった。発表者のみなさま、会場を提供していただいたOracleのみなさまなど関係者の方々ありがとうございました。

@RKajiyamaさん MySQL Connect基調講演の概要

  • いつOracleはMySQLを殺すのかと言われてきた → うわさを打ち消すために3年半の間大量のリリースをしてきた
  • チーム全体も増員、特に品質管理チーム
  • DMR(Development Milestone Release)というやり方
    • リリース候補版になったコンポーネントを含んだリリース
    • 18から24ヶ月ごとにメジャーリリースしたい
  • Webや組み込み系に強いDBとしてOracleにとっても価値がある
    • 現在もLinux系の最も重要なスキル=MySQL
    • 今もユーザは多数
  • 5.7.2 DMRの発表
    • Release noteが超長かった=たくさんの更新が含まれている
    • InnoDBパフォーマンス向上
    • explain for connectionで別セッションのexplain
    • Optimzerの結果をWorkbenchでさらに詳しく
    • performance schema改善
      • メモリの使用状況
      • storedの詳細
    • tmpテーブルがInnoに
    • 同じDB内でのマルチスレッドレプリケーション
  • 5.7の以後のバージョンでの予定
    • マルチソースレプリケーション
  • MySQL Utilities 1.3
    • レプリケーションのフェイルオーバをデーモンで
  • MySQL Utilities 1.4から
    • Fabric
      • アプリから意識せずにシャーディングできる
      • Connectorが接続を受けて振り分ける
      • レンジかハッシュ、リシャーディング

いちいさん@Gree, いけださん@SCSK MySQL Connectの感想

  • Oracle OpenWorld、JavaOneと一緒にやってる
  • SFのホテルいくつも貸し切り、道路も閉鎖して休憩スペースに
  • FacebookのMySQLの話
  • まつのぶさん MySQL 5.6@Facebook
    • 5.1にパッチ当てたのを使っている
      • 圧縮、クラッシュセーフスレーブ、フラッシングの高速化など
    • シャドウサーバ
    • 5.5を飛ばして5.6へ
      • 低リスクのところから徐々に移行
  • GoogleがMySQLをやめてMariaDBに全面移行するというのは、XLDBというカンファレンスでの話を元にした記者の煽り記事で、Googleの人曰く迷惑しているそうだ

@yyamasaki1さん JSON UDFs

ドキュメントデータベースとして MySQLを使う!? ~MySQL JSON UDF~ from yoyamasaki
  • MySQL json UDFs
  • カラムにJSONをつっこんだものをファンクションで処理できる

@RKajiyamaさん MySQL Fabric

  • ラボ版のMySQL Utilitiesに搭載された新機能
  • マスタにスレーブがぶら下がってる構成
    • これを1つのシャード(グループ)として扱う
  • アプリからConnectorを使ってアクセスする
    • ConnectorはFabricに問い合わせ先を確認してからシャードにアクセス
    • state storeに情報保存
    • スキーマの情報などだけもってデータは持たない
  • グローバルグループ
    • 全体に影響のある処理に関係するメタ情報を持つ
  • アクセス時にRWかROを指定すると、Fabricが自動でマスタあるいはスレーブにアクセスを振る
  • lab版は罠だらけなので気をつけよう。。
  • 開発者の方のブログが役に立つ

赤井さん GNU 30周年とMySQL

  • GNUプロジェクトが始まって30年
  • MySQLの成長はGNUの恩恵を受けた
  • GNUへのリスペクトを忘れないようにしよう

 

MySQL Cluster Casual Talksメモ

MySQL Cluster Casual Talks

一応仕事でMySQLをよく触っている身として、軽く検証はしてみたものの、担当している業務では参照メインのDBが多いこともあって実運用では使ったことがなかったMySQL Cluster。改めて利点も欠点も聞いておきたいと思ったのと、会社からすぐ近くのGMOさんが会場ということもあって参加してみた。

MySQL Clusterの本も書かれている@nippondanjiこと奥野さんから、MySQL Clusterは何に向いていて、どう使えばよさを引き出せるのかを聞いたうえで、そのサポートを受けながら4年間運用されている@tsakuradaさんの実運用上のハマりどころを聞くことで、どういうところにMySQL Clusterを使えばいいのかイメージが浮かんだので、非常に今後の役に立ちそう。

発表者のみなさま、会場提供していただいたGMOのみなさまありがとうございましたm(__)m さくらのクラウド2万円分クーポンももらったし、GMOクラウドのキャラクタのシールもたくさんもらったので宣伝しますw

既にまとめはgarage-kidさんが書いてくれているので、これは個人的なポイントのまとめ。

@RKajiyamaさん MySQL Cluster大地に立つ!「5.6とは違うのだよ、5.6とは!」

  • MySQL Clusterの概要
    • 分散型、共有ディスク不要のHAクラスタ
  • 使用しているユーザ
    • 元々はモバイル通信の位置情報をリアルタイムかつ高可用性を持って保存するためにできた
    • SQLインタフェースは昨今ゲーム業界などで使われ始めてから追加されてきた機能
    • 艦○れでも使われている?

@nippondanjiさん カジュアルにMySQL Clusterを使ってみよう

カジュアルにMySQL Clusterを使ってみよう@MySQL Cluster Casual Talks 2013.09 from Mikiya Okuno

データノード、SQLノード、管理ノードの3種類からなる

  • 1台だけならndb(MySQL Clusterのエンジン)よりInnoDBの方が速い
  • ただしNDB APIを使うならClusterの方が圧倒的に速い
  • ノードを増やすとスケールしていく点に優位性があるが、いつでも速くなるとは限らない(後述)
  • 新しいバージョン使いましょう

シェアードナッシング型

  • データノードは2台ペアでノードグループを構成
  • データをフラグメントに分けて、それをノードグループ内で同期レプリする
  • RAID10的な感じでグループ内で1台落ちてもデータは保全される

InnoDBとは特性が違う & いつでもノードを増やせばスケールするとは限らない

  • 主キーを使った検索 → データノード数に応じてスケール
  • (少数の行を取ってくる)スキャンは苦手
    • データがノードに分散しているので複数ノードをスキャンする必要があるため
    • フェッチするレコードが多いと並列処理できるので早くなる
    • Engine Condition Pushdown : where句部分を丸ごとデータノードに渡して並列処理して高速化する仕組み
    • sysbenchをただ走らせると遅いのはこのせい
  • ユーザ定義パーティション
    • スキャンを高速化させる仕組み
    • 2つのテーブルの関連を考慮してデータノードへの分散を定義すれば、読み書きを特定のノードに抑えられるので高速に
  • レプリケーション
    • ndbに不得意な処理があるならInnoDBのスレーブを作るという手もある
    • データノードが書き込みしたことをSQLノードに通知し、それをbinlogに書き込んでスレーブに送るという仕組み
    • 通知を受け取るのがbinlog injector thread
  • インメモリDBだけど永続化処理が多いのでディスク書き込み多い=速いディスクがいい
  • blobを別テーブルに保存するのでJOIN的処理が発生して遅くなる
    • varcharで頑張ろう
  • NoSQLインタフェースを使えば爆速
    • 各種言語のインタフェースあり
    • InnoDBのmemcachedインタフェースよりMySQL Clusterの方が現時点では賢い

まとめ(MySQL Clusterの使いどころ)

  • 大量の更新をさばきたい
  • HA機能が欲しい
  • 高速JOINしたい

@tsakuradaさん MySQL Clusterと丸4年の付き合いを振り返ってのよもやま話と、Version 7.3への期待(もっとユーザが増えるといいな~)

MCCT20130926 tsakuradac from Takeshi Sakurada

使用開始時の期待と使ってみたギャップ、現在の期待

  • インメモリだから速いはず
    • 参照に関していえばFIO+InnoDBでも変わらないかも
  • スケールアウト簡単
    • 構成によってはスケールしないこともあるので要考慮
  • 高可用性
    • 期待通り、フェイルオーバーは数秒で完了
  • ライセンスがGPLでオープンソース
  • 7.3でInnoとの互換性が上がって期待

サーバの構成

  • SQLノードと管理ノードは同居してもよい、データノード2台と合わせて最低4台からが現実的
  • データが多いならデータノードを増やす(が制約はあるので注意)
  • アクセスが多いならSQLノードを増やす。制約は少ないので割と簡単
  • せっかくのMySQL ClusterなんだからHW構成上もSPOFを減らそう
  • クエリがキャンセルされた時それを検出して後続処理をやるアプリ作り込み必須
    • ノード障害時にクエリがキャンセルされるため

InnoDBとの組み合わせ

  • Innoと同じ感覚でテーブル設計してもよいか?
    • 場合による。最近のバージョンではやってみる価値あり
  • InnoDBスレーブとの組み合わせ
    • 分離レベルが違う点は要注意だがおおむね問題なし

ハマりどころ(資料が詳しいのでそちら参照)

  • GCP Stop
  • ローリングリスタート
  • ボトルネックが見えづらい
  • データのライフサイクルを考えよう
  • リストアが大変

4年間でだいぶ地雷を踏んだのでもう大丈夫w 皆さんMySQL Cluster使いましょう

@yyamasaki1さん MySQL Cluster Auto-Installerのデモ

5分で作るMySQL Cluster環境 from yoyamasaki

Auto-Installer簡単なので使いましょう

  • ブラウザベースでぽちぽちやればインストール可能
  • 初期パラメータをいくつかいじった方がいい

@yoku0825さん ウチがNDBCLUSTERを使わない理由をもう一度考える

MySQL Clusterというと紛らわしいので、NDB Clusterと言いましょう<table border=0>

</table>

Nagiosのプラグイン作成や設定ファイル操作にpynagが超便利!

Nagiosの設定ファイルをパースする簡単な方法ないかなと思って調べてたら、pynagという超便利なパッケージ発見。日本語の情報ほとんどないけど、Fedoraの標準パッケージになっているってことは割と一般的なんだろうか。

  • Nagiosのプラグインを簡単に作りたい
  • Nagiosの設定ファイルをパースして値を取りたい
  • Nagiosの設定をコマンドラインやプログラムから取得・変更したい

って時に重宝する。pynagという名の通り、pythonで書かれている。公式ページのそのまんま訳に近いけど、使い方ご紹介。

インストール

Fedoraの最近のバージョンには標準で含まれており、CentOSやRHELならepelを使えるようにしておけばyumでインストールできる。

  
$ sudo yum install http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
  
$ sudo yum install pynag
  

pipが使えるならpipでもインストールできる。

  
$ sudo pip install pynag
  

設定ファイルのパース

pynagパッケージのModelモジュールを使えば、 /etc/nagios など代表的なパスから nagios.cfg を探し出して読み込んでくれる。含まれるホストとそのホストに関連づいたContact groupを表示する例。

  
from pynag import Model

# Get all hosts
  
all_hosts = Model.Host.objects.all
  
for i in all_hosts:
      
print i.host_name, i.contact_groups
  

設定書き換え

同じようにして、設定を保存することもできる。ホスト名がexamplehostのホストのContact groupを「mycontactgroup」にする例。

  
from pynag import Model

services = Model.Service.objects.filter(host_name='examplehost')
  
for i in services:
    
i.contactgroups = "mycontactgroup"
    
i.save()
  

ステータスの取得

監視結果が保存されているstatus.datファイルのパースもしてくれるので、ホストやサービスのステータス取得もできる。

ホストグループ名とサービス名を引数に与えてやると、ホストグループに所属するホスト全てに関するサービスのステータスを返すスクリプト。

  
import sys
  
from pynag import Model
  
from pynag.Parsers import status

argvs = sys.argv
  
argc = len(argvs)
  
status = status()

if (argc != 3):
          
print
          
print("Usage: ./%s hostgroup service" % argvs[0])
          
print
          
sys.exit()

hostgroups = Model.Hostgroup.objects.filter(hostgroup_name=argvs[1])
  
for hostgroup in hostgroups:
          
print("Hostgroup: %s" % hostgroup.hostgroup_name)
          
print("Member:")
          
for host in hostgroup.members.split(','):
                  
print("%s %s" % (host, status.get_servicestatus(host, argvs[2])['current_state']))
  

status.datのパースにはやや時間がかかるので、監視対象サーバの台数が多いと使用に耐えない。そういう場合は、高速にステータスを取得できるMK Livestatusと組み合わせることもできる。インストール方法は割愛するのでWebページを参照するべし。MK Livestatusを使って、上のスクリプトと同じようにホストグループとサービス名を引数に与えてホストのステータスを取得する例。


import sys
  
from pynag import Model
  
from pynag.Parsers import mk_livestatus

argvs = sys.argv
  
argc = len(argvs)
  
livestatus = mk_livestatus()

if (argc != 3):
          
print
          
print("Usage: ./%s hostgroup service" % argvs[0])
          
print
          
sys.exit()

hostgroups = Model.Hostgroup.objects.filter(hostgroup_name=argvs[1])
  
for hostgroup in hostgroups:
          
print("Hostgroup: %s" % hostgroup.hostgroup_name)
          
print("Member:")
          
for host in hostgroup.members.split(','):
                  
print(host)
                  
print(livestatus.get_service(host,argvs[2])['host_services_with_info'])
  

コマンドラインから使う

Pythonのスクリプト内だけでなく、pynagコマンドとしてシェルから直接使うこともできる。where句で対象を絞ることが可能。

全ホストオブジェクトを表示する例。

  
$ pynag list where object_type=host
  
object_type shortname filename
  
——————————————————————————-
  
host server01 /etc/nagios/Default_collector/hosts.cfg
  
host server02 /etc/nagios/Default_collector/hosts.cfg
  
(中略)
  
———-123 objects matches search condition———————————-
  

MySQL_Connect_cというサービスのチェックコマンドを表示する例。

  
$ pynag list effective_command_line where service_description=MySQL_Connect_c
  
effective_command_line
  
——————————————————————————-
  
/usr/lib64/nagios/plugins/check_mysql_health -hostname -user nagios -password nagios -mode connection-time -database test -critical 1
  
———-1 objects matches search condition————————————
  

もちろんコマンドラインから設定の変更も可能。ホスト名server01をserver02に変更する例。

  
$ pynag update set host_name=server02 where host_name=server01 and object_type=host
  

where句にはlikeのような部分一致が使えないようだ。複雑なクエリを発行したいときは、pythonスクリプトとして作った方がいいかもしれない。コマンドラインでの使い方はWikiにもう少し詳しく書いてある。

Nagiosプラグイン作成時に使う

個人的に一番ツボなのがこの機能。自作のプラグインに、Nagiosのプラグインを書く際のガイドラインに準じた引数の処理などを簡単に加えることができる。

/proc/loadavgの中身から、ロードアベレージを引いてくる簡単な例。

  
#!/usr/bin/python
  
import os,sys

## プラグインのオプションを生成
  
np = Plugin()

## コマンドライン引数を追加
  
np.add_arg("l","load-file", "Enter a load average file", required=None)

## プラグインをアクティベート
  
np.activate()

## load-fileオプションが指定されたらそのファイルからLAを読み込む
  
## デバッグと、add_argメソッドのサンプルとして
  
if np['load-file']:
      
load_file = np['load-file']
  
else:
      
load_file = "/proc/loadavg"

## ちょっとしたエラーチェック
  
if not os.path.isfile(load_file):
      
np.nagios_exit(np.UNKNOWN, "Missing Load average file %s" % load_file)

## チェックに使う値を取得
  
current_load = os.popen("cat %s" % load_file).readline().split()[0]

## パフォーマンスデータを付加
  
np.add_perfdata("1min", current_load)

## チェック実行
  
np.check_range(current_load)
  

上のスクリプトをcheck_cpu.pyとして保存しておく。5行目のPlugin()で、プラグインとして必要なオプションが用意されるので、以下のようにスクリプトに引数を指定しないで実行しただけで、簡易ヘルプが表示される。

  
$ ./check_load.py
  
usage: check_load.py [options]

check_load.py: error: You must provide a WARNING and/or CRITICAL value
  

さらに、-hオプションをつけると、詳細なヘルプが表示される。

  
$ ./check_load.py -h
  
usage: check_load.py [options]

options:
    
-h, -help show this help message and exit
    
-l LOAD-FILE, -load-file=LOAD-FILE
                          
Enter a load average file
    
-v VERBOSE, -verbose=VERBOSE
                          
Verbosity Level
    
-H HOST, -host=HOST Target Host
    
-t TIMEOUT, -timeout=TIMEOUT
                          
Connection Timeout
    
-c CRITICAL, -critical=CRITICAL
                          
Critical Threshhold
    
-w WARNING, -warning=WARNING
                          
Warn Threshhold
  

ここで、スクリプト内の8行目、add_argメソッドで追加したオプションが、ヘルプの中に「-l LOAD-FILE, -load-file=LOAD-FILE」として表示されている。また、-Hでの監視対象ホスト指定や-c,-wによる閾値の指定オプションがはじめから用意されていることがわかる。自作スクリプトを書くたびにオプションのパースから書いていた事を考えれば、なんという簡単さ!

もちろん、ヘルプでみたとおりのオプションを与えてやれば、プラグインとして使用可能。

  
$ uptime
   
13:16:19 up 396 days, 22:32, 3 users, load average: 0.60, 1.08, 1.04

$ ./check_load.py -w 1 127.0.0.1
  
OK: 0.60 is inside warning=1 and critical=None | '1min'=0.60;;;;
  

元々やりたかったのは「同一ホストグループ内のある台数のチェック失敗まではWARNING、その台数以上のチェック失敗でCRITICALアラートを上げたい」ということだったのだが、以下のような短いプラグインスクリプトで実現できた。

  
#!/usr/bin/python

import sys
  
from pynag import Model
  
from pynag.Parsers import status
  
from pynag.Plugins import simple as Plugin

np = Plugin()
  
status = status()

np.add_arg("g", "hostgroup", "Hostgroup name", required=1)
  
np.add_arg("s", "service", "Service name", required=1)

np.activate()

errornum = 0
  
hostgroups = Model.Hostgroup.objects.filter(hostgroup_name=np['hostgroup'])
  
for hostgroup in hostgroups:
          
for host in hostgroup.members.split(','):
                  
if status.get_servicestatus(host, np['service'])['current_state'] != "0":
                          
errornum = errornum + 1
  
np.add_perfdata("WARN/CRIT", errornum)

np.check_range(errornum)
  

2台のチェックに失敗している時の例。

  
# 2より多いとwarn、3より多いとcrit
  
$ python check_wipeout.py -hostgroup=common_dbs -service=ifSpeed_eth0_w -w 2 -c 3
  
OK: 2 is inside warning=2 and critical=3 | 'WARN/CRIT'=2;;;;

$ echo $?
  


# 1より多いとwarn、3より多いとcrit
  
$ python check_wipeout.py -hostgroup=common_dbs -service=ifSpeed_eth0_w -w 1 -c 3
  
WARNING: 2 is outside warning range: 1 | 'WARN/CRIT'=2;;;;

$ echo $?
  
1

# 1より多いとcrit
  
$ python check_wipeout.py -hostgroup=common_dbs -service=ifSpeed_eth0_w -c 1
  
CRITICAL: 2 is outside critical range: 1 | 'WARN/CRIT'=2;;;;
  
$ echo $?
  
2
  

というわけで、pynagがあるとNagiosプラグインを書くのが超簡単になる! pynag万歳!

ドキュメントはGithub上のWikiを見るとよい。Wikiからだと分からない部分も多いが、ソース自体はそれほど複雑ではないので読んでみればわかるのでは。