こんにちは、WEBサービス開発部あらためWEBサービス開発グループの伊達です。つい先週部署名が変わりました。
ニフティのウェブサービスでは、サービスの各種データやお客様の行動ログをTreasureDataに蓄積し、Redashで可視化することでサービスの分析に役立てています。
TreasureDataはfluentdやembulkでおなじみのトレジャーデータ社のデータ管理サービスです。類似のサービスには、GoogleのBigQueryがありますね。ニフティでは、@nifty不動産や@nifty温泉を始めとした多くのサービスでスマホアプリのイベントデータやウェブサイトのログをTreasureDataに溜めています。
Redashは、RDB、NoSQL、あるいはTreasureDataやBigQueryなどのマネージドサービスのデータソースから抽出したデータをグラフなどで可視化できるソフトウェアです。有償のSaaS版と無償で利用できるOSS版があり、ニフティでは後者を活用しています。
TreasureDataはクエリ課金型ではありませんので、従量課金死の心配なくRedashなどのツールと連携して利用できます。そんな便利なTreasureDataとRedashですが、Redash上で日本語を含むクエリをTreasureDataに対して実行しようとするとエラーになる問題がv1.0.3にあるため、今回はその回避策について共有します。
環境構築から順を踏んで説明しますので、お急ぎの方は「エラーになるクエリ」からお読みください。
Redash環境を作る
今回はDocker Composeで環境を作ります。詳しくは Setting up a Redash instance のDocker Composeの項を参照ください。
- docker-compose.yml を用意します。今回はproduction用のをそのまま使います
(実用する際には、REDASH_COOKIE_SECRETやpostgresのvolumesを設定してください) - docker-compose -f docker-compose.production.yml run --rm server create_db を実行して、データベースの初期化をします
- docker-compose -f docker-compose.production.yml upを実行するとRedashが動きます
docker-compose.production.ymlを使いますと、Redash本体はserverとworkerの2コンテナが立ち上がります。manage.pyコマンドを実行するとバージョンの確認ができます。
1 2 |
$ docker exec -ti redash_server_1 ./manage.py version 1.0.3+b2850 |
(※ serverコンテナの名前がredash_server_1だった場合)
2017/06/22現在、redash/redash:latestのイメージを使用すると、上記の通り1.0.3+b2850です。
Adminユーザの設定
http://サーバのIPアドレス:5000/ にアクセスすると初回のみAdminユーザの設定画面が表示されます。
適当に入力して「Setup」をクリックしてください。
TreasureDataのデータソースを設定
さて、Adminユーザの設定が終わりますと、上記のような画面が表示されます。
データソースを設定しないと始まりませんので、右上のData Sourcesアイコンをクリックしてください。
続けて、「New Data Source」をクリック。
TreasureDataのサンプルのデータセットをデータソースに設定してみます。Typeにはクエリの種類を指定できます。契約しているプランに応じて、hiveまたはprestoを記入してください。
クエリを実行する
さて、やっと本題に入ります。まず、画面上部のメニューの Queries> New Query を選んで新しいクエリの作成画面に遷移します。
例えばサンプルのデータベース www_access から1行取得してみます。
1 |
select * from www_access limit 1; |
とクエリ欄に記入してExecuteをクリックすればスクリーンショットのように結果が返ってきます。
そして、例えば以下のようなクエリを実行すると、
1 |
select 'abc', * from www_access limit 1; |
という結果になります。
エラーになるクエリ
ところが、ここで文字列を日本語にするとエラーが発生します。
1 |
select 'あいう', * from www_access limit 1; |
1 |
Error running query: (psycopg2.IntegrityError) null value in column "data" violates not-null constraint DETAIL: Failing row contains (5, 1, 1, 4811345db1ef6a1f8c7a0510455a8932, select 'あいう', * from www_access limit 1;, null, 0.625991106033325, 2017-06-22 06:00:28.026034+00). |
調べたところ、TreasureDataがデータソースであり、非ASCII文字が含まれている場合には、どんなクエリでもエラーが発生するようでした。
原因
結論としては、Redashが使っているTreasureData接続用のライブラリであるtd-clientのバージョンが古いのが原因です。
requirements_all_ds.txt に依存ライブラリが記載されていますが、1.0.3+b2850ではtd-client==0.4.1となっています。
対処方法
2.0.0を使う
このコミットで使用するtd-clientが0.8.0に変更されていますので、未リリースですが2.0.0であれば問題は改善されています。
Docker Hubのredash/redashには2.0.0のタグもありますので、それを使うのも手です。
td-clientのバージョンを上げる
あるいは、Redashは1.0.3を使いつつ、td-clientのバージョンだけ上げても問題は起きなくなります。本当はイメージをビルドすべきですが、簡単のためコンテナにアタッチしてtd-clientのバージョンだけ上げてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ docker exec -ti redash_worker_1 /bin/bash redash@531856e2bb90:/app$ pip install td-client==0.8.0 Collecting td-client==0.8.0 Downloading td_client-0.8.0-py2.py3-none-any.whl (72kB) 100% |################################| 81kB 2.3MB/s Collecting urllib3<2.0,>=1.10 (from td-client==0.8.0) Downloading urllib3-1.21.1-py2.py3-none-any.whl (131kB) 100% |################################| 133kB 2.6MB/s Collecting six (from td-client==0.8.0) Downloading six-1.10.0-py2.py3-none-any.whl Collecting msgpack-python<0.5,>=0.4 (from td-client==0.8.0) Downloading msgpack-python-0.4.8.tar.gz (113kB) 100% |################################| 122kB 3.7MB/s Collecting python-dateutil<2.5.0,>=2.4.0 (from td-client==0.8.0) Downloading python_dateutil-2.4.2-py2.py3-none-any.whl (188kB) 100% |################################| 194kB 3.1MB/s Building wheels for collected packages: msgpack-python Running setup.py bdist_wheel for msgpack-python ... done Stored in directory: /home/redash/.cache/pip/wheels/2c/e7/e7/9031652a69d594665c5ca25e41d0fb3faa024e730b590e4402 Successfully built msgpack-python Installing collected packages: urllib3, six, msgpack-python, python-dateutil, td-client Successfully installed msgpack-python-0.4.8 python-dateutil-2.4.2 six-1.10.0 td-client-0.4.1 urllib3-1.20 |
アプリケーションを再起動すれば完了です。
1 2 3 4 5 6 |
$ docker-compose -f docker-compose.production.yml up Starting redash_redis_1 Starting redash_worker_1 Starting redash_postgres_1 Starting redash_server_1 Starting redash_nginx_1 |
再び日本語を含むクエリを実行してみますと、エラーは起きず結果が得られました。
1 |
select 'あいう', * from www_access limit 1; |
ということで、快適な可視化生活を送ることができるようになりました。