Skip to content

Go

GreptimeDB 使用不同的客户端库来写入和查询数据。 你根据需求可以选择合适的客户端库。

写入数据

GreptimeDB 提供了一个 ingester 库来帮助你写入数据。 它使用 gRPC 协议,支持自动生成表结构,无需在写入数据前创建表。 更多信息请参考 自动生成表结构

GreptimeDB 提供的 Go Ingest SDK 是一个轻量级、并发安全的库,使用起来非常简单。

安装

使用下方的命令安装 Go Ingest SDK:

shell
go get github.com/GreptimeTeam/greptimedb-client-go@v0.1.2 google.golang.org/grpc google.golang.org/grpc/credentials/insecure
go get github.com/GreptimeTeam/greptimedb-client-go@v0.1.2 google.golang.org/grpc google.golang.org/grpc/credentials/insecure

引入到代码中:

go
import (
    greptime "github.com/GreptimeTeam/greptimedb-client-go"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)
import (
    greptime "github.com/GreptimeTeam/greptimedb-client-go"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)

连接数据库

连接 GreptimeDB 时,通常需要用户名和密码。 关于如何设置 GreptimeDB 的鉴权方式,请参考鉴权。 这里我们在使用 ingester 库连接 GreptimeDB 时设置用户名和密码。

go
options := []grpc.DialOption{
    grpc.WithTransportCredentials(insecure.NewCredentials()),
}
// To connect a database that needs authentication, for example, those on Greptime Cloud,
// `Username` and `Password` are needed when connecting to a database that requires authentication.
// Leave the two fields empty if connecting a database without authentication.
cfg := greptime.NewCfg("127.0.0.1").
    WithDatabase("public").      // change to your real database
    WithPort(4001).              // default port
    WithAuth("username", "password").            // `Username` and `Password`
    WithDialOptions(options...). // specify your gRPC dail options
    WithCallOptions()            // specify your gRPC call options

client, _ := greptime.NewClient(cfg)
options := []grpc.DialOption{
    grpc.WithTransportCredentials(insecure.NewCredentials()),
}
// To connect a database that needs authentication, for example, those on Greptime Cloud,
// `Username` and `Password` are needed when connecting to a database that requires authentication.
// Leave the two fields empty if connecting a database without authentication.
cfg := greptime.NewCfg("127.0.0.1").
    WithDatabase("public").      // change to your real database
    WithPort(4001).              // default port
    WithAuth("username", "password").            // `Username` and `Password`
    WithDialOptions(options...). // specify your gRPC dail options
    WithCallOptions()            // specify your gRPC call options

client, _ := greptime.NewClient(cfg)

行对象

表中的每条行数据包含三种类型的列:TagTimestampField。更多信息请参考 数据模型。 列值的类型可以是 StringFloatIntTimestamp 等。更多信息请参考 数据类型

Go Ingest SDK 使用 Series 来表示一行数据,多个 Series 可以添加到 Metric 中,然后写入到 GreptimeDB 中。

创建行数据

下面的例子展示了如何创建包含 TagTimestampField 列的行。Tag 列是 String 类型,Timestamp 列是 Timestamp 类型,Field 列是 Float 类型。

为了提高写入数据的效率,你可以一次创建多行数据写入 GreptimeDB。

go
seriesHost1 := greptime.Series{}
seriesHost1.AddStringTag("host", "host1")
seriesHost1.AddFloatField("cpu", 0.90)
seriesHost1.SetTimestamp(time.Now())

seriesHost2 := greptime.Series{}
seriesHost2.AddStringTag("host", "host2")
seriesHost2.AddFloatField("cpu", 0.70)
seriesHost2.SetTimestamp(time.Now())

metric := greptime.Metric{}
metric.AddSeries(seriesHost1, seriesHost2)
seriesHost1 := greptime.Series{}
seriesHost1.AddStringTag("host", "host1")
seriesHost1.AddFloatField("cpu", 0.90)
seriesHost1.SetTimestamp(time.Now())

seriesHost2 := greptime.Series{}
seriesHost2.AddStringTag("host", "host2")
seriesHost2.AddFloatField("cpu", 0.70)
seriesHost2.SetTimestamp(time.Now())

metric := greptime.Metric{}
metric.AddSeries(seriesHost1, seriesHost2)

保存行数据

下方的例子展示了如何将行数据保存到 GreptimeDB 中。

go
seriesHost1 := greptime.Series{}
seriesHost1.AddStringTag("host", "host1")
seriesHost1.AddFloatField("cpu", 0.90)
seriesHost1.SetTimestamp(time.Now())

seriesHost2 := greptime.Series{}
seriesHost2.AddStringTag("host", "host2")
seriesHost2.AddFloatField("cpu", 0.70)
seriesHost2.SetTimestamp(time.Now())

metric := greptime.Metric{}
metric.AddSeries(seriesHost1, seriesHost2)

monitorReq := greptime.InsertRequest{}
monitorReq.WithTable("monitor").WithMetric(metric)

insertsRequest := greptime.InsertsRequest{}
insertsRequest.Append(monitorReq)

res, err := client.Insert(context.Background(), insertsRequest)
if err != nil {
    fmt.Printf("fail to insert, err: %+v\n", err)
    // error handling
    // ...
}
fmt.Printf("AffectedRows: %d\n", res.GetAffectedRows().Value)
seriesHost1 := greptime.Series{}
seriesHost1.AddStringTag("host", "host1")
seriesHost1.AddFloatField("cpu", 0.90)
seriesHost1.SetTimestamp(time.Now())

seriesHost2 := greptime.Series{}
seriesHost2.AddStringTag("host", "host2")
seriesHost2.AddFloatField("cpu", 0.70)
seriesHost2.SetTimestamp(time.Now())

metric := greptime.Metric{}
metric.AddSeries(seriesHost1, seriesHost2)

monitorReq := greptime.InsertRequest{}
monitorReq.WithTable("monitor").WithMetric(metric)

insertsRequest := greptime.InsertsRequest{}
insertsRequest.Append(monitorReq)

res, err := client.Insert(context.Background(), insertsRequest)
if err != nil {
    fmt.Printf("fail to insert, err: %+v\n", err)
    // error handling
    // ...
}
fmt.Printf("AffectedRows: %d\n", res.GetAffectedRows().Value)

更新行数据

请参考 更新数据了解更新机制。 下面的例子展示了先保存一行数据,然后更新这行数据。

go
// save a row data
series := greptime.Series{}
series.AddStringTag("host", "host1")
series.AddFloatField("cpu", 0.90)
series.SetTimestamp(1703832681000)
metric := greptime.Metric{}
metric.AddSeries(series)
monitorReq := greptime.InsertRequest{}
monitorReq.WithTable("monitor").WithMetric(metric)
insertsRequest := greptime.InsertsRequest{}
insertsRequest.Append(monitorReq)
res, _ := client.Insert(context.Background(), insertsRequest)

// update the row data
newSeries := greptime.Series{}
// The same tag `host1`
newSeries.AddStringTag("host", "host1")
// The same time index `1703832681000`
newSeries.SetTimestamp(1703832681000)
// The new field value `0.80`
newSeries.AddFloatField("cpu", 0.80)
// overwrite the existing data
metric := greptime.Metric{}
metric.AddSeries(newSeries)
monitorReq := greptime.InsertRequest{}
monitorReq.WithTable("monitor").WithMetric(metric)
insertsRequest := greptime.InsertsRequest{}
insertsRequest.Append(monitorReq)
res, _ := client.Insert(context.Background(), insertsRequest)
// save a row data
series := greptime.Series{}
series.AddStringTag("host", "host1")
series.AddFloatField("cpu", 0.90)
series.SetTimestamp(1703832681000)
metric := greptime.Metric{}
metric.AddSeries(series)
monitorReq := greptime.InsertRequest{}
monitorReq.WithTable("monitor").WithMetric(metric)
insertsRequest := greptime.InsertsRequest{}
insertsRequest.Append(monitorReq)
res, _ := client.Insert(context.Background(), insertsRequest)

// update the row data
newSeries := greptime.Series{}
// The same tag `host1`
newSeries.AddStringTag("host", "host1")
// The same time index `1703832681000`
newSeries.SetTimestamp(1703832681000)
// The new field value `0.80`
newSeries.AddFloatField("cpu", 0.80)
// overwrite the existing data
metric := greptime.Metric{}
metric.AddSeries(newSeries)
monitorReq := greptime.InsertRequest{}
monitorReq.WithTable("monitor").WithMetric(metric)
insertsRequest := greptime.InsertsRequest{}
insertsRequest.Append(monitorReq)
res, _ := client.Insert(context.Background(), insertsRequest)

更多示例

有关更多可运行的代码片段和常用方法的解释,请参阅示例

Ingester 库参考

查询数据

GreptimeDB 使用 SQL 作为主要查询语言,兼容 MySQL 和 PostgreSQL。 因此,我们推荐使用成熟的 SQL 驱动来查询数据。

推荐的查询库

我们推荐使用 Gorm 库来查询数据。

安装

使用下方的命令安装 Gorm:

shell
go get -u gorm.io/gorm
go get -u gorm.io/gorm

以 MySQL 为例安装 driver:

shell
go get -u gorm.io/driver/mysql
go get -u gorm.io/driver/mysql

引入到代码中:

go
import (
    "gorm.io/gorm"
    "gorm.io/driver/mysql"
)
import (
    "gorm.io/gorm"
    "gorm.io/driver/mysql"
)

连接到数据库

下方的例子展示了如何连接到 GreptimeDB:

go
type Mysql struct {
	Host     string
	Port     string
	User     string
	Password string
	Database string

	DB *gorm.DB
}

m := &Mysql{
    Host:     "127.0.0.1",
    Port:     "4002", // default port for MySQL
    User:     "username",
    Password: "password",
    Database: "public",
}

dsn := fmt.Sprintf("tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
    m.Host, m.Port, m.Database)
dsn = fmt.Sprintf("%s:%s@%s", m.User, m.Password, dsn)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
    //error handling 
}
m.DB = db
type Mysql struct {
	Host     string
	Port     string
	User     string
	Password string
	Database string

	DB *gorm.DB
}

m := &Mysql{
    Host:     "127.0.0.1",
    Port:     "4002", // default port for MySQL
    User:     "username",
    Password: "password",
    Database: "public",
}

dsn := fmt.Sprintf("tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
    m.Host, m.Port, m.Database)
dsn = fmt.Sprintf("%s:%s@%s", m.User, m.Password, dsn)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
    //error handling 
}
m.DB = db

Raw SQL

我们推荐使用 Raw SQL 来体验 GreptimeDB 的全部功能。 下面的例子展示了如何使用 Raw SQL 查询数据:

go
type Monitor struct {
	Host        string    `gorm:"column:host;primaryKey"`
	Ts          time.Time `gorm:"column:ts;primaryKey"`
	Cpu         float64   `gorm:"column:cpu"`
}

func (Monitor) TableName() string {
	return "monitor"
}

var monitor Monitor
db.Raw("SELECT host, cpu, ts FROM users WHERE ts > ?", 1701360000000).Scan(&result)
type Monitor struct {
	Host        string    `gorm:"column:host;primaryKey"`
	Ts          time.Time `gorm:"column:ts;primaryKey"`
	Cpu         float64   `gorm:"column:cpu"`
}

func (Monitor) TableName() string {
	return "monitor"
}

var monitor Monitor
db.Raw("SELECT host, cpu, ts FROM users WHERE ts > ?", 1701360000000).Scan(&result)

查询库参考

有关如何使用查询库的更多信息,请参考相应库的文档: