クリックハウスの使い方とテーブルデザインの紹介

PostgreSQLとの違い

ClickHouseの概要を説明するイントロページは非常に優れています。

ClickHouseはPostgreSQLのような従来のOLTP(オンライントランザクション処理)データベースとは多くの違いがあります。基礎となるアーキテクチャが少し異なり、処理は従来のデータベースよりもCPUに依存します。ClickHouseはログ中心のデータベースで、不変性が重要な要素です。このようなアプローチの利点はよく文書化されています[1]が、更新が非常に難しくなります。UPDATE/DELETEをサポートするオペレーションについてはClickHouseのドキュメントを参照してください。これらのオペレーションは頻繁に行われるものではありません。

この区別はテーブルを設計する際に重要です。どちらかです:

  • 更新が不要(最良のケース)
  • 更新が必要な場合は、クエリ実行中に実行されません。

ACID互換性

ClickHouseのTransactionalサポートの概要は少し異なり、保証は特定のテーブルへの挿入データのブロックまでしか適用されません。詳細はTransactional(ACID) サポートドキュメントを参照してください。

複数のテーブルにまたがるトランザクションのサポートはマテリアライズド・ビューでのみカバーされているため、1回の書き込みで複数の挿入を行うことは避けるべきです。

ClickHouseは、分析クエリに対してクラス最高のサポートを提供することに重点を置いています。集計のようなオペレーションは非常に高速で、これらの機能を強化するためのいくつかの機能があります。ClickHouseには、集計の詳細をカバーする優れたブログ記事がいくつかあります。

プライマリインデックス、ソートインデックス、辞書

ClickHouseのインデックスを理解するために、”ClickHouseにおけるプライマリインデックスの実践的な紹介 “を読むことを強くお勧めします。

特に、ClickHouseにおけるデータベース・インデックス設計が、PostgreSQLのようなトランザクション・データベースにおけるインデックス設計とどのように異なるかについてです。

プライマリインデックスの設計はクエリのパフォーマンスにおいて非常に重要な役割を果たすため、慎重に記述する必要があります。完全なデータスキャンには時間がかかるため、ほとんど全てのクエリはプライマリインデックスに依存する必要があります。

MergeTreeテーブル・エンジン(ClickHouseのデフォルト・テーブル・エンジン)において、インデックスがクエリ・パフォーマンスにどのような影響を与えるかについては、クエリにおける主キーとインデックスについてのドキュメントをお読みください。

ClickHouseのセカンダリ・インデックスは、他のシステムで利用できるものとは異なります。データ・スキップ・インデックスとも呼ばれ、データ・ブロックをスキップするために使用されます。データ・スキップ・インデックスについては、ドキュメントを参照してください。

ClickHouseは、外部インデックスとして使用できる“辞書 “も提供しています。辞書はメモリからロードされ、クエリ実行時に値を検索するために使用できます。

データ型とパーティショニング

ClickHouseはSQL互換のデータ型と、いくつかの特殊なデータ型を提供しています:

テーブルの設計で重要なのは、パーティショニング・キーです。パーティションは任意の式にすることができますが、通常は月、日、週などの時間的な期間を指定します。ClickHouseは、最小のパーティションセットを使用することで、データの読み取りを最小化する最善のアプローチを取ります。

推奨される読み方

シャーディングとレプリケーション

シャーディングは、データを複数のClickHouseノードに分割し、スループットを向上させ、レイテンシを減少させる機能です。シャーディング機能は、ローカルテーブルによってバックアップされたディストリビューションエンジンを使用します。分散エンジンはデータを保存しない「仮想」テーブルです。データの挿入やクエリを行うインターフェースとして使用されます。

レプリケーションとシャーディングについてはClickHouseのドキュメントとこのセクションを参照してください。ClickHouseはコンセンサスを維持するために、ClickHouse Keeperと呼ばれるコンポーネントを介してZookeeperまたは独自の互換APIを使用することができます。

ノードがセットアップされた後は、クライアントから見えなくなり、どのノードに対しても書き込みと読み込みのクエリを発行することができます。

ほとんどの場合、クラスターは固定数のノード(~シャード)からスタートします。シャードの再バランスはオペレーションが重く、厳密なテストが必要です。

レプリケーションは MergeTree テーブルエンジンでサポートされています。レプリケーションの定義方法についてはドキュメントのレプリケーションのセクションを参照してください。ClickHouseは、クォーラムに参加しているノードを追跡するために、ディストリビューション・コーディネーション・コンポーネント(ZookeeperまたはClickHouse Keeper)に依存しています。レプリケーションは非同期かつマルチリーダーです。インサートはどのノードにもイシューすることができ、ある程度のレイテンシで他のノードに表示されます。必要であれば、特定のノードへのスティッキネスを使用して、読み込みが最新の書き込みデータを観察するようにすることができます。

マテリアライズド・ビュー

ClickHouseの特徴のひとつにマテリアライズド・ビューがあります。機能的にはClickHouseの挿入トリガーに似ています。マテリアライズド・ビューは様々なユースケースに使用することができます。

公式ドキュメントのviewsセクションを読んで、どのように動作するのか理解を深めることをお勧めします。

ドキュメントを引用します:

ClickHouseのマテリアライズド・ビューは、挿入トリガーのように実装されています。ビューのクエリに集約がある場合、それは挿入されたばかりのデータのバッチにのみ適用されます。ソース・テーブルの既存のデータに対する変更(更新、削除、パーティションの削除など)は、マテリアライズド・ビューを変更しません。

セキュアで賢明なデフォルト

ClickHouseインスタンスは以下のセキュリティに関する推奨事項に従ってください:

ユーザー

ファイル:users.xmlconfig.xml.

トピックセキュリティ要件理由
user_name/passwordユーザー名は空白であってはなりません。パスワードはpassword_sha256_hex を使用し、空白であってはなりません plaintextpassword_double_sha1_hex は安全ではありません。ユーザー名が指定されない場合、default が使用され、パスワード は使用されません。
access_managementサーバー設定ファイル users.xml およびconfig.xml を使用してください。SQL ド リ ブ ンの ワー ク フ ロ ーは避けて く だ さ い。SQL駆動型ワークフローは、少なくとも1人のユーザーがaccess_management 、設定ファイルによって回避できることを意味します。同じアクセス実体を両方の設定方法で同時に管理することはできません。
user_name/networks <ip>,<host>,<host_regexp> のうち少なくとも1つは設定されていなければなりません。どのネットワークに対しても、<ip>::/0</ip> を使ってアクセスを開かないでください。ネットワーク制御。(慎重に信頼する原則)
user_name/profileプロファイルを使用して、複数のユーザー間で同様のプロパティを設定し、制限を設定します(ユーザーインターフェイスから)。 最小特権の原則と制限。
user_name/quota可能な限りユーザーにクォータを設定します。一定期間のリソース使用量を制限するか、リソースの使用状況を追跡します。
user_name/databasesデータへのアクセスを制限し、フルアクセスできるユーザーを避けます。 最小特権の原則。

ネットワーク

ファイルconfig.xml

トピックセキュリティ要件理由
mysql_port厳密に必要な場合を除き、MySQL アクセスを無効にします:
<!-- <mysql_port>9004</mysql_port> -->.
不要なポートや機能の露出を閉じます。(深層防衛の原則)
postgresql_port厳密な必要性がない限り、PostgreSQLへのアクセスを無効にしてください:
<!-- <mysql_port>9005</mysql_port> -->
不要なポートや機能の露出を閉じます。(深層防衛の原則)
http_port/https_port &tcp_port/tcp_port_secure SSL-TLSを設定し、非SSLポートを無効にします。
<!-- <http_port>8123</http_port> -->
<!-- <tcp_port>9000</tcp_port> -->
、セキュリティポートを有効にします:
<https_port>8443</https_port>
<tcp_port_secure>9440</tcp_port_secure>
転送中のデータを暗号化します。(深層防御の原則)
interserver_http_hostClickHouseがクラスターとして設定されている場合、interserver_http_host を無効にし、interserver_https_host (<interserver_https_port>9010</interserver_https_port>) を使用します。転送中のデータを暗号化します。(深層防御の原則)

ストレージ

トピックセキュリティ要件理由
権限ClickHouse はデフォルトでclickhouse ユーザーで動作します。root として実行する必要はありません。フォルダには最小権限の原則を使用してください:/etc/clickhouse-server /var/lib/clickhouse /var/log/clickhouse-server 。これらのフォルダーはclickhouse ユーザーとグループに属し、他のシステム・ユーザーはアクセスできません。デフォルトのパスワード、ポート、ルールは「オープンドア」です。(セキュアに失敗し、セキュアなデフォルトを使用する原則)
暗号化REDデータが処理される場合、ログとデータには暗号化されたストレージを使用します。Kubernetesでは、使用するStorageClassを暗号化する必要があります。GKEと EKSは、すでにすべてのデータを静止状態で暗号化しています。この場合、独自のキーを使用するのがベストですが、必須ではありません。データの暗号化(深層防御)

伐採

トピックセキュリティ要件理由
logger Log およびerrorlog は、clickhouseによって定義され、書き込み可能でなければなりません。ログが保存されていることを確認してください。
SIEMGitLab.comでホストされている場合、ClickHouseインスタンスまたはクラスターは私たちのSIEM(内部リンク)にログを報告する必要があります。 GitLab は重要な情報システムのアクティビティを記録します。
機密データのログ機密データをログに記録する場合は、クエリのマスキングルールを使用する必要があります。マスキングルールの例を参照してください。 カラムレベルの暗号化を使用すると、機密データ(キー)がログに漏れる可能性があります。

マスキングルールの例

<query_masking_rules>
    <rule>
        <name>hide SSN</name>
        <regexp>(^|\D)\d{3}-\d{2}-\d{4}($|\D)</regexp>
        <replace>000-00-0000</replace>
    </rule>
    <rule>
        <name>hide encrypt/decrypt arguments</name>
        <regexp>
           ((?:aes_)?(?:encrypt|decrypt)(?:_mysql)?)\s*\(\s*(?:'(?:\\'|.)+'|.*?)\s*\)
        </regexp>
        <replace>\1(???)</replace>
    </rule>
</query_masking_rules>