自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我用ClickHouse JDBC官方驅(qū)動,踩坑無數(shù)。。

開發(fā) 前端
最近遇到一個ClickHouse的線上問題:Code: 242, e.displayText() = DB::Exception: Table is in readonly mode(zookeeper path:/clickhouse/tables/02/xxx) (version 21.12.4.1) (official build)這個問題我在網(wǎng)上查原因說是由于Zookeeper壓力過大

?前言

最近遇到一個ClickHouse的線上問題:Code: 242, e.displayText() = DB::Exception: Table is in readonly mode(zookeeper path:/clickhouse/tables/02/xxx) (version 21.12.4.1) (official build)

這個問題我在網(wǎng)上查原因說是由于Zookeeper?壓力過大,表變成只讀狀態(tài),導(dǎo)致ClickHouse插入數(shù)據(jù)失敗。

具體原因有兩個:

  • 寫入數(shù)據(jù)頻率過高。
  • Zookeeper中的集群節(jié)點掛掉。

而我們項目出現(xiàn)這個問題的原因是第一個:寫入數(shù)據(jù)頻率過高。

但是在網(wǎng)上搜資料的過程中,我又發(fā)現(xiàn)了另外一個問題:我們項目用了JDBC驅(qū)動?Maven groupId ru.yandex.clickhouse?,但ClickHouse官方并不推薦。

于是我果斷的訪問了ClickHouse的官網(wǎng),通過它訪問了ClickHouse的GitHub地址:https://github.com/ClickHouse/clickhouse-jdbc。

證實了官網(wǎng)確實不建議使用ru.yandex.clickhouse?驅(qū)動:

圖片

而應(yīng)該改成?com.clickhouse?驅(qū)動,并且推薦使用0.3.2?以上的版本:

圖片

于是,后面幾天開始了?ClickHouse的JDBC驅(qū)動升級之旅。踩了不少坑,拿出來跟大家一起分享一下,希望對你會有所幫助。

1. 第一次升級

ClickHouse?官方GitHub上面推薦使用的JDBC驅(qū)動是0.3.2?以上的版本:

圖片

于是,我果斷把項目中的?pom.xml?文件中的groupId?換成了com.clickhouse?,版本換成了0.3.2。

刷新了一下maven,本地啟動項目,能夠正常運行。

然后在本地測試了一下業(yè)務(wù)功能,能夠正常從ClickHouse中讀取和寫入數(shù)據(jù)。

心里不禁在想:這次升級實在太容易了。

2. 第二次升級

后來,項目組的同事建議換成最新版本,說有更多新功能,并且性能有很大提升。

我聽到性能有很大提升這幾個字,就決定再升級試試。

于是,把版本升級成了0.3.2-patch11。

在本地再次測試,業(yè)務(wù)功能一切正常。

然后把項目部署到測試環(huán)境了。

3. 發(fā)現(xiàn)問題了

第二天收到了兩封sentry?的報警郵件,報警級別都是warn。

第一封郵件中提示異常:This driver is DEPRECATED. Please use [com.clickhouse.jdbc.ClickHouseDriver] instead。

意思是說ru.yandex.clickhouse的驅(qū)動已經(jīng)被廢棄了,請使用com.clickhouse.jdbc.ClickHouseDriver驅(qū)動。

第二封郵件中提示異常:Also everything in package [ru.yandex.clickhouse] will be removed starting from 0.4.0。

意思是說ru.yandex.clickhouse將被移除。

看到這兩封郵件,我當(dāng)時有點懵,不就是用的com.clickhouse?驅(qū)動包嗎,ru.yandex.clickhouse是從哪里來的?

于是全局搜索了一下ru.yandex.clickhouse關(guān)鍵字,并沒有搜到任何記錄。

這讓我更懵了。

接下來,我打開了clickhouse-jdbc-0.3.2-patch11-all.jar文件,看到了讓人意想不到的結(jié)果:

圖片

這個jar包下面竟然有兩個目錄:?com.clickhouse和ru.yandex.clickhouse,也就是說jar包中新驅(qū)動和老驅(qū)動兩種都支持。

而且ClickhouseDriver?類有兩個:

圖片

我此時心里有十萬個為什么:為什么不直接把?ru.yandex.clickhouse包的代碼刪除了,卻在日志文件中打印一些警告呢?

這實在太坑了吧。

也就是說升級驅(qū)動之后,項目依然用的老驅(qū)動的代碼,我測試了個寂寞。。。

4. 如何使用新驅(qū)動?

接下來我內(nèi)心的OS是:既然ClickHouse官方驅(qū)動包,新老驅(qū)動都支持,必然有個開關(guān)控制是使用新的JDBC驅(qū)動,還是使用老的JDBC驅(qū)動。

從目前來看,如果沒有調(diào)整開關(guān),ClickHouse官方驅(qū)動包默認使用的是老的JDBC驅(qū)動。

接下來,最重要的問題是要搞清楚:如何使用新驅(qū)動?

很快,我查到通過配置下面的參數(shù):

spring.datasource.clickhouse.drive-class-name=com.clickhouse.jdbc.ClickHouseDriver

就能指定Spring使用的JDBC驅(qū)動。

果然在application.properties?文件中,配置數(shù)據(jù)源的地方,增加了這樣一個配置,重啟項目,Spring就是使用了新的ClickHouse JDBC驅(qū)動。

日志中沒有打印郵件中那兩個warn了。

此時,心里暗自竊喜,終于使用了ClickHouse官方推薦的JDBC驅(qū)動。

項目已經(jīng)正常運行起來了,趕緊測試一下業(yè)務(wù)功能是否正常。

5. 出現(xiàn)了兩個新問題

結(jié)果馬上被啪啪打臉了。

在測試批量insert數(shù)據(jù)的業(yè)務(wù)場景時,系統(tǒng)運行日志中出現(xiàn)了兩個異常:

異常1:Code: 6. DB:Exception: Cannot prse string '2022-11-22 14:42:37.025' as DateTime:syntax error at position 19...?從提示的信息看,它表示時間2022-11-22 14:42:37.025不能轉(zhuǎn)換成DateTime類型。

異常2:Please consider to use one and only one values expression, for example: use 'values(?)' instead of 'values(?),(?).'從提示的信息看,它表示不支持批量insert數(shù)據(jù)。

我去。。。

升級ClickHouse JDBC驅(qū)動出問題了。

ClickHouse 官方最新的JDBC驅(qū)動竟然不支持批量insert數(shù)據(jù),這個問題更嚴重。

趕緊搜索一下解決辦法。

6. 回退版本

很快,在clickhouse-jdbc的issues中查到了類似的問題,地址:https://github.com/ClickHouse/clickhouse-jdbc/issues/1106?。問題如下:

圖片

下面有人回答:

圖片

使用老版本就沒有這個警告。

我一下子如夢初醒。

不要迷戀最新的版本,clickhouse-jdbc一定要找最合適的版本。

于是,我查了dev、st和ga環(huán)境的ClickHouse服務(wù)器版本,發(fā)現(xiàn)dev用的是20.12.8.5?,而st和ga用的21.12.4.1。

為了兼容dev環(huán)境,ClickHouse服務(wù)器版本以20+為準(zhǔn),再看看clickhouse-jdbc能用什么版本。

很快在releases中查到,clickhouse-jdbc能用0.3.2,最高只能0.3.2-patch1。因為0.3.2-patch2以上,要求ClickHouse服務(wù)器是21+的版本。

因此,我只能將clickhouse-jdbc的版本回退到:0.3.2-patch1。

果然,回退版本之后,不能批量insert的問題解決了。

接下來,就是一個問題。

7. DateTime

讓我們一起回顧一下那個問題:Code: 6. DB:Exception: Cannot prse string '2022-11-22 14:42:37.025' as DateTime:syntax error at position 19...?從提示的信息看,它表示時間2022-11-22 14:42:37.025不能轉(zhuǎn)換成DateTime類型。

而DateTime的時間格式是:yyyy-MM-dd HH:mm:ss?,這個問題是由于2022-11-22 14:42:37.025包含了毫秒,不能直接轉(zhuǎn)換成2022-11-22 14:42:37導(dǎo)致的。

我查了一下代碼和表結(jié)構(gòu),代碼中Entity中time字段定義成的Date類型。

而表中定義的time字段是DateTime類型。

ClickHouse官方驅(qū)動無法將Date類型的時間直接轉(zhuǎn)換成DateTime類型。

怎么解決這個問題呢?

答:修改表中的字段類型不就行了,將DateTime?轉(zhuǎn)換成DateTime64,DateTime64?是支持毫秒的。

我親測過,使用DateTime64類型接收Java中Date類型的時間,能夠正常解析。

那張表有三個DateTime類型的字段:create_time、edit_time和time。

前面兩個字段的字段類型,很容易就修改成功了。

但修改time字段時,卻報了一個異常:Code: 524,e.displayText() = DB::Exception: Alter of key column time from type DateTime to type DateTime64(3) must be metadata-only (20.12.8.5)

提示作為key的字段不能被修改。

這又是為什么?

8. order by

我這一次直接查看了那張表的建表語句:

show create table test;

發(fā)現(xiàn)該表處理主鍵和普通索引之外,還特別加了order by的索引。

例如:order by (code, time)。

看到這里我迅速明白了,原來time字段是order by的索引字段,難怪不允許隨便修改的。

于是,找DBA商討對策。

DBA說要修改ClickHouse中表的索引字段的類型,只能重新建表,然后把數(shù)據(jù)同步過去。

很顯然這個方案太麻煩了。

我在想有沒有其他更簡單的方案呢?

9. date_time_input_format參數(shù)

我此時在思考,不就是時間轉(zhuǎn)換出的問題嗎?

讓ClickHouse在保存數(shù)據(jù)時,自動轉(zhuǎn)換一個時間格式不就解決問題了嗎?

我在官網(wǎng)上查到一個叫:date_time_input_format的參數(shù)。

該參數(shù)允許選擇日期和時間的文本表示的解析器。

它可能的值:

  • 'best_effort' — Enables extended parsing.

ClickHouse可以解析基本 YYYY-MM-DD HH:MM:SS 格式和所有 ISO 8601 日期和時間格式。例如, '2018-06-08T01:02:03.000Z'.

  • 'basic' — Use basic parser.

ClickHouse只能解析基本的 YYYY-MM-DD HH:MM:SS 格式。例如, '2019-08-20 10:18:56'.

默認值: 'basic'.

原來這個是時間轉(zhuǎn)換失敗的根源,如果我們把date_time_input_format?的值設(shè)置成best_effort,不就解決問題了。

為了不影響全局,我想只給那三張表調(diào)整date_time_input_format的值。

但是在保存設(shè)置時,報錯了。

原來date_time_input_format參數(shù)只允許在MergeTree?存儲引擎上使用,而我們表的存儲引擎用的ReplacingMergeTree。

暈死了。。。

只能想想其他辦法了。

10. parseDateTimeBestEffortOrNull

在insert數(shù)據(jù)的地方,用函數(shù)手動轉(zhuǎn)換一下不就OK了嗎?

當(dāng)然修改Java的Entity中的Date類型,改成String也是可以的,不過review了一下代碼,這種改動有點大,涉及的地方很多。

最小的改動是在mapper層處理,因為一個mapper中最多只有一個insert存在。

而我review了所有的ClickHouse表,只有3張表用了DateTime類型,其他的表都是DateTime64類型。

剛開始,我在ClickHouse的官方文檔中查到了formatDateTime函數(shù),測試之后發(fā)現(xiàn)該函數(shù)不太合適。

后來找到了parseDateTimeBestEffort?系列函數(shù),決定使用parseDateTimeBestEffortOrNull函數(shù)。

只需在mapper.xml的insert語句中,使用parseDateTimeBestEffortOrNull(#{item.time})改造一下即可。

測試后發(fā)現(xiàn),時間轉(zhuǎn)換問題被解決了。

后來,有條select語句中又出現(xiàn)了這個異常。

我剛開始以為是toDate(time)函數(shù)導(dǎo)致的,但后面發(fā)現(xiàn)該select的where條件中使用了time字段作為查詢條件,才導(dǎo)致了該問題的發(fā)生。

這時同樣使用parseDateTimeBestEffortOrNull函數(shù),解決了問題。

至此,ClickHouse的JDBC驅(qū)動包升級完成,沒有再出現(xiàn)其他的問題。

需要特別注意的是:以后新創(chuàng)建的表或新加的字段,如果有時間類型的字段,務(wù)必要定義成DateTime64類型的。

其實,我們在使用ClickHouse的過程中,同樣也遇到過很多坑,文章開頭的那個問題只是其中一個,后面會有一篇專題文章分享給大家,敬請期待。

責(zé)任編輯:武曉燕 來源: 蘇三說技術(shù)
相關(guān)推薦

2017-12-29 08:54:58

高可用數(shù)據(jù)庫架構(gòu)

2024-05-06 00:00:00

緩存高并發(fā)數(shù)據(jù)

2025-04-02 08:17:42

2019-10-30 14:44:41

Prometheus開源監(jiān)控系統(tǒng)

2017-10-16 09:56:16

2021-02-21 09:28:24

kafka系統(tǒng)并發(fā)量

2020-09-15 08:46:26

Kubernetes探針服務(wù)端

2023-01-18 23:20:25

編程開發(fā)

2023-02-20 08:11:04

2017-05-05 08:12:51

Spark共享變量

2021-10-28 19:10:02

Go語言編碼

2009-06-19 17:14:47

JDBC驅(qū)動設(shè)置

2009-06-19 15:08:23

JDBC驅(qū)動

2024-04-10 08:39:56

BigDecimal浮點數(shù)二進制

2021-09-03 11:15:18

場景sql配置

2024-04-01 08:05:27

Go開發(fā)Java

2023-12-14 17:34:22

Kubernetes集群K8s

2017-07-17 15:46:20

Oracle并行機制

2021-05-27 22:46:00

Nacos Clien版本Nacos

2023-09-22 11:29:11

JavasubList
點贊
收藏

51CTO技術(shù)棧公眾號