怎么使用 Go 語言操作 Apache Doris

Apache Doris 是一個基于 MPP 架構(gòu)的高性能、實(shí)時的分析型數(shù)據(jù)庫炕倘,以極速易用的特點(diǎn)被人們所熟知寸谜,僅需亞秒級響應(yīng)時間即可返回海量數(shù)據(jù)下的查詢結(jié)果癌椿,不僅可以支持高并發(fā)的點(diǎn)查詢場景肚菠,也能支持高吞吐的復(fù)雜分析場景舔箭。基于此蚊逢,Apache Doris 能夠較好的滿足報表分析限嫌、即席查詢、統(tǒng)一數(shù)倉構(gòu)建时捌、數(shù)據(jù)湖聯(lián)邦查詢加速等使用場景,用戶可以在此之上構(gòu)建用戶行為分析炉抒、AB 實(shí)驗(yàn)平臺奢讨、日志檢索分析、用戶畫像分析焰薄、訂單分析等應(yīng)用拿诸。

使用 Doris 的用戶都知道 Doris 是完全兼容 MySQL 協(xié)議的,我們可以使用任意 MySQL 客戶端或者 Connector 去連接 Doris塞茅,用 SQL 操作 Doris亩码,這樣你可以使用任意語言來操作 Doris。今天我們演示使用 Go 語言來訪問 Doris 野瘦,完成查詢和 插入操作描沟。

Go 與 MySQL 的結(jié)合還是比較容易的飒泻,像是連接,增吏廉、刪泞遗、改這些操作都比較簡單。

Go 語言的安裝配置還是很簡單的席覆,這里我們就不做介紹了史辙,直接開始

安裝驅(qū)動

安裝 Go 連接 MySQL的驅(qū)動

go get github.com/go-sql-driver/mysql

在我們程序里導(dǎo)入依賴庫

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

連接Doris數(shù)據(jù)庫

var (
  // 定義一個全局對象db
  db *sql.DB
  //連接Doris的用戶名
  userName string = "root"
  //連接Doris的密碼
  password string = ""
  //連接Doris的地址
  ipAddress string = "127.0.0.1"
  //連接Doris的端口號,默認(rèn)是9030
  port int = 9030
  //連接Doris的具體數(shù)據(jù)庫名稱
  dbName string = "test"
)

func initDB() (err error) {
  dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", userName, password, ipAddress, port, dbName)
  //Open打開一個driverName指定的數(shù)據(jù)庫,dataSourceName指定數(shù)據(jù)源
  //不會校驗(yàn)用戶名和密碼是否正確佩伤,只會對dsn的格式進(jìn)行檢測
  db, err = sql.Open("mysql", dsn)
  //dsn格式不正確的時候會報錯
  if err != nil { 
    return err
  }
  //嘗試與數(shù)據(jù)庫連接聊倔,校驗(yàn)dsn是否正確
  err = db.Ping()
  if err != nil {
    fmt.Println("校驗(yàn)失敗,err", err)
    return err
  }
  // 設(shè)置最大連接數(shù)
  db.SetMaxOpenConns(50)
  // 設(shè)置最大的空閑連接數(shù)
  // db.SetMaxIdleConns(20)
  fmt.Println("連接數(shù)據(jù)庫成功!")
  return nil
}

驗(yàn)證連接

func main() {
  err := initDB()
  if err != nil {
    fmt.Println("初始化數(shù)據(jù)庫失敗,err", err)
    return
  }
}

查詢數(shù)據(jù)表

這里我們簡單做一個查詢表里的所有數(shù)據(jù)

我的表結(jié)構(gòu)如下:

CREATE TABLE `t_cn_search` (
  `md5` varchar(100) NULL,
  `book_line` text NULL,
  INDEX idx_line (`book_line`) USING INVERTED PROPERTIES("parser" = "chinese", "support_phrase" = "true") COMMENT ''
) ENGINE=OLAP
DUPLICATE KEY(`md5`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`md5`) BUCKETS 2
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"is_being_synced" = "false",
"storage_format" = "V2",
"light_schema_change" = "true",
"disable_auto_compaction" = "false",
"enable_single_replica_compaction" = "false"
);

我這個表是一個日志檢索用的表生巡,使用了 Doris 的倒排索引耙蔑,我們匹配任意關(guān)鍵字粒子

查詢程序:

// 查詢數(shù)據(jù)
func QueryRow() {
  rows, _ := db.Query("select * from t_cn_search where book_line MATCH_ANY '粒子'") //獲取所有數(shù)據(jù)
  var md5 int
  var book_line string
  for rows.Next() { //循環(huán)顯示所有的數(shù)據(jù)
    rows.Scan(&md5, &book_line)
    fmt.Println(md5, "--", book_line)
  }
}

我們執(zhí)行程序可以看到查詢結(jié)果:

image.png

插入數(shù)據(jù)

我們現(xiàn)在來演示怎么插入數(shù)據(jù),這個演示的是我們通過 Doris 提供的 TVF(Table Value Function)將 HDFS 上文件數(shù)據(jù)直接導(dǎo)入到 Doris 的表里障斋。

我的 hdfs 上的文件格式是 Parquet纵潦,我們可以通過 TVF 來看一下這個表的數(shù)據(jù)結(jié)構(gòu)

mysql> desc function hdfs(
    ->             "uri" = "hdfs://localhost:9000/tmp/test.parquet",
    ->             "fs.defaultFS" = "hdfs://localhost:9000",
    ->             "hadoop.username" = "doris",
    ->             "format" = "parquet");
+----------------+------+------+-------+---------+-------+
| Field          | Type | Null | Key   | Default | Extra |
+----------------+------+------+-------+---------+-------+
| date           | TEXT | Yes  | false | NULL    | NONE  |
| user_src       | TEXT | Yes  | false | NULL    | NONE  |
| order_src      | TEXT | Yes  | false | NULL    | NONE  |
| order_location | TEXT | Yes  | false | NULL    | NONE  |
| new_order      | INT  | Yes  | false | NULL    | NONE  |
| payed_order    | INT  | Yes  | false | NULL    | NONE  |
| pending_order  | INT  | Yes  | false | NULL    | NONE  |
| cancel_order   | INT  | Yes  | false | NULL    | NONE  |
| reject_order   | INT  | Yes  | false | NULL    | NONE  |
| good_order     | INT  | Yes  | false | NULL    | NONE  |
| report_order   | INT  | Yes  | false | NULL    | NONE  |
+----------------+------+------+-------+---------+-------+
11 rows in set (0.16 sec)

Doris 的表結(jié)構(gòu)如下:

 CREATE TABLE `order_analysis` (
  `date` varchar(57) NULL,
  `user_src` varchar(27) NULL,
  `order_src` varchar(33) NULL,
  `order_location` varchar(6) NULL,
  `new_order` int(11) NULL,
  `payed_order` int(11) NULL,
  `pending_order` int(11) NULL,
  `cancel_order` int(11) NULL,
  `reject_order` int(11) NULL,
  `good_order` int(11) NULL,
  `report_order` int(11) NULL
) ENGINE=OLAP
DUPLICATE KEY(`date`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`date`) BUCKETS 2
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"is_being_synced" = "false",
"storage_format" = "V2",
"light_schema_change" = "true",
"disable_auto_compaction" = "false",
"enable_single_replica_compaction" = "false"
);

將 hdfs 文件數(shù)據(jù)導(dǎo)入到 Doris 表里,這里我們使用的是 insert into tbl select 這個操作

func insert() {
  result, err := db.Exec("insert into order_analysis select * from hdfs(" +
    "\"uri\" = \"hdfs://localhost:9000/tmp/test.parquet\"," +
    "\"fs.defaultFS\" = \"hdfs://localhost:9000\"," +
    "\"hadoop.username\" = \"doris\"," +
    "\"format\" = \"parquet\")")
  if err != nil {
    fmt.Println("預(yù)處理失敗:", err)
    return
  }

  if err != nil {
    fmt.Println("執(zhí)行預(yù)處理失敗:", err)
    return
  } else {
    rows, _ := result.RowsAffected()
    fmt.Println("執(zhí)行成功,影響行數(shù)", rows, "行")
  }
}

執(zhí)行完成之后我們可以看到返回的結(jié)果

連接數(shù)據(jù)庫成功垃环!
執(zhí)行成功,影響行數(shù) 5061 行

總結(jié)

是不是很簡單邀层,你可以使用任意語言通過 MySQL 協(xié)議來操作 Doris ,后面我們會在講解通過 Go 語言使用 Doris 提供的 Stream load(http協(xié)議)來完成數(shù)據(jù)導(dǎo)入的操作遂庄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寥院,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涛目,更是在濱河造成了極大的恐慌秸谢,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件霹肝,死亡現(xiàn)場離奇詭異估蹄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沫换,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門臭蚁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人讯赏,你說我怎么就攤上這事垮兑。” “怎么了漱挎?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵系枪,是天一觀的道長。 經(jīng)常有香客問我磕谅,道長私爷,這世上最難降的妖魔是什么雾棺? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮当犯,結(jié)果婚禮上垢村,老公的妹妹穿的比我還像新娘。我一直安慰自己嚎卫,他們只是感情好嘉栓,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拓诸,像睡著了一般侵佃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奠支,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天馋辈,我揣著相機(jī)與錄音,去河邊找鬼倍谜。 笑死迈螟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尔崔。 我是一名探鬼主播答毫,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼季春!你這毒婦竟也來了洗搂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤载弄,失蹤者是張志新(化名)和其女友劉穎耘拇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宇攻,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惫叛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逞刷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挣棕。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亲桥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情固耘,我是刑警寧澤题篷,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站厅目,受9級特大地震影響番枚,放射性物質(zhì)發(fā)生泄漏法严。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一葫笼、第九天 我趴在偏房一處隱蔽的房頂上張望深啤。 院中可真熱鬧,春花似錦路星、人聲如沸溯街。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呈昔。三九已至,卻和暖如春友绝,著一層夾襖步出監(jiān)牢的瞬間堤尾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工迁客, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留郭宝,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓掷漱,卻偏偏與公主長得像粘室,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子切威,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容