clickhouse-odbcインストールでぶつかったgccバージョン固定の壁をSCL (Software Collection)で乗り越えた手順

マーベリック株式会社、インフラエンジニアの小川です。

特に古めの枯れたOSを使ったサーバ上で新しめのミドルウェアを使いたいと思った時、OS標準のパッケージやライブラリが古くてすんなり入らない…といったケースは多々起きると思います。弊社では以前、ClickHouseというOSSのデータベース導入を試みたときに上記の問題に遭遇しました。そこで、弊社でどうやってそれを乗り越えたかを、SCL(Software Collections)の使い方とともに紹介します。

1年で数億件以上のレコードが追加される予測

弊社でClickHouse導入を決めたのはある広告系のプロダクトでした。プロダクト開発の初期段階でデータベースの検討を行っていたとき、ひとつのレポーティング系テーブルのサイズが非常に大きくなることが懸念されました。過去の別プロダクトのデータなどをもとに見積もると、1年間の運用で数億件のレコードが追加されていくとの予測でした。もしビジネスが予想以上に拡大すればレコード数の成長速度も更に上がります。困ったことにレポーティング系のテーブルなので基本的にデータが減ることはなく、時間の経過とともにレコード数は増える一方です。レポーティングは毎回その巨大なテーブルに対しクエリを走らせねばなりません。

f:id:maverick-techblog:20191202121802p:plain

ClickHouse

そこで目をつけたのがClickHouseです。ClickHouseは以下のような特徴を持ち、ClickHouseのデータ構造に適したケースでは行指向なデータベースより高い性能を期待できます。

  • 列指向(カラムナ)データベース管理システム
  • OLAP処理向きのデータ分析基盤
  • オープンソース
  • SQLクエリを使用して分析データレポートをリアルタイムで生成できる

社内で行ったベンチマークでは、テーブルの構成や検索条件でばらつきがありましたが、クエリを走らせたとき1秒あたり数千万~1億以上のレコードをスキャンできました。これで十分実用に耐えうる速度がでたのでClickHouseを本番導入することが決定し、以下のような構成で当時の弊社のEC2環境、Amazon Linux 1イメージのインスタンス群上でアプリケーションの構築を目指しました。

f:id:maverick-techblog:20191202122112p:plain

clickhouse-odbc

さて、自社開発アプリケーションからClickHouseに接続するにはいくつかの方法があります。このアプリケーションはHaskellで書かれていたため、ODBCドライバを経由してClickHouseを利用することにしました。

  • アプリから ClickHouse を扱うための ODBC ドライバ
    • Haskell 製アプリ → unixODBC → clickhouse-odbc → ClickHouse
  • RHEL7/CentOS7/Amazon Linux 2 用のドライバは .rpm が提供されているため、特に困らない(はず)
  • RHEL6/CentOS6/Amazon Linux 1 用は .rpm パッケージが提供されていない

f:id:maverick-techblog:20191202122233p:plain

さてこれでClickHouseのデータベースとドライバがあれば動くはずでしたが…。

gcc バージョン問題にぶち当たる

GitHub からソースを取得して、Amazon Linux 1環境のサーバ上でビルドを試みるも失敗してしまいました。 https://github.com/ClickHouse/clickhouse-odbc#installing-prerequisites-linux

You'll need to have installed:

- Fresh C compiler, which understands -std=c++14
- Static libraries
    - static libgcc
    - static libstdc++
    - static libodbc
- cmake >= 3

Fresh C compiler, which understands -std=c++14

理由としては要求されるビルド環境の条件が厳しかったことです。特に gcc の「C++14」が大きな壁で、当時弊社の環境でのEC2インスタンスのOSはAmazon Linux 1で、gcc は「C++11」なので、ビルドが通りませんでした。

何ということでしょう

OSのバージョンをAmazon Linux 2に上げずに上げずに何とかできないものか…? と探していたとき

ありました

SCL (Software Collection)

https://www.softwarecollections.org/

SCLは現環境を壊さずに、新しめのミドルウェアが使えるものです。 (Node.js における nvm, Python における PyEnv などに使用感が近いです)

SCL の使い方

scl enable devtoolset-7 bash

→ bash が新たに起動し、ライブラリは SCL 提供のものを使うようになります

使ってみた on Amazon Linux 1

$ cat /etc/system-release
Amazon Linux AMI release 2018.03
  • 通常時の GCC バージョン
$ g++ --version
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  • SCL 切り替え後
$ scl enable devtoolset-7 bash
$ g++ --version
g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

これなら行けそうな気がしてきました!

clickhouse-odbc インストール手順

新しめの unixODBC をインストール

cd /opt/
wget http://www.unixodbc.org/unixODBC-2.3.7.tar.gz
tar zxvf unixODBC-2.3.7.tar.gz 
cd unixODBC-2.3.7
./configure && make && make install

Cmake, その他必要なものをインストール

yum -y install git cmake3 libtool-ltdl-devel --enablerepo=epel

CentOS SCL(Software Collections) インストール
元々のビルドツールやライブラリを壊すことなく、より新しいバージョンのツール/ライブラリを利用できる。 C++14 対応の gcc もこの中に含まれている。

cd /opt/
wget http://mirror.centos.org/centos/6/extras/x86_64/Packages/centos-release-scl-rh-2-4.el6.centos.noarch.rpm
wget http://mirror.centos.org/centos/6/extras/x86_64/Packages/centos-release-scl-7-4.el6.centos.noarch.rpm
wget http://vault.centos.org/6.7/SCL/x86_64/scl-utils/scl-utils-20120927-11.el6.centos.alt.x86_64.rpm
wget http://vault.centos.org/6.7/SCL/x86_64/scl-utils/scl-utils-build-20120927-11.el6.centos.alt.x86_64.rpm
yum -y install *.rpm
yum install -y devtoolset-7-gcc-c++ devtoolset-7-make devtoolset-7-build --enablerepo=epel
scl enable devtoolset-7 bash

clickhouse-odbc インストール

git clone --recursive https://github.com/yandex/clickhouse-odbc.git
cd clickhouse-odbc/
git checkout -b v0523 refs/tags/v1.0.0.20190523
mkdir -p build; cd build && cmake3 .. && make -j $(nproc || sysctl -n hw.ncpu || echo 4)
make install

無事ビルドが通れば、以下の場所に clickhouse-odbc の ODBC ドライバが出来上がる。

ls -la /usr/local/lib64/odbc/libclickhouseodbc.so 

ODBC への組み込み

ODBC で認識するように、ドライバの設定ファイルを用意する。 /etc/odbcinst.ini

[ClickHouse]
Driver=/usr/local/lib64/odbc/libclickhouseodbc.so

~/.odbc.ini

[ClickHouse]
Driver = /usr/local/lib64/odbc/libclickhouseodbc.so
url = https://localhost

動作確認

clickhouse-odbc ドライバが動作するか確認する。

isql -v ClickHouse

動作確認結果
成功すれば、ODBCのクライアントが起動する

# isql -v ClickHouse
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> 

失敗の場合は、 Segment Fault 等のエラーが出る

動作確認完了
確認できたら、クライアントから抜ける。

SQL> quit

まとめ

SCL について

冒頭で述べたように、ミドルウェアをインストールする際にOS標準のパッケージやライブラリが古くてすんなり入らないといったケースは、長年使い続けている環境だと起こりがちです。本来は素直にOSのバージョンを上げて最新に近いものを使うべきでしょうが、あらゆるしがらみでできないことがよくあります。特に GCC に手を加えるのは…正直避けて通りたいものですよね。

そういった時、今回利用した SCL で元々のOSライブラリに影響なく、より新しいバージョンのツールが使える手立てがあるのは本当に助かりました。多用するのは気が引けますが、いざ! どうしても! という時の選択肢として活用できれば良いかなと思います。

ClickHouse について

また、 ClickHouse はまだまだ知名度が低い感じがあるものの、テーブル単位でレプリケーションが設定できたりと、噛むほど面白そうなカラムナDBです。まだまだ運用して日が浅いですが、今後弊社内でも活躍の場が増えそうな予感がしています。興味あるかたはぜひチェックしてみて下さい。

参考文献