狠狠撸

狠狠撸Share a Scribd company logo
? 2017 e-Seikatsu Co., Ltd.
Sharding
with
SQLAlchemy
松崎 明 (Akira Matsuzaki / @akipom)
? 2017 e-Seikatsu Co., Ltd.
自己紹介
松崎 明
CTO / 常務取締役 @
Python 歴 7年 (その前はJava 10年ぐらい)
DB/インフラ周りも一通り行ける (15年ぐらいやってます)
フロントエンドは最近弄ってない (ここ6年ぐらい)
旨い酒と美味い飯が大好物
ちなみにCTO歴は11年ぐらい (プログラマ歴は25年ぐらい)
基本的にLinuxデスクトップでお仕事 (Linux大好き)
最近はGo弄ってることもある (でも今日は喋りません)
? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd.
マルチテナント型サービスの悩み
まずは課題から
? 2017 e-Seikatsu Co., Ltd.
マルチテナント型サービス運用の悩み
マルチテナント
=
複数ユーザ(企業)が同居
=
B2B(企業向け)サービスだとありがち
? 2017 e-Seikatsu Co., Ltd.
マルチテナント型サービス運用の悩み
企業A
企業B
企業C 利用者が少ない頃はそうでもないが
? 2017 e-Seikatsu Co., Ltd.
マルチテナント型サービス運用の悩み
サービスが成長してくると
どうスケールアウトするかが重要に
? 2017 e-Seikatsu Co., Ltd.
どこがスケールアウトしにくいか
? 全ユーザで共通
? ノード数/ホスト数で
スケールアウトしやすい
アプリケーション データベース (RDBMS)
? ユーザ毎に情報が違う
? ノード数/ホスト数で
スケールアウトしにくい
? 特に書き込み系がツラい
? 2017 e-Seikatsu Co., Ltd.
DBのスケールアウトしづらい側面
? 左図は典型的なDB構成
? 読み込み系は、スレーブを増やすことで、
ある程度スケールアウトできる
? 書き込み系は、マスターに集中するので、
スケールアウトしづらい
? 書き込み系処理が増えると、必然的に
レプリケーション量も増える
write
App
read
replication
Slaves
Master
Hot Stand-by
replication
? 2017 e-Seikatsu Co., Ltd.
ユーザ毎に全部割る
? メリット
– シンプル
– アプリ側は考えること少ない
– 障害発生時の影響が限定的
? デメリット
– アプリのデプロイ大変
– 自動化頑張る必要性
– 監視対象多くて死ねる
– リソース効率は良くないかも
? 2017 e-Seikatsu Co., Ltd.
DBだけインスタンスごと割る
? メリット
– アプリは共通、データは固有を
そのまま体現
– DBスケールアウトしにくい問題は解決
– アプリ側のリソース効率は悪くない
? デメリット
– アプリ-DB間の接続数ヤバい
– 何かと運用が面倒なDBの数が多い
? 2017 e-Seikatsu Co., Ltd.
スキーマだけ割る
? メリット
– アプリは共通、データは固有を
一応体現
– アプリ側のリソース効率は悪くない
? デメリット
– DBスケールアウト問題が未解決
? 2017 e-Seikatsu Co., Ltd.
3パターン合わせ技
? 銀の弾丸はない
? ユーザ毎のスキーマを複数まとめて
DBインスタンスに格納
? アプリ側もいくつかの塊にクラスタ化
? データ量やスループットを見ながら
調整しつつ運用
? 2017 e-Seikatsu Co., Ltd.
前説が長くなりましたが
これを でどう扱うのか?
が
このトークのテーマです
? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd.
SQLAlchemy概要
SQLAlchemyの簡単な紹介と前提知識の準備
? 2017 e-Seikatsu Co., Ltd.
そもそも ORM って何?
ORM = Object-relational Mapping (Mapper)
book_id
1
2
3
title
AAA
BBB
CCC
author_id
1
2
3
publisher_id
1
2
3
num_pages
120
300
280
birth_date
1963-03-05
1982-11-21
1975-09-28
author_id
1
2
3
name
著者 太郎
本 花子
John Doe
publisher_id
1
2
3
name
XX出版
YY社
ZZ Publishing
class Book(object):
title = None
num_pages = 0
__author_id = None
__publisher_id = None
@classmethod
def get_by_id(self, id):
…
return book
@property
def author(self):
return Author.get_by_id(
self.__author_id)
@property
def publisher(self):
return Publisher.get_by_id(
self.__publisher_id)
class Author(object):
name = None
birth_date = None
gender = GENDER_UNKNOWN
@classmethod
def get_by_id(self, id):
…
return author
class Publisher(object):
name = None
@classmethod
def get_by_id(self, id):
…
return publisher
オブジェクト指向的な世界 リレーショナルDBな世界
? 2017 e-Seikatsu Co., Ltd.
Python の ORM
SQLAlchemy
django ORM
peewee
Pony
単体のORMとしては最も有名
Django の ビルトインORM
シンプルで軽量さが売りのORM
generator式 や lambda でクエリが
書ける Pythonic なORM
今現在、アクティブに開発が続けられているORMは少ない
? 2017 e-Seikatsu Co., Ltd.
SQLAlchemy の構成
SQLAlchemy ORM SQLAlchemy Core
SQL文、DB接続、トランザクション管理等、
RDBMSをそのまま扱うための機能群を提供。
DBのリレーショナルモデルをそのまま扱う
スキーマ指向のモジュール群。
DBに格納されたデータを Python の
オブジェクトとして自然に扱うための
機能を提供。
ドメインモデル指向のモジュール群で、
一般的にはこちらを使う。
内部的には Core で提供される機能を使って
いる。
? 2017 e-Seikatsu Co., Ltd.
2種のマッピング
Classical Mapping
Python オブジェクト(を表すクラス)と
Table を表すクラスを別個に定義し、
この2つを紐づける(マッピングする)方法。
古いバージョンからある方法だが、今でも利
用可能。
Declarative Mapping
1つのクラス定義で、テーブル定義 と
マッピングを同時にやる方法。
バージョン 0.6 あたりから導入され、現在で
はこちらが推奨されている。
Table を表すクラスは自動生成される。
? 2017 e-Seikatsu Co., Ltd.
Autoload
Autoload しない
Python のクラス内で DBのカラムや、
テーブル間のリレーションを定義し、
それのみを用いる方法。
SQLAlchemy から DBのスキーマを作成する
こともできるが、標準機能では ALTER
TABLEはできない。
ALTERを行うためには、Alembic や
SQLAlchemy-Migrate のような補助ツールを
使う必要がある。
SQLAlchemy と DBのスキーマ定義がずれる
と、色々問題が発生したりする。
Autoload する
DBのスキーマ定義に基づいて、
カラム定義を自動でロードする方法。
Classical Mapping を使用する場合には、
テーブル間のリレーションは手動定義の必要
あり。
Declarative Mapping を使用する場合には、
0.9.1から導入された Automap Base を使うこ
とで、リレーションも推定してくれるように
なった。(明示的に指定することも可能)
動的型付け言語だからこそできる芸当。
? 2017 e-Seikatsu Co., Ltd.
Table と Mapped Objectの関係
<<instance>>
Metadata
<<instance>>
Table
<<class>>
Table
インスタンス化
<<class>>
Mapped
Class
<<instance>>
Mapped
Class
インスタンス化
マッピング
集約
Table インスタンス と
Python クラス定義 が
マッピングされている
スキーマ情報の
コレクション
? 2017 e-Seikatsu Co., Ltd.
Session, Engine, Pool, Dialect, Connection
Session
Mapped
Object
オブジェクトの
ライフサイクル管理
トランザクション管理
Mapped
Object
ユーザが扱う
データモデル
Engine
Engine
接続先のDBの表現
DBの接続URL
接続パラメータ
…etc
Pool
Dialect
DB
Connection
Connection
Pool
Dialect
DB
Connection
Connection
DBMSの種類の表現
MySQL, PostgreSQL, Oracle …
物理接続
接続の管理
? 2017 e-Seikatsu Co., Ltd.
コードサンプル
from sqlalchemy imoport create_engine
from sqlalchemy.orm import Session
from sqlalchemy.ext.auto_map import automap_base
# Mapped Class のベースクラスを作成
Base = automap_base()
# Engine を定義
engine = create_engine(‘mysql+pymysql://user:password@host_name:3306/?charset=utf8mb4’)
# Table と Mapped Class を生成
Base.prepare(engine, reflect=True)
# 生成されたMapped Class はテーブル名と同じになっているので、モジュールレベルの変数に格納
Book = Base.classes.book
Author = Base.classes.author
Publisher = Base.classes.publisher
# 単一のEngine から Session を作成
session = Session(engine)
# データのロード(先頭の100行)
for book in session.query(Book).order_by(Book.book_id)[:100]:
print(book.title)
# 新規Bookインスタンスの作成
new_author = Author(name=“foo”)
new_publisher = Publisher(name=“bar”)
new_book = Book(title=“Foo Bar”, author=new_author, publisher=new_publisher)
# Sessionへ追加?コミット
session.add(new_book)
Session.commit()
? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd.
Shardingへの対応方法
ようやく役者が出そろったので
? 2017 e-Seikatsu Co., Ltd.
実現したいこと
Master/Slave パターンへの対応
書き込み系はMasterへ、参照系はSlaveへ自動振り分けしたい
Sharding パターンへの対応
ユーザ情報などに基づいて、接続先DBやスキーマを自動振り分けしたい
整理すると 何らかのコンテキスト情報に基づいて
単一の Session 内で Engine を切り替えたいだけ
? 2017 e-Seikatsu Co., Ltd.
Session 内で Engine 切り替え
Session
Mapped
Object
オブジェクトの
ライフサイクル管理
トランザクション管理
Mapped
Object
ユーザが扱う
データモデル
Engine
Engine
接続先のDBの表現
DBの接続URL
接続パラメータ
…etc
Pool
Dialect
DB
Connection
Connection
Pool
Dialect
DB
Connection
Connection
DBMSの種類の表現
MySQL, PostgreSQL, Oracle …
物理接続
接続の管理
つまりここ
? 2017 e-Seikatsu Co., Ltd.
実は SQLAlchemy で用意されてます
https://github.com/zzzeek/sqlalchemy/blob/rel_1_1/lib/sqlalchemy/ext/horizontal_shard.py
ソース
https://docs.sqlalchemy.org/en/latest/_modules/examples/sharding/attribute_shard.html
サンプルコード
※ 「SQLAlchemy Sharding」でググれば 出てきます
「書き込み系はMasterへ、参照系はSlaveへ自動振り分けしたい」
ただし下記の機能がない
? 2017 e-Seikatsu Co., Ltd.
公式の ShardedSession のポイント
Engine の選択で重要なのは Session.get_bind()
? 2017 e-Seikatsu Co., Ltd.
実際にやること
1. カスタムSessionクラスを作る
ShardedSession のサブクラスでもいいし、Session のサブクラスでもいい
2. 書き込み系の処理中かどうかを表すSessionの内部変数を作る
一度でも書き込み系の処理が走ったら、commit() または rollback() が
呼ばれるまでは、master を参照するようにする。(一貫性保証のため)
3. get_bind() をオーバーライドする
詳細は次ページで。
? 2017 e-Seikatsu Co., Ltd.
get_bind() のオーバーライド内容
1. clause 引数が渡された場合
sqlalchemy.sql.expression.UpdateBase のインスタンスかどうかで
更新系SQLかどうか判断できる。
であれば、内部変数を「更新中」とマークする。
isinstance(clause, UpdateBase) is True
2. mapper 引数が渡された場合
ORM系の更新処理の場合、Session._flushing 変数が True になる。
https://github.com/zzzeek/sqlalchemy/blob/rel_1_1/lib/sqlalchemy/orm/session.py#L733
この値を評価して、内部変数を「更新中」とマークするか判断する
3. Engineを選択する
内部変数が「更新中」なら、master を指す Engine を、
そうでなければ、slave を指す Engine からラウンドロビンやランダムで選択
? 2017 e-Seikatsu Co., Ltd.
注意点
Engine のメモリフットプリントが意外と大きい
それは
この方法には大きな落とし穴があります
Engine は一度生成されると、インタプリタが終了するまで消えない
かつ
という点です
(CPython で 実測15MB程度 食います)
Shard が多数、あるいは Slave多数だと
メモリが足りなくなります
? 2017 e-Seikatsu Co., Ltd.
単一DBインスタンスに複数スキーマの場合
最初の方で触れた
単一DBインスタンスに複数スキーマ
の場合では、
もう一つ別のアプローチが取れます
? 2017 e-Seikatsu Co., Ltd.
SQLAlchemy イベントリスナ
https://docs.sqlalchemy.org/en/latest/core/events.html
? 2017 e-Seikatsu Co., Ltd.
Poolからのチェックアウト時にスキーマ切替
Session
Mapped
Object
オブジェクトの
ライフサイクル管理
トランザクション管理
Mapped
Object
ユーザが扱う
データモデル
Engine
Engine
接続先のDBの表現
DBの接続URL
接続パラメータ
…etc
Pool
Dialect
DB
Connection
Connection
Pool
Dialect
DB
Connection
Connection
DBMSの種類の表現
MySQL, PostgreSQL, Oracle …
物理接続
接続の管理
今度はここ
? 2017 e-Seikatsu Co., Ltd.
実際にやること
1. イベントハンドラの関数を作る
Schema選択アルゴリズムは、Shard 選択と同様の感じで。
ただし引数で、Mapped Object や Clause は渡されないため、
呼び出しタイミングは、get_bind() より後であることを利用して、
Threadlocalな変数に、選択したスキーマ情報を載せておく形になります。
また、スキーマの変更SQLはRDBMS固有のため、RDBMS毎に関数を用意する必要があります
2. Engine初期化後にイベントハンドラを登録する
sqlalchemy.event.listen(engine, ‘checkout’, handler_func)
または
@sqlalchemy.event.listen_for(engine, ‘checkout’)
デコレータで登録できます。
? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd.
まとめ
? 2017 e-Seikatsu Co., Ltd.
1. カスタム Session クラスを用意すれば、DB接続周りで色々できる
2. イベントリスナーを有効活用しよう
Sharding 対応や Master/Slave対応など、そこまで難しい実装はいらない
今回紹介したイベント以外も色々あるので、うまく活用すれば色々できる
3. とはいえ銀の弾丸はない
リソースは常に有限なので、無限にスケールできる単一のソリューションはない
全体のアーキテクチャバランスを取りながら、複数の手法を組み合わせよう
? 2017 e-Seikatsu Co., Ltd.
ご清聴ありがとうございました
? 2017 e-Seikatsu Co., Ltd.
やるなら
この後 ジョブフェア でLTします
Ad

Recommended

Magnum IO GPUDirect Storage 最新情報
Magnum IO GPUDirect Storage 最新情報
NVIDIA Japan
?
Rescale で Singularity を使ってみよう!
Rescale で Singularity を使ってみよう!
Shinnosuke Furuya
?
Amazon EKS への道 ~ EKS 再入門 ~
Amazon EKS への道 ~ EKS 再入門 ~
Hideaki Aoyagi
?
贬补诲辞辞辫の概念と基本的知识
贬补诲辞辞辫の概念と基本的知识
Ken SASAKI
?
ネットストーカー御用达翱厂滨狈罢ツール叠濒补肠办叠颈谤诲を触ってみた.辫辫迟虫
ネットストーカー御用达翱厂滨狈罢ツール叠濒补肠办叠颈谤诲を触ってみた.辫辫迟虫
Shota Shinogi
?
痴补肠耻耻尘彻底解説
痴补肠耻耻尘彻底解説
Masahiko Sawada
?
JenkinsとDockerって何が良いの? ?言うてるオレもわからんわ? #jenkinsstudy
JenkinsとDockerって何が良いの? ?言うてるオレもわからんわ? #jenkinsstudy
Kazuhito Miura
?
使ってみませんか?辫驳冲丑颈苍迟冲辫濒补苍
使ってみませんか?辫驳冲丑颈苍迟冲辫濒补苍
NTT DATA OSS Professional Services
?
インフラ颁滨颁顿の勘所
インフラ颁滨颁顿の勘所
Toru Makabe
?
「自分のとこでは動くけど…」を無くす devcontainer
「自分のとこでは動くけど…」を無くす devcontainer
Yuta Matsumura
?
リアルタイムサーバー ?Erlang/OTPで作るPubSubサーバー?
リアルタイムサーバー ?Erlang/OTPで作るPubSubサーバー?
Yugo Shimizu
?
顿辞肠办别谤から肠辞苍迟补颈苍别谤诲への移行
顿辞肠办别谤から肠辞苍迟补颈苍别谤诲への移行
Kohei Tokunaga
?
ゼロから始めるサブスク生活
ゼロから始めるサブスク生活
KLab Inc. / Tech
?
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
NTT DATA OSS Professional Services
?
え!? Power BI の画面からデータ更新なんてできるの!? ~PowerApps カスタムビジュアルの可能性~
え!? Power BI の画面からデータ更新なんてできるの!? ~PowerApps カスタムビジュアルの可能性~
Yugo Shimizu
?
顿辞肠办别谤コンテナで骋颈迟を使う
顿辞肠办别谤コンテナで骋颈迟を使う
Kazuhiro Suga
?
罢补产濒别补耻のつまづきポイント
罢补产濒别补耻のつまづきポイント
Shinji Tamura
?
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
Ryo Sakamoto
?
監視 Overview
監視 Overview
IIJ
?
その Pod 突然落ちても大丈夫ですか!?(OCHaCafe5 #5 実験!カオスエンジニアリング 発表資料)
その Pod 突然落ちても大丈夫ですか!?(OCHaCafe5 #5 実験!カオスエンジニアリング 発表資料)
NTT DATA Technology & Innovation
?
インフラエンシ?ニアってなんて?したっけ(仮)
インフラエンシ?ニアってなんて?したっけ(仮)
Akihiro Kuwano
?
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
ManaMurakami1
?
ネットワークOS野郎 ~ インフラ野郎Night 20160414
ネットワークOS野郎 ~ インフラ野郎Night 20160414
Kentaro Ebisawa
?
负荷分散勉强会
负荷分散勉强会
Yuji Otani
?
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
NTT DATA Technology & Innovation
?
厂濒耻谤尘のジョブスケジューリングと実装
厂濒耻谤尘のジョブスケジューリングと実装
Ryuichi Sakamoto
?
次世代データ基盤としてのSnowflakeの可能性 SnowDay 20211208
次世代データ基盤としてのSnowflakeの可能性 SnowDay 20211208
Kazuhiro Mitsuhashi
?
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
NTT DATA Technology & Innovation
?
Guide to Cassandra for Production Deployments
Guide to Cassandra for Production Deployments
smdkk
?
Presto As A Service - Treasure DataでのPresto運用事例
Presto As A Service - Treasure DataでのPresto運用事例
Taro L. Saito
?

More Related Content

What's hot (20)

インフラ颁滨颁顿の勘所
インフラ颁滨颁顿の勘所
Toru Makabe
?
「自分のとこでは動くけど…」を無くす devcontainer
「自分のとこでは動くけど…」を無くす devcontainer
Yuta Matsumura
?
リアルタイムサーバー ?Erlang/OTPで作るPubSubサーバー?
リアルタイムサーバー ?Erlang/OTPで作るPubSubサーバー?
Yugo Shimizu
?
顿辞肠办别谤から肠辞苍迟补颈苍别谤诲への移行
顿辞肠办别谤から肠辞苍迟补颈苍别谤诲への移行
Kohei Tokunaga
?
ゼロから始めるサブスク生活
ゼロから始めるサブスク生活
KLab Inc. / Tech
?
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
NTT DATA OSS Professional Services
?
え!? Power BI の画面からデータ更新なんてできるの!? ~PowerApps カスタムビジュアルの可能性~
え!? Power BI の画面からデータ更新なんてできるの!? ~PowerApps カスタムビジュアルの可能性~
Yugo Shimizu
?
顿辞肠办别谤コンテナで骋颈迟を使う
顿辞肠办别谤コンテナで骋颈迟を使う
Kazuhiro Suga
?
罢补产濒别补耻のつまづきポイント
罢补产濒别补耻のつまづきポイント
Shinji Tamura
?
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
Ryo Sakamoto
?
監視 Overview
監視 Overview
IIJ
?
その Pod 突然落ちても大丈夫ですか!?(OCHaCafe5 #5 実験!カオスエンジニアリング 発表資料)
その Pod 突然落ちても大丈夫ですか!?(OCHaCafe5 #5 実験!カオスエンジニアリング 発表資料)
NTT DATA Technology & Innovation
?
インフラエンシ?ニアってなんて?したっけ(仮)
インフラエンシ?ニアってなんて?したっけ(仮)
Akihiro Kuwano
?
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
ManaMurakami1
?
ネットワークOS野郎 ~ インフラ野郎Night 20160414
ネットワークOS野郎 ~ インフラ野郎Night 20160414
Kentaro Ebisawa
?
负荷分散勉强会
负荷分散勉强会
Yuji Otani
?
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
NTT DATA Technology & Innovation
?
厂濒耻谤尘のジョブスケジューリングと実装
厂濒耻谤尘のジョブスケジューリングと実装
Ryuichi Sakamoto
?
次世代データ基盤としてのSnowflakeの可能性 SnowDay 20211208
次世代データ基盤としてのSnowflakeの可能性 SnowDay 20211208
Kazuhiro Mitsuhashi
?
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
NTT DATA Technology & Innovation
?
インフラ颁滨颁顿の勘所
インフラ颁滨颁顿の勘所
Toru Makabe
?
「自分のとこでは動くけど…」を無くす devcontainer
「自分のとこでは動くけど…」を無くす devcontainer
Yuta Matsumura
?
リアルタイムサーバー ?Erlang/OTPで作るPubSubサーバー?
リアルタイムサーバー ?Erlang/OTPで作るPubSubサーバー?
Yugo Shimizu
?
顿辞肠办别谤から肠辞苍迟补颈苍别谤诲への移行
顿辞肠办别谤から肠辞苍迟补颈苍别谤诲への移行
Kohei Tokunaga
?
ゼロから始めるサブスク生活
ゼロから始めるサブスク生活
KLab Inc. / Tech
?
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
NTT DATA OSS Professional Services
?
え!? Power BI の画面からデータ更新なんてできるの!? ~PowerApps カスタムビジュアルの可能性~
え!? Power BI の画面からデータ更新なんてできるの!? ~PowerApps カスタムビジュアルの可能性~
Yugo Shimizu
?
顿辞肠办别谤コンテナで骋颈迟を使う
顿辞肠办别谤コンテナで骋颈迟を使う
Kazuhiro Suga
?
罢补产濒别补耻のつまづきポイント
罢补产濒别补耻のつまづきポイント
Shinji Tamura
?
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
Ryo Sakamoto
?
監視 Overview
監視 Overview
IIJ
?
その Pod 突然落ちても大丈夫ですか!?(OCHaCafe5 #5 実験!カオスエンジニアリング 発表資料)
その Pod 突然落ちても大丈夫ですか!?(OCHaCafe5 #5 実験!カオスエンジニアリング 発表資料)
NTT DATA Technology & Innovation
?
インフラエンシ?ニアってなんて?したっけ(仮)
インフラエンシ?ニアってなんて?したっけ(仮)
Akihiro Kuwano
?
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
「NVIDIA プロファイラを用いたPyTorch学習最適化手法のご紹介(修正版)」
ManaMurakami1
?
ネットワークOS野郎 ~ インフラ野郎Night 20160414
ネットワークOS野郎 ~ インフラ野郎Night 20160414
Kentaro Ebisawa
?
负荷分散勉强会
负荷分散勉强会
Yuji Otani
?
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
入門 Kubeflow ~Kubernetesで機械学習をはじめるために~ (NTT Tech Conference #4 講演資料)
NTT DATA Technology & Innovation
?
厂濒耻谤尘のジョブスケジューリングと実装
厂濒耻谤尘のジョブスケジューリングと実装
Ryuichi Sakamoto
?
次世代データ基盤としてのSnowflakeの可能性 SnowDay 20211208
次世代データ基盤としてのSnowflakeの可能性 SnowDay 20211208
Kazuhiro Mitsuhashi
?
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
NTT DATA Technology & Innovation
?

Similar to Sharding with sql alchemy (20)

Guide to Cassandra for Production Deployments
Guide to Cassandra for Production Deployments
smdkk
?
Presto As A Service - Treasure DataでのPresto運用事例
Presto As A Service - Treasure DataでのPresto運用事例
Taro L. Saito
?
NoSQL Bigtable and Azure Table
NoSQL Bigtable and Azure Table
Takekazu Omi
?
[db tech showcase Tokyo 2014] L32: Apache Cassandraに注目!!(IoT, Bigdata、NoSQLのバ...
[db tech showcase Tokyo 2014] L32: Apache Cassandraに注目!!(IoT, Bigdata、NoSQLのバ...
Insight Technology, Inc.
?
Cassandra(no sql)によるシステム提案と開発
Cassandra(no sql)によるシステム提案と開発
kishimotosc
?
MySQL Cluster 7.4で楽しむスケールアウト @DB Tech Showcase 2015/06
MySQL Cluster 7.4で楽しむスケールアウト @DB Tech Showcase 2015/06
Mikiya Okuno
?
マルチテナントのアプリケーション実装?実践编?
マルチテナントのアプリケーション実装?実践编?
Yoshiki Nakagawa
?
ComSys WIP
ComSys WIP
Shun Nakamura
?
惭辞苍驳辞顿叠概要:金融业界での惭辞苍驳辞顿叠
惭辞苍驳辞顿叠概要:金融业界での惭辞苍驳辞顿叠
ippei_suzuki
?
Okuyama説明資料 20120119 ss
Okuyama説明資料 20120119 ss
Takahiro Iwase
?
Prestoで実現するインタラクティブクエリ - dbtech showcase 2014 Tokyo
Prestoで実現するインタラクティブクエリ - dbtech showcase 2014 Tokyo
Treasure Data, Inc.
?
[db tech showcase Tokyo 2014] D33: Prestoで実現するインタラクティブクエリ by トレジャーデータ株式会社 斉藤太郎
[db tech showcase Tokyo 2014] D33: Prestoで実現するインタラクティブクエリ by トレジャーデータ株式会社 斉藤太郎
Insight Technology, Inc.
?
事例で学ぶApache Cassandra
事例で学ぶApache Cassandra
Yuki Morishita
?
iOS/Androidにも対応した SQL Anywhere 12の魅力
iOS/Androidにも対応した SQL Anywhere 12の魅力
nisobe58
?
20220331_DSSA_MigrationToYugabyteDB
20220331_DSSA_MigrationToYugabyteDB
Masaki Yamakawa
?
データベースアプリケーション开発セミナー?最新のデータベースとアプリケーション开発の関係
データベースアプリケーション开発セミナー?最新のデータベースとアプリケーション开発の関係
Kaz Aiso
?
Guide to Cassandra for Production Deployments
Guide to Cassandra for Production Deployments
smdkk
?
Presto As A Service - Treasure DataでのPresto運用事例
Presto As A Service - Treasure DataでのPresto運用事例
Taro L. Saito
?
NoSQL Bigtable and Azure Table
NoSQL Bigtable and Azure Table
Takekazu Omi
?
[db tech showcase Tokyo 2014] L32: Apache Cassandraに注目!!(IoT, Bigdata、NoSQLのバ...
[db tech showcase Tokyo 2014] L32: Apache Cassandraに注目!!(IoT, Bigdata、NoSQLのバ...
Insight Technology, Inc.
?
Cassandra(no sql)によるシステム提案と開発
Cassandra(no sql)によるシステム提案と開発
kishimotosc
?
MySQL Cluster 7.4で楽しむスケールアウト @DB Tech Showcase 2015/06
MySQL Cluster 7.4で楽しむスケールアウト @DB Tech Showcase 2015/06
Mikiya Okuno
?
マルチテナントのアプリケーション実装?実践编?
マルチテナントのアプリケーション実装?実践编?
Yoshiki Nakagawa
?
惭辞苍驳辞顿叠概要:金融业界での惭辞苍驳辞顿叠
惭辞苍驳辞顿叠概要:金融业界での惭辞苍驳辞顿叠
ippei_suzuki
?
Okuyama説明資料 20120119 ss
Okuyama説明資料 20120119 ss
Takahiro Iwase
?
Prestoで実現するインタラクティブクエリ - dbtech showcase 2014 Tokyo
Prestoで実現するインタラクティブクエリ - dbtech showcase 2014 Tokyo
Treasure Data, Inc.
?
[db tech showcase Tokyo 2014] D33: Prestoで実現するインタラクティブクエリ by トレジャーデータ株式会社 斉藤太郎
[db tech showcase Tokyo 2014] D33: Prestoで実現するインタラクティブクエリ by トレジャーデータ株式会社 斉藤太郎
Insight Technology, Inc.
?
事例で学ぶApache Cassandra
事例で学ぶApache Cassandra
Yuki Morishita
?
iOS/Androidにも対応した SQL Anywhere 12の魅力
iOS/Androidにも対応した SQL Anywhere 12の魅力
nisobe58
?
20220331_DSSA_MigrationToYugabyteDB
20220331_DSSA_MigrationToYugabyteDB
Masaki Yamakawa
?
データベースアプリケーション开発セミナー?最新のデータベースとアプリケーション开発の関係
データベースアプリケーション开発セミナー?最新のデータベースとアプリケーション开発の関係
Kaz Aiso
?
Ad

Sharding with sql alchemy

  • 1. ? 2017 e-Seikatsu Co., Ltd. Sharding with SQLAlchemy 松崎 明 (Akira Matsuzaki / @akipom)
  • 2. ? 2017 e-Seikatsu Co., Ltd. 自己紹介 松崎 明 CTO / 常務取締役 @ Python 歴 7年 (その前はJava 10年ぐらい) DB/インフラ周りも一通り行ける (15年ぐらいやってます) フロントエンドは最近弄ってない (ここ6年ぐらい) 旨い酒と美味い飯が大好物 ちなみにCTO歴は11年ぐらい (プログラマ歴は25年ぐらい) 基本的にLinuxデスクトップでお仕事 (Linux大好き) 最近はGo弄ってることもある (でも今日は喋りません)
  • 3. ? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd. マルチテナント型サービスの悩み まずは課題から
  • 4. ? 2017 e-Seikatsu Co., Ltd. マルチテナント型サービス運用の悩み マルチテナント = 複数ユーザ(企業)が同居 = B2B(企業向け)サービスだとありがち
  • 5. ? 2017 e-Seikatsu Co., Ltd. マルチテナント型サービス運用の悩み 企業A 企業B 企業C 利用者が少ない頃はそうでもないが
  • 6. ? 2017 e-Seikatsu Co., Ltd. マルチテナント型サービス運用の悩み サービスが成長してくると どうスケールアウトするかが重要に
  • 7. ? 2017 e-Seikatsu Co., Ltd. どこがスケールアウトしにくいか ? 全ユーザで共通 ? ノード数/ホスト数で スケールアウトしやすい アプリケーション データベース (RDBMS) ? ユーザ毎に情報が違う ? ノード数/ホスト数で スケールアウトしにくい ? 特に書き込み系がツラい
  • 8. ? 2017 e-Seikatsu Co., Ltd. DBのスケールアウトしづらい側面 ? 左図は典型的なDB構成 ? 読み込み系は、スレーブを増やすことで、 ある程度スケールアウトできる ? 書き込み系は、マスターに集中するので、 スケールアウトしづらい ? 書き込み系処理が増えると、必然的に レプリケーション量も増える write App read replication Slaves Master Hot Stand-by replication
  • 9. ? 2017 e-Seikatsu Co., Ltd. ユーザ毎に全部割る ? メリット – シンプル – アプリ側は考えること少ない – 障害発生時の影響が限定的 ? デメリット – アプリのデプロイ大変 – 自動化頑張る必要性 – 監視対象多くて死ねる – リソース効率は良くないかも
  • 10. ? 2017 e-Seikatsu Co., Ltd. DBだけインスタンスごと割る ? メリット – アプリは共通、データは固有を そのまま体現 – DBスケールアウトしにくい問題は解決 – アプリ側のリソース効率は悪くない ? デメリット – アプリ-DB間の接続数ヤバい – 何かと運用が面倒なDBの数が多い
  • 11. ? 2017 e-Seikatsu Co., Ltd. スキーマだけ割る ? メリット – アプリは共通、データは固有を 一応体現 – アプリ側のリソース効率は悪くない ? デメリット – DBスケールアウト問題が未解決
  • 12. ? 2017 e-Seikatsu Co., Ltd. 3パターン合わせ技 ? 銀の弾丸はない ? ユーザ毎のスキーマを複数まとめて DBインスタンスに格納 ? アプリ側もいくつかの塊にクラスタ化 ? データ量やスループットを見ながら 調整しつつ運用
  • 13. ? 2017 e-Seikatsu Co., Ltd. 前説が長くなりましたが これを でどう扱うのか? が このトークのテーマです
  • 14. ? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd. SQLAlchemy概要 SQLAlchemyの簡単な紹介と前提知識の準備
  • 15. ? 2017 e-Seikatsu Co., Ltd. そもそも ORM って何? ORM = Object-relational Mapping (Mapper) book_id 1 2 3 title AAA BBB CCC author_id 1 2 3 publisher_id 1 2 3 num_pages 120 300 280 birth_date 1963-03-05 1982-11-21 1975-09-28 author_id 1 2 3 name 著者 太郎 本 花子 John Doe publisher_id 1 2 3 name XX出版 YY社 ZZ Publishing class Book(object): title = None num_pages = 0 __author_id = None __publisher_id = None @classmethod def get_by_id(self, id): … return book @property def author(self): return Author.get_by_id( self.__author_id) @property def publisher(self): return Publisher.get_by_id( self.__publisher_id) class Author(object): name = None birth_date = None gender = GENDER_UNKNOWN @classmethod def get_by_id(self, id): … return author class Publisher(object): name = None @classmethod def get_by_id(self, id): … return publisher オブジェクト指向的な世界 リレーショナルDBな世界
  • 16. ? 2017 e-Seikatsu Co., Ltd. Python の ORM SQLAlchemy django ORM peewee Pony 単体のORMとしては最も有名 Django の ビルトインORM シンプルで軽量さが売りのORM generator式 や lambda でクエリが 書ける Pythonic なORM 今現在、アクティブに開発が続けられているORMは少ない
  • 17. ? 2017 e-Seikatsu Co., Ltd. SQLAlchemy の構成 SQLAlchemy ORM SQLAlchemy Core SQL文、DB接続、トランザクション管理等、 RDBMSをそのまま扱うための機能群を提供。 DBのリレーショナルモデルをそのまま扱う スキーマ指向のモジュール群。 DBに格納されたデータを Python の オブジェクトとして自然に扱うための 機能を提供。 ドメインモデル指向のモジュール群で、 一般的にはこちらを使う。 内部的には Core で提供される機能を使って いる。
  • 18. ? 2017 e-Seikatsu Co., Ltd. 2種のマッピング Classical Mapping Python オブジェクト(を表すクラス)と Table を表すクラスを別個に定義し、 この2つを紐づける(マッピングする)方法。 古いバージョンからある方法だが、今でも利 用可能。 Declarative Mapping 1つのクラス定義で、テーブル定義 と マッピングを同時にやる方法。 バージョン 0.6 あたりから導入され、現在で はこちらが推奨されている。 Table を表すクラスは自動生成される。
  • 19. ? 2017 e-Seikatsu Co., Ltd. Autoload Autoload しない Python のクラス内で DBのカラムや、 テーブル間のリレーションを定義し、 それのみを用いる方法。 SQLAlchemy から DBのスキーマを作成する こともできるが、標準機能では ALTER TABLEはできない。 ALTERを行うためには、Alembic や SQLAlchemy-Migrate のような補助ツールを 使う必要がある。 SQLAlchemy と DBのスキーマ定義がずれる と、色々問題が発生したりする。 Autoload する DBのスキーマ定義に基づいて、 カラム定義を自動でロードする方法。 Classical Mapping を使用する場合には、 テーブル間のリレーションは手動定義の必要 あり。 Declarative Mapping を使用する場合には、 0.9.1から導入された Automap Base を使うこ とで、リレーションも推定してくれるように なった。(明示的に指定することも可能) 動的型付け言語だからこそできる芸当。
  • 20. ? 2017 e-Seikatsu Co., Ltd. Table と Mapped Objectの関係 <<instance>> Metadata <<instance>> Table <<class>> Table インスタンス化 <<class>> Mapped Class <<instance>> Mapped Class インスタンス化 マッピング 集約 Table インスタンス と Python クラス定義 が マッピングされている スキーマ情報の コレクション
  • 21. ? 2017 e-Seikatsu Co., Ltd. Session, Engine, Pool, Dialect, Connection Session Mapped Object オブジェクトの ライフサイクル管理 トランザクション管理 Mapped Object ユーザが扱う データモデル Engine Engine 接続先のDBの表現 DBの接続URL 接続パラメータ …etc Pool Dialect DB Connection Connection Pool Dialect DB Connection Connection DBMSの種類の表現 MySQL, PostgreSQL, Oracle … 物理接続 接続の管理
  • 22. ? 2017 e-Seikatsu Co., Ltd. コードサンプル from sqlalchemy imoport create_engine from sqlalchemy.orm import Session from sqlalchemy.ext.auto_map import automap_base # Mapped Class のベースクラスを作成 Base = automap_base() # Engine を定義 engine = create_engine(‘mysql+pymysql://user:password@host_name:3306/?charset=utf8mb4’) # Table と Mapped Class を生成 Base.prepare(engine, reflect=True) # 生成されたMapped Class はテーブル名と同じになっているので、モジュールレベルの変数に格納 Book = Base.classes.book Author = Base.classes.author Publisher = Base.classes.publisher # 単一のEngine から Session を作成 session = Session(engine) # データのロード(先頭の100行) for book in session.query(Book).order_by(Book.book_id)[:100]: print(book.title) # 新規Bookインスタンスの作成 new_author = Author(name=“foo”) new_publisher = Publisher(name=“bar”) new_book = Book(title=“Foo Bar”, author=new_author, publisher=new_publisher) # Sessionへ追加?コミット session.add(new_book) Session.commit()
  • 23. ? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd. Shardingへの対応方法 ようやく役者が出そろったので
  • 24. ? 2017 e-Seikatsu Co., Ltd. 実現したいこと Master/Slave パターンへの対応 書き込み系はMasterへ、参照系はSlaveへ自動振り分けしたい Sharding パターンへの対応 ユーザ情報などに基づいて、接続先DBやスキーマを自動振り分けしたい 整理すると 何らかのコンテキスト情報に基づいて 単一の Session 内で Engine を切り替えたいだけ
  • 25. ? 2017 e-Seikatsu Co., Ltd. Session 内で Engine 切り替え Session Mapped Object オブジェクトの ライフサイクル管理 トランザクション管理 Mapped Object ユーザが扱う データモデル Engine Engine 接続先のDBの表現 DBの接続URL 接続パラメータ …etc Pool Dialect DB Connection Connection Pool Dialect DB Connection Connection DBMSの種類の表現 MySQL, PostgreSQL, Oracle … 物理接続 接続の管理 つまりここ
  • 26. ? 2017 e-Seikatsu Co., Ltd. 実は SQLAlchemy で用意されてます https://github.com/zzzeek/sqlalchemy/blob/rel_1_1/lib/sqlalchemy/ext/horizontal_shard.py ソース https://docs.sqlalchemy.org/en/latest/_modules/examples/sharding/attribute_shard.html サンプルコード ※ 「SQLAlchemy Sharding」でググれば 出てきます 「書き込み系はMasterへ、参照系はSlaveへ自動振り分けしたい」 ただし下記の機能がない
  • 27. ? 2017 e-Seikatsu Co., Ltd. 公式の ShardedSession のポイント Engine の選択で重要なのは Session.get_bind()
  • 28. ? 2017 e-Seikatsu Co., Ltd. 実際にやること 1. カスタムSessionクラスを作る ShardedSession のサブクラスでもいいし、Session のサブクラスでもいい 2. 書き込み系の処理中かどうかを表すSessionの内部変数を作る 一度でも書き込み系の処理が走ったら、commit() または rollback() が 呼ばれるまでは、master を参照するようにする。(一貫性保証のため) 3. get_bind() をオーバーライドする 詳細は次ページで。
  • 29. ? 2017 e-Seikatsu Co., Ltd. get_bind() のオーバーライド内容 1. clause 引数が渡された場合 sqlalchemy.sql.expression.UpdateBase のインスタンスかどうかで 更新系SQLかどうか判断できる。 であれば、内部変数を「更新中」とマークする。 isinstance(clause, UpdateBase) is True 2. mapper 引数が渡された場合 ORM系の更新処理の場合、Session._flushing 変数が True になる。 https://github.com/zzzeek/sqlalchemy/blob/rel_1_1/lib/sqlalchemy/orm/session.py#L733 この値を評価して、内部変数を「更新中」とマークするか判断する 3. Engineを選択する 内部変数が「更新中」なら、master を指す Engine を、 そうでなければ、slave を指す Engine からラウンドロビンやランダムで選択
  • 30. ? 2017 e-Seikatsu Co., Ltd. 注意点 Engine のメモリフットプリントが意外と大きい それは この方法には大きな落とし穴があります Engine は一度生成されると、インタプリタが終了するまで消えない かつ という点です (CPython で 実測15MB程度 食います) Shard が多数、あるいは Slave多数だと メモリが足りなくなります
  • 31. ? 2017 e-Seikatsu Co., Ltd. 単一DBインスタンスに複数スキーマの場合 最初の方で触れた 単一DBインスタンスに複数スキーマ の場合では、 もう一つ別のアプローチが取れます
  • 32. ? 2017 e-Seikatsu Co., Ltd. SQLAlchemy イベントリスナ https://docs.sqlalchemy.org/en/latest/core/events.html
  • 33. ? 2017 e-Seikatsu Co., Ltd. Poolからのチェックアウト時にスキーマ切替 Session Mapped Object オブジェクトの ライフサイクル管理 トランザクション管理 Mapped Object ユーザが扱う データモデル Engine Engine 接続先のDBの表現 DBの接続URL 接続パラメータ …etc Pool Dialect DB Connection Connection Pool Dialect DB Connection Connection DBMSの種類の表現 MySQL, PostgreSQL, Oracle … 物理接続 接続の管理 今度はここ
  • 34. ? 2017 e-Seikatsu Co., Ltd. 実際にやること 1. イベントハンドラの関数を作る Schema選択アルゴリズムは、Shard 選択と同様の感じで。 ただし引数で、Mapped Object や Clause は渡されないため、 呼び出しタイミングは、get_bind() より後であることを利用して、 Threadlocalな変数に、選択したスキーマ情報を載せておく形になります。 また、スキーマの変更SQLはRDBMS固有のため、RDBMS毎に関数を用意する必要があります 2. Engine初期化後にイベントハンドラを登録する sqlalchemy.event.listen(engine, ‘checkout’, handler_func) または @sqlalchemy.event.listen_for(engine, ‘checkout’) デコレータで登録できます。
  • 35. ? 2017 e-Seikatsu Co., Ltd.? 2017 e-Seikatsu Co., Ltd. まとめ
  • 36. ? 2017 e-Seikatsu Co., Ltd. 1. カスタム Session クラスを用意すれば、DB接続周りで色々できる 2. イベントリスナーを有効活用しよう Sharding 対応や Master/Slave対応など、そこまで難しい実装はいらない 今回紹介したイベント以外も色々あるので、うまく活用すれば色々できる 3. とはいえ銀の弾丸はない リソースは常に有限なので、無限にスケールできる単一のソリューションはない 全体のアーキテクチャバランスを取りながら、複数の手法を組み合わせよう
  • 37. ? 2017 e-Seikatsu Co., Ltd. ご清聴ありがとうございました
  • 38. ? 2017 e-Seikatsu Co., Ltd. やるなら この後 ジョブフェア でLTします