Edited at

dockerで稼働するredashのトラブルと対策

More than 1 year has passed since last update.


概要

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

image-20180322014156917.png


クエリが返って来ない

test connectionはOKでもクエリーを発行すると戻って来ない時がある。

コンテナの一つ一つ見ていくと、workerで処理が来ていないことがわかった。

スケジュールに登録されているクエリが多すぎるのでは?という仮説に至った。

考えてみればスケジュールされていなければいけない必要性もない。

QUEUESごとにworkerプロセスを分けて見ることにした。

をオフにすることにした。

https://github.com/getredash/redash/blob/master/setup/ubuntu/files/supervisord.conf


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を使い始めた

スクリーンショット 2018-03-29 14.34.25.png

celeryというPythonのjob queue処理で何かか詰まっていたようだ。

しばらくしたら解消した。


redashのversionUP

以下の流れで実施する

0. Postgressのデータをバックアップする

1. コンテナを止め、削除

2. docker-composeファイルを修正する

3. DBのスキーマ変更処理をする

4. 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

作業前と、作業後でスキーマを見比べて見たが、

今回新しく追加されたカラムが結構あったので、本処理は必須。

スクリーンショット 2018-03-29 15.24.27.png

無事アップデートが完了した。


参考情報

http://tech.curama.jp/entry/2018/03/02/120000