This document summarizes a microservices meetup hosted by @mosa_siru. Key points include:
1. @mosa_siru is an engineer at DeNA and CTO of Gunosy.
2. The meetup covered Gunosy's architecture with over 45 GitHub repositories, 30 stacks, 10 Go APIs, and 10 Python batch processes using AWS services like Kinesis, Lambda, SQS and API Gateway.
3. Challenges discussed were managing 30 microservices, ensuring API latency below 50ms across availability zones, and handling 10 requests per second with nginx load balancing across 20 servers.
This document discusses N:1 replication, which allows multiple master databases to replicate to a single slave database. It describes how N:1 replication works and some limitations, like inability to keep up with schema changes or restarting easily. The document then introduces MHA (Master High Availability), a tool that can automate failover between masters. While N:1 replication and MHA have similar mechanisms for switching masters, N:1 replication requires specifying the exact binlog position, so it does not support automatic failover when a master completely fails like MHA can.
Despite the existence of data analysis tools such as R, SQL, Excel and others, it is still insufficient to cope with today's big data analysis needs.
The author proposes a CUI (Character User Interface) toolset with dozens of functions to neatly handle tabular data in TSV (Tab Separated Values) files.
It implements many basic and useful functions that have not been implemented in existing software with each function borrowing the ideas of Unix philosophy and covering the most frequent pre-analysis tasks during the initial exploratory stage of data analysis projects.
Also, it greatly speeds up basic analysis tasks, such as drawing cross tables, Venn diagrams, etc., while existing software inevitably requires rather complicated programming and debugging processes for even these basic tasks.
Here, tabular data mainly means TSV (Tab-Separated Values) files as well as other CSV (Comma Separated Value)-type files which are all widely used for storing data and suitable for data analysis.
2022/3/24に開催した「オンプレML基盤 on Kubernetes」の資料です。機械学習モデルの開発者が、よりモデルの開発にのみ集中できるようにすることを目指して開発している「LakeTahoe(レイクタホ)」について紹介します。
https://ml-kubernetes.connpass.com/event/239859/
2022/3/24に開催した「オンプレML基盤 on Kubernetes」の資料です。オンプレミス環境のKubernetesを使って構築した機械学習基盤の開発、運用の取り組みをご紹介します。
https://ml-kubernetes.connpass.com/event/239859/
11. • インデックスはツリー構造
• データはソートされている
• リーフノードに値と行のPKを格納
なぜ、インデックスで高速化するのか?
PK col1 time
1 a 11:15
2 f 01:10
3 d 03:01
: : :
SELECT * FROM t WHERE col1 = ‘f’
インデックス対象
a-p r-z
a
pk=1
d
pk=3
f
pk=2
p
pk=9
r
pk=4
t
pk=5
12. カーディナリティ
mysql> show index from t;
+-----+----------+----------+------------+-<SNIP>-+-----------+-------------+
|Table|Non_unique| Key_name |Seq_in_index| | Collation | Cardinality |
+-----+----------+----------+------------+--------+-----------+-------------+
| t | 0| PRIMARY | 1| | A | 5 |
+-----+----------+----------+------------+--------+-----------+-------------+
1 row in set (0.00 sec)
インデックス内のユニークな値
の多さを表した指数
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
15. PK is_pk_1000multi
(PKが1000の倍数?)
time
1 0 11:15
: 0 12:31
1000 1 13:44
: : 14:01
: : :
1000000 1 20:01
例外
0
pk=1
pk=2
pk=3
:
:
:
1
pk=1000
pk=2000
pk=3000
:
SELECT * FROM t WHERE is_pk_1000multi = 1
AND time <= 12:00
• 分布が偏っていれば効果が大きくなる
• 条件によって効果が異なる
インデックス対象
×
1000回
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
16. Left-Most-Index
以下のインデックスは同じ?
違います
インデックスA.
CREATE INDEX idxA1 ON mytable (col1);
CREATE INDEX idxA2 ON mytable (col2);
インデックスB.
CREATE INDEX idxB1 ON mytable (col1, col2);
インデックスC.
CREATE INDEX idxC1 ON mytable (col2, col1);
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
17. 複合インデックスでは指定順が重要
a
pk=1
9 a
pk=2
8 b
pk=3
7 b
pk=4
6
5
pk=1
c 6
pk=4
b 7
pk=2
b 8
pk=3
a
インデックスB.
CREATE INDEX idxB1 ON mytable (col1, col2);
インデックスC.
CREATE INDEX idxC1 ON mytable (col2, col1);
a b~c
5~6 7~9
col2col1
col1col2
c
pk=5
5
9
pk=5
a
18. 複合インデックスでは指定順が重要
絞り込み対象カラム
→
1.WHRER col1 =
‘x’
2.WHERE col2 =
‘x’
3.WHERE col1 = ‘x’ AND col2 = ‘x’
インデックスA idxA1
が利用される
idxA2
が利用される
idxA1, idxA2 どちらかが利用される。
※
インデックスB idxB1
が利用される
インデックスは利
用されない
idxB1 が利用される。
idxA1, idxA2より高速。
インデックスC インデックスは利
用されない
idxC1
が利用される
idxC1が利用される。
idxA1, idxA2より高速。
※ 場合によってはインデックスマージ
インデックスA.
CREATE INDEX idxA1 ON mytable (col1);
CREATE INDEX idxA2 ON mytable (col2);
インデックスB.
CREATE INDEX idxB1 ON mytable (col1, col2);
インデックスC.
CREATE INDEX idxC1 ON mytable (col2, col1);
27. 実行計画の確認
• 実行計画=クエリの処理の流れ
• 「EXPLAIN」をクエリの先頭に付ける
• 更新系クエリはSELECTに書き換え
UPDATE t SET col = newvalue WHERE condition = ‘x’;
EXPLAIN SELECT col FROM t WHERE condition = ‘x’;
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
28. EXPLAINの結果の例
mysql> EXPLAIN SELECT t1.pk, t1.col1, t2.col2
FROM t1 INNER JOIN t2
ON (t1.pk = t2.fk)
WHERE t1.pk = 1;
+----+------------+------+------+--------------------+--------+--------+------+-----+-------------+
| id | select_type| table| type | possible_keys | key | key_len| ref | rows| Extra |
+----+------------+------+------+--------------------+--------+--------+------+-----+-------------+
| 1 | SIMPLE | t1 | const| PRIMARY,pk_col1_idx| PRIMARY| 4 | const| 1| |
| 1 | SIMPLE | t2 | ALL | NULL | NULL | NULL | NULL | 5| Using where |
+----+------------+------+------+--------------------+--------+--------+------+-----+-------------+
カラム 説明
id SELECTごとに振られるID。処理順ではない点に注意。
select_type SELECTの種類。SIMPLE, SUBQUERY, UNIONなど。
type テーブルへのアクセス方法。インデックスの利用有無、読取範囲などがわかる。
possible_keys 利用可能なインデックス。
key 実際に利用されたインデックス。possible_keys からインデックスの内容や統計情報を加味して、選択さ
れたインデックス。
key_len 読み取ったインデックスのバイト数。
ref 比較するカラム。constの場合は定数(WHERE x = 1のような場合)。
rows スキャンする見積もり行数。JOINやサブクエリが関係する場合は外部表のrows × 内部表のrowsがス
キャンする行になる。
Extra その他の情報
34. インデックスが効かない条件
Extra
関数 WHERE datediff(now(), mod_date) > '180'
式 WHERE col1 / 2 = 0
否定構文 WHERE col1 != 3
LIKE検索
※ 前方一致除く
WHERE col1 LIKE ‘%string%’
WHERE col1 LIKE ‘%string’
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
35. 【1.フルスキャン】チューニング結果
mysql> CREATE INDEX idx01 ON push_info(deleted, mod_date);
mysql> EXPLAIN SELECT push_id FROM push_info
WHERE deleted=1 AND mod_date < date_sub(NOW(), INTERVAL 180 DAY);
+----+-------------+-----------+-------+-------+------+------+--------------------------+
| id | select_type | table | type | key | ref | rows | Extra |
+----+-------------+-----------+-------+-------+------+------+--------------------------+
| 1 | SIMPLE | push_info | range | idx01 | NULL | 10 | Using index |
+----+-------------+-----------+-------+-------+------+------+--------------------------+
インデックスの
範囲読み込み
行数が10行 インデックスだ
けで解決でき
るクエリ
• Before: 380msec → After: 0msec
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
36. 代表的なチューニング例
1. type=ALL または type=index で rows が大きい
2. Extra に Using temporary; Using filesort でrowsが大きい
3. select_type が DEPENDENT SUBQUERY
4. JOINにおいて2つ目以降のExtraにUsing whereが出力さていて
rows が大きい
5. 大量更新
6. データ削除
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
37. 【2.ソート】
mysql> EXPLAIN SELECT order_time,seller_id,image_id,item_id,<省略>
FROM order_master WHERE is_hidden_page = '0'
ORDER BY order_time DESC LIMIT 20;
+--+-----------+--------------+----+---------------+----+----------+-----------------------------+
|id|select_type| table |type| possible_keys |key | rows | Extra |
+--+-----------+--------------+----+---------------+----+----------+-----------------------------+
| 1|SIMPLE | order_master |ALL | NULL |NULL| 12200494 | Using where; Using filesort |
+--+-----------+--------------+----+---------------+----+----------+-----------------------------+
• is_hidden_page は殆どの行で0
• カーディナリティが低いため×
• ソートにインデックスは有効か?
• LIMIT句がある場合に効果が高い
1200万件
ソートしている
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
38. 【2.ソート】チューニング結果
mysql> CREATE INDEX OM_OTM ON order_master (order_time);
mysql> EXPLAIN SELECT order_time,seller_id,image_id,item_id,<省略>
FROM order_master WHERE is_hidden_page = '0'
ORDER BY order_time DESC LIMIT 20;
+--+-------------+--------------+-----+---------------+--------+------+-------------+
|id| select_type | table |type | possible_keys | key | rows | Extra |
+--+-------------+--------------+-----+---------------+--------+------+-------------+
| 1| SIMPLE | order_master |index| NULL | OM_OTM | 20 | Using where |
+--+-------------+--------------+-----+---------------+--------+------+-------------+
20個だけ取る
• インデックスはソート済みのため、ソートが不要
• 上位20件だけ取ったら、処理を終了
• Before: 4300sec → After: 0sec
ソートがなくなるインデックス利用
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
41. 代表的なチューニング例
1. type=ALL または type=index で rows が大きい
2. Extra に Using temporary; Using filesort でrowsが大きい
3. select_type が DEPENDENT SUBQUERY
4. JOINにおいて2つ目以降のExtraにUsing whereが出力さていて
rows が大きい
5. 大量更新
6. データ削除
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
42. 【3.相関サブクエリ】
mysql> EXPLAIN SELECT team_name
FROM team
WHERE team_id IN (SELECT team_id FROM member WHERE skill IN ("C"));
+----+--------------------+--------+------+---------------+省略+------+-------------+
| id | select_type | table | type | possible_keys | | rows | Extra |
+----+--------------------+--------+------+---------------+----+------+-------------+
| 1 | PRIMARY | team | ALL | NULL | | 3 | Using where |
| 2 | DEPENDENT SUBQUERY | member | ALL | NULL | | 5 | Using where |
+----+--------------------+--------+------+---------------+----+------+-------------+
team_id team_name
1 Team1
2 Team2
3 Team3
team_id member_name skill
1 Yahoo Taro C
1 Yahoo Jiro Python
2 Yahoo Hanako Ruby
2 Yahoo Saburo PHP
3 Yahoo Sirou Perl
■ member■ team
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
43. 【3.相関サブクエリ】 期待する動作
team_id team_name
1 Team1
2 Team2
3 Team3
team_id member_name skill
1 Yahoo Taro C
1 Yahoo Jiro Python
2 Yahoo Hanako Ruby
2 Yahoo Saburo PHP
3 Yahoo Sirou Perl
mysql> EXPLAIN SELECT team_name
FROM team
WHERE team_id IN (SELECT team_id FROM member WHERE skill IN ("C"));
最初に実行される
ことを期待
①skill=Cを探す②team_id=1を探す
• memberテーブルを1回読み込む
• teamテーブルを1回読み込む
• 合計=5 + 3 = 8行の読み込みを期待する
44. 【3.相関サブクエリ】 実際の動き
mysql> EXPLAIN SELECT team_name
FROM team
WHERE team_id IN (SELECT team_id FROM member WHERE skill IN ("C"));
team_id team_name
1 Team1
2 Team2
3 Team3
team_id member_name skill
1 Yahoo Taro C
1 Yahoo Jiro Python
2 Yahoo Hanako Ruby
2 Yahoo Saburo PHP
3 Yahoo Sirou Perl
team_id =1 AND skill=C
のレコードを探す
• 合計= 3 + 3 * 5 = 18行の読み込み
• 実行計画の「PRIMARY」は外部表(親)を示す
• なぜ、期待どうりに動かないのか?
• MySQLの仕様です。。。(5.6で改善されます)
45. 【3.相関サブクエリ】 チューニング方法(1)
mysql> CREATE INDEX idx_skill ON member(skill, team_id);
mysql> EXPLAIN SELECT team_name
FROM team
WHERE team_id IN (SELECT team_id FROM member WHERE skill IN ("C"));
+----+--------------------+--------+------+---------------+-----------+省略+------+-------------+
| id | select_type | table | type | possible_keys | key | | rows | Extra |
+----+--------------------+--------+------+---------------+-----------+省略+------+-------------+
| 1 | PRIMARY | team | ALL | NULL | NULL | | 3 | Using where |
| 2 | DEPENDENT SUBQUERY | member | ref | idx_skill | idx_skill | | 1 | Using where |
+----+--------------------+--------+------+---------------+-----------+省略+------+-------------+
•サブクエリの実行にインデックスを利用
•3 + 3 * 1 = 6行に(見積もり)
+----+--------------------+--------+------+---------------+省略+------+-------------+
| id | select_type | table | type | possible_keys | | rows | Extra |
+----+--------------------+--------+------+---------------+----+------+-------------+
| 1 | PRIMARY | team | ALL | NULL | | 3 | Using where |
| 2 | DEPENDENT SUBQUERY | member | ALL | NULL | | 5 | Using where |
+----+--------------------+--------+------+---------------+----+------+-------------+
インデックス未使用
46. 【3.相関サブクエリ】 チューニング方法(2)
mysql> EXPLAIN SELECT team_name
FROM team JOIN member USING(team_id)
WHERE member.skill IN ("C");
+----+-------------+--------+--------+---------------+-----------+---------------------+------+
| id | select_type | table | type | possible_keys | key | ref | rows |
+----+-------------+--------+--------+---------------+-----------+---------------------+------+
| 1 | SIMPLE | member | ref | idx_skill | idx_skill | const | 1 |
| 1 | SIMPLE | team | eq_ref | PRIMARY | PRIMARY | test.member.team_id | 1 |
+----+-------------+--------+--------+---------------+-----------+---------------------+------+
member表を先に読む
• JOINに書き換える
• 相関サブクエリ、だいたいJOINで書き直せる
• オプティマイザが親子を自動判断
• member表を外部表(駆動表)にする
+----+--------------------+--------+------+---------------+-----------+省略+------+-------------+
| id | select_type | table | type | possible_keys | key | | rows | Extra |
+----+--------------------+--------+------+---------------+-----------+省略+------+-------------+
| 1 | PRIMARY | team | ALL | NULL | NULL | | 3 | Using where |
| 2 | DEPENDENT SUBQUERY | member | ref | idx_skill | idx_skill | | 1 | Using where |
+----+--------------------+--------+------+---------------+-----------+省略+------+-------------+
47. 代表的なチューニング例
1. type=ALL または type=index で rows が大きい
2. Extra に Using temporary; Using filesort でrowsが大きい
3. select_type が DEPENDENT SUBQUERY
4. JOINにおいて2つ目以降のExtraにUsing whereが出力さ
ていて rows が大きい
5. 大量更新
6. データ削除
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
60. 必要なデータが大きいもの
SELECT COUNT(*) FROM access_log;
SELECT SUM(a) FROM access_log WHERE data BETWEEN ‘1995-01-01’ AND NOW();
必要なデータが大きいものは遅い
• MySQLは1セッション=1スレッド=1CPU
• 作りから見直す必要がある
• 例) 集計テーブルを作り更新時に同時にカウ
ントアップする
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止