1111- for go-clickhouse v1 ` $ go get -u github.com/zikwall/clickhouse-buffer `
1212- for go-clickhouse v2 ` $ go get -u github.com/zikwall/clickhouse-buffer/v2 `
1313
14- ## Why and why
14+ ### Why and why
1515
1616In the practice of using the Clickhouse database (in real projects),
1717you often have to resort to creating your own ~~ bicycles~~ in the form of queues
@@ -21,7 +21,7 @@ and send one large data package to the Clickhouse database.
2121This is due to the fact that Clickhouse is designed so that it better processes new data in batches
2222(and this is recommended by the authors themselves).
2323
24- ## Features
24+ ### Features
2525
2626- [x] ** non-blocking** - (recommend) async write client uses implicit batching.
2727 Data are asynchronously written to the underlying buffer and they are automatically sent to a server
@@ -35,23 +35,29 @@ This is due to the fact that Clickhouse is designed so that it better processes
3535- [x] ** redis** - use redis server as queue and buffer
3636- [x] ** retries** - resending "broken" or for some reason not sent packets
3737
38- ## Usage
38+ ### Usage
3939
4040``` go
4141import (
42- " github.com/zikwall/clickhouse-buffer/v2/src/database/native"
43- " github.com/zikwall/clickhouse-buffer/v2/src/database/sql"
42+ " database/sql"
43+
44+ cxnative " github.com/zikwall/clickhouse-buffer/v2/src/database/native"
45+ cxsql " github.com/zikwall/clickhouse-buffer/v2/src/database/sql"
4446)
4547
46- // simple use
47- ch := native.NewClickhouseWithConn (conn: driver.Conn )
48- // or use database/sql
49- ch := sql.NewClickhouseWithConn (conn: *sql.DB )
48+ // if you already have a connection to Clickhouse you can just use wrappers
49+ // with native interface
50+ ch := cxnative.NewClickhouseWithConn (conn: driver.Conn )
51+ // or use database/sql interface
52+ ch := cxsql.NewClickhouseWithConn (conn: *sql.DB )
5053```
5154
5255``` go
53- // another way to use
54- ch , conn , err := native.NewClickhouse (ctx,&clickhouse.Options {
56+ // if you don't want to create connections yourself,
57+ // package can do it for you, just call the connection option you need:
58+
59+ // with native interface
60+ ch , conn , err := cxnative.NewClickhouse (ctx,&clickhouse.Options {
5561 Addr : ctx.StringSlice (" clickhouse-host" ),
5662 Auth : clickhouse.Auth {
5763 Database: ctx.String (" clickhouse-database" ),
@@ -65,11 +71,11 @@ ch, conn, err := native.NewClickhouse(ctx,&clickhouse.Options{
6571 Compression : &clickhouse.Compression {
6672 Method: clickhouse.CompressionLZ4 ,
6773 },
68- Debug : true ,
74+ Debug : ctx. Bool ( " debug " ) ,
6975 },
7076)
71- // or use database/sql
72- ch , conn , err := sql .NewClickhouse (ctx, &clickhouse.Options {
77+ // or with database/sql interface
78+ ch , conn , err := cxsql .NewClickhouse (ctx, &clickhouse.Options {
7379 Addr : ctx.StringSlice (" clickhouse-host" ),
7480 Auth : clickhouse.Auth {
7581 Database: ctx.String (" clickhouse-database" ),
@@ -83,50 +89,49 @@ ch, conn, err := sql.NewClickhouse(ctx, &clickhouse.Options{
8389 Compression : &clickhouse.Compression {
8490 Method: clickhouse.CompressionLZ4 ,
8591 },
86- Debug : true ,
87- }, &sql .RuntimeOptions {},
92+ Debug : ctx. Bool ( " debug " ) ,
93+ }, &cxsql .RuntimeOptions {},
8894)
8995```
9096
9197#### Create main data streamer client and write data
9298
9399``` go
94100import (
95- chbuffer " github.com/zikwall/clickhouse-buffer/v2"
96- " github.com/zikwall/clickhouse-buffer/v2/src/buffer"
97- " github.com/zikwall/clickhouse-buffer/v2/src/buffer/memory"
98- " github.com/zikwall/clickhouse-buffer/v2/src/buffer/redis"
101+ cx " github.com/zikwall/clickhouse-buffer/v2"
102+ cxbuffer " github.com/zikwall/clickhouse-buffer/v2/src/buffer"
103+ cxmemory " github.com/zikwall/clickhouse-buffer/v2/src/buffer/memory"
104+ cxredis " github.com/zikwall/clickhouse-buffer/v2/src/buffer/redis"
99105)
100-
101- client := chbuffer .NewClientWithOptions (ctx, ch,
102- clikchousebuffer .DefaultOptions ().SetFlushInterval (1000 ).SetBatchSize (5000 ),
106+ // create root client
107+ client := cxbuffer .NewClientWithOptions (ctx, ch,
108+ cx .DefaultOptions ().SetFlushInterval (1000 ).SetBatchSize (5000 ),
103109)
104-
105- engine := memory .NewBuffer (
110+ // create buffer engine
111+ buffer := cxmemory .NewBuffer (
106112 client.Options ().BatchSize (),
107113)
108- // or
109- engine := redis .NewBuffer (
114+ // or use redis
115+ buffer := cxredis .NewBuffer (
110116 contetx, *redis.Client , " bucket" , client.Options ().BatchSize (),
111117)
112-
113- writeAPI := client.Writer (buffer .View {
118+ // create new writer api: table name with columns
119+ writeAPI := client.Writer (cxbuffer .View {
114120 Name : " clickhouse_database.clickhouse_table" ,
115121 Columns : []string {" id" , " uuid" , " insert_ts" },
116- }, engine)
117-
122+ }, buffer)
118123
124+ // define your custom data structure
119125type MyCustomDataView struct {
120126 id int
121127 uuid string
122128 insertTS time.Time
123129}
124-
125- func (t *MyCustomDataView ) Row () chbuffer .RowSlice {
126- return chbuffer .RowSlice {t.id , t.uuid , t.insertTS .Format (time.RFC822 )}
130+ // and implement cxbuffer.Inline interface
131+ func (t *MyCustomDataView ) Row () cxbuffer .RowSlice {
132+ return cxbuffer .RowSlice {t.id , t.uuid , t.insertTS .Format (time.RFC822 )}
127133}
128-
129- // write your data
134+ // async write your data
130135writeAPI.WriteRow (MyCustomDataView{
131136 id: 1 , uuid: " 1" , insertTS: time.Now (),
132137})
@@ -146,11 +151,12 @@ go func() {
146151Using the blocking writer interface
147152
148153``` go
149- writerBlocking := client.WriterBlocking (View{
154+ // create new writer api: table name with columns
155+ writerBlocking := client.WriterBlocking (cxbuffer.View {
150156 Name : " clickhouse_database.clickhouse_table" ,
151157 Columns : []string {" id" , " uuid" , " insert_ts" },
152158})
153-
159+ // non-asynchronous writing of data directly to Clickhouse
154160err := writerBlocking.WriteRow (ctx, []MyCustomDataView {
155161 {
156162 id: 1 , uuid: " 1" , insertTS: time.Now (),
@@ -187,7 +193,7 @@ type Queueable interface {
187193and set it as an engine:
188194
189195``` go
190- DefaultOptions ().SetDebugMode (true ).SetRetryIsEnabled (true ).SetQueueEngine (CustomQueueable)
196+ cx. DefaultOptions ().SetDebugMode (true ).SetRetryIsEnabled (true ).SetQueueEngine (CustomQueueable)
191197```
192198
193199#### Logs:
@@ -203,11 +209,29 @@ type Logger interface {
203209
204210``` go
205211// example with default options
206- DefaultOptions ().SetDebugMode (true ).SetLogger (SomeLogger)
212+ cx. DefaultOptions ().SetDebugMode (true ).SetLogger (SomeLogger)
207213```
208214
209215#### Tests:
210216
211217- ` $ go test -v ./... `
212- - ` $ go test -v ./... -tags=integration `
213- - ` $ golangci-lint run --config ./.golangci.yml `
218+ - ` $ golangci-lint run --config ./.golangci.yml `
219+
220+ ** Integration Tests:**
221+
222+ ``` shell
223+ export CLICKHOUSE_HOST=111.11.11.11:9000
224+ export REDIS_HOST=111.11.11.11:6379
225+ export REDIS_PASS=password_if_needed
226+
227+ $ go test -v ./... -tags=integration
228+ ```
229+
230+ ### TODO:
231+
232+ - [ ] buffer interfaces
233+ - [ ] more retry buffer interfaces
234+ - [ ] rewrite retry lib
235+ - [ ] create binary app for streaming data to clickhouse
236+ - [ ] client and server with HTTP interface
237+ - [ ] client and server with gRPC interface
0 commit comments