MySQL Binlog Events でストリーム処理してみた #MySQLUC15

293 Views

December 16, 15

スライド概要

MySQL Binlog Events を検証してみました

profile-image

2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp

シェア

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Binlog Events で ストリーム処理してみた ヤフー株式会社 三谷 智史

2.

自己紹介 • 三谷 智史(@mita2) • 所属 ヤフー(株) DBMS技術 • RDB専門部隊 13名 • DB Administration 黒帯 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 2

3.

本日の流れ 1. Yahoo JAPAN! のMySQL 利用状況 2. ストリーム処理の利点 3. Binlog Events を検証してみた 1. サンプルコード解説 2. 更新内容を取り出す方法 3. ありそうで、なかった機能 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 3

4.

本日の流れ 1. Yahoo JAPAN! のMySQL 利用状況 2. ストリーム処理の利点 3. Binlog Events を検証してみた 1. サンプルコード解説 2. 更新内容を取り出す方法 3. ありそうで、なかった機能 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 4

5.

Yahoo! JAPANのMySQL環境 • Yahoo!ニュース、Yahoo!ショッピン グ、Yahoo!ブログ、Yahoo!路線 etc ほぼ全サービスで利用 • 約550DB

6.

構成 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 6

7.

サーバ台数 • 約220台 バックアップ用 • オンプレです スレーブ マスター サーバ スレーブ サーバ • 容量18TB • ※ マスターのみカウント サーバ構成比率 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 7

8.

共有ストレージのHAです • 複数MySQLを集約 • 商用ストレージ • 詳細: 「レプリケーションを使わない」 でWEB検索 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 8

9.

共有ストレージのHAです • 複数MySQLを集約 • 商用ストレージ • 詳細: 「レプリケーションを使わない」 Oracle でWEB検索 Clusterware 使ってます Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 9

10.

世間で実績の少なそうな?機能の実績 • 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

11.

We love MySQL 600 500 400 We Love 300 200 100 0 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 11

12.

本日の流れ 1. Yahoo JAPAN! のMySQL 利用状況 2. ストリーム処理の利点 3. Binlog Events を検証してみた 1. サンプルコード解説 2. 更新内容を取り出す方法 3. ありそうで、なかった機能 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 12

13.

Yahoo! におけるストリーム処理 • 設立初期からストリーム処理を活用 • fluentd的なミドルウェア プレミアム 会員購入 非同期転送 決済システム 購入処理 Log Reader トランザク ションログ ECサービス システム Log Consumer キャンペーン フラグON 処理イメージ、実際とは異なります ストレージサービス システム Log Consumer 容量増量 フラグON 13

14.

ストリーム処理の3つの利点 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 14

15.

1.スケールアウト スケールアウトしやすい ECサービス システム 決済システム Log Reader1 購入処理 Log Reader2 トランザク ションログ Log Consumer1 Log Consumer2 ユーザIDで 分散 キャンペーン フラグON Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 15

16.

2.連携先の影響を受けにくい 連携先の影響を受けにくい 非同期転送 決済システム 購入処理 Log Reader トランザク ションログ ECサービス システム Log DOWN Consumer キャンペーン フラグON Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 ストレージサービス システム Log Consumer 容量増量 フラグON 16

17.

3.リアルタイム リアルタイム Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 17

18.

(社内の声) ☆ チン マチクタビレタ~ マチクタビレタ~ ☆ チン 〃 ∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ヽ ___\(\・∀・) < MySQLでストリーム処理まだ~ \_/⊂ ⊂_ ) \_____________ / ̄ ̄ ̄ ̄ ̄ ̄ /| | ̄ ̄ ̄ ̄ ̄ ̄ ̄| | | 愛媛みかん |/ Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 18

19.

本日の流れ 1. Yahoo JAPAN! のMySQL 利用事例 2. ストリーム処理の利点 3. Binlog Events を検証してみた 1. サンプルコード解説 2. 更新内容を取り出す方法 3. ありそうで、なかった機能 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 19

20.

MySQL Binlog Events • バイナリログを用いたストリーム処理ができる • MySQL Labs で公開中(2015/12現在) • 昔はBinlog APIっていうやつがあったらしい • C++ libraries Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 20

21.

利用イメージ • さっきの例だとこう 非同期転送 決済システム 購入処理 ECサービス システム BinlogEvents を使ったプログラム キャンペーン フラグON バイナリログ ストレージサービス システム BinlogEvents を使ったプログラム 容量増量 フラグON 処理イメージ Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 21

22.

まずはサンプルコード Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 22

23.

Binlog Eventsのビルド • Labs から mysql-binlog-events-1.0.1-src.tar.gz をDL • サンプルが同梱されてます • mysql-devel パッケージだけではビルド不可 • MySQL5.7 のソースもダウンロードしましょう $ 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. 無断引用・転載禁止 23

24.

接続先はどのバージョンでも大丈夫 MySQL 5.5 MySQL 5.6 MySQL 5.7 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 24

25.

CHANGE LOG ############################ 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 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 25

26.

付属のサンプルは3つ • basic-1 • basic-2 • binlog-browser Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 26

27.

付属のサンプルは3つ • basic-1 • basic-2 • binlog-browser Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 27

28.

basic-1 $ ./basic-1 mysql://root:Password123_@localhost:3306 • URI の書き方 mysql://user:password@localhost:3306 file:///var/lib/mysql/mysql-bin.000002 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 28

29.

basic-1 のソース - 接続方法 Binary_log_driver *drv= create_transport(argv[1]); URIを渡して接続 if (drv == NULL) return 1; Binary_log binlog(drv); if (binlog.connect() != ERR_OK) { delete drv; return 1; } Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 29

30.

basic-1 を動かしてみる mysql> CREATE TABLE `mytable` ~ mysql> INSERT INTO mytable (v1) VALUES('abc'); $ ./basic-1 Found event Found event Found event mysql://root:Password123_@localhost:3306 of type 2 of type 19 of type 30 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 30

31.

イベントとは • 1つのトランザクションは複数イベントで構成 • 「Table_Map」や「Rotate」など特殊なイベン トもある トランザクション イベントタイプ Query イベント内容(イメージ) BEGIN Table_Map 処理する対象テーブルの指定 Write_rows INSERT INTO ~ Update_rows UPDATE ~ Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 POS POS POS POS 31

32.

EVENT_TYPE 一覧 Unknown Start_v3 Query Stop Rotate Intvar Load Slave Create_file Append_block Exec_load 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 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 32

33.

付属のサンプルは3つ • basic-1 • basic-2 • binlog-browser Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 33

34.

basic-2 を動かしてみる $ ./basic-2 mysql://root:Password123_@localhost:3306 create table mytable (pk serial, v1 varchar(255)) BEGIN 置換されてない insert into mytable (v1) values(@myvar) • SQLが表示される・・・? • basic-2 はバグってます • 本当は 変数 を値に置換してSQLを表示する プログラムです Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 34

35.

なおしました パッチ https://gist.github.com/anonymous/02593d4981ac826f9837 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 35

36.

basic-2 を動かしてみる(修正ver) mysql> CREATE TABLE mytable (pk SERIAL, v1 VARCHAR(5)); mysql> SET @myvar=“123”; mysql> INSERT INTO mytable (v1) VALUES(@myvar); $ ./basic-2 mysql://root:Password123_@localhost:3306 create database hogex create table mytable (pk serial, v1 varchar(255)) insert into mytable (v1) values(123) @myvarが置換される • binlog_format=STATEMENTで動かしましょう Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 36

37.

basic-2 のソース Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 37

38.

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

39.

Binlog Events の設計思想 • 1イベントごとにハンドラで定義し たprocess_eventが呼び出される • イベントタイプごとに処理したい内 容をコーディングする • コンテンツハンドラは複数設定可能 ループ Get_next_event コンテンツハンドラ コンテンツハンドラ (クラス) コンテンツハンドラ INSERTされたとき に実施したい処理を 書く - process_event(Delete_rows) - process_event(Write_rows) ループ Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 39

40.
[beta]
Save_variablesコンテンツハンドラ
template <class AssociativeContainer>
変数のSETイベント
class Save_variables : public Content_handler { を受け入れる

例)SET @abc = 123

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;
}

val には値(123)が
入ってる

グローバル変数のハッシュに
登録しておく
例)m_var[abc] = 123

Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

40

41.
[beta]
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] + "'");
}
Save_variablesで
@~
を置換
event->query= query.c_str();
保存しておいたもの

return event;
}
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

41

42.

付属のサンプルは3つ • basic-1 • basic-2 • binlog-browser Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 42

43.

binlog-browser $ ./binlog-browser mysql://root:Password123_@localhost:3306 Start Position End Position Event Length Event Type 219 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: BEGIN 482 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 statement 584 615 31 Xid[16] Event Info: Xid ID=26 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 43

44.
[beta]
binlog-browser のソース
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. 無断引用・転載禁止

44

45.

バイナリログから更新内容 を取り出すには? Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 45

46.

サンプルコードにはない • tests/replaybinlog.cpp が参考になります • ・・・これも動かなかった orz • Binlog API のテストコードっぽい Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 46

47.

値を取り出すサンプル https://gist.github.com/anonymous/ 4f9e59a6e22593fdcaf0 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 47

48.
[beta]
カラムの値をとるコード
Binary_log_event *process_event(binary_log::Rows_event *event) {

ROWモードの
イベントを受け取る

Int2event_map::iterator ti_it= m_table_index.find(event->get_table_id());
binary_log::Row_event_set rows(event, ti_it->second);
直前のTable_Map
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" <<
INSERTの場合
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());
Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

48

49.

実行例 mysql> INSERT INTO mytable VALUES(1, "123"); mysql> UPDATE mytable SET c1 = "456"; mysql> DELETE mytable WHERE pk = 1; $ ./decode mysql://root:Password123_@localhost:3306 1401 INSERT t.mytable 1 123 1664 UPDATE t.mytable 1 123 1 1941 DELETE t.mytable 1 456 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 456 49

50.

バイナリログ関連の 設定について Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 50

51.

サーバのbinlog_formatはROWで • binlog_format=ROW • • • • タイプ Rows_event で記録 変更内容がバイナリで記録されている バイナリから実際の値にデコードする関数がある binlog eventsを使うにはこちらが前提 • binlog_format=STATEMENT • タイプ Query_event で記録 • SQLがそのままバイナリログに記載される • SQLから変更内容を特定するのは困難、Binlog Events を使う場合は使わない想定 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 51

52.

binlog_image にも注意 • binlog_image=full • デフォルト • 変更された行のPKと、その行の内容を記録 • binlog_image=minimal • • • • 更新を再現するのに最小限の情報のみを記録 バイナリログのサイズが小さくて済む 例)DELETEだとPKのみ Binlog Events でPKしか拾えなくなるので注意 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 52

53.

ありそうで、なかった機能 x2 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 53

54.

ありそうで、なかった機能 その1 分散、ルーティングの仕組み Binlog Events ユーザID: 1-1000を担当 するサーバ バイナリログ 関係ないログは 読み飛ばす実装 が必要 Binlog Events ユーザID: 1000-2000を担当 するサーバ Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 54

55.

ありそうで、なかった機能 その2 「どこまで処理したか」を記録しておく仕組み • 「BEGIN」イベントが来たら、それまでのバイ ナリログ、ログポジションをファイルに書く • 再開時、ファイルを読んで、そこまで読み飛ばす Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 55

56.

まとめ Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 56

57.

まとめ なんとかストリーム処理できそうです C++つらい LLラッパーを一緒に書いてくれる人募集 Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 57

58.

Enjoy MySQL Copyright (C) 2015 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 58