mysql binlog events でストリーム処理してみた #mysqluc15
TRANSCRIPT
Binlog Events でストリーム処理してみた
ヤフー株式会社
三谷 智史
自己紹介
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止2
• 三谷 智史(@mita2)
• 所属ヤフー(株)DBMS技術
• RDB専門部隊 13名
• DB Administration 黒帯
本日の流れ
1. Yahoo JAPAN! のMySQL 利用状況
2. ストリーム処理の利点
3. Binlog Events を検証してみた
1. サンプルコード解説
2. 更新内容を取り出す方法
3. ありそうで、なかった機能
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止3
本日の流れ
1. Yahoo JAPAN! のMySQL 利用状況
2. ストリーム処理の利点
3. Binlog Events を検証してみた
1. サンプルコード解説
2. 更新内容を取り出す方法
3. ありそうで、なかった機能
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止4
Yahoo! JAPANのMySQL環境
• Yahoo!ニュース、Yahoo!ショッピング、Yahoo!ブログ、Yahoo!路線 etcほぼ全サービスで利用
• 約550DB
構成
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止6
サーバ台数
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止7
• 約220台
• オンプレです
• 容量18TB• ※ マスターのみカウント
マスター
サーバ
スレーブ
サーバ
バックアップ用
スレーブ
サーバ構成比率
共有ストレージのHAです
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止8
• 複数MySQLを集約
• 商用ストレージ
• 詳細:「レプリケーションを使わない」でWEB検索
共有ストレージのHAです
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止9
• 複数MySQLを集約
• 商用ストレージ
• 詳細:「レプリケーションを使わない」でWEB検索
Oracle Clusterware使ってます
Oracle Clusterware使ってます
世間で実績の少なそうな?機能の実績
• 5.6 + GTID
• 100DB以上で動かしてますが問題ないです
• パーティション
• 20DB以上で採用
• DROP PARITTIONによる高速データ削除
• ALTERに問題あり、使うなら5.6から… (Bug 77318)
• InnoDBテーブル 圧縮
• 20DB以上で採用。READ IO減ってかなりGOOD。
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止10
We love MySQL
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止11
0
100
200
300
400
500
600
We Love
本日の流れ
1. Yahoo JAPAN! のMySQL 利用状況
2. ストリーム処理の利点
3. Binlog Events を検証してみた
1. サンプルコード解説
2. 更新内容を取り出す方法
3. ありそうで、なかった機能
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止12
Yahoo! におけるストリーム処理
13
• 設立初期からストリーム処理を活用
• fluentd的なミドルウェア
決済システム
購入処理購入処理
LogReader
LogReader
Log Consumer
Log Consumer
Log Consumer
Log Consumer
トランザクションログトランザクションログ
ECサービスシステム
ストレージサービスシステム
キャンペーンフラグON
容量増量フラグON
プレミアム会員購入 非同期転送
処理イメージ、実際とは異なります
ストリーム処理の3つの利点
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止14
1.スケールアウト
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止15
スケールアウトしやすいスケールアウトしやすい
決済システム
購入処理購入処理
LogReader1
LogReader1
Log Consumer2
Log Consumer2
Log Consumer1
Log Consumer1
トランザクションログトランザクションログ
ECサービスシステム
キャンペーンフラグON
LogReader2
LogReader2
ユーザIDで分散
ユーザIDで分散
2.連携先の影響を受けにくい
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止16
連携先の影響を受けにくい連携先の影響を受けにくい
決済システム
購入処理購入処理
LogReader
LogReader
Log Consumer
Log Consumer
Log Consumer
Log Consumer
トランザクションログトランザクションログ
ECサービスシステム
ストレージサービスシステム
キャンペーンフラグON
容量増量フラグON
非同期転送
DOWNDOWN
3.リアルタイム
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止17
リアルタイムリアルタイム
☆ チン マチクタビレタ~
マチクタビレタ~
☆ チン 〃 ∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
ヽ ___\(\・∀・) < MySQLでストリーム処理まだ~
\_/⊂ ⊂_ ) \_____________
/ ̄ ̄ ̄ ̄ ̄ ̄ /|
| ̄ ̄ ̄ ̄ ̄ ̄ ̄| |
| 愛媛みかん |/
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止18
(社内の声)
本日の流れ
1. Yahoo JAPAN! のMySQL 利用事例
2. ストリーム処理の利点
3. Binlog Events を検証してみた
1. サンプルコード解説
2. 更新内容を取り出す方法
3. ありそうで、なかった機能
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止19
MySQL Binlog Events
• バイナリログを用いたストリーム処理ができる
• MySQL Labs で公開中(2015/12現在)
• 昔はBinlog APIっていうやつがあったらしい
• C++ libraries
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止20
利用イメージ
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止21
決済システム
購入処理購入処理BinlogEventsを使ったプログラムBinlogEventsを使ったプログラム
バイナリログバイナリログ
ECサービスシステム
ストレージサービスシステム
キャンペーンフラグON
容量増量フラグON
非同期転送
処理イメージ
• さっきの例だとこう
BinlogEventsを使ったプログラムBinlogEventsを使ったプログラム
まずはサンプルコード
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止22
Binlog Eventsのビルド
• Labs から mysql-binlog-events-1.0.1-src.tar.gz をDL
• サンプルが同梱されてます
• mysql-devel パッケージだけではビルド不可
• MySQL5.7 のソースもダウンロードしましょう
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止23
$ cmake -DMYSQLCLIENT_STATIC_LINKING:BOOL=TRUE ¥-DMYSQL_DIR=/usr/bin ¥-DMYSQL_SOURCE_INCLUDE_DIR=<ソース置いた場所>/include ¥-DENABLE_DOWNLOADS=1 .
$ make
$ cd example
$ make
接続先はどのバージョンでも大丈夫
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止24
MySQL 5.5
MySQL 5.6
MySQL 5.7
CHANGE LOG
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止25
############################
ChangeLog for Binary Log API
############################
Release 0.1.0 (released April 20, 2013)
---------------------------------------
* BAPI-1: In the binlog-replication-listener library,
mysql::Binary_log::connect function does not abort when
non-existent file name or server is provided
付属のサンプルは3つ
• basic-1
• basic-2
• binlog-browser
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止26
付属のサンプルは3つ
• basic-1
• basic-2
• binlog-browser
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止27
basic-1
• URI の書き方
mysql://user:password@localhost:3306
file:///var/lib/mysql/mysql-bin.000002
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止28
$ ./basic-1 mysql://root:Password123_@localhost:3306
basic-1 のソース - 接続方法
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止29
Binary_log_driver *drv= create_transport(argv[1]);
if (drv == NULL)
return 1;
Binary_log binlog(drv);
if (binlog.connect() != ERR_OK)
{
delete drv;
return 1;
}
URIを渡して接続URIを渡して接続
basic-1 を動かしてみる
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止30
$ ./basic-1 mysql://root:Password123_@localhost:3306Found event of type 2Found event of type 19Found event of type 30
mysql> CREATE TABLE `mytable` ~mysql> INSERT INTO mytable (v1) VALUES('abc');
イベントとは
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止31
QueryQuery BEGINBEGIN
Table_MapTable_Map 処理する対象テーブルの指定処理する対象テーブルの指定
Write_rowsWrite_rows INSERT INTO ~INSERT INTO ~
Update_rowsUpdate_rows UPDATE ~UPDATE ~
• 1つのトランザクションは複数イベントで構成
• 「Table_Map」や「Rotate」など特殊なイベントもある
イベントタイプ イベント内容(イメージ)
トランザクション
POS
POS
POS
POS
EVENT_TYPE 一覧
Unknown
Start_v3
Query
Stop
Rotate
Intvar
Load
Slave
Create_file
Append_block
Exec_load
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止32
Delete_file
New_load
RAND
User var
Format_desc
Xid
Begin_load_query
Execute_load_query
Table_map
Write_rows_event_old
Update_rows_event_old
Delete_rows_event_old
Write_rows_v1
Update_rows_v1
Delete_rows_v1
Incident
Heartbeat
Ignorable
Rows_query
Write_rows
Update_rows
Delete_rows
Gtid
Anonymous_Gtid
Previous_gtids
User Defined
付属のサンプルは3つ
• basic-1
• basic-2
• binlog-browser
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止33
basic-2 を動かしてみる
• SQLが表示される・・・?
• basic-2 はバグってます
• 本当は 変数 を値に置換してSQLを表示するプログラムです
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止34
$ ./basic-2 mysql://root:Password123_@localhost:3306create table mytable (pk serial, v1 varchar(255))BEGINinsert into mytable (v1) values(@myvar) 置換されてない置換されてない
なおしました
パッチhttps://gist.github.com/anonymous/02593d4981ac826f9837
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止35
basic-2 を動かしてみる(修正ver)
• binlog_format=STATEMENTで動かしましょう
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止36
$ ./basic-2 mysql://root:Password123_@localhost:3306create database hogexcreate table mytable (pk serial, v1 varchar(255))insert into mytable (v1) values(123) @myvarが置換される@myvarが置換される
mysql> CREATE TABLE mytable (pk SERIAL, v1 VARCHAR(5));mysql> SET @myvar=“123”;mysql> INSERT INTO mytable (v1) VALUES(@myvar);
basic-2 のソース
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止37
basic-2 のソース - main
Map variables;
Save_variables<Map> save_variables(variables);
Content_stream_handler handler;
handler.add_listener(save_variables);
Replace_variables<Map> replace_variables(variables);
handler.add_listener(replace_variables);
<snip>
while (true)
{
int error_number;
error_number= drv->get_next_event(&buf_and_len);
<snip>
handler.handle_event(&event);
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止38
ハンドラーを生成ハンドラーを生成
ハンドラーを登録ハンドラーを登録
バイナリログからイベントを読み取るバイナリログからイベントを読み取る
登録したハンドラーにイベントを渡してを処理登録したハンドラーにイベントを渡してを処理
ループループ
Binlog Events の設計思想
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止39
Get_next_eventGet_next_event
ループループ
ループ
コンテンツハンドラ(クラス)
コンテンツハンドラ(クラス)
- process_event(Delete_rows)- process_event(Write_rows)- process_event(Delete_rows)- process_event(Write_rows)
コンテンツハンドラコンテンツハンドラ
コンテンツハンドラコンテンツハンドラ
• 1イベントごとにハンドラで定義したprocess_eventが呼び出される
• イベントタイプごとに処理したい内容をコーディングする
• コンテンツハンドラは複数設定可能
INSERTされたときに実施したい処理を
書く
INSERTされたときに実施したい処理を
書く
Save_variablesコンテンツハンドラ
template <class AssociativeContainer>
class Save_variables : public Content_handler {
Binary_log_event *process_event(User_var_event *event) {
std::string a(event->val, 0, event->val_len);
m_var[event->name] = a;
return event;
}
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止40
変数のSETイベントを受け入れる
例)SET @abc = 123
変数のSETイベントを受け入れる
例)SET @abc = 123
val には値(123)が入ってる
val には値(123)が入ってる
グローバル変数のハッシュに登録しておく
例)m_var[abc] = 123
グローバル変数のハッシュに登録しておく
例)m_var[abc] = 123
Replace_variablesコンテンツハンドラ
Binary_log_event *process_event(Query_event *event) {
std::string query = event->query;
size_t start, end = 0;
while (true) {
start = query.find_first_of("@", end);
if (start == std::string::npos)
break;
end = query.find_first_not_of("abcdefghijklmnopqrstuvwxyz", start+1);
std::string key = query.substr(start + 1, end - start - 1);
query.replace(start, end - start, "'" + m_var[key] + "'");
}
event->query= query.c_str();
return event;
}
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止41
クエリから@を探すクエリから@を探す
@に続く英字の位置を検索@に続く英字の位置を検索
@~ を置換@~ を置換
クエリに対するイベントのみ処理するクエリに対する
イベントのみ処理する
Save_variablesで保存しておいたものSave_variablesで保存しておいたもの
付属のサンプルは3つ
• basic-1
• basic-2
• binlog-browser
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止42
binlog-browser
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止43
$ ./binlog-browser mysql://root:Password123_@localhost:3306Start Position End Position Event Length Event Type219 344 125 Query[2]Event Info: use `hoge`; create table mytable (pk serial, v1 varchar(255))344 409 65 Anonymous_Gtid[34]Event Info:409 482 73 Query[2]Event Info: BEGIN482 536 54 Table_map[19]Event Info: table id: 109 (hogex.mytable)536 584 48 Write_rows[30]Event Info: table id: 109 flags: Last event of the statement584 615 31 Xid[16]Event Info: Xid ID=26
binlog-browser のソース
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止44
Binary_log_driver *drv= create_transport(uri.c_str());
Binary_log binlog(drv);
int error_number= binlog.connect();
if (const char* msg= str_error(error_number))
cerr << msg << endl;
<snip>
if (binlog.set_position(opt_start_pos) != ERR_OK)
{
cerr << "The specified position "
<< opt_start_pos
<< " cannot be set"
<< endl;
return 1;
}
引数で指定したポジションにジャンプ
引数で指定したポジションにジャンプ
バイナリログから更新内容を取り出すには?
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止45
サンプルコードにはない
• tests/replaybinlog.cpp が参考になります
• ・・・これも動かなかった orz
• Binlog API のテストコードっぽい
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止46
値を取り出すサンプル
https://gist.github.com/anonymous/4f9e59a6e22593fdcaf0
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止47
カラムの値をとるコード
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止48
Binary_log_event *process_event(binary_log::Rows_event *event) {
Int2event_map::iterator ti_it= m_table_index.find(event->get_table_id());
binary_log::Row_event_set rows(event, ti_it->second);
binary_log::Row_of_fields fields= *row_it;
if (event->get_event_type() == binary_log::WRITE_ROWS_EVENT ||
event->get_event_type() == binary_log::WRITE_ROWS_EVENT_V1) {
std::cout << event_start_pos << "¥tINSERT¥t" <<
ti_it->second->m_dbnam << "." << ti_it->second->m_tblnam << "¥t";
binary_log::Row_of_fields::iterator field_it= fields.begin();
binary_log::Converter converter;
if (field_it != fields.end()) {
do {
std::string str;
converter.to(str, *field_it);
std::cout << str << "¥t";
} while (++field_it != fields.end());
ROWモードのイベントを受け取る
ROWモードのイベントを受け取る
INSERTの場合INSERTの場合
バイナリをデコードバイナリをデコード
直前のTable_Mapイベントからテーブル情報を
取得
直前のTable_Mapイベントからテーブル情報を
取得
実行例
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止49
$ ./decode mysql://root:Password123_@localhost:33061401 INSERT t.mytable 1 1231664 UPDATE t.mytable 1 123 1 4561941 DELETE t.mytable 1 456
mysql> INSERT INTO mytable VALUES(1, "123");mysql> UPDATE mytable SET c1 = "456";mysql> DELETE mytable WHERE pk = 1;
バイナリログ関連の設定について
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止50
サーバのbinlog_formatはROWで
• binlog_format=ROW
• タイプ Rows_event で記録
• 変更内容がバイナリで記録されている
• バイナリから実際の値にデコードする関数がある
• binlog eventsを使うにはこちらが前提
• binlog_format=STATEMENT
• タイプ Query_event で記録
• SQLがそのままバイナリログに記載される
• SQLから変更内容を特定するのは困難、BinlogEvents を使う場合は使わない想定
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止51
binlog_image にも注意
• binlog_image=full
• デフォルト
• 変更された行のPKと、その行の内容を記録
• binlog_image=minimal
• 更新を再現するのに最小限の情報のみを記録
• バイナリログのサイズが小さくて済む
• 例)DELETEだとPKのみ
• Binlog Events でPKしか拾えなくなるので注意
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止52
ありそうで、なかった機能x2
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止53
ありそうで、なかった機能 その1
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止54
分散、ルーティングの仕組み分散、ルーティングの仕組み
BinlogEventsBinlogEvents
バイナリログバイナリログ
処理イメージ
ユーザID: 1-1000を担当するサーバ
BinlogEventsBinlogEvents
ユーザID: 1000-2000を担当するサーバ
関係ないログは読み飛ばす実装
が必要
関係ないログは読み飛ばす実装
が必要
ありそうで、なかった機能 その2
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止55
「どこまで処理したか」を記録しておく仕組み「どこまで処理したか」を記録しておく仕組み
• 「BEGIN」イベントが来たら、それまでのバイナリログ、ログポジションをファイルに書く
• 再開時、ファイルを読んで、そこまで読み飛ばす
まとめ
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止56
まとめ
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止57
C++つらいC++つらい
なんとかストリーム処理できそうですなんとかストリーム処理できそうです
LLラッパーを一緒に書いてくれる人募集LLラッパーを一緒に書いてくれる人募集
Enjoy MySQL
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止58