国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

海量數據下的分庫分表及ClickHouse解決方案

數據庫 MySQL
本文結合業務,尋求海量數據的解決方案。現有業務使用的是MySQL數據庫,且數據量暫時可控,因此目前采用分庫分表的策略。

背景

最近在做的業務中,用戶相關的數據不斷增長,給系統帶來了不小的壓力,在 SQL優化實戰-千萬量級后的慢查 一文中也總結了一些針對慢查的解決方案。但每次活動下來,都會有幾百上千萬的用戶相關數據產生,單純的sql優化已經無法解決,本文站在前人肩膀上,總結了海量數據情景下的解決方案。

分區&分庫分表

目前業務中使用的是MySQL,針對關系型數據庫,可以采用分區或者分庫分表的策略。首先看一下其各自的實現原理及優缺點:

(1)分區

  • 分區原理:分區表是由多個相關的底層表實現,存儲引擎管理分區的各個底層表和管理普通表一樣,只是分區表在各個底層表上各自加上一個相同的索引(分區表要求所有的底層表都必須使用相同的存儲引擎)。
  • 分區優點:它對用戶屏蔽了sharding的細節,即使查詢條件沒有sharding column,它也能正常工作(只是這時候性能一般)。
  • 分區缺點:連接數、網絡吞吐量等資源都受到單機的限制;并發能力遠遠達不到互聯網高并發的要求。(主要因為雖然每個分區可以獨立存儲,但是分區表的總入口還是一個MySQL示例)。
  • 適用場景:并發能力要求不高;數據不是海量(分區數有限,存儲能力就有限)。

(2)分庫分表

互聯網行業處理海量數據的通用方法:分庫分表。 分庫分表中間件全部可以歸結為兩大類型:

  • CLIENT模式;
  • PROXY模式;

CLIENT模式代表有阿里的TDDL,開源社區的sharding-jdbc(sharding-jdbc的3.x版本即sharding-sphere已經支持了proxy模式)。架構如下:

PROXY模式代表有阿里的cobar,民間組織的MyCAT。架構如下:

無論是CLIENT模式,還是PROXY模式。幾個核心的步驟是一樣的:SQL解析重寫路由執行結果歸并

分庫分表實現(MYSQL)

針對分區與分庫分表的適用場景,選擇分庫分表的實現方案。結合實際業務:學生(user表)定期參加體能測試(detect表),每一次體測之后,保留對應檢測數據(data表),因此,數據data表中的核心數據:

data_id

數據ID

user_id

學生ID

detect_id

檢測任務ID

project_id

檢測項目ID,如跳高、跳遠

project_result

檢測結果

分庫分表第一步也是最重要的一步,即sharding column的選取,sharding column選擇的好壞將直接決定整個分庫分表方案最終是否成功。sharding column的選取跟業務強相關。

  • 選擇方法:分析你的API流量,將流量比較大的API對應的SQL提取出來,將這些SQL共同的條件作為sharding column。
  • 選擇示例:例如一般的OLTP系統都是對用戶提供服務,這些API對應的SQL都有條件用戶ID,那么,用戶ID就是非常好的sharding column。

在上述學生體測業務中,我們需要匯總統計一次體測任務中,所有學生各項的體測結果,所以按照上述的原則,需要根據體測任務ID,即detect_id進行分表,以盡量減少在統計一次體測任務的數據時的跨表查詢;但實際業務中,在學生端也有縱向對比的需求,即學生需要查看自己所有參加過的體測任務中的數據,這樣的話,按照detect_id分表,再以user_id作為查詢條件,就需要跨表查詢,效率會很低。因此,最終方案是:不同字段冗余分表

(1)冗余全量表

每個sharding列對應的表的數據都是全量的。以用戶體測數據為例:分別使用三個獨立的sharding column,即data_id(數據ID),detect_id(體測任務ID),user_id(學生ID)。

(2)冗余關系表選擇

只有一個sharding column的分庫分表的數據是全量的,其他分庫分表只是與這個sharding column的關系表。實際使用中可能會冗余更多常用字段,如學生姓名、體測任務名稱等。

(3)冗余全量表 VS 冗余關系表

  • 速度對比:冗余全量表速度更快,冗余關系表需要二次查詢,即使有引入緩存,還是多一次網絡開銷;
  • 存儲成本:冗余全量表需要幾倍于冗余關系表的存儲成本;
  • 維護代價:冗余全量表維護代價更大,涉及到數據變更時,多張表都要進行修改。

選擇冗余全量表還是索引關系表,這是一種架構上的權衡,兩者的優缺點明顯,在我們的業務中采用冗余全量表的方式。

非關系型數據庫(ClickHouse)

上面提到的都是條件中有sharding column的SQL執行。但是,總有一些查詢條件是不包含sharding column的,同時,我們也不可能為了這些請求量并不高的查詢,無限制的冗余分庫分表。另外,在分表前,我們會事先定義好分表的數量,隨著業務擴張,單表數據達到大幾千萬甚至上億,對于MySQL而言,還是不大友好的,再去增加分表數量,也是不大現實的。因此,專業的事情最好還是使用專業的工具-ClickHouse。

ClickHouse 是近年來備受關注的開源列式數據庫,主要用于數據分析(OLAP)領域。目前國內社區火熱,各個大廠紛紛跟進大規模使用:

  • 今日頭條內部用 ClickHouse 來做用戶行為分析,內部一共幾千個 ClickHouse 節點,單集群最大 1200 節點,總數據量幾十 PB,日增原始數據 300TB 左右。
  • 騰訊內部用 ClickHouse 做游戲數據分析,并且為之建立了一整套監控運維體系。
  • 攜程內部從 18 年 7 月份開始接入試用,目前 80% 的業務都跑在 ClickHouse 上。每天數據增量十多億,近百萬次查詢請求。
  • 快手內部也在使用 ClickHouse,存儲總量大約 10PB, 每天新增 200TB, 90% 查詢小于 3S。

在 1 億數據集體量的情況下,ClickHouse 的平均響應速度是 Vertica 的 2.63 倍、InfiniDB 的 17 倍、MonetDB 的 27 倍、Hive 的 126 倍、MySQL 的 429 倍以及Greenplum 的 10 倍。

ClickHouse更多內容參考:https://juejin.cn/post/7120519057761107999

在 OLAP 數據庫中,可變數據通常不受歡迎。ClickHouse 也不歡迎可變數據。然而現實情況,更新情況不可避免。比如,學生在體測過程中,是可以進行重復測試的,即需要進行更新數據。以下是關于clickhouse更新的解決方案:

參考:https://zhuanlan.zhihu.com/p/485645089

(1)Alter/Update Table

ClickHouse團隊在2018年發布了UPDATE和DELETE,但是它不是原生的UPDATE和DELETE語句,而是被實現為ALTER TABLE UPDATE語句,如下所示:

ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr;

如更新檢測結果,ALTER UPDATE語句如下:

ALTER TABLE UPDATE detect_result=1 WHERE detect_id = 1 and user_id=4;

需要注意的是,ClickHouse的更新是一個異步的操作。當用戶執行一個如上的Update操作獲得返回時,ClickHouse內核其實只做了兩件事情:

  • 檢查Update操作是否合法;
  • 保存Update命令到存儲文件中,喚醒一個異步處理merge和mutation的工作線程;

異步線程的工作流程極其復雜,總結其精髓描述如下:先查找到需要update的數據所在datapart,之后對整個datapart做掃描,更新需要變更的數據,然后再將數據重新落盤生成新的datapart,最后用新的datapart做替代并remove掉過期的datapart。

這就是ClickHouse對update指令的執行過程,可以看出,頻繁的update指令對于ClickHouse來說將是災難性的。(當然,我們可以通過設置,將這個異步的過程變成同步的過程,詳細請看:Synchronicity of ALTER Queries,然而同步阻塞就會比較嚴重)。

(2)Incremental Log

Incremental log的思想是什么了?比如對于用戶瀏覽統計表中的一條數據,如下所示:

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐ 
│ 4324182021466249494 │         5 │      146 │    1 │ 
└─────────────────────┴───────────┴──────────┴──────┘

現在有更新了:用戶又瀏覽了一個頁面,所以我們應該改變pageview從5到6,以及持續時間從146到185。那么按照Incremental log的思想,再插入兩行:

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐ 
│ 4324182021466249494 │         5 │      146 │   -1 │ 
│ 4324182021466249494 │         6 │      185 │    1 │ 
└─────────────────────┴───────────┴──────────┴──────┘

第一個是刪除行。它和我們已經得到的行是一樣的只是Sign被設為-1。第二個更新行,所有數據設置為新值。之后我們有三行數據:

┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐ 
│ 4324182021466249494 │         5 │      146 │    1 │ 
│ 4324182021466249494 │         5 │      146 │   -1 │ 
│ 4324182021466249494 │         6 │      185 │    1 │ 
└─────────────────────┴───────────┴──────────┴──────┘

那么對于count,sum,avg的計算方法如下:

-- number of sessions
count() -> sum(Sign)  
-- total number of pages all users checked 
sum(PageViews) -> sum(Sign * PageViews)  
-- average session duration, how long user usually spent on the website 
avg(Duration) -> sum(Sign * Duration) / sum(Sign)

這就是Incremental log方法,這種方法的不足之處在于:

  • 首先需要獲取到原數據,那么就需要先查一遍CK,或者將數據保存到其他存儲中便于檢索查詢,然后我們才可以針對原數據插入一條 ‘delete’ rows;
  • Sign operations在某些計算場景并不適合,比如min、max、quantile等其他場景;
  • 額外的寫入放大:當每個對象的平均更新次數為個位數時,更適合使用。

針對Incremental log方式的寫入方案存儲開銷問題,clickhouse提供了CollapsingMergeTree,使用CollapsingMergeTree,“刪除”行和舊的“刪除”行將在合并過程中折疊。但是,注意這個引擎,只是解決了寫放大問題,并不是說查詢模式就不是Incremental Log這種,我們還是需要通過對sign的特殊計算方式,達到效果。

(3)Insert+xxxMergeTree

用Insert加特定引擎,也可以實現更新效果。該方法適用于xxxMergeTree,如ReplacingMergeTree或AggregatingMergeTree。但是了,更新是異步的。因此剛插入的數據,并不能馬上看到最新的結果,因此并不是準實時的。

比如使用AggregatingMergeTree,用法如下:

CREATE TABLE IF NOT EXISTS whatever_table ON CLUSTER default (     
  user_id UInt64,
  gender SimpleAggregateFunction(anyLast, Nullable(Enum('女' = 0, '男' = 1))),
  ...
)
ENGINE = AggregatingMergeTree() partition by toYYYYMMDD(reg_date) ORDER BY user_id;

就以上建標語句展開分析,AggregatingMergeTree會將除主鍵(user)外的其余列,配合anyLast函數,替換每行數據為一種預聚合狀態。其中anyLast聚合函數聲明聚合策略為保留最后一次的更新數據。

實時性: 非準實時。

優點在于:
ClickHouse提供的這些mergeTree引擎,可以幫助我們達到最終一致性。
缺點在于:
xxxMergeTree并不能保證任何時候的查詢都是聚合過后的結果,并且也沒有提供標志位用于查詢數據的聚合狀態與進度。因此,為了確保數據在查詢前處于已聚合的狀態,還需手動下發optimize指令強制聚合過程的執行。

(4)Insert+xxxxMergeTree+Final

用xxxMergeTree是異步的,如何達到準實時的效果了?ClickHouse提供了FINAL關鍵字來解決這個問題。當指定FINAL后,ClickHouse會在返回結果之前完全合并數據,從而執行給定表引擎合并期間發生的所有數據轉換。

用法

首先Insert數據:

INSERT INTO test_a (*) VALUES (1, 'a', 1) ;

查詢時,加入final關鍵字,如下所示:

SELECT COUNT()FROM test_a FINAL

優缺點

對上述語句,explain后,查詢執行計劃如下所示:

Expression ((Projection + Before ORDER BY))
  Aggregating
    Expression (Before GROUP BY)
      SettingQuotaAndLimits (Set limits and quota after reading from storage)
        Expression (Remove unused columns after reading from storage)
          MergingFinal (Merge rows for FINAL)
            Expression (Calculate sorting key expression)
              ReadFromStorage (MergeTree with final)

從執行計劃可以看出代價比較高:

  • 是一個串行過程;
  • 會進行分區合并;

因此,這個FINAL,也不宜頻繁的使用。

總結

本文結合業務,尋求海量數據的解決方案。現有業務使用的是MySQL數據庫,且數據量暫時可控,因此目前采用分庫分表的策略。同時,也在為日益膨脹的數據做準備,擬采用ClickHouse,并使用Insert+ReplacingMergeTree及查詢中去重的方案解決其更新問題。最后,歡迎有經驗的伙伴多多指點!

責任編輯:姜華 來源: 今日頭條
相關推薦

2022-12-27 11:06:35

海量接口并發

2013-07-26 11:13:29

海量郵件系統數據歸檔解決方案

2022-03-09 21:55:30

HBase數據入倉

2023-08-26 20:08:15

分庫分表Spring

2023-11-03 14:50:14

2024-02-21 12:17:00

2020-12-01 09:03:22

分庫分表MySQL

2022-02-23 08:55:06

數據遷移分庫分表數據庫

2020-07-30 17:59:34

分庫分表SQL數據庫

2018-05-29 08:39:26

DBA數據庫案例

2022-06-15 07:32:24

數據庫分庫分表

2015-07-27 16:56:24

LinuxQQ

2014-06-18 14:33:58

數據保護

2019-12-17 09:29:02

數據庫架構分庫分表

2020-06-24 09:00:43

分庫分表MySQL

2019-11-12 09:54:20

分庫分表數據

2019-01-16 14:00:54

數據庫分庫分表

2024-08-02 15:47:28

數據庫分庫分表

2020-01-07 09:40:25

數據庫MySQLRedis

2024-07-26 00:16:11

點贊
收藏

51CTO技術棧公眾號

欧美日韩免费观看一区三区| 亚洲国产精品综合| 日本成人在线不卡| 无遮挡动作视频在线观看免费入口| 中文字幕一区二区三区日韩精品| 精品一区二区三区欧美| 欧美少妇xxx| 国产有码一区二区| 加勒比日本影视| www.久久爱.com| 奇米一区二区三区| 欧美蜜桃一区二区三区| 亚洲iv一区二区三区| 一个人看的免费视频色| 欧美电影在线观看完整版| 99视频热这里只有精品免费| 日韩一级二级三级精品视频| 国产精品区二区三区日本| 在线观看视频网站你懂得| 色老板在线视频一区二区| 国产日韩欧美麻豆| 色噜噜狠狠狠综合曰曰曰88av| 在线无限看免费粉色视频| 麻豆视频在线观看免费网站| 午夜精品久久久久久久四虎美女版| 亚洲欧美综合另类在线卡通| 久久艳片www.17c.com | 欧美最猛黑人xxxxx猛交| 国产精品永久在线| 免费播放av| 天天操综合520| 国产精品午夜在线| 欧美精品激情在线| 麻豆av免费在线| 国产高清日韩| 久久无码av三级| 久久视频这里只有精品| 免费拍拍拍网站| 久久久人成影片一区二区三区在哪下载 | 少妇高潮 亚洲精品| 波多野结衣 作品| av日韩国产| 免费成人在线视频观看| 精品国产伦一区二区三区观看方式| 久久久99国产精品免费| 91xxx在线观看| 在线国产精品一区| 欧美视频精品在线观看| 成人综合色站| av中文字幕在线| 亚洲理论电影网| 日本道精品一区二区三区| 91高跟黑色丝袜呻吟在线观看| 蜜桃视频在线免费| 亚洲精品影院在线观看| 欧美一区二区三区四区在线观看 | 国产精品99久久| 精品露脸国产偷人在视频| 成人免费视频网| 男同在线观看| 在线观看日韩av电影| 欧美一级日韩不卡播放免费| 天堂精品视频| 成人影院网站| 97久久超碰国产精品| 久热精品视频在线观看一区| 日本男人操女人| 日韩丝袜视频| 亚洲图片有声小说| 91免费看片在线| 日本最新在线视频| 日本午夜一本久久久综合| 精品视频久久久久久| 国产一二三在线视频| 精品国产亚洲一区二区三区在线| 国产精品久久久久久妇女6080| 国产精品国产三级国产专播精品人 | 91欧美激情一区二区三区成人| 欧美日韩不卡合集视频| 国产真实生活伦对白| 热久久天天拍国产| 欧美亚洲丝袜传媒另类| 欧美高清性xxxxhd| 午夜影院在线播放| 久久尤物电影视频在线观看| 欧美一级大胆视频| 成年人在线播放| 亚洲激情不卡| 亚洲精品国产精品久久清纯直播| www成人免费| 57pao国产一区二区| 亚洲男人的天堂网| 岛国视频一区| 日本在线高清| 国产欧美在线观看一区| 国产精品中文字幕久久久| 久久黄色美女电影| 岛国精品在线播放| 欧美一区在线直播| 天天在线视频色| 国产成人av电影在线观看| 国外成人在线直播| 日韩精品系列| 久热成人在线视频| 欧美激情网站在线观看| 亚洲女人天堂在线| 蜜臀久久久99精品久久久久久| 久久天天躁狠狠躁夜夜爽蜜月 | 亚洲一二三区不卡| 久久riav| 国产精品xxx| 一区二区三区毛片| 久久综合入口| 亚洲一区二区av| 亚洲午夜精品久久久久久久久| 国产三级精品在线不卡| 伊人久久av| 亚洲色图在线看| 国产精品区一区| 成人精品三级| 亚洲精品精品亚洲| 免费中文日韩| 蜜桃精品一区二区三区| 精品久久久中文| 一区二区在线观看网站| 91精品短视频| 精品视频一区三区九区| 日韩精品在线视频免费观看| 在线日韩一区| 欧美成人精品二区三区99精品| 免费在线观看毛片网站| 66视频精品| 亚洲另类欧美自拍| 二区中文字幕| 日韩精品电影在线观看| 欧美劲爆第一页| avav免费在线观看| 国产不卡视频在线播放| 国产大片精品免费永久看nba| 国产素人视频在线观看| 久久久99精品久久| 国产综合色一区二区三区| 97精品资源在线观看| 色婷婷精品久久二区二区蜜臂av | 蜜臀av一区二区在线免费观看 | 精品国产欧美日韩| 亚洲第一福利网| 爱爱永久免费视频| 日韩高清一区在线| 91爱爱小视频k| 激情在线视频播放| 亚洲色图一区二区| 视频在线一区二区三区| 色狼人综合干| 亚洲国产精品人久久电影| 国产主播色在线| 理论电影国产精品| 国产精品美女网站| 波多视频一区| 欧美日韩亚洲高清| 精品视频在线观看一区| 午夜久久一区| 久久成人在线视频| 黄色免费在线观看| 中文字幕一区二区三区av| 欧美专区一二三 | 国产精品免费一区豆花| 成人直播视频| 日本高清免费不卡视频| 国产免费黄色av| 99综合在线| 91精品国产亚洲| 国产粉嫩在线观看| 五月综合激情日本mⅴ| 国产91沈先生在线播放| 自拍偷拍欧美专区| 欧美国产日韩在线| av中文在线资源库| 午夜国产精品影院在线观看| 乱妇乱女熟妇熟女网站| 日韩午夜在线| 青青久久av北条麻妃海外网| 永久免费毛片在线播放| 色婷婷综合久久久久中文| 国产真人无码作爱视频免费| 天堂av在线一区| 国产精品视频一区二区三区四 | 成本人h片动漫网站在线观看| 国产精品一区不卡| 成人91视频| 日韩精品丝袜美腿| 亚洲香蕉成人av网站在线观看| 国产在线观看高清视频| 国产精品天干天干在线综合| 亚洲精品一区二区三区樱花 | 亚洲精品日产| 日本精品视频一区二区| 国内外成人免费在线视频| 国产一区二区三区观看| 国产福利久久精品|