Ubuntu 18.04でClickHouseをインストールして使用する方法

著者は、Write for DOnationsプログラムの一部として寄付を受け取るためにFree and Open Source Fundを選択しました。

前書き

ClickHouseは、OLAPおよびビッグデータのユースケース向けにYandexによって作成されたオープンソースの列指向分析データベースです。 ClickHouseのリアルタイムクエリ処理のサポートにより、1秒未満の分析結果を必要とするアプリケーションに適しています。 ClickHouseのクエリ言語はSQLの方言であり、強力な宣言型クエリ機能を可能にすると同時に、エンドユーザーに使い慣れた学習曲線を提供します。

Column-orientedデータベースは、行ではなく列でグループ化されたブロックにレコードを格納します。 クエリにない列のデータを読み込まないことにより、列指向データベースはクエリの完了中にデータを読み取る時間を短縮します。 その結果、これらのデータベースは、OLAPなどの特定のワークロードに対して、従来の行ベースのシステムよりもはるかに高速に結果を計算して返すことができます。

Online Analytics Processing(OLAP)システムでは、大量のデータを整理し、複雑なクエリを実行できます。 ペタバイトのデータを管理し、クエリ結果を迅速に返すことができます。 このように、OLAPはデータサイエンスやビジネス分析などの分野での作業に役立ちます。

このチュートリアルでは、ClickHouseデータベースサーバーとクライアントをマシンにインストールします。 通常のタスクにDBMSを使用し、オプションで別のサーバーからリモートアクセスを有効にして、別のマシンからデータベースに接続できるようにします。 次に、サンプルのWebサイト訪問データをモデリングおよびクエリして、ClickHouseをテストします。

前提条件

  • sudoが有効な非rootユーザーとファイアウォールのセットアップを備えた1つのUbuntu18.04サーバー。 サーバーの初期設定tutorialに従って、ユーザーを作成し、ファイアウォールを設定できます。

  • (オプション)sudoが有効な非rootユーザーとファイアウォールのセットアップを備えたセカンダリUbuntu18.04サーバー。 サーバーの初期設定tutorialに従うことができます。

[[step-1 -—- installing-clickhouse]] ==ステップ1—ClickHouseのインストール

このセクションでは、apt-getを使用してClickHouseサーバーおよびクライアントプログラムをインストールします。

最初に、次を実行してサーバーにSSH接続します。

ssh [email protected]_server_ip

Yandexは、ClickHouseの最新バージョンを含むAPTリポジトリを管理しています。 検証済みのClickHouseパッケージを安全にダウンロードできるように、リポジトリのGPGキーを追加します。

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4

次のような出力が表示されます。

Output
Executing: /tmp/apt-key-gpghome.JkkcKnBAFY/gpg.1.sh --keyserver keyserver.ubuntu.com --recv E0C56BD4

gpg: key C8F1E19FE0C56BD4: public key "ClickHouse Repository Key " imported
gpg: Total number processed: 1
gpg:               imported: 1

出力により、キーが正常に検証および追加されたことが確認されます。

以下を実行して、APTリポジトリリストにリポジトリを追加します。

echo "deb http://repo.yandex.ru/clickhouse/deb/stable/ main/" | sudo tee /etc/apt/sources.list.d/clickhouse.list

ここでは、echoの出力をsudo teeにパイプ処理して、この出力をルート所有のファイルに出力できるようにしました。

次に、apt-get updateを実行してパッケージを更新します。

sudo apt-get update

これで、clickhouse-serverおよびclickhouse-clientパッケージをインストールできるようになります。 以下を使用してインストールします。

sudo apt-get install -y clickhouse-server clickhouse-client

ClickHouseサーバーとクライアントを正常にインストールしました。 これで、データベースサービスを開始し、それが正しく実行されていることを確認する準備ができました。

[[step-2 -—- starting-the-service]] ==ステップ2—サービスの開始

前のセクションでインストールしたclickhouse-serverパッケージは、データベースサーバーの起動、停止、再起動などのアクションを実行するsystemdサービスを作成します。 systemdは、Linuxがサービスを初期化および管理するためのinitシステムです。 このセクションでは、サービスを開始し、正常に実行されていることを確認します。

次のコマンドを実行して、clickhouse-serverサービスを開始します。

sudo service clickhouse-server start

前のコマンドは出力を表示しません。 サービスが正常に実行されていることを確認するには、次を実行します。

sudo service clickhouse-server status

次のような出力が表示されます。

Output
● clickhouse-server.service - ClickHouse Server (analytic DBMS for big data)
   Loaded: loaded (/etc/systemd/system/clickhouse-server.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2018-12-22 07:23:20 UTC; 1h 9min ago
 Main PID: 27101 (ClickHouse-serv)
    Tasks: 34 (limit: 1152)
   CGroup: /system.slice/ClickHouse-server.service
           └─27101 /usr/bin/ClickHouse-server --config=/etc/ClickHouse-server/config.xml

出力は、サーバーが実行中であることを示しています。

これでClickHouseサーバーが正常に起動し、clickhouse-clientCLIプログラムを使用してサーバーに接続できるようになります。

[[step-3 -—- creating-databases-and-tables]] ==ステップ3—データベースとテーブルの作成

ClickHouseでは、対話型データベースプロンプトでSQLステートメントを直接実行することにより、データベースを作成および削除できます。 ステートメントは、特定の構文に従うコマンドで構成され、必要なデータとともに要求された操作を実行するようデータベースサーバーに指示します。 CREATE DATABASE table_name構文を使用してデータベースを作成します。 データベースを作成するには、まず次のコマンドを実行してクライアントセッションを開始します。

clickhouse-client

このコマンドは、ClickHouse SQLステートメントを実行して次のようなアクションを実行できるクライアントプロンプトにログインします。

  • データベース、テーブル、インデックス、パーティション、ビューの作成、更新、削除。

  • クエリを実行して、さまざまな条件を使用してオプションでフィルター処理およびグループ化されたデータを取得します。

このステップでは、ClickHouseクライアントでデータを挿入する準備ができたら、データベースとテーブルを作成します。 このチュートリアルでは、testという名前のデータベースを作成し、その中に、Webサイトへのアクセス時間を追跡するvisitsという名前のテーブルを作成します。

ClickHouseコマンドプロンプトが表示されたら、次のコマンドを実行してtestデータベースを作成します。

CREATE DATABASE test;

データベースが作成されたことを示す次の出力が表示されます。

Output
CREATE DATABASE test

Ok.

0 rows in set. Elapsed: 0.003 sec.

ClickHouseテーブルは、他のリレーショナルデータベースのテーブルに似ています。構造化された形式で関連データのコレクションを保持します。 タイプとともに列を指定し、データの行を追加し、テーブルに対してさまざまな種類のクエリを実行できます。

ClickHouseでテーブルを作成するための構文は、次の構造例に従います。

CREATE TABLE table_name
(
    column_name1 column_type [options],
    column_name2 column_type [options],
    ...
) ENGINE = engine

table_nameおよびcolumn_nameの値は、任意の有効なASCII識別子にすることができます。 ClickHouseは、幅広い列タイプをサポートしています。最も人気のあるものは次のとおりです。

  • UInt64:0〜18446744073709551615の範囲の整数値を格納するために使用されます。

  • Float64:2039.23、10.5などの浮動小数点数を格納するために使用されます。

  • String:可変長文字を格納するために使用されます。 任意の長さを格納できるため、最大長属性は必要ありません。

  • DateYYYY-MM-DD形式に従う日付を格納するために使用されます。

  • DateTime:日付と時刻を格納するために使用され、YYYY-MM-DD HH:MM:SS形式に従います。

列の定義後、テーブルに使用されるエンジンを指定します。 ClickHouseでは、Enginesは、基になるデータの物理構造、テーブルのクエリ機能、その同時アクセスモード、およびインデックスのサポートを決定します。 さまざまなエンジン要件は、さまざまなアプリケーション要件に適しています。 最も一般的に使用され、広く適用可能なエンジンタイプはMergeTreeです。

テーブル作成の概要ができたので、テーブルを作成します。 変更するデータベースを確認することから始めます。

USE test;

defaultデータベースからtestデータベースに切り替えたことを示す次の出力が表示されます。

Output
USE test

Ok.

0 rows in set. Elapsed: 0.001 sec.

このガイドの残りの部分では、このデータベースのコンテキスト内でステートメントを実行することを想定しています。

次のコマンドを実行して、visitsテーブルを作成します。

CREATE TABLE visits (
 id UInt64,
 duration Float64,
 url String,
 created DateTime
) ENGINE = MergeTree()
PRIMARY KEY id
ORDER BY id;

コマンドの機能の内訳は次のとおりです。 4つの列を持つvisitsという名前のテーブルを作成します。

  • id:主キー列。 他のRDBMSシステムと同様に、ClickHouseの主キー列は行を一意に識別します。各行には、この列の一意の値が必要です。

  • duration:各訪問の期間を秒単位で格納するために使用されるfloat列。 float列には、12.50などの10進値を格納できます。

  • urlhttp://example.comなど、アクセスしたURLを格納する文字列列。

  • created:訪問がいつ発生したかを追跡する日付と時刻の列。

列定義の後で、テーブルのストレージエンジンとしてMergeTreeを指定します。 エンジンのMergeTree familyは、大規模なリアルタイム挿入の最適化されたサポート、全体的な堅牢性、およびクエリサポートのため、本番データベースに推奨されます。 さらに、MergeTreeエンジンは、主キーによる行の並べ替え、行のパーティション分割、データの複製とサンプリングをサポートしています。

ClickHouseを使用して、頻繁にクエリされないデータをアーカイブしたり、一時データを保存したりする場合は、エンジンのLog familyを使用して、そのユースケースに合わせて最適化できます。

列の定義後、他のテーブルレベルのオプションを定義します。 PRIMARY KEY句はidを主キー列として設定し、ORDER BY句はid列でソートされた値を格納します。 主キーは行を一意に識別し、単一行への効率的なアクセスと行の効率的なコロケーションに使用されます。

createステートメントを実行すると、次の出力が表示されます。

OutputCREATE TABLE visits
(
    id UInt64,
    duration Float64,
    url String,
    created DateTime
)
ENGINE = MergeTree()
PRIMARY KEY id
ORDER BY id

Ok.

0 rows in set. Elapsed: 0.010 sec.

このセクションでは、Webサイト訪問データを追跡するためのデータベースとテーブルを作成しました。 次のステップでは、テーブルにデータを挿入し、既存のデータを更新して、そのデータを削除します。

[[step-4 -—- inserting-updating-and-deleting-data-and-columns]] ==ステップ4—データと列の挿入、更新、および削除

このステップでは、visitsテーブルを使用して、データを挿入、更新、および削除します。 次のコマンドは、ClickHouseテーブルに行を挿入するための構文の例です。

INSERT INTO table_name VALUES (column_1_value, column_2_value, ....);

次に、次の各ステートメントを実行して、サンプルのWebサイト訪問データをvisitsテーブルに数行挿入します。

INSERT INTO visits VALUES (1, 10.5, 'http://example.com', '2019-01-01 00:01:01');
INSERT INTO visits VALUES (2, 40.2, 'http://example1.com', '2019-01-03 10:01:01');
INSERT INTO visits VALUES (3, 13, 'http://example2.com', '2019-01-03 12:01:01');
INSERT INTO visits VALUES (4, 2, 'http://example3.com', '2019-01-04 02:01:01');

挿入ステートメントごとに次の出力が繰り返されます。

Output
INSERT INTO visits VALUES

Ok.

1 rows in set. Elapsed: 0.004 sec.

各行の出力は、それがvisitsテーブルに正常に挿入されたことを示しています。

次に、visitsテーブルに列を追加します。 既存のテーブルから列を追加または削除する場合、ClickHouseはALTER構文をサポートします。

たとえば、テーブルに列を追加するための基本的な構文は次のとおりです。

ALTER TABLE table_name ADD COLUMN column_name column_type;

次のステートメントを実行して、Webサイトへの訪問の場所を格納するlocationという名前の列を追加します。

ALTER TABLE visits ADD COLUMN location String;

次のような出力が表示されます。

OutputALTER TABLE visits
    ADD COLUMN
    location String


Ok.

0 rows in set. Elapsed: 0.014 sec.

出力は、location列が正常に追加されたことを示しています。

バージョン19.3.6の時点では、ClickHouseは実装の制約のため、データの個々の行の更新と削除をサポートしていません。 ただし、ClickHouseは一括更新と一括削除をサポートしており、これらの操作の標準ではない使用法を強調するための明確なSQL構文を備えています。

次の構文は、行を一括更新する例です。

ALTER TABLE table_name UPDATE  column_1 = value_1, column_2 = value_2 ...  WHERE  filter_conditions;

次のステートメントを実行して、durationが15未満のすべての行のurl列を更新します。 データベースプロンプトに入力して実行します。

ALTER TABLE visits UPDATE url = 'http://example2.com' WHERE duration < 15;

一括更新ステートメントの出力は次のとおりです。

Output
ALTER TABLE visits
    UPDATE url = 'http://example2.com' WHERE duration < 15


Ok.

0 rows in set. Elapsed: 0.003 sec.

出力は、更新クエリが正常に完了したことを示しています。 出力の0 rows in setは、クエリが行を返さなかったことを示します。これは、更新および削除クエリの場合に当てはまります。

行を一括削除するための構文例は、行の更新に似ており、次の構造を持っています。

ALTER TABLE table_name DELETE WHERE filter_conditions;

データの削除をテストするには、次のステートメントを実行して、durationが5未満のすべての行を削除します。

ALTER TABLE visits DELETE WHERE duration < 5;

一括削除ステートメントの出力は次のようになります。

Output
ALTER TABLE visits
    DELETE WHERE duration < 5


Ok.

0 rows in set. Elapsed: 0.003 sec.

出力は、5秒未満の期間で行を削除したことを確認します。

テーブルから列を削除するには、構文は次の構造例に従います。

ALTER TABLE table_name DROP COLUMN column_name;

次のコマンドを実行して、前に追加したlocation列を削除します。

ALTER TABLE visits DROP COLUMN location;

列を削除したことを確認するDROP COLUMNの出力は、次のようになります。

OutputALTER TABLE visits
    DROP COLUMN
    location String


Ok.

0 rows in set. Elapsed: 0.010 sec.

visitsテーブルの行と列を正常に挿入、更新、および削除したので、次の手順でデータのクエリに進みます。

[[step-5 --- querying-data]] ==ステップ5—データのクエリ

ClickHouseのクエリ言語は、分析ワークロードに適した拡張機能を備えたSQLのカスタム方言です。 このステップでは、選択クエリと集計クエリを実行して、visitsテーブルからデータと結果を取得します。

選択クエリを使用すると、指定した条件でフィルタリングされたデータの行と列を、取得する行数などのオプションとともに取得できます。 SELECT構文を使用して、データの行と列を選択できます。 SELECTクエリの基本的な構文は次のとおりです。

SELECT func_1(column_1), func_2(column_2) FROM table_name WHERE filter_conditions row_options;

次のステートメントを実行して、urlhttp://example.comである行のurlおよびduration値を取得します。

SELECT url, duration FROM visits WHERE url = 'http://example2.com' LIMIT 2;

次の出力が表示されます。

OutputSELECT
    url,
    duration
FROM visits
WHERE url = 'http://example2.com'
LIMIT 2

┌─url─────────────────┬─duration─┐
│ http://example2.com │     10.5 │
└─────────────────────┴──────────┘
┌─url─────────────────┬─duration─┐
│ http://example2.com │       13 │
└─────────────────────┴──────────┘

2 rows in set. Elapsed: 0.013 sec.

出力は、指定した条件に一致する2つの行を返しました。 値を選択したら、集計クエリの実行に移行できます。

集計クエリは、一連の値を操作し、単一の出力値を返すクエリです。 分析データベースでは、これらのクエリは頻繁に実行され、データベースによって適切に最適化されます。 ClickHouseでサポートされている集計関数は次のとおりです。

  • count:指定された条件に一致する行の数を返します。

  • sum:選択した列の値の合計を返します。

  • avg:選択した列値の平均を返します。

ClickHouse固有の集計関数には次のものがあります。

  • uniq:一致した個別の行のおおよその数を返します。

  • topK:近似アルゴリズムを使用して、特定の列の最も頻度の高い値の配列を返します。

集計クエリの実行を示すために、sumクエリを実行して、訪問の合計期間を計算します。

SELECT SUM(duration) FROM visits;

次のような出力が表示されます。

Output
SELECT SUM(duration)
FROM visits

┌─SUM(duration)─┐
│          63.7 │
└───────────────┘

1 rows in set. Elapsed: 0.010 sec.

次に、以下を実行して上位2つのURLを計算します。

SELECT topK(2)(url) FROM visits;

次のような出力が表示されます。

OutputSELECT topK(2)(url)
FROM visits

┌─topK(2)(url)──────────────────────────────────┐
│ ['http://example2.com','http://example1.com'] │
└───────────────────────────────────────────────┘

1 rows in set. Elapsed: 0.010 sec.

visitsテーブルのクエリが正常に完了したので、次の手順でテーブルとデータベースを削除します。

[[step-6 -—- deleting-tables-and-databases]] ==ステップ6—テーブルとデータベースの削除

このセクションでは、visitsテーブルとtestデータベースを削除します。

テーブルを削除するための構文は、この例に従います。

DROP TABLE table_name;

visitsテーブルを削除するには、次のステートメントを実行します。

DROP TABLE visits;

テーブルが正常に削除されたことを宣言する次の出力が表示されます。

outputDROP TABLE visits

Ok.

0 rows in set. Elapsed: 0.005 sec.

DROP database table_name構文を使用してデータベースを削除できます。 testデータベースを削除するには、次のステートメントを実行します。

DROP DATABASE test;

結果の出力は、データベースが正常に削除されたことを示しています。

Output
DROP DATABASE test

Ok.

0 rows in set. Elapsed: 0.003 sec.

この手順でテーブルとデータベースを削除しました。 ClickHouseインスタンスでデータベース、テーブル、データを作成、更新、削除したので、次のセクションでデータベースサーバーへのリモートアクセスを有効にします。

[[step-7 -—- setting-up-firewall-rules-optional]] ==ステップ7—ファイアウォールルールの設定(オプション)

同じサーバーで実行されているアプリケーションでClickHouseをローカルでのみ使用する場合、またはサーバーでファイアウォールを有効にしていない場合は、このセクションを完了する必要はありません。 代わりに、ClickHouseデータベースサーバーにリモートで接続する場合は、この手順に従う必要があります。

現在、サーバーのファイアウォールは有効になっており、すべてのポートにアクセスするパブリックIPアドレスが無効になっています。 リモートアクセスを許可するには、次の2つの手順を完了します。

  • ClickHouseの構成を変更し、すべてのインターフェイスでリッスンできるようにします。

  • ClickHouseサーバーが実行するHTTPポートであるポート8123への着信接続を許可するファイアウォールルールを追加します。

データベースプロンプト内にいる場合は、CTRL+Dと入力して終了します。

以下を実行して構成ファイルを編集します。

sudo nano /etc/clickhouse-server/config.xml

次に、次のファイルのように、<!-- <listen_host>0.0.0.0</listen_host> -->を含む行のコメントを解除します。

/etc/clickhouse-server/config.xml

...
 example.yandex.ru
    -->

    
    
    
    0.0.0.0

    
    
...

ファイルを保存し、nanoを終了します。 新しい構成を適用するには、次を実行してサービスを再起動します。

sudo service clickhouse-server restart

このコマンドからの出力は表示されません。 ClickHouseのサーバーは、ポート8123でHTTP接続をリッスンし、ポート9000clickhouse-clientからの接続をリッスンします。 次のコマンドを使用して、2番目のサーバーのIPアドレスの両方のポートへのアクセスを許可します。

sudo ufw allow from second_server_ip/32 to any port 8123
sudo ufw allow from second_server_ip/32 to any port 9000

両方のポートへのアクセスを有効にしたことを示す両方のコマンドの次の出力が表示されます。

OutputRule added

ClickHouseは、追加したIPからアクセスできるようになります。 必要に応じて、ローカルマシンのアドレスなどのIPを自由に追加してください。

リモートマシンからClickHouseサーバーに接続できることを確認するには、最初に2番目のサーバーでこのチュートリアルのステップ1の手順に従い、clickhouse-clientがインストールされていることを確認します。

2番目のサーバーにログインしたので、次を実行してクライアントセッションを開始します。

clickhouse-client --host your_server_ip

サーバーに正常に接続されたことを示す次の出力が表示されます。

OutputClickHouse client version 19.3.6.
Connecting to your_server_ip:9000 as user default.
Connected to ClickHouse server version 19.3.6 revision 54415.

hostname :)

この手順では、ファイアウォールルールを調整して、ClickHouseデータベースサーバーへのリモートアクセスを有効にしました。

結論

サーバーにClickHouseデータベースインスタンスを正常にセットアップし、データベースとテーブルを作成し、データを追加し、クエリを実行し、データベースを削除しました。 ClickHouseのドキュメントでは、他のオープンソースおよび商用の分析データベースに対するbenchmarksと、一般的なリファレンスdocumentsについて読むことができます。 さらにfeatures ClickHouseが提供するものには、パフォーマンスを向上させ、異なるshardsにデータを保存することでデータ損失から保護するために、複数のサーバーに分散クエリ処理が含まれます。