開箱即用的 GoWind Admin|風(fēng)行,企業(yè)級前后端一體中后臺框架:ClickHouse集成指南

開箱即用的 GoWind Admin|風(fēng)行,企業(yè)級前后端一體中后臺框架:ClickHouse集成指南

ClickHouse 是一款由俄羅斯搜索引擎公司 Yandex 開發(fā)的開源列式存儲數(shù)據(jù)庫,專為海量數(shù)據(jù)實(shí)時(shí)分析設(shè)計(jì)。它以極致的查詢性能高吞吐寫入能力著稱,尤其擅長處理PB 級別的結(jié)構(gòu)化數(shù)據(jù),并能在毫秒到秒級內(nèi)完成復(fù)雜的聚合分析(如多維度統(tǒng)計(jì)、漏斗計(jì)算、用戶行為分析等),是大數(shù)據(jù)分析、數(shù)據(jù)倉庫、實(shí)時(shí)報(bào)表等場景的核心工具。

ClickHouse 的核心概念

概念 說明
表(Table) 類似關(guān)系型數(shù)據(jù)庫的表,存儲結(jié)構(gòu)化數(shù)據(jù),但底層按列存儲。
引擎(Engine) 決定表的存儲方式、查詢特性和分布式行為,是 ClickHouse 的核心設(shè)計(jì)。例如:
- MergeTree 系列:最常用,支持索引、分區(qū)、副本,適合海量數(shù)據(jù)存儲;
- Log 系列:輕量無索引,適合臨時(shí)小表;
- Distributed:分布式表,用于管理集群分片。
分區(qū)(Partition) 按規(guī)則(如時(shí)間、地區(qū))將表數(shù)據(jù)拆分,查詢時(shí)可快速過濾分區(qū),減少掃描范圍(如按 “日期” 分區(qū),查詢 “2023 年 10 月數(shù)據(jù)” 僅需掃描對應(yīng)分區(qū))。
主鍵(Primary Key) 用于排序和快速查找,不同于關(guān)系型數(shù)據(jù)庫的唯一約束,ClickHouse 主鍵允許重復(fù),主要作用是優(yōu)化查詢性能。
跳數(shù)索引(Skip Index) 輔助索引,用于快速判斷某一范圍內(nèi)是否存在符合條件的數(shù)據(jù)(如 “數(shù)值是否在 100-200 之間”),進(jìn)一步減少掃描量。
分片(Shard) 集群中數(shù)據(jù)的物理拆分單位,每個(gè)分片存儲表的一部分?jǐn)?shù)據(jù),分布在不同節(jié)點(diǎn),實(shí)現(xiàn)并行處理。
副本(Replica) 同一分片的冗余備份,用于故障恢復(fù)和負(fù)載均衡(查詢可分散到不同副本),保證數(shù)據(jù)不丟失。

ClickHouse 與其他數(shù)據(jù)庫的差異

維度 ClickHouse 傳統(tǒng)關(guān)系型數(shù)據(jù)庫(如 MySQL) Hadoop 生態(tài)(如 Hive)
核心場景 實(shí)時(shí)海量數(shù)據(jù)分析(PB 級,毫秒 / 秒級響應(yīng)) 事務(wù)性業(yè)務(wù)(增刪改查,強(qiáng)一致性) 離線批處理分析(TB/PB 級,分鐘 / 小時(shí)級)
存儲方式 列式存儲,高壓縮 行式存儲,壓縮率低 列式存儲(ORC/Parquet),壓縮率高
寫入特性 高吞吐,近實(shí)時(shí),不支持事務(wù) 支持事務(wù),寫入性能適中 批處理寫入,延遲高
查詢性能 極致的聚合查詢速度 適合單行 / 小批量查詢,復(fù)雜分析慢 支持復(fù)雜分析,但速度慢(依賴 MapReduce/Spark)
靈活性 不支持行級更新 / 刪除,事務(wù)弱 支持行級增刪改查,事務(wù)強(qiáng) 不支持實(shí)時(shí)更新,靈活性低

Docker部署

docker pull bitnami/clickhouse:latest

docker run -itd \
    --name clickhouse-server \
    --network=app-tier \
    -p 8123:8123 \
    -p 9000:9000 \
    -p 9004:9004 \
    -e ALLOW_EMPTY_PASSWORD=no \
    -e CLICKHOUSE_ADMIN_USER=default \
    -e CLICKHOUSE_ADMIN_PASSWORD=123456 \
    bitnami/clickhouse:latest

在 Go Wind Admin 中使用 ClickHouse

我把ClickHouse的SDK封裝了起來,并且提供了配置文件的支持,使用起來非常簡單。

ClickHouse支持go的sql標(biāo)準(zhǔn)庫更新查詢,但是,會有一些限制,比如不支持事務(wù)等。所以,想要完整的功能,還是需要使用ClickHouse的官方SDK。因此,我們僅提供了原生的ClickHouse SDK 封裝。

首先,我們需要安裝庫:

go get github.com/tx7do/kratos-bootstrap/database/clickhouse

接著在數(shù)據(jù)庫的配置文件data.yaml中添加ClickHouse的配置:

data:
  clickhouse:
    addresses:
      - "localhost:9000"
    username: "default"
    password: "123456"
    database: "finances"

添加好了配置之后,我們就可以在data包里面創(chuàng)建Clickhouse的客戶端了:

package data

import (
    "github.com/tx7do/kratos-bootstrap/database/clickhouse"
)

func NewClickHouseClient(logger log.Logger, cfg *conf.Bootstrap) *clickhouse.Client {
    cli, err := clickhouse.NewClient(logger, cfg)
    if err != nil {
        return nil
    }
    return cli
}

data/init.go注入到wire:

//go:build wireinject
// +build wireinject

package data

import "github.com/google/wire"

var ProviderSet = wire.NewSet(
    NewClickHouseClient,
)

在這里,我們以股票的K線(蠟燭圖)為實(shí)例,來講解如何使用ClickHouse。

首先,定義模型:

package data

import "time"

type Candle struct {
    Timestamp *time.Time `json:"timestamp" ch:"timestamp"`
    Symbol    *string    `json:"symbol" ch:"symbol"`
    Open      *float64   `json:"open" ch:"open"`
    High      *float64   `json:"high" ch:"high"`
    Low       *float64   `json:"low" ch:"low"`
    Close     *float64   `json:"close" ch:"close"`
    Volume    *float64   `json:"volume" ch:"volume"`
}

最后,實(shí)現(xiàn)CandleRepo

package data

import (
    "github.com/go-kratos/kratos/v2/log"
    "github.com/tx7do/kratos-bootstrap/database/clickhouse"
)

const candleTableName = "candles"

type CandleRepo struct {
    client *clickhouse.Client
    log    *log.Helper
}

func NewCandleRepo(logger log.Logger, client *clickhouse.Client) *CandleRepo {
    repo := &CandleRepo{
        log:    log.NewHelper(log.With(logger, "module", "candle/ck/repo")),
        client: client,
    }

    return repo
}

func (r *CandleRepo) Create(ctx context.Context, req *Candle) error {
    if req == nil {
        return candleV1.ErrorBadRequest("request data is required")
    }

    err := r.client.Insert(ctx, candleTableName, "", req)
    if err != nil {
        r.log.Errorf("create candle failed: %s", err.Error())
        return candleV1.ErrorInternalServerError("create candle failed")
    }
    return nil
}

項(xiàng)目代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容