トップ  > メモ一覧  > カテゴリ「可要性」の絞り込み結果 : 3件

3件中 1 〜 3 表示  1 

No.3588【引用】DeNAによる大規模なMySQLノンストップ運用の裏側にある、フェイルオーバー自動化ツール

DeNAによる大規模なMySQLノンストップ運用の裏側にある、フェイルオーバー自動化ツール
2011年4月15日

4月11日から米サンタクララで行われた「 MySQL Conference & Expo 2011 」。このイベントでDeNAの松信嘉範(まつのぶよしのり)氏が、同社の大規模なMySQLの運用を支えている技術とツールについてのセッション「Automated, Non-Stop MySQL Operations and Failover」を行いました。
プレゼンテーションの中で、社内で利用しているフェイルオーバーの自動化ツールをオープンソース化することにも触れています(英語...

引用元

更新:2011/04/21 10:35 カテゴリ: MySQL  > 可要性 ▲トップ

No.2124 EC2上でMySQLMulti-masterフェイルオーバー

EC2上でMySQL Multi-masterフェイルオーバー

EC2上では、仮想IPアドレスなどのIPレベルの機能が制限されているため、仮想IPアドレスを使用した冗長化は基本的には使用できません。が、DNSを使用することで、VIPほどの精度は高くないもののMySQL Multi-master構成を構築することができました。

今回は、MySQL Multi-masterの切り替え用の支援ツールとして、Multi-Master Replication Manager for MySQLを使用します。このツールでは、MySQLの死活監視と仮想IPアドレスの切り替えを行ってくれます。

もちろん、EC2上では仮想IPアドレスは使えないので、そのままではうまく動作しません。ここで、このツールに含まれるns_agentを使用することで仮想IPアドレスではなく、DNSによる切り替えができるようになり、EC2上でMulti-masterを構築することができます。

今回は、このMulti-Master Replication Manager for MySQLとns_agentを使って、DNSによるMulti-masterのフェイルオーバーを実現してみます。

概要について、AWS UGのLTで使ったスライドを貼っておきます。

準備編

環境設定

Amazon EC2 API Toolsを使えるようにしましょう。ドキュメントを参照するか、ググってください。

次に、インスタンスを2台起動します。個人的な趣味で、RightScaleのCentOS 5.2 32bitのイメージを使用しています。セキュリティグループ(mmm_test)は、内部通信は可能にしておきます。

ec2-run-instances ami-ab2071ee -g mmm_test -k mmm_test
ec2-run-instances ami-ab2071ee -g mmm_test -k mmm_test

立ち上がったインスタンスを、host1とhost2とします。

それぞれのホストで、必要なツールをざくざくインストールします。

rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm
yum -y install perl-Proc-Daemon perl-Algorithm-Diff perl-Log-Log4perl perl-MailTools perl-Log-Dispatch perl-Class-Singleton
yum -y install mysql-server mysql
yum -y install php libnet
MySQLの設定

MySQLのMulti-master replicationを構築します。Multi-master replicationの構築方法は、Googleで検索するか、実践ハイパフォーマンスMySQLの第8章を参照してください。

次にMulti-master replication manager用の権限を設定します。パスワードは適当の変更してください。

GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'%' IDENTIFIED BY 'monitor_password';
GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'%'   IDENTIFIED BY 'agent_password';
GRANT SUPER, REPLICATION CLIENT, PROCESS,REPLICATION SLAVE ON *.* TO 'replication'@'%' IDENTIFIED BY 'replication_password';
bindの設定

適切なサーバ(例えば、host1)にbindの設定を行います。参考にほぼ最小構成のbindの設定を書いておきます。ここでは、db.testdomainという名前を使用しています。DNSでフェイルオーバーしますのでTTLを短め(ここでは10秒)に設定することが肝です。

  • /etc/named.conf
options
{
        directory "/var/named"; // the default
        dump-file               "data/cache_dump.db";
        statistics-file         "data/named_stats.txt";
        memstatistics-file      "data/named_mem_stats.txt";

        recursion no;

};

zone "testdomain" IN {
    type master;
    file "zones/mmm.zone";
};
$ORIGIN testdomain.
$TTL 10 ; 10 seconds
@       IN SOA  testdomain. postmaster.testdomain. (
        1002044230 ; serial
        3600       ; refresh (1 hour)
        1200       ; retry (20 min.)
        1209600    ; expire (2 weeks)
        900        ; minimum (15 min.)
        )
@               IN  NS          ns1.testdomain.
ns1             IN  A           10.xx.yy.zz
db IN A 10.xx.yy.zz

また各ホストのresolv.confにhost1のIPアドレスを追加しておきます。一応、timeoutも短めに設定しておきましょう。

  • /etc/resolve-conf
search us-west-1.compute.internal
timeout 3
nameserver 10.xx.yy.zz
nameserver 172.16.0.23

DNSによるMySQL Multi-master フェイルオーバー

Multi-Master Replication Manager for MySQL

Multi-Master Replication Manager for MySQLをチェックアウトして、初期設定を行います。

svn checkout http://mysql-master-master.googlecode.com/svn/trunk/ mysql-master-master-read-only
ln -s mysql-master-master-readonly /usr/local/mmm
ln -s /usr/local/mmm/scripts/init.d/mmm_mon /etc/init.d
ln -s /usr/local/mmm/scripts/init.d/mmm_agent /etc/init.d

ns_agentを使用するために、ifconfig.pmを書換えておきます。

mv /usr/local/mmm/lib/ifconfig.pm /usr/local/mmm/lib/ifconfig.original.pm
ln -s /usr/local/mmm/contrib/ns_agent/ifconfig.pm /usr/local/mmm/lib
MySQL Multi-master Manager + ns_agent

MySQL Multi-master Managerとns_agentによる構成は以下の3種類のデーモンプロセスが動作します。

  • データベースに同居させるmmmd_agent
  • 監視・切り替え制御を行うmmmd_mon
    • サーバの状態を管理し、mmmd_agentを通じて、各サーバの監視・制御を行う
  • DNSサーバに同居させるns_agent
    • zoneファイルを書換えて、DNSの制御を行う
設定ファイル

ずらずらと設定ファイルを並べておきます。

  • mmm_common.conf
# Cluster interface
cluster_interface eth0

# Debug mode
debug yes

# Paths
bin_path /usr/local/mmm/bin

# Logging setup
log mydebug
    file /usr/local/mmm/var/mmm-debug.log
    level debug

log mytraps
    file /usr/local/mmm/var/mmm-traps.log
    level trap
    email root@localhost

# Email notification settings
email notify
    from_address stanaka@hatena.ne.jp
    from_name MMM Control

# Define roles
active_master_role writer

# MMMD command socket tcp-port
agent_port 9989
monitor_ip 127.0.0.1

# Cluster hosts addresses and access params
host db1
    ip 10.xx.yy.zz
    port 3306
    user replication
    password replication_password
    mode master
    peer db2

host db2
    ip 10.xx.yy.zzz
    port 3306
    user replication
    password replication_password
    mode master
    peer db1

# Mysql Writer role
role writer
    mode exclusive
    servers db1, db2
    ip db.testdomain

# Replication credentials used by slaves to connect to the master
replication_user replication
replication_password replication_password

# Checks parameters

# Ping checker
check ping
    check_period 1
    trap_period 5
    timeout 2

# Mysql checker
# (restarts after 10000 checks to prevent memory leaks)
check mysql
    check_period 1
    trap_period  2
    timeout 2
    restart_after 10000

# Mysql replication backlog checker
# (restarts after 10000 checks to prevent memory leaks)
check rep_backlog
    check_period 5
    trap_period 10
    max_backlog 60
    timeout 2
    restart_after 10000

# Mysql replication threads checker
# (restarts after 10000 checks to prevent memory leaks)
check rep_threads
    check_period 1
    trap_period 5
    timeout 2
    restart_after 10000
  • mmm_agent.conf
include mmm_common.conf

# Paths
pid_path /usr/local/mmm/var/mmmd_agent.pid

# MMMD command socket tcp-port and ip
bind_port 9989

# Define current server id
this db1

# Cluster hosts addresses and access params
host db1
    user mmm_agent
    password agent_password

host db2
    user mmm_agent
    password agent_password

nameserver ns1
    ip 10.160.47.21
    port 9994
  • mmm_mon.conf
include mmm_common.conf

# Paths
pid_path /usr/local/mmm/var/mmmd.pid
status_path /usr/local/mmm/var/mmmd.status

# MMMD command socket tcp-port
bind_port 9988

# Choose the default failover method [manual|wait|auto]
failover_method wait

# How many seconds to wait for both masters to become ONLINE
# before switching from WAIT to AUTO failover method, 0 = wait indefinitely
wait_for_other_master 60

# How many seconds to wait before switching node status from AWAITING_RECOVERY to ONLINE
# 0 = disabled
auto_set_online 10

monitor_user mmm_monitor
monitor_password monitor_password
  • mmm_ns_agent.conf
[nameserver_agent]
port = 9994
zoneFile = /var/named/zones/mmm.zone
起動

あとは各デーモンプロセスを起動するのみです。まず、各データベースサーバで、mmm_agentを起動します。

/etc/init.d/mmm_agent start
Starting MMM Agent daemon: MySQL Multi-Master Replication Manager
Version: 1.2.6
[2010-02-22 22:15:59]: Scanning network interfaces for the existing roles...
[2010-02-22 22:15:59]: Core: Execute_bin('/usr/local/mmm/bin/mysql_deny_write 'mmm_agent.conf'')
[2010-02-22 22:15:59]: Listener: Waiting for connection...
[2010-02-22 22:16:00]: Listener: Connect!
[2010-02-22 22:16:00]: SET_STATUS 0, ONLINE, , db1
...

次に、監視サーバでmmm_monを起動します。

# /etc/init.d/mmm_mon start
Daemon bin: '/usr/local/mmm/sbin/mmmd_mon'
Daemon pid: '/usr/local/mmm/var/mmmd.pid'
Starting MMM Monitor daemon: MySQL Multi-Master Replication Manager
Version: 1.2.6
Reading config file: 'mmm_mon.conf'
[2010-02-22 22:16:24]: Spawning checker 'rep_backlog'...
[2010-02-22 22:16:24]: Spawning checker 'mysql'...
[2010-02-22 22:16:24]: Spawning checker 'ping'...
[2010-02-22 22:16:24]: Spawning checker 'rep_threads'...
[2010-02-22 22:16:25]: Trying initial check 'rep_backlog' on host 'db2'...
[2010-02-22 22:16:25]: rep_backlog('db2') = 'OK'
[2010-02-22 22:16:25]: Trying initial check 'mysql' on host 'db2'...
[2010-02-22 22:16:25]: mysql('db2') = 'OK'
...

最後にDNSサーバでns_agentを起動します。

# php /usr/local/mmm/contrib/ns_agent/ns_agent.php
Daemon started, listening on 9994
動作確認

ここでアクティブ側のdb1(host1)のmysqldを落してみます。

/etc/init.d/mysqld stop

そうするとmmm_monの監視が動いて、ns_agentに情報が伝わり、zoneファイルが書換えられます。

Command Received: ADDIP:db.testdomain:10.160.47.21
Executing: sed -i.last '/db.*/d' /var/named/zones/mmm.zone
Executing: echo 'db IN A 10.xx.yy.zzz' >> /var/named/zones/mmm.zone
Updating /var/named/zones/mmm.zone with new serial:1002044230

その後、zoneファイルが再読み込みされ、DNS情報が更新されフェイルオーバーが実現されます。

フェイルオーバーの様子を、監視していると、以下のように数秒で切り替わったことが確認できます。

# while /bin/true; do date; mysqladmin -ummm_agent -pagent_password -hdb.testdomain variables | grep server_id; sleep 2; done
....
Mon Feb 22 22:20:53 EST 2010
| server_id                       | 1                                                          |
Mon Feb 22 22:20:55 EST 2010
| server_id                       | 1                                                          |
Mon Feb 22 22:20:57 EST 2010
mysqladmin: connect to server at 'db.testdomain' failed
error: 'Lost connection to MySQL server at 'reading initial communication packet', system error: 111'
Mon Feb 22 22:20:59 EST 2010
mysqladmin: connect to server at 'db.testdomain' failed
error: 'Lost connection to MySQL server at 'reading initial communication packet', system error: 111'
Mon Feb 22 22:21:01 EST 2010
| server_id                       | 2                                                          |
Mon Feb 22 22:21:03 EST 2010
| server_id                       | 2                                                          |
...

おわり

MySQLのMulti-masterのフェイルオーバーに数秒かかってしまいますが、用途によっては、なんとか我慢できるところもあると思います。EC2のホストも時々は落ちることがある、という話はよく聞きますので、少なくともシングルマスターの場合よりは安心できると思います。

もし、よりよい方法があったら、是非教えてください!!

引用元

更新:2010/02/25 07:47 カテゴリ: MySQL  > 可要性 ▲トップ

No.1727 実録、ほぼ無停止なMySQLのフェイルオーバ(動画もあるよ)

実録、ほぼ無停止なMySQLのフェイルオーバ (動画もあるよ)

レプリケーションしてるMySQLで、マスタやスレーブが障害停止した場合のリカバリプラン でも掲げたゴールである、「マスタが落ちてもぐーすか寝ていられるようにしたい」がほぼできたので、ほとんどサービスが停止することなく、フェイルオーバする様をスクリーンキャストに収めました。

埋め込みプレイヤーだと、小さくてわからないと思うので、リンク直接でみてください。

http://www.irori.org/pub/mysql-mm.mov

登場するホスト

登場するホストは2台、db901とdb902です。

最初は、db901が更新系クエリを受けるプライマリでdb900の浮動IPアドレスを持っています。

画面分割

画面は5分割しています。

  • 左上 = 「select sysdate(),@@server_id」をdb900に対して(sleep 1しながら)延々と実行しまくりんぐ
  • 右上 = ping -n db900
  • 右下の2つ = 上のが ping -n db901、下のが ping -n db902
  • 左下 = db901を落とそうと待ち構えているターミナル

動画の解説

00:00
はじまりはじまり。db900に対するselect、db900,db901,db902に対するping、すべて正常に流れている。selectのserver_idは、db901のものである「901」が返ってきているのを覚えておいてください。
00:11
この時点でのプライマリでもあるdb901を強制終了する。強制終了には SysRq を使ってバルスっと落とす (# echo b > /proc/sysrq-trigger)
00:12
db901が停止したので、db901に対するpingがとまる。db901はdb900でもあったので、db900に対するpingとdb900に対するselectも止まる。
00:17
首尾よくフェイルオーバが完了し、db902がdb900となったので、db900に対するpingとdb900に対するselectが回復(server_idが「901」から「902」に変わっている点に注目!)した。yay!

フェイルオーバのメカニズム

今回のケースでは、停止から 5 秒後には、

  • 異常の検知
  • プライマリのフェイルオーバ

が完了しています。

フェイルオーバのメカニズムは、レプリケーションしてるMySQLで、マスタやスレーブが障害停止した場合のリカバリプラン の 「<セカンダリをプライマリに昇格>」に書いた通りなんですが、監視とこのフェイルオーバ処理の実装は、

  • keepalived --vrrp
  • MySQLのL7レベルの監視をするスクリプト (check-service.db)
  • 状態変更時にもろもろの処理をするスクリプト (trigger-vrrp.db)
    • keepalived.confのnotifyや、check-service.db から実行される

で行ってます。

あとがき

これでお正月は安心しておもちがたべられそうです ^ρ^

引用元

更新:2009/11/12 09:38 カテゴリ: MySQL  > 可要性 ▲トップ
3件中 1 〜 3 表示  1 

FuelPHP

Mac

フロントエンド開発

web開発

プロマネ

マネタイズ

プレゼン

webサービス運用

webサービス

Linux

サーバ管理

MySQL

ソース・開発

svn・git

PHP

HTML・CSS

JavaScript

ツール, ライブラリ

ビジネス

テンプレート

負荷・チューニング

Windows

メール

メール・手紙文例

CodeIgniter

オブジェクト指向

UI・フロントエンド

cloud

マークアップ・テキスト

Flash

デザイン

DBその他

Ruby

PostgreSQL

ユーティリティ・ソフト

Firefox

ハードウェア

Google

symfony

OpenPNE全般

OpenPNE2

Hack(賢コツ)

OpenPNE3

リンク

個人開発

その他

未確認

KVS

ubuntu

Android

負荷試験

オープンソース

社会

便利ツール

マネー

Twig

食品宅配

WEB設計

オーディオ

一般常識

アプリ開発

サイトマップ

うずら技術ブログ

たませんSNS

rss2.0