1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        ES不香嗎,為啥還要ClickHouse?

        共 8043字,需瀏覽 17分鐘

         ·

        2021-12-23 14:21

        點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)

        作者:Gang Tao 編輯:陶家龍

        來(lái)源:zhuanlan.zhihu.com/p/353296392


        Elasticsearch是一個(gè)實(shí)時(shí)的分布式搜索分析引擎,它的底層是構(gòu)建在 Lucene 之上的。簡(jiǎn)單來(lái)說(shuō)是通過(guò)擴(kuò)展 Lucene 的搜索能力,使其具有分布式的功能。

        ES 通常會(huì)和其它兩個(gè)開(kāi)源組件 Logstash(日志采集)和 Kibana(儀表盤(pán))一起提供端到端的日志/搜索分析的功能,常常被簡(jiǎn)稱為 ELK。

        Clickhouse 是俄羅斯搜索巨頭 Yandex 開(kāi)發(fā)的面向列式存儲(chǔ)的關(guān)系型數(shù)據(jù)庫(kù)。ClickHouse 是過(guò)去兩年中 OLAP 領(lǐng)域中最熱門(mén)的,并于 2016 年開(kāi)源。

        ES 是最為流行的大數(shù)據(jù)日志和搜索解決方案,但是近幾年來(lái),它的江湖地位受到了一些挑戰(zhàn),許多公司已經(jīng)開(kāi)始把自己的日志解決方案從 ES 遷移到了 Clickhouse,這里就包括:攜程,快手等公司。

        架構(gòu)和設(shè)計(jì)的對(duì)比


        ES 的底層是 Lucenc,主要是要解決搜索的問(wèn)題。搜索是大數(shù)據(jù)領(lǐng)域要解決的一個(gè)常見(jiàn)的問(wèn)題,就是在海量的數(shù)據(jù)量要如何按照條件找到需要的數(shù)據(jù)。搜索的核心技術(shù)是倒排索引和布隆過(guò)濾器。

        ES 通過(guò)分布式技術(shù),利用分片與副本機(jī)制,直接解決了集群下搜索性能與高可用的問(wèn)題。
        ElasticSearch 是為分布式設(shè)計(jì)的,有很好的擴(kuò)展性,在一個(gè)典型的分布式配置中,每一個(gè)節(jié)點(diǎn)(node)可以配制成不同的角色。
        如上圖所示:
        • Client Node,負(fù)責(zé) API 和數(shù)據(jù)的訪問(wèn)的節(jié)點(diǎn),不存儲(chǔ)/處理數(shù)據(jù)。

        • Data Node,負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和索引。

        • Master Node,管理節(jié)點(diǎn),負(fù)責(zé) Cluster 中的節(jié)點(diǎn)的協(xié)調(diào),不存儲(chǔ)數(shù)據(jù)。


        ClickHouse 是基于 MPP 架構(gòu)的分布式 ROLAP(關(guān)系 OLAP)分析引擎。每個(gè)節(jié)點(diǎn)都有同等的責(zé)任,并負(fù)責(zé)部分?jǐn)?shù)據(jù)處理(不共享任何內(nèi)容)。

        ClickHouse 是一個(gè)真正的列式數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)。在 ClickHouse 中,數(shù)據(jù)始終是按列存儲(chǔ)的,包括矢量(向量或列塊)執(zhí)行的過(guò)程。

        讓查詢變得更快,最簡(jiǎn)單且有效的方法是減少數(shù)據(jù)掃描范圍和數(shù)據(jù)傳輸時(shí)的大小,而列式存儲(chǔ)和數(shù)據(jù)壓縮就可以幫助實(shí)現(xiàn)上述兩點(diǎn)。

        Clickhouse 同時(shí)使用了日志合并樹(shù),稀疏索引和 CPU 功能(如 SIMD 單指令多數(shù)據(jù))充分發(fā)揮了硬件優(yōu)勢(shì),可實(shí)現(xiàn)高效的計(jì)算。

        Clickhouse 使用 Zookeeper 進(jìn)行分布式節(jié)點(diǎn)之間的協(xié)調(diào)。
        為了支持搜索,Clickhouse 同樣支持布隆過(guò)濾器。

        查詢對(duì)比實(shí)戰(zhàn)


        為了對(duì)比 ES 和 Clickhouse 的基本查詢能力的差異,我寫(xiě)了一些代碼來(lái)驗(yàn)證:
        https://github.com/gangtao/esvsch

        這個(gè)測(cè)試的架構(gòu)如下:
        架構(gòu)主要有四個(gè)部分組成:

        ①ES stack

        ES stack 有一個(gè)單節(jié)點(diǎn)的 Elastic 的容器和一個(gè) Kibana 容器組成,Elastic 是被測(cè)目標(biāo)之一,Kibana 作為驗(yàn)證和輔助工具。

        部署代碼如下:
        version:?'3.7'

        services:
        ??elasticsearch:
        ????image:?docker.elastic.co/elasticsearch/elasticsearch:7.4.0
        ????container_name:?elasticsearch
        ????environment:
        ??????-?xpack.security.enabled=false
        ??????-?discovery.type=single-node
        ????ulimits:
        ??????memlock:
        ????????soft:?-1
        ????????hard:?-1
        ??????nofile:
        ????????soft:?65536
        ????????hard:?65536
        ????cap_add:
        ??????-?IPC_LOCK
        ????volumes:
        ??????-?elasticsearch-data:/usr/share/elasticsearch/data
        ????ports:
        ??????-?9200:9200
        ??????-?9300:9300
        ????deploy:
        ??????resources:
        ????????limits:
        ??????????cpus:?'4'
        ??????????memory:?4096M
        ????????reservations:
        ??????????memory:?4096M

        ??kibana:
        ????container_name:?kibana
        ????image:?docker.elastic.co/kibana/kibana:7.4.0
        ????environment:
        ??????-?ELASTICSEARCH_HOSTS=http://elasticsearch:9200
        ????ports:
        ??????-?5601:5601
        ????depends_on:
        ??????-?elasticsearch

        volumes:
        ??elasticsearch-data:
        ????driver:?local

        ②Clickhouse stack

        Clickhouse stack 有一個(gè)單節(jié)點(diǎn)的 Clickhouse 服務(wù)容器和一個(gè) TabixUI 作為 Clickhouse 的客戶端。

        部署代碼如下:
        version:?"3.7"
        services:
        ??clickhouse:
        ????container_name:?clickhouse
        ????image:?yandex/clickhouse-server
        ????volumes:
        ??????-?./data/config:/var/lib/clickhouse
        ????ports:
        ??????-?"8123:8123"
        ??????-?"9000:9000"
        ??????-?"9009:9009"
        ??????-?"9004:9004"
        ????ulimits:
        ??????nproc:?65535
        ??????nofile:
        ????????soft:?262144
        ????????hard:?262144
        ????healthcheck:
        ??????test:?["CMD",?"wget",?"--spider",?"-q",?"localhost:8123/ping"]
        ??????interval:?30s
        ??????timeout:?5s
        ??????retries:?3
        ????deploy:
        ??????resources:
        ????????limits:
        ??????????cpus:?'4'
        ??????????memory:?4096M
        ????????reservations:
        ??????????memory:?4096M

        ??tabixui:
        ????container_name:?tabixui
        ????image:?spoonest/clickhouse-tabix-web-client
        ????environment:
        ??????-?CH_NAME=dev
        ??????-?CH_HOST=127.0.0.1:8123
        ??????-?CH_LOGIN=default
        ????ports:
        ??????-?"18080:80"
        ????depends_on:
        ??????-?clickhouse
        ????deploy:
        ??????resources:
        ????????limits:
        ??????????cpus:?'0.1'
        ??????????memory:?128M
        ????????reservations:
        ??????????memory:?128M

        ③數(shù)據(jù)導(dǎo)入 stack

        數(shù)據(jù)導(dǎo)入部分使用了 Vector.dev 開(kāi)發(fā)的 vector,該工具和 fluentd 類似,都可以實(shí)現(xiàn)數(shù)據(jù)管道式的靈活的數(shù)據(jù)導(dǎo)入。

        ④測(cè)試控制 stack

        測(cè)試控制我使用了 Jupyter,使用了 ES 和 Clickhouse 的 Python SDK 來(lái)進(jìn)行查詢的測(cè)試。

        用 Docker compose 啟動(dòng) ES 和 Clickhouse 的 stack 后,我們需要導(dǎo)入數(shù)據(jù),我們利用 Vector 的 generator 功能,生成 syslog,并同時(shí)導(dǎo)入 ES 和 Clickhouse。

        在這之前,我們需要在 Clickhouse 上創(chuàng)建表。ES 的索引沒(méi)有固定模式,所以不需要事先創(chuàng)建索引。

        創(chuàng)建表的代碼如下:
        CREATE?TABLE?default.syslog(
        ????application?String,
        ????hostname?String,
        ????message?String,
        ????mid?String,
        ????pid?String,
        ????priority?Int16,
        ????raw?String,
        ????timestamp?DateTime('UTC'),
        ????version?Int16
        )?ENGINE?=?MergeTree()
        ????PARTITION?BY?toYYYYMMDD(timestamp)
        ????ORDER?BY?timestamp
        ????TTL?timestamp?+?toIntervalMonth(1);

        創(chuàng)建好表之后,我們就可以啟動(dòng) vector,向兩個(gè) stack 寫(xiě)入數(shù)據(jù)了。vector 的數(shù)據(jù)流水線的定義如下:
        [sources.in]
        ??type?=?"generator"
        ??format?=?"syslog"
        ??interval?=?0.01
        ??count?=?100000

        [transforms.clone_message]
        ??type?=?"add_fields"
        ??inputs?=?["in"]
        ??fields.raw?=?"{{?message?}}"

        [transforms.parser]
        ??#?General
        ??type?=?"regex_parser"
        ??inputs?=?["clone_message"]
        ??field?=?"message"?#?optional,?default
        ??patterns?=?['^<(?P\d*)>(?P\d)?(?P\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z)?(?P\w+\.\w+)?(?P\w+)?(?P\d+)?(?PID\d+)?-?(?P.*)$']

        [transforms.coercer]
        ??type?=?"coercer"
        ??inputs?=?["parser"]
        ??types.timestamp?=?"timestamp"
        ??types.version?=?"int"
        ??types.priority?=?"int"

        [sinks.out_console]
        ??#?General
        ??type?=?"console"
        ??inputs?=?["coercer"]?
        ??target?=?"stdout"?

        ??#?Encoding
        ??encoding.codec?=?"json"?


        [sinks.out_clickhouse]
        ??host?=?"http://host.docker.internal:8123"
        ??inputs?=?["coercer"]
        ??table?=?"syslog"
        ??type?=?"clickhouse"

        ??encoding.only_fields?=?["application",?"hostname",?"message",?"mid",?"pid",?"priority",?"raw",?"timestamp",?"version"]
        ??encoding.timestamp_format?=?"unix"

        [sinks.out_es]
        ??#?General
        ??type?=?"elasticsearch"
        ??inputs?=?["coercer"]
        ??compression?=?"none"?
        ??endpoint?=?"http://host.docker.internal:9200"?
        ??index?=?"syslog-%F"

        ??#?Encoding

        ??#?Healthcheck
        ??healthcheck.enabled?=?true

        這里簡(jiǎn)單介紹一下這個(gè)流水線:
        • source.in:生成 syslog 的模擬數(shù)據(jù),生成 10w 條,生成間隔和 0.01 秒。

        • transforms.clone_message:把原始消息復(fù)制一份,這樣抽取的信息同時(shí)可以保留原始消息。

        • transforms.parser:使用正則表達(dá)式,按照 syslog 的定義,抽取出 application,hostname,message,mid,pid,priority,timestamp,version 這幾個(gè)字段。

        • transforms.coercer:數(shù)據(jù)類型轉(zhuǎn)化。

        • sinks.out_console:把生成的數(shù)據(jù)打印到控制臺(tái),供開(kāi)發(fā)調(diào)試。

        • sinks.out_clickhouse:把生成的數(shù)據(jù)發(fā)送到Clickhouse。

        • sinks.out_es:把生成的數(shù)據(jù)發(fā)送到 ES。


        運(yùn)行 Docker 命令,執(zhí)行該流水線:

        docker?run?\
        ????????-v?$(mkfile_path)/vector.toml:/etc/vector/vector.toml:ro?\
        ????????-p?18383:8383?\
        ????????timberio/vector:nightly-alpine


        數(shù)據(jù)導(dǎo)入后,我們針對(duì)一下的查詢來(lái)做一個(gè)對(duì)比。ES 使用自己的查詢語(yǔ)言來(lái)進(jìn)行查詢,Clickhouse 支持 SQL,我簡(jiǎn)單測(cè)試了一些常見(jiàn)的查詢,并對(duì)它們的功能和性能做一些比較。

        返回所有的記錄:
        #?ES
        {
        ??"query":{
        ????"match_all":{}
        ??}
        }

        #?Clickhouse?
        "SELECT?*?FROM?syslog"

        匹配單個(gè)字段:
        #?ES
        {
        ??"query":{
        ????"match":{
        ??????"hostname":"for.org"
        ????}
        ??}
        }

        #?Clickhouse?
        "SELECT?*?FROM?syslog?WHERE?hostname='for.org'"

        匹配多個(gè)字段:
        #?ES
        {
        ??"query":{
        ????"multi_match":{
        ??????"query":"up.com?ahmadajmi",
        ????????"fields":[
        ??????????"hostname",
        ??????????"application"
        ????????]
        ????}
        ??}
        }

        #?Clickhouse、
        "SELECT?*?FROM?syslog?WHERE?hostname='for.org'?OR?application='ahmadajmi'"

        單詞查找,查找包含特定單詞的字段:
        #?ES
        {
        ??"query":{
        ????"term":{
        ??????"message":"pretty"
        ????}
        ??}
        }

        #?Clickhouse
        "SELECT?*?FROM?syslog?WHERE?lowerUTF8(raw)?LIKE?'%pretty%'"

        范圍查詢,查找版本大于 2 的記錄:
        #?ES
        {
        ??"query":{
        ????"range":{
        ??????"version":{
        ????????"gte":2
        ??????}
        ????}
        ??}
        }

        #?Clickhouse
        "SELECT?*?FROM?syslog?WHERE?version?>=?2"

        查找到存在某字段的記錄:
        #?ES
        {
        ??"query":{
        ????"exists":{
        ??????"field":"application"
        ????}
        ??}
        }

        #?Clickhouse
        "SELECT?*?FROM?syslog?WHERE?application?is?not?NULL"

        ES 是文檔類型的數(shù)據(jù)庫(kù),每一個(gè)文檔的模式不固定,所以會(huì)存在某字段不存在的情況;而 Clickhouse 對(duì)應(yīng)為字段為空值。

        正則表達(dá)式查詢,查詢匹配某個(gè)正則表達(dá)式的數(shù)據(jù):
        #?ES
        {
        ??"query":{
        ????"regexp":{
        ??????"hostname":{
        ????????"value":"up.*",
        ??????????"flags":"ALL",
        ????????????"max_determinized_states":10000,
        ??????????????"rewrite":"constant_score"
        ??????}
        ????}
        ??}
        }

        #?Clickhouse
        "SELECT?*?FROM?syslog?WHERE?match(hostname,?'up.*')"

        聚合計(jì)數(shù),統(tǒng)計(jì)某個(gè)字段出現(xiàn)的次數(shù):
        #?ES
        {
        ??"aggs":{
        ????"version_count":{
        ??????"value_count":{
        ????????"field":"version"
        ??????}
        ????}
        ??}
        }

        #?Clickhouse
        "SELECT?count(version)?FROM?syslog"

        聚合不重復(fù)的值,查找所有不重復(fù)的字段的個(gè)數(shù):
        #?ES
        {
        ??"aggs":{
        ????"my-agg-name":{
        ??????"cardinality":{
        ????????"field":"priority"
        ??????}
        ????}
        ??}
        }

        #?Clickhouse
        "SELECT?count(distinct(priority))?FROM?syslog?"

        我用 Python 的 SDK,對(duì)上述的查詢?cè)趦蓚€(gè) Stack 上各跑 10 次,然后統(tǒng)計(jì)查詢的性能結(jié)果。

        我們畫(huà)出出所有的查詢的響應(yīng)時(shí)間的分布:
        總查詢時(shí)間的對(duì)比如下:
        通過(guò)測(cè)試數(shù)據(jù)我們可以看出 Clickhouse 在大部分的查詢的性能上都明顯要優(yōu)于 Elastic。

        在正則查詢(Regex query)和單詞查詢(Term query)等搜索常見(jiàn)的場(chǎng)景下,也并不遜色。

        在聚合場(chǎng)景下,Clickhouse 表現(xiàn)異常優(yōu)秀,充分發(fā)揮了列村引擎的優(yōu)勢(shì)。

        注意,我的測(cè)試并沒(méi)有任何優(yōu)化,對(duì)于 Clickhouse 也沒(méi)有打開(kāi)布隆過(guò)濾器??梢?jiàn) Clickhouse 確實(shí)是一款非常優(yōu)秀的數(shù)據(jù)庫(kù),可以用于某些搜索的場(chǎng)景。

        當(dāng)然 ES 還支持非常豐富的查詢功能,這里只有一些非?;镜牟樵?,有些查詢可能存在無(wú)法用 SQL 表達(dá)的情況。

        總結(jié)


        本文通過(guò)對(duì)于一些基本查詢的測(cè)試,對(duì)比了 Clickhouse 和 Elasticsearch 的功能和性能。

        測(cè)試結(jié)果表明,Clickhouse 在這些基本場(chǎng)景表現(xiàn)非常優(yōu)秀,性能優(yōu)于 ES,這也解釋了為什么用很多的公司應(yīng)從 ES 切換到 Clickhouse 之上。


        1、Log4j2維護(hù)者吐槽沒(méi)工資還要挨罵,GO安全負(fù)責(zé)人建議開(kāi)源作者向公司收費(fèi)

        2、太難了!讓程序員崩潰的8個(gè)瞬間

        3、2021年程序員們都在用的神級(jí)數(shù)據(jù)庫(kù)

        4、Windows重要功能被閹割,全球用戶怒噴數(shù)月后微軟終于悔改

        5、牛逼!國(guó)產(chǎn)開(kāi)源的遠(yuǎn)程桌面火了,只有9MB 支持自建中繼器!

        6、摔到老三的 Java,未來(lái)在哪?

        7、真香!用 IDEA 神器看源碼,效率真高!

        點(diǎn)分享

        點(diǎn)收藏

        點(diǎn)點(diǎn)贊

        點(diǎn)在看

        瀏覽 52
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            娇妻被健身教练挺进嗯啊视频 | 午夜成年人视频 | 天堂w妖精外观加属性吗 | 中文无码观看 | 操操操操操逼 | 国产娇小性色xxxxx视频 | 爱啪综合 | 男女在线视频 | AAAAAAA免费看片看最后的 | 一个添两个吃奶扒开腿视频 |