بخش اول : معماری، مفاهیم پایه و شروع کار با کلیک‌هوس
بخش دوم : مهارت‌های پیشرفته تحلیلی و آشنایی با انواع انجین‌ها
بخش سوم : مقیاس‌پذیری، امنیت و عملکرد در محیط عملیاتی
کارگاه‌ها و مثال‌های کاربردی

کارگاه عملی : آشنایی با مکانیزم تکرار داده‌‌ها (Replication) در ClickHouse

ClickHouse یک پایگاه داده تحلیلی توزیع‌شده و بسیار سریع است که برای پردازش داده‌های بزرگ در محیط‌های OLAP طراحی شده است. یکی از قابلیت‌های کلیدی آن Replication یا تکرار داده‌ها است که باعث می‌شود داده‌ها در چند نود ذخیره شوند تا هم دسترسی بالا فراهم شود و هم تحمل خطا در نودها ممکن باشد.

در این کارگاه عملی، ما یک کلاستر با ۴ نود، ۲ شارد و ۲ رپلیکا برای هر شارد ایجاد می‌کنیم و با مکانیزم توزیع و رپلیکیشن داده‌ها در ClickHouse آشنا می‌شویم.


مکانیزم پشت صحنه Replication

در ClickHouse، هر جدول می‌تواند روی چند نود توزیع شود. برای افزایش دسترس‌پذیری و تحمل خطا، از ReplicatedMergeTree استفاده می‌کنیم.

  • هر شارد می‌تواند یک یا چند رپلیکا داشته باشد.
  • رپلیکاها به کمک ClickHouse Keeper (یا Zookeeper) با هم هماهنگ می‌شوند تا داده‌ها و متادیتای جدول در همه رپلیکاها یکسان باشد.
  • Distributed Table نقش پروکسی را ایفا می‌کند: هیچ داده‌ای خودش ذخیره نمی‌کند، بلکه کوئری‌ها را به شاردها ارسال می‌کند و نتایج را جمع‌آوری می‌کند.
  • هنگام درج داده، رپلیکیشن به صورت خودکار داده را به همه رپلیکاهای شارد مربوطه کپی می‌کند.

نکته مهم: برای اینکه رپلیکیشن درست کار کند، هر نود باید ماکروها و کانفیگ مخصوص خود را داشته باشد و مسیر ZooKeeper (یا ClickHouse Keeper) برای هر جدول منحصر به شارد و رپلیکا باشد.


۱. پیکربندی سرورها

در این کارگاه، چهار نود داریم:

نودشاردرپلیکا
chnode1۱replica_1
chnode3۱replica_2
chnode2۲replica_1
chnode4۲replica_2

ابتدا در فایل کانفیگ هر نود، بخش remote_servers را مطابق ساختار کلاستر به روز می‌کنیم:

<clickhouse>
  <remote_servers replace="true">
    <cluster_2S_2R>
      <!-- Shard 1 -->
      <shard>
        <internal_replication>true</internal_replication>
        <replica><host>chnode1</host><port>9000</port></replica>
        <replica><host>chnode3</host><port>9000</port></replica>
      </shard>

      <!-- Shard 2 -->
      <shard>
        <internal_replication>true</internal_replication>
        <replica><host>chnode2</host><port>9000</port></replica>
        <replica><host>chnode4</host><port>9000</port></replica>
      </shard>
    </cluster_2S_2R>
  </remote_servers>
</clickhouse>

توجه: هر نود یک پوشه کانفیگ مجزا دارد، و تنظیمات باید بر اساس نقش آن نود در شارد و رپلیکا متفاوت باشد.


۲. پیکربندی Macros

در فایل macros.xml هر نود، اطلاعات شارد و رپلیکا خود را تعریف می‌کنیم:

  • Node 1 (chnode1)
<macros>
  <shard>1</shard>
  <replica>replica_1</replica>
</macros>
  • Node 3 (chnode3)
<macros>
  <shard>1</shard>
  <replica>replica_2</replica>
</macros>
  • Node 2 (chnode2)
<macros>
  <shard>2</shard>
  <replica>replica_1</replica>
</macros>
  • Node 4 (chnode4)
<macros>
  <shard>2</shard>
  <replica>replica_2</replica>
</macros>

۳. تعریف جدول‌های توزیع و تکرارشده

۳.۱ جدول محلی (Local Table)
CREATE TABLE rides.trips_local ON CLUSTER 'cluster_2S_2R'
(
    VendorID Int32,
    tpep_pickup_datetime DateTime64(6),
    tpep_dropoff_datetime DateTime64(6),
    passenger_count Nullable(Int64),
    trip_distance Nullable(Float64),
    RatecodeID Nullable(Int64),
    store_and_fwd_flag Nullable(String),
    PULocationID Int32,
    DOLocationID Int32,
    payment_type Nullable(Int64),
    fare_amount Nullable(Float64),
    extra Nullable(Float64),
    mta_tax Nullable(Float64),
    tip_amount Nullable(Float64),
    tolls_amount Nullable(Float64),
    improvement_surcharge Nullable(Float64),
    total_amount Nullable(Float64),
    congestion_surcharge Nullable(Float64),
    Airport_fee Nullable(Float64)
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/rides/trips_local', '{replica}')
PARTITION BY toYYYYMM(tpep_pickup_datetime)
ORDER BY (tpep_pickup_datetime, tpep_dropoff_datetime, PULocationID, DOLocationID)
SETTINGS index_granularity = 8192;
  • مسیر /clickhouse/tables/{shard}/rides/trips_local مخصوص هر شارد است.
  • {replica} با نام رپلیکای نود جایگزین می‌شود.
۳.۲ جدول توزیع شده (Distributed Table)
CREATE TABLE rides.trips_distributed ON CLUSTER 'cluster_2S_2R'
AS rides.trips_local
ENGINE = Distributed('cluster_2S_2R', rides, trips_local, toMonth(tpep_pickup_datetime) % 2);

Distributed Table داده را نگه نمی‌دارد، فقط کوئری‌ها را به شاردها هدایت می‌کند.


۴. درج داده‌ها

برای وارد کردن داده به کلاستر، از جدول توزیع شده استفاده می‌کنیم:

INSERT INTO rides.trips_distributed
FROM INFILE '/var/lib/clickhouse/user_files/nyc_taxi/*.parquet'
FORMAT Parquet;
  • داده‌ها به طور خودکار بین رپلیکاهای هر شارد کپی می‌شوند.
  • حتی اگر یکی از نودها خاموش باشد، داده در رپلیکاهای دیگر ثبت می‌شود و دسترسی همچنان برقرار است.

۵. بررسی وضعیت رپلیکیشن

برای اطمینان از اینکه همه جداول دارای رپلیکا هستند:

SELECT 
    database,
    table,
    is_leader,
    total_replicas,
    active_replicas,
    is_readonly
FROM system.replicas
WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA')
ORDER BY database, table;
  • total_replicas = 2 → هر شارد دو رپلیکا دارد
  • active_replicas = 2 → همه رپلیکاها فعال هستند

جمع‌بندی

با این کارگاه:

  1. ساختار ۴ نود، ۲ شارد، ۲ رپلیکا ایجاد شد.
  2. داده‌ها به صورت خودکار بین رپلیکاها توزیع و همگام‌سازی شدند.
  3. جدول Distributed نقش پروکسی را برای اجرای کوئری‌ها ایفا می‌کند.
  4. از ClickHouse Keeper برای هماهنگی رپلیکیشن و مدیریت متادیتا استفاده شد.

نکته حرفه‌ای: اگر بعداً تعداد نودها یا شاردها تغییر کند، باید جدول‌های توزیع شده دوباره ساخته شوند تا فرمول توزیع (Shard Key) بر اساس تعداد جدید نودها اعمال شود.

فروشگاه
جستجو
دوره ها

لطفا کلمات کلیدی را وارد کنید