2017年12月3日

Dockerを使ってデータ分析用にPostgreSQLを使ってみる

これは PostgreSQL Advent Calendar 2017 の Day3 の記事です。昨日はMorihayaさんの「DB Management tool新時代の幕開けか!? OmniDBを評価させていただく!」でした。

さて、最近ようやくDockerに触り始めたのですが、使い方が少しずつ分かってきたのでいろいろと遊んでいます。

今回は、In-Database AnalyticsとDockerです。

■全部入りのDockerイメージを作ってみた


最近、In-Database Analyticsがマイブームになっていますので、ボチボチと遊んでいます。

いろいろ遊んではいるのですが、いろいろセットアップしたり変更したり、アレが足りない、コレが動かない、みたいなことをやっているのが面倒になってきていました。面倒さが原因で手が動かないことも。。

これはいかん。

というわけで、データ分析に使えそうなExtensionをいろいろと入れ込んだ(自分的な)全部入りのPostgreSQLのDockerイメージを作ってみました。
  • CentOS 7
    • Python 2.7
  • PostgreSQL 10.1
    • PL/Python
    • postgres_fdw
  • PL/R 8.3.0.17
    • R 3.4.2
  • Apache MADlib 1.13-dev
  • pg_bigm 1.2
  • mecab 0.996
    • mecab-ipadic 2.7.0
    • mecab-python 0.993
  • numpy / scipy / scikit-learn / pandas / matplotlib
おかげで1.7GBもあるイメージになってしまいましたが、まぁそこはご愛敬、ということで。

とりあえず、Rのグラフィック関連のパッケージはゴリゴリと削ってたのですが、numpyとかscipyとかが案外大きいんですね。。無理して削った関係上、動かない機能があったらすみません。連絡いただければ修正する所存です。。

■Dockerコンテナを起動してPostgreSQLに接続する


まぁ何はともあれ、まずは使ってみましょう。起動するコマンドは以下です。
docker pull uptimejp/postgres4analytics
docker imagesを叩くとこんな感じになります。
# docker images
REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
docker.io/uptimejp/postgres4analytics   latest              3421a544c9a5        7 hours ago         1.722 GB
docker.io/centos                        7                   196e0ce0c9fb        11 weeks ago        196.6 MB
#
docker run -p 5432:5432 -ti uptimejp/postgres4analytics

簡単ですねー。イメージが大きい関係上、pullに少し時間がかかります。

Dockerコンテナを起動するとPostgreSQLのバックエンドが起動している様子が分かります。
# docker run -p 5432:5432 -ti uptimejp/postgres4analytics
2017-12-02 00:02:07.922 UTC [5] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2017-12-02 00:02:07.922 UTC [5] LOG:  listening on IPv6 address "::", port 5432
2017-12-02 00:02:07.939 UTC [5] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2017-12-02 00:02:07.949 UTC [5] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2017-12-02 00:02:07.961 UTC [5] LOG:  redirecting log output to logging collector process
2017-12-02 00:02:07.961 UTC [5] HINT:  Future log output will appear in directory "log".

ここで別のターミナルからPostgreSQLに接続します。

ユーザ postgres で、データベース template2 に接続します。

この template2 データベースが全部入りをセットアップしたデータベースになります。(template1 には MADlib をうまくセットアップできなかったためです・・・) もちろん postgres はスーパーユーザーですが、その辺は気にしない方向で。
$ psql -h localhost -U postgres template2
psql (10.1)
Type "help" for help.

template2=# select version();
                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 10.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16), 64-bit
(1 row)

template2=# 

■各種Extensionを見てみる


というわけで、セットアップされたExtension諸々を見てみます。
template2=# \dx
                                      List of installed extensions
     Name     | Version  |   Schema   |                           Description
--------------+----------+------------+------------------------------------------------------------------
 pg_bigm      | 1.2      | public     | text similarity measurement and index searching based on bigrams
 plpgsql      | 1.0      | pg_catalog | PL/pgSQL procedural language
 plpythonu    | 1.0      | pg_catalog | PL/PythonU untrusted procedural language
 plr          | 8.3.0.17 | public     | load R interpreter and execute R script from within a database
 postgres_fdw | 1.0      | public     | foreign-data wrapper for remote PostgreSQL servers
(5 rows)

template2=#

こんな感じで、いくつかのExtensionがあらかじめセットアップされています。

まず PL/R。
template2=# select r_version();
                    r_version
-------------------------------------------------
 (platform,x86_64-redhat-linux-gnu)
 (arch,x86_64)
 (os,linux-gnu)
 (system,"x86_64, linux-gnu")
 (status,"")
 (major,3)
 (minor,4.2)
 (year,2017)
 (month,09)
 (day,28)
 ("svn rev",73368)
 (language,R)
 (version.string,"R version 3.4.2 (2017-09-28)")
 (nickname,"Short Summer")
(14 rows)

template2=#
おぉ、動いてるっぽい。

続いてApache MADlib。
template2=# select madlib.version();
                                                                                                              version

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------
 MADlib version: 1.13-dev, git revision: unknown, cmake configuration time: Sat Nov 25 07:43:17 UTC 2017, build type: RelWithDebInfo, build system: Linux-3.10.0-693.2.1.el7.x86_64, C compil
er: gcc 4.8.5, C++ compiler: g++ 4.8.5
(1 row)

template2=#
1.13-devが入ってますね。

次。なぜか勢いで入れてしまったpg_bigm。
template2=# select show_bigm('進捗は如何ですか。');
                       show_bigm
-------------------------------------------------------
 {"。 ",か。,すか,です,は如,何で,如何,捗は,進捗," 進"}
(1 row)

template2=#
きちんと動いてます。ところで進捗は如何ですか。

次、みんな大好きPythonもPostgreSQLで動きます。ここでは以下のようにMecabを使って形態素解析をするUDFを作って動作確認して見ます。
CREATE OR REPLACE FUNCTION mecab_tokenize(string text)
  RETURNS text[]
AS $$
    import MeCab
    import plpy

    a = []
    m =  MeCab.Tagger("-Ochasen")
    """
    Mecabに渡すためにはunicodeではなくutf-8である必要がある。
    Mecabから戻ってきたらunicodeに戻す。

    また、Mecabはエンコード済みのutf-8文字列へのポインタを返すので、
    on-the-flyでutf-8に変換するのではなく、変数として保持しておく
    必要がある。(でないとメモリ領域がGCで回収されてデータが壊れる)

    参照:
    http://shogo82148.github.io/blog/2012/12/15/mecab-python/
    """
    enc_string = string
    node = m.parseToNode(enc_string)
    while node:
        n = node.surface.decode('utf-8')
        if n:
            a.append(n)
        node = node.next
    return a
$$ LANGUAGE plpythonu;

動かしてみます。
template2=# select mecab_tokenize('進捗は如何ですか。');
      mecab_tokenize
---------------------------
 {進捗,は,如何,です,か,。}
(1 row)

template2=#
動いてます。進捗は如何ですか。

こんな感じで、このDockerイメージを使うと、「聞いたことはあるけれど使ったことは無い」ものが一瞬(?)で使えるようになります。

あと、postgres_fdwなどもセットアップされていますので、リモートにあるPostgreSQLのテーブルをそのまま取ってくる、みたいなことも簡単に(?)できます。できるはずです。

■Dockerfile


ちなみに、Dockerfileは以下から入手できます。
こういうの追加したい、みたいなのがあれば、forkしていじってみるなり、プルリクしてみるなりして頂ければと思います。

■まとめ


そんなわけで、全部入りPostgreSQL(しかも最新版)を作ってみた、というお話でした。自分も、今後はこれを使っていこうと思っています。

Happy In-Database Analytics Lifeを!

では。

PostgreSQL Advent Calendar 2017、明日はvidaisukiさんです。

0 件のコメント:

コメントを投稿