SlideShare a Scribd company logo
Django/Celeyを用いた 
データ分析Webアプリケーションにおける 
非同期処理の設計と実装 
永安悟史 
pgcon14j 
12/5/2014
Who Am I?
Who Am I? 
• Database Engineer 
• Data Center Engineer 
• ITSM Specialist 
• Data Steward 
• System Architect 
• Co-founder 
• CTO
Agenda 
• Background & Motivation 
• Django 
• Async Processing in Django 
• Async Processing with Django/Celery 
• Design and Implementation 
for the Analytics App 
• Wrap-up
Background & Motivation
バックグラウンド 
• ヘルスケアデータベース 
– レセプトと検診データ 
– データベースサイズは100GB程度 
– 1テーブル数千万~1億レコード 
• 分析用のデータ抽出・集計のために、半定型な 
クエリを投げるようになってきた 
– 条件を変えて何度も繰り返し投げる 
– これまではエンジニアがSQLのテンプレを都度書き換 
えて作業 
– エンドユーザも検索できるようにしたい
モチベーションと要求事項 
• 半定型の集計クエリ(レポーティング) 
– 診断名、医薬品名、その他抽出条件が都度変わる 
• Webインターフェースを提供する必要性 
– 非技術者が使えるように 
• クエリの実行時間は「Webとしては」長い 
– 数十秒から長くて10分程度 
• スマートなWebインターフェースを提供したい 
– ブロッキングやタイムアウトをさせない 
– 開発期間(着手~プロトデモ)は実質的に1週間程度
Django
Django
About Django 
• PythonのWebフレームワーク 
– https://www.djangoproject.com/ 
• PythonにおけるRails的な位置付け(らしい) 
– 全部入りのフレームワーク 
• MTV (Model, Template, View) モデル 
– Template/ViewはMVCにおけるView/Controller 
• 組み込みO/Rマッパー入り 
– その他、SQLAlchemyも使える
Django Architecture 
出典:Djangoチュートリアル(前編) :CodeZine http://codezine.jp/article/detail/4065?p=2
Why Django? 
• 別件で使ったことがあった( 同じチームで) 
• 最小限の手間で、そこそこのものが作れる 
• 細かいところにそんなに拘らない 
• 普段、Webアプリ作らないので詳しくない 
• データ分析系なので、Pythonスキルを獲得・維持 
したい
Platforms and Frameworks 
• Windows 7 & Linux 
• Apache 
• Django 
• PostgreSQL 
• psycopg2 
• Twitter Bootstrap
Async Processing in Django
Long running queries in Django 
• クエリの実行時間は「Webとしては」長い 
– 数十秒から長くて10分程度 
• 実行時間を短縮させる必要性はさほどない 
– パフォーマンス改善における費用対効果の問題 
• スマートなWebインターフェースを提供したい 
– ブロッキングやタイムアウトをさせない 
• あまり大きなアーキテクチャにはしたくない 
– 運用性、保守性、属人性を考慮する
Async processing in Django 
https://www.djangopackages.com/grids/g/workers-queues-tasks/ 
As of Sep/21/2014
Development Status 
• Production/Stable 
• Beta 
• Beta 
• n/a 
• Beta 
• Alpha 
• Unknown 
• Unknown 
• Beta 
• Alpha 
As of Sep/21/2014 
So, which one should I choose? 
Lots of options, but no choice.
Djangoにおける非同期処理 
• django-tasks (623,000) 
– https://code.google.com/p/django-tasks/ 
• django-async (185,000) 
– https://pypi.python.org/pypi/django-async/ 
• django-rq (172,000) 
– http://python-rq.org/patterns/django/ 
• Celery (240,000) 
– http://www.celeryproject.org/
Async Processing with 
Django/Celery
UI/UX We Need 
• 一般的なWebUI 
– 検索条件を入力したら非同期処理を飛ばす 
• クエリを実行している間はspinnerを回す 
– バックグラウンドで実行 
• クエリが終わったら結果を表示
Celery 
• Distributed Task Queue 
• Real-time & Scheduled task 
• Simple & Easy to implement 
www.celeryproject.org
Celery Components 
• Client 
• Broker 
• Backend 
• Worker 
• Task 
Client 
Broker 
Backend 
Worker Worker
Supported Components
Celery Tasks 
• Pythonの関数として作成 
– 任意の引数、戻り値の定義が可能 
• DecolatorでCeleryのタスクとして定義
Celery Metadata 
• BackendとBrokerのデータ
Design and Implementation 
for the Analytics App
System Architecture 
Apache 
Django 
Celery 
PostgreSQL 
(Broker/Backend) 
PostgreSQL 
(Healthcare DB) 
1 Core, 1GB RAM 
25GB SAN DISK 
4 Core, 16GB RAM 
25+100GB SAN DISK 
Internet
From Query Templates To 
Celery Tasks 
• 条件に応じてSQLテンプレートからクエリを生成 
– テンプレートファイルを読み込み 
– 独自のプリプロセス処理(ifdef & endif) 
– プレースホルダにパラメータをバインド 
– O/Rマッパーは使わずpsycopg2を直叩き 
• Djangoのテンプレート+独自テンプレート 
– データ構造がModelに綺麗に当てはまらない 
– テンプレートを読み込んでプレースホルダを置き換え 
• 最後にCeleryのキューに投入する
Bind Parameters and Macros 
SELECT "連番" 
FROM "rez_iyaku" 
WHERE "薬剤コード" IN ( :DRUGCODE ) 
-- #ifdef EXCLUDE_DRUGCODE 
AND "薬剤コード" NOT IN ( :EXCLUDE_DRUGCODE ) 
-- #endif EXCLUDE_DRUGCODE 
SELECT "連番" 
FROM "rez_iyaku" 
WHERE "薬剤コード" IN ( 123456, 234567 ) 
/* 
AND "薬剤コード" NOT IN ( :EXCLUDE_DRUGCODE ) 
*/
From Query Templates To 
Celery Tasks 
Query 
Templates 
実行するクエリの元となるテンプレート 
(1クエリにテーブル6、WITH句6、約100行) 
Bind 
Parameters 
プレースホルダに対して 
入力条件である変数をバインド 
Preprocess 
Macros 
検索の条件に応じて 
ifdefマクロを 
コメントアウト処理 
Celery Tasks 
Celeryのタスク 
としてキューに 
投入
Internal Sequence 
Template View 
QueryBuilder QueryRunner 
Celery 
Broker Backend Worker 
Submit 
Polling 
Result 
Executing 
App Moudle 
Django
Processing a Task within 
Backend 
[2014-11-24 22:11:26,330: INFO/MainProcess] Received task: 
webui.QueryRunner.runQuery[1b5b8fd2-9296-4a25-9e98-f002b2068fdd] 
[2014-11-24 22:11:26,330: DEBUG/MainProcess] TaskPool: Apply <function 
_fast_trace_task at 0x2267938> (args:('webui.QueryRunner.runQuery', 
'1b5b8fd2-9296-4a25-9e98-f002b2068fdd', (...) 
[2014-11-24 22:11:26,333: DEBUG/MainProcess] Task accepted: 
webui.QueryRunner.runQuery[1b5b8fd2-9296-4a25-9e98-f002b2068fdd] 
pid:10450 
[2014-11-24 22:18:35,504: INFO/MainProcess] Task 
webui.QueryRunner.runQuery[1b5b8fd2-9296-4a25-9e98-f002b2068fdd] 
succeeded in 429.172908468s: {‘CCC_2_60_69_2012_REZ': '-', 
‘CCC_2_30_39_2010_ID': '-', ‘AAA_2_20_29_2012_ID': '172', 
‘AAA_1_30_39_2013_REZ': '324',...
Wrap-up
Wrap-up 
• Ad-hoc系で時間のかかる半定型クエリの実行を 
Webシステムとして実現 
• Django/Celeryを使って、DBAが実質2週間程 
度で開発(Djangoで1週間、Celeryで1週間)
感想 
• Djangoはデータ分析アプリに向いている 
– Web的なパフォーマンスを求められない 
– 全部入りでアプリの開発は比較的容易 
• Celeryは非同期処理に向いている 
– 特に問題なく動作している 
– 但し、Windowsでの動作は怪しい
And currently working on... 
1 min 50 sec ⇒ 0.2 sec
Thank you.

More Related Content

Django/Celeyを用いたデータ分析Webアプリケーションにおける非同期処理の設計と実装

  • 3. Who Am I? • Database Engineer • Data Center Engineer • ITSM Specialist • Data Steward • System Architect • Co-founder • CTO
  • 4. Agenda • Background & Motivation • Django • Async Processing in Django • Async Processing with Django/Celery • Design and Implementation for the Analytics App • Wrap-up
  • 6. バックグラウンド • ヘルスケアデータベース – レセプトと検診データ – データベースサイズは100GB程度 – 1テーブル数千万~1億レコード • 分析用のデータ抽出・集計のために、半定型な クエリを投げるようになってきた – 条件を変えて何度も繰り返し投げる – これまではエンジニアがSQLのテンプレを都度書き換 えて作業 – エンドユーザも検索できるようにしたい
  • 7. モチベーションと要求事項 • 半定型の集計クエリ(レポーティング) – 診断名、医薬品名、その他抽出条件が都度変わる • Webインターフェースを提供する必要性 – 非技術者が使えるように • クエリの実行時間は「Webとしては」長い – 数十秒から長くて10分程度 • スマートなWebインターフェースを提供したい – ブロッキングやタイムアウトをさせない – 開発期間(着手~プロトデモ)は実質的に1週間程度
  • 10. About Django • PythonのWebフレームワーク – https://www.djangoproject.com/ • PythonにおけるRails的な位置付け(らしい) – 全部入りのフレームワーク • MTV (Model, Template, View) モデル – Template/ViewはMVCにおけるView/Controller • 組み込みO/Rマッパー入り – その他、SQLAlchemyも使える
  • 11. Django Architecture 出典:Djangoチュートリアル(前編) :CodeZine http://codezine.jp/article/detail/4065?p=2
  • 12. Why Django? • 別件で使ったことがあった( 同じチームで) • 最小限の手間で、そこそこのものが作れる • 細かいところにそんなに拘らない • 普段、Webアプリ作らないので詳しくない • データ分析系なので、Pythonスキルを獲得・維持 したい
  • 13. Platforms and Frameworks • Windows 7 & Linux • Apache • Django • PostgreSQL • psycopg2 • Twitter Bootstrap
  • 15. Long running queries in Django • クエリの実行時間は「Webとしては」長い – 数十秒から長くて10分程度 • 実行時間を短縮させる必要性はさほどない – パフォーマンス改善における費用対効果の問題 • スマートなWebインターフェースを提供したい – ブロッキングやタイムアウトをさせない • あまり大きなアーキテクチャにはしたくない – 運用性、保守性、属人性を考慮する
  • 16. Async processing in Django https://www.djangopackages.com/grids/g/workers-queues-tasks/ As of Sep/21/2014
  • 17. Development Status • Production/Stable • Beta • Beta • n/a • Beta • Alpha • Unknown • Unknown • Beta • Alpha As of Sep/21/2014 So, which one should I choose? Lots of options, but no choice.
  • 18. Djangoにおける非同期処理 • django-tasks (623,000) – https://code.google.com/p/django-tasks/ • django-async (185,000) – https://pypi.python.org/pypi/django-async/ • django-rq (172,000) – http://python-rq.org/patterns/django/ • Celery (240,000) – http://www.celeryproject.org/
  • 19. Async Processing with Django/Celery
  • 20. UI/UX We Need • 一般的なWebUI – 検索条件を入力したら非同期処理を飛ばす • クエリを実行している間はspinnerを回す – バックグラウンドで実行 • クエリが終わったら結果を表示
  • 21. Celery • Distributed Task Queue • Real-time & Scheduled task • Simple & Easy to implement www.celeryproject.org
  • 22. Celery Components • Client • Broker • Backend • Worker • Task Client Broker Backend Worker Worker
  • 24. Celery Tasks • Pythonの関数として作成 – 任意の引数、戻り値の定義が可能 • DecolatorでCeleryのタスクとして定義
  • 25. Celery Metadata • BackendとBrokerのデータ
  • 26. Design and Implementation for the Analytics App
  • 27. System Architecture Apache Django Celery PostgreSQL (Broker/Backend) PostgreSQL (Healthcare DB) 1 Core, 1GB RAM 25GB SAN DISK 4 Core, 16GB RAM 25+100GB SAN DISK Internet
  • 28. From Query Templates To Celery Tasks • 条件に応じてSQLテンプレートからクエリを生成 – テンプレートファイルを読み込み – 独自のプリプロセス処理(ifdef & endif) – プレースホルダにパラメータをバインド – O/Rマッパーは使わずpsycopg2を直叩き • Djangoのテンプレート+独自テンプレート – データ構造がModelに綺麗に当てはまらない – テンプレートを読み込んでプレースホルダを置き換え • 最後にCeleryのキューに投入する
  • 29. Bind Parameters and Macros SELECT "連番" FROM "rez_iyaku" WHERE "薬剤コード" IN ( :DRUGCODE ) -- #ifdef EXCLUDE_DRUGCODE AND "薬剤コード" NOT IN ( :EXCLUDE_DRUGCODE ) -- #endif EXCLUDE_DRUGCODE SELECT "連番" FROM "rez_iyaku" WHERE "薬剤コード" IN ( 123456, 234567 ) /* AND "薬剤コード" NOT IN ( :EXCLUDE_DRUGCODE ) */
  • 30. From Query Templates To Celery Tasks Query Templates 実行するクエリの元となるテンプレート (1クエリにテーブル6、WITH句6、約100行) Bind Parameters プレースホルダに対して 入力条件である変数をバインド Preprocess Macros 検索の条件に応じて ifdefマクロを コメントアウト処理 Celery Tasks Celeryのタスク としてキューに 投入
  • 31. Internal Sequence Template View QueryBuilder QueryRunner Celery Broker Backend Worker Submit Polling Result Executing App Moudle Django
  • 32. Processing a Task within Backend [2014-11-24 22:11:26,330: INFO/MainProcess] Received task: webui.QueryRunner.runQuery[1b5b8fd2-9296-4a25-9e98-f002b2068fdd] [2014-11-24 22:11:26,330: DEBUG/MainProcess] TaskPool: Apply <function _fast_trace_task at 0x2267938> (args:('webui.QueryRunner.runQuery', '1b5b8fd2-9296-4a25-9e98-f002b2068fdd', (...) [2014-11-24 22:11:26,333: DEBUG/MainProcess] Task accepted: webui.QueryRunner.runQuery[1b5b8fd2-9296-4a25-9e98-f002b2068fdd] pid:10450 [2014-11-24 22:18:35,504: INFO/MainProcess] Task webui.QueryRunner.runQuery[1b5b8fd2-9296-4a25-9e98-f002b2068fdd] succeeded in 429.172908468s: {‘CCC_2_60_69_2012_REZ': '-', ‘CCC_2_30_39_2010_ID': '-', ‘AAA_2_20_29_2012_ID': '172', ‘AAA_1_30_39_2013_REZ': '324',...
  • 34. Wrap-up • Ad-hoc系で時間のかかる半定型クエリの実行を Webシステムとして実現 • Django/Celeryを使って、DBAが実質2週間程 度で開発(Djangoで1週間、Celeryで1週間)
  • 35. 感想 • Djangoはデータ分析アプリに向いている – Web的なパフォーマンスを求められない – 全部入りでアプリの開発は比較的容易 • Celeryは非同期処理に向いている – 特に問題なく動作している – 但し、Windowsでの動作は怪しい
  • 36. And currently working on... 1 min 50 sec ⇒ 0.2 sec