mysql binlog events でストリーム処理してみた #mysqluc15

Post on 12-Apr-2017

1.974 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

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

top related