#概要
redashは複数のコンテナによって構成されている。
ざっくり役割は以下の通り。
redash_worker_1
データの結果取得に時間がかかる場合が多いので、
実際のクエリーを実行する処理はこのコンテナが行う。
celeryというPythonのjob queue処理を行うためのフレームワークが使われている。
以下の2種類存在している
adhoc workers
アドホックに実行したクエリーを処理する
scheduled queries workers
スケジュールされた通りにクエリーを実行する
切り替えはcelery worker起動時に-Qオプションで制御される。
1つのworkerで両方の機能を担うことも、 別々のworkerに分けることも可能。
redash_nginx_1
webサーバ リバースプロキシとして稼働
redash_server_1
Pythonで実装されたWeb console画面。
基本的にこの画面を利用して ユーザはクエリーの発行やデータの可視化を行う。
Application Serverとしてgunicornが使われている。
redash_redis_1
celeryではクエリーを貯めておく場所としてredisを利用することができる。
このredis内にserverからjobがqueueに登録され、 workerが引き出して実行を行う。
redash_postgres_1
ユーザ情報や作成したQuery/Dashboardの情報が格納される。
#トラブルシューティング
コンテナのリソース状況を確認したい
redashというか、dockerでの管理の話しになるが、
ctopというコマンドを使うと、管理しやすい
https://qiita.com/S-T/items/d5a43076a51f5814ee32
クエリが返って来ない
test connectionはOKでもクエリーを発行すると戻って来ない時がある。
コンテナの一つ一つ見ていくと、workerで処理が来ていないことがわかった。
スケジュールに登録されているクエリが多すぎるのでは?という仮説に至った。
考えてみればスケジュールされていなければいけない必要性もない。
QUEUESごとにworkerプロセスを分けて見ることにした。
をオフにすることにした。
appears only in the queue list of "redash_celery_scheduled"
before
worker:
image: redash/redash:latest
command: scheduler
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
QUEUES: "queries,scheduled_queries,celery"
WORKERS_COUNT: 1
restart: always
after
workerコンテナを3分割した
worker-queries:
image: redash/redash:latest
command: scheduler
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
QUEUES: "queries"
WORKERS_COUNT: 1
restart: always
worker-scheduled_queries:
image: redash/redash:latest
command: scheduler
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
QUEUES: "scheduled_queries"
WORKERS_COUNT: 1
restart: always
worker-celery:
image: redash/redash:latest
command: scheduler
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
QUEUES: "celery"
WORKERS_COUNT: 1
restart: always
コンテナを分けた後、ctopで再度リソースを確認したところ
worker-celeryが極端にCPUを使い始めた
celeryというPythonのjob queue処理で何かか詰まっていたようだ。
しばらくしたら解消した。
redashのversionUP
以下の流れで実施する
0. Postgressのデータをバックアップする
- コンテナを止め、削除
- docker-composeファイルを修正する
- DBのスキーマ変更処理をする
- redash起動
Postgressのデータをバックアップする
docker ps
docker exec -it redash_postgres_1 /bin/bash
pg_dump -U postgres postgres | gzip > /tmp/redash_backup.gz
exit
docker cp redash_postgres_1:/tmp/redash_backup.gz .
コンテナを止め、削除
docker stop redash_worker-scheduled_queries_1 redash_worker-celery_1 redash_worker-queries_1 redash_server_1
docker rm redash_worker-scheduled_queries_1 redash_worker-celery_1 redash_worker-queries_1 redash_server_1
docker-composeファイルを修正する
#image: redash/redash:latest
image: redash/redash:4.0.0-rc.1
DBのスキーマ変更処理をする
https://gitter.im/getredash/redash/archives/2017/03/26
で@arikfr氏が提案してくれているコマンドを実施したが、
エラーが出るわけでもなく、何が起こったのかわからない。
しかし、ブラウザで画面を確認すると500errorになっている。
# docker-compose run --rm server manage db upgrade
Starting redash_redis_1
[2018-03-29 05:52:16,551][PID:1][INFO][root] Generating grammar tables from /usr/lib/python2.7/lib2to3/Grammar.txt
[2018-03-29 05:52:16,586][PID:1][INFO][root] Generating grammar tables from /usr/lib/python2.7/lib2to3/PatternGrammar.txt
[2018-03-29 05:52:17,848][PID:1][INFO][alembic.runtime.migration] Context impl PostgresqlImpl.
[2018-03-29 05:52:17,848][PID:1][INFO][alembic.runtime.migration] Will assume transactional DDL.
#
よくよく考えたら、
composeを起動する時のymlファイルを指定してなかった。。
# docker-compose -f docker-compose.production.yml run --rm server manage db upgrade
[2018-03-29 06:05:30,551][PID:1][INFO][root] Generating grammar tables from /usr/lib/python2.7/lib2to3/Grammar.txt
[2018-03-29 06:05:30,585][PID:1][INFO][root] Generating grammar tables from /usr/lib/python2.7/lib2to3/PatternGrammar.txt
[2018-03-29 06:05:32,423][PID:1][INFO][alembic.runtime.migration] Context impl PostgresqlImpl.
[2018-03-29 06:05:32,424][PID:1][INFO][alembic.runtime.migration] Will assume transactional DDL.
[2018-03-29 06:05:32,433][PID:1][INFO][alembic.runtime.migration] Running upgrade d1eae8b9893e -> 7671dca4e604, empty message
[2018-03-29 06:05:32,439][PID:1][INFO][alembic.runtime.migration] Running upgrade 7671dca4e604 -> 5ec5c84ba61e, Add Query.search_vector field for full text search.
[2018-03-29 06:05:32,565][PID:1][INFO][alembic.runtime.migration] Running upgrade 5ec5c84ba61e -> 6b5be7e0a0ef, Re-index Query.search_vector with existing queries.
[2018-03-29 06:05:32,661][PID:1][INFO][alembic.runtime.migration] Running upgrade 6b5be7e0a0ef -> 969126bd800f, Update widget's position data based on dashboard layout.
Updating dashboards position data:
Updating dashboard: 1
Building widgets map:
Widget: 1
Widget: 2
Iterating over layout:
Row: 0 - [1, 2]
Column: 0 - 1
Column: 1 - 2
Updating dashboard: 2
Building widgets map:
Widget: 3
Iterating over layout:
Row: 0 - [3]
Column: 0 - 3
Updating dashboard: 4
Building widgets map:
Widget: 18
Iterating over layout:
Row: 0 - [18]
Column: 0 - 18
Updating dashboard: 5
Building widgets map:
Widget: 21
Widget: 22
Widget: 31
Widget: 32
Widget: 41
Widget: 42
Widget: 82
Widget: 93
Iterating over layout:
Row: 0 - [93]
Column: 0 - 93
Row: 1 - [21]
Column: 0 - 21
Row: 2 - [22]
Column: 0 - 22
Row: 3 - [31]
Column: 0 - 31
Row: 4 - [32]
Column: 0 - 32
Row: 5 - [41]
Column: 0 - 41
Row: 6 - [42]
Column: 0 - 42
Row: 7 - [82]
Column: 0 - 82
Updating dashboard: 9
Building widgets map:
Widget: 53
Widget: 94
Iterating over layout:
Row: 0 - [94]
Column: 0 - 94
Row: 1 - [53]
Column: 0 - 53
Updating dashboard: 7
Building widgets map:
Widget: 38
Widget: 40
Widget: 95
Iterating over layout:
Row: 0 - [95]
Column: 0 - 95
Row: 1 - [38]
Column: 0 - 38
Row: 2 - [40]
Column: 0 - 40
Updating dashboard: 11
Building widgets map:
Widget: 71
Widget: 67
Widget: 70
Iterating over layout:
Row: 0 - [67]
Column: 0 - 67
Row: 1 - [70]
Column: 0 - 70
Row: 2 - [71]
Column: 0 - 71
Updating dashboard: 3
Building widgets map:
Widget: 5
Widget: 11
Widget: 13
Widget: 14
Widget: 15
Widget: 16
Widget: 17
Widget: 28
Widget: 51
Widget: 77
Widget: 78
Widget: 80
Iterating over layout:
Row: 0 - [14, 15]
Column: 0 - 14
Column: 1 - 15
Row: 1 - [17, 16]
Column: 0 - 17
Column: 1 - 16
Row: 2 - [11, 13]
Column: 0 - 11
Column: 1 - 13
Row: 3 - [28]
Column: 0 - 28
Row: 4 - [5]
Column: 0 - 5
Row: 5 - [77, 78]
Column: 0 - 77
Column: 1 - 78
Row: 6 - [51, 80]
Column: 0 - 51
Column: 1 - 80
Updating dashboard: 13
Building widgets map:
Widget: 83
Iterating over layout:
Row: 0 - [83]
Column: 0 - 83
Updating dashboard: 14
Building widgets map:
Iterating over layout:
Updating dashboard: 12
Building widgets map:
Iterating over layout:
Row: 0 - [
Column: 0 - [
Row: 1 - ]
Column: 0 - ]
Updating dashboard: 16
Building widgets map:
Widget: 102
Widget: 103
Widget: 104
Widget: 105
Iterating over layout:
Row: 0 - [102, 103]
Column: 0 - 102
Column: 1 - 103
Row: 1 - [104, 105]
Column: 0 - 104
Column: 1 - 105
Updating dashboard: 6
Building widgets map:
Widget: 25
Widget: 26
Widget: 29
Widget: 30
Widget: 33
Widget: 34
Widget: 43
Widget: 45
Widget: 46
Widget: 47
Widget: 48
Widget: 91
Iterating over layout:
Row: 0 - [91, 48]
Column: 0 - 91
Column: 1 - 48
Row: 1 - [47, 45]
Column: 0 - 47
Column: 1 - 45
Row: 2 - [46]
Column: 0 - 46
Row: 3 - [43]
Column: 0 - 43
Row: 4 - [25]
Column: 0 - 25
Row: 5 - [26]
Column: 0 - 26
Row: 6 - [29]
Column: 0 - 29
Row: 7 - [30]
Column: 0 - 30
Row: 8 - [33]
Column: 0 - 33
Row: 9 - [34]
Column: 0 - 34
Updating dashboard: 10
Building widgets map:
Widget: 57
Widget: 59
Widget: 61
Widget: 63
Widget: 65
Widget: 62
Widget: 92
Iterating over layout:
Row: 0 - [92]
Column: 0 - 92
Row: 1 - [62]
Column: 0 - 62
Row: 2 - [57]
Column: 0 - 57
Row: 3 - [63]
Column: 0 - 63
Row: 4 - [59]
Column: 0 - 59
Row: 5 - [65]
Column: 0 - 65
Row: 6 - [61]
Column: 0 - 61
Updating dashboard: 17
Building widgets map:
Widget: 108
Widget: 107
Widget: 109
Widget: 110
Widget: 111
Iterating over layout:
Row: 0 - [108]
Column: 0 - 108
Row: 1 - [109]
Column: 0 - 109
Row: 2 - [107]
Column: 0 - 107
Row: 3 - [110, 111]
Column: 0 - 110
Column: 1 - 111
Updating dashboard: 15
Building widgets map:
Widget: 98
Widget: 99
Widget: 100
Widget: 101
Iterating over layout:
Row: 0 - [99, 100]
Column: 0 - 99
Column: 1 - 100
Row: 1 - [98, 101]
Column: 0 - 98
Column: 1 - 101
Updating dashboard: 18
Building widgets map:
Widget: 112
Widget: 113
Widget: 114
Iterating over layout:
Row: 0 - [112, 113]
Column: 0 - 112
Column: 1 - 113
Row: 1 - [114]
Column: 0 - 114
Updating dashboard: 8
Building widgets map:
Widget: 68
Widget: 85
Widget: 86
Widget: 87
Widget: 88
Widget: 89
Widget: 115
Widget: 116
Iterating over layout:
Row: 0 - [68, 116]
Column: 0 - 68
Column: 1 - 116
Row: 1 - [115]
Column: 0 - 115
Row: 2 - [85]
Column: 0 - 85
Row: 3 - [86, 89]
Column: 0 - 86
Column: 1 - 89
Row: 4 - [87]
Column: 0 - 87
Row: 5 - [88]
Column: 0 - 88
Updating dashboard: 20
Building widgets map:
Iterating over layout:
Updating dashboard: 21
Building widgets map:
Widget: 122
Iterating over layout:
Row: 0 - [122]
Column: 0 - 122
Updating dashboard: 19
Building widgets map:
Widget: 120
Widget: 121
Widget: 124
Widget: 118
Iterating over layout:
Row: 0 - [118]
Column: 0 - 118
Row: 1 - [124]
Column: 0 - 124
Row: 2 - [120]
Column: 0 - 120
Row: 3 - [121]
Column: 0 - 121
作業前と、作業後でスキーマを見比べて見たが、
今回新しく追加されたカラムが結構あったので、本処理は必須。
参考情報