Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
バッチ処理をパイプラインパターンで上手くやる
Search
yusuke misawa
September 17, 2019
Programming
1.6k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
バッチ処理をパイプラインパターンで上手くやる
yusuke misawa
September 17, 2019
More Decks by yusuke misawa
See All by yusuke misawa
KYCとは何なのか
yusukemisa
0
490
Other Decks in Programming
See All in Programming
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
350
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
380
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
550
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
250
FreeBSDでZabbixを動かす
kenkino
0
310
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
470
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
220
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.1k
Security issues being discussed on Web Platforms
petamoriken
0
980
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
200
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1k
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
150
Featured
See All Featured
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.9k
Visualization
eitanlees
152
17k
Designing Powerful Visuals for Engaging Learning
tmiket
1
570
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
エンジニアに許された特別な時間の終わり
watany
109
250k
Docker and Python
trallard
47
4.2k
The Curious Case for Waylosing
cassininazir
1
510
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
440
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
200
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
700
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Transcript
バッチ処理をパイプライン パターンで上手くやる Yusuke Misawa MediaDo.go@2019/09/17
Yusuke Misawa(三澤 悠介) • 決済系の自社サービスの会社 バックエンドエンジニア • 仕事でGoを使うようになって1年 • Goで個人情報周りの
マイクロサービス開発 • 趣味:ボルダリング♂ • Twitter: https://twitter.com/FpmpAmpm
話の流れ • なにかとバッチ処理を作る機会があるという話 • バッチ処理作成時の課題がいろいろあるよねという話 • パイプラインパターンでうまくやろうという話 ◦ パイプラインとはステージと呼ばれるデータ操作の組み合わせのパターン ◦
ステージをうまくやるためのパターン(ファンアウト・ファンイン・キャンセル) • パイプラインを使えばうまく作れそうだが残る課題として ◦ ゴルーチンがリークしないようにする話 ◦ チャネルのブロックと panicを防ぐ話 • まとめ
なにかとバッチ処理を作る機会がある • ユーザーデータの不整合を解消したい • 非同期で動くイベント送信が失敗したので再送したい (なお自動でリカバリーする仕組みはない) • ユーザーが個人情報の削除を要請してきた • 追加機能開発で増えたDBカラムの既存レコード分のデータ作成
• とにかくいろいろある
なにかとバッチ処理を作る機会がある • 組織・チーム体制にもよるけど前職だと関わっていたサービスの規模が大きく専業 のバッチチームやインフラチームがあった。 • なので個人的には最近まであまりバッチ処理を作る機会はあまりなかった • マイクロサービス構成だと各サービスの開発者がなんとかするしかない。
バッチ処理作成時の課題 • 処理量が多いので並行処理しようとするが複雑化 • 動きそうだがオレオレ実装で可読性が悪くレビューもし辛い • できれば再利用・拡張性あるものにしたい • ゴルーチンがうまく扱えているか不安 •
チャネルがうまく扱えているか不安 →コードの見通しが良く拡張性があり 安全でいい感じの実装方式があれば真似したい
「Goで並行処理するときにはパ ターンがあったな・・・」
並行処理のパターンに関する情報源 • The Go Blog:Go Concurrency Patterns: Pipelines and cancellation
◦ https://blog.golang.org/pipelines • 書籍「Go言語による並行処理」 ◦ オライリージャパン ◦ Katherine Cox-Buday 著、山口 能迪 訳 ◦ 原書: Concurrency in Go ◦ https://www.oreilly.co.jp/books/9784873118468/
• 入力を受け取り何らかの一連の操作(ステージと呼ぶ)を行い出力する この組み合わせをパイプラインと呼ぶ(Go特有の概念ではない) パイプラインと呼ばれる考え方 ステージ1 ステージ2 ステージ3 入力 出力
• Goで実装する場合ステージ間はチャネルでデータを共有する パイプラインと呼ばれる考え方 ステージ1 ステージ2 ステージ3 入力 出力 データを渡すチャネルを作りステージ 2に
渡し、入力をチャネルに流す データ受信チャネルを引数に持ち、そこ から入力を受信後データ操作を行う
• 各ステージは独立して修正や入れ替えが可能 ステージをファンアウト・ファンインにすることで 並行処理とその結果の集約もできる。 コードの見通しはよくなりそう。 パイプラインと呼ばれる考え方 ステージ1 ステージ2 ステージ3 入力
出力
• ステージ1で出力されたデータを複数のステージ2で処理 複数のゴルーチンでステージ2を行う ファンアウト ステージ1 ステージ2 ステージ3 入力 出力
• ステージ2で別々に出力されたデータをステージ3で集約 ファンインで結果の集約 ステージ1 ステージ2 ステージ3 入力 出力
パイプライン全体の擬似コード // ステージ1(ctx以下は入力) in := gen(ctx, 1,2,3,4,5) //genは受信専用チャネルinを返す // ステージ2
(ファンアウト) c1 := sq(ctx,in) // 何らかの操作を並行実行 c2 := sq(ctx,in) // c1,c2は実行結果の受信専用チャネル // ステージ3(ファンイン) for n := range merge(ctx,c1, c2) { // mergeもc1,c2をまとめた受信専用チャネルを返す fmt.Println(n) }
ファンインで複数のチャネルをまとめる 引数のチャネル個数分それぞれデータを取り出し返却済のチャネル に送信する データ集約先のチャネルは先に返却
バッチ処理作成時の課題(再掲) • 処理量が多いので並行処理しようとするが複雑化 ◦ ◎パイプラインで見通し良さそう • 動きそうだがオレオレ実装で可読性が悪くレビューもし辛い ◦ ◎パイプラインの考え方が共有されていれば話が早そうだしコードの見通し良さそう。 •
できれば再利用・拡張性あるものにしたい ◦ ◎パイプラインで拡張性良さそう • ゴルーチンがうまく扱えているか不安 ◦ パイプラインのステージ内の実装による • チャネルがうまく扱えているか不安 ◦ パイプラインのステージ内の実装による
ゴルーチンのリークが起きないようにしたい • リーク(=漏れ) ◦ 情報のリーク:関係者がマスコミに秘密を漏らしちゃう • ゴルーチンのリーク ◦ 非メインのゴルーチンが終了せず残り続けること。 ◦
ガベージコレクションで回収されずその分メモリを圧迫する。 ◦ バッチ処理の場合どこかでプロセスが終わるので永遠に増え続けることはな いが意図しないリークは避けたい。
ゴルーチンのリーク例 https://play.golang.org/p/_YJcrlApJRq
コンテキストキャンセルで解決 https://play.golang.org/p/U18DkwkN0SO メインゴルーチンのdefer cancel()が伝播してctx.Doneがcloseされこ ちらのゴルーチンも終了する。
パイプラインでチャネルをうまく扱う • panicが起きる条件を知る ◦ closedチャネルへの送信(https://play.golang.org/p/puTTlBWgSTh) ◦ closedチャネルのclose ◦ nilチャネルのclose •
意図せずブロックしないようにする ◦ nilチャネルの読み書きをしない(https://play.golang.org/p/jCnURn3qaiU ) ◦ 所有権(誰が初期化するか、送受信の制限)を決める
チャネルのpanicを回避するパターン defer でcloseして二重にcloseを防ぎ、初期化 スコープでやることで nilチャネルのcloseを防ぐ 初期化したスコープでのみ送信する チャネルは初期化して受信専用で返却する(外 部で勝手に書き込ませない)
チャネルのブロックを回避するパターン • 作成者(ジェネレーター) ◦ パイプラインに流すデータのチャネルの作成、初期化し返却 ◦ 並行してデータ送信、チャネルのclose • 消費者(コンシューマー) ◦
ジェネレーターから受け取ったチャネルからデータ受信 ◦ もちろん必要な業務上の処理をやる
バッチ処理作成時の課題(再々掲) • 処理量が多いので並行処理しようとするが複雑化 ◦ ◎パイプラインで見通し良さそう • 動きそうだがオレオレ実装で可読性が悪くレビューもし辛い ◦ ◎パイプラインの考え方が共有されていれば話が早そうだしコードの見通し良さそう。 •
できれば再利用・拡張性あるものにしたい ◦ ◎パイプラインで拡張性良さそう • ゴルーチンがうまく扱えているか不安 ◦ ◎コンテキストで処理終了を伝えゴルーチンのリークを回避 • チャネルがうまく扱えているか不安 ◦ ◎チャネルの作成者と消費者で役割分担し不要なブロックや panicを回避
パイプラインまとめ ステージ1 ステージ2 ステージ3 入力 出力 • パイプラインは入力を受け取りステージと呼ばれる独立したデータ操作の組み合わせるパターン • ステージの組み合わせで柔軟に処理の分割、並行実行が可能になる。
◦ ステージ同士はチャネルでデータを受け渡しする • ステージ(個々のデータ操作を上手くやる)のためのパターン ◦ ファンアウト・ファンイン(ステージ同士の連携のためのパターン) ◦ コンテキストキャンセル(ステージを安全に終了するためのパターン) ◦ ジェネレーターとコンシューマー(ステージを安全に終了するための役割分担のパターン)
最後に • バッチ処理作成時に課題と思ったいくつかのトピックは解決できた。 しかし並行処理の沼はまだまだ深い。 ◦ 競合状態 ◦ ロック ◦ エラー処理
◦ ゴルーチンのスケジューリング ◦ 並行処理の速度・律速問題 etc… • 今ここで話すために並行処理の勉強をしたけどまだ氷山の一角に過ぎないと感じ た。これからも備えていきたい。 • 懇親会では是非声をかけてください。