Skip to content

Commit f8f8c55

Browse files
authored
Merge pull request #5 from innogames/packaging
Packaging
2 parents ad883e1 + 4bc5108 commit f8f8c55

File tree

9 files changed

+166
-4
lines changed

9 files changed

+166
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
graphite-ch-optimizer
2+
build/

Makefile

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
NAME = graphite-ch-optimizer
2+
VERSION = $(shell git describe --long --tags 2>/dev/null | sed 's/^v//;s/\([^-]*-g\)/c\1/;s/-/./g')
3+
VENDOR = "System Administration <[email protected]>"
4+
URL = https://github.com/innogames/$(NAME)
5+
define DESC =
6+
'Service to optimize stale GraphiteMergeTree tables
7+
This software looking for tables with GraphiteMergeTree engine and evaluate if some of partitions should be optimized. It could work both as one-shot script and background daemon.'
8+
endef
9+
PKG_FILES = build/$(NAME)_$(VERSION)_amd64.deb build/$(NAME)-$(VERSION)-1.x86_64.rpm
10+
11+
.PHONY: clean all
12+
13+
all: build
14+
15+
clean:
16+
rm -rf build
17+
rm -rf $(NAME)
18+
19+
rebuild: clean all
20+
21+
build: $(NAME)
22+
23+
$(NAME):
24+
go build -ldflags "-X 'main.version=$(VERSION)'" -o $@ .
25+
26+
build/$(NAME): $(NAME).go
27+
GOOS=linux GOARCH=amd64 go build -ldflags "-X 'main.version=$(VERSION)'" -o $@ .
28+
29+
build/config.toml.example: build/$(NAME)
30+
./build/$(NAME) --print-defaults > $@
31+
32+
packages: $(PKG_FILES)
33+
34+
.ONESHELL:
35+
build/pkg: build/$(NAME) build/config.toml.example
36+
cd build
37+
mkdir -p pkg/etc/$(NAME)
38+
mkdir -p pkg/usr/bin
39+
cp -l $(NAME) pkg/usr/bin/
40+
cp -l config.toml.example pkg/etc/$(NAME)
41+
42+
deb: $(word 1, $(PKG_FILES))
43+
44+
rpm: $(word 2, $(PKG_FILES))
45+
46+
# Set TYPE to package suffix w/o dot
47+
$(PKG_FILES): TYPE = $(subst .,,$(suffix $@))
48+
$(PKG_FILES): build/pkg
49+
fpm --verbose \
50+
-s dir \
51+
-a x86_64 \
52+
-t $(TYPE) \
53+
--vendor $(VENDOR) \
54+
-m $(VENDOR) \
55+
--url $(URL) \
56+
--description $(DESC) \
57+
--license MIT \
58+
-n $(NAME) \
59+
-v $(VERSION) \
60+
--after-install packaging/postinst \
61+
--before-remove packaging/prerm \
62+
-p build \
63+
build/pkg/=/ \
64+
packaging/$(NAME).service=/lib/systemd/system/$(NAME).service

README.md

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,35 @@
11
# Service to optimize stale GraphiteMergeTree tables
2+
When you use [GraphiteMergeTree](https://clickhouse.yandex/docs/en/operations/table_engines/graphitemergetree) in ClickHouse DBMS, it applies retention policies from `system.graphite_retentions` configuration during merge processes. Unfortunately, ClickHouse doesn't launch merges for partitions a) without active inserts or b) with only one part in. It means, that it never will watch for the actual retention scheme applied to partitions.
23
This software looking for tables with GraphiteMergeTree engine and evaluate if some of partitions should be optimized. It could work both as one-shot script and background daemon.
34

5+
## Build
6+
To build a binary just run `make`.
7+
8+
You should have make, golang and [fpm](https://github.com/jordansissel/fpm) installed to build packages. To build packages run one of the following:
9+
10+
```
11+
make packages
12+
make deb
13+
make rpm
14+
```
15+
416
## FAQ
517
* The `go` version 1.13 or newer is required
6-
* Deamon mode is preferable over one-shot script for the normal work
18+
* Daemon mode is preferable over one-shot script for the normal work
719
* It's safe to run it on the cluster hosts
820
* You could either run it on the one of replicated host or just over the all hosts
921
* If you have big partitions (month or something like this) and will get exceptions about timeout, then you need to adjust `read_timeout` parameter in DSN
1022
* `optimize_throw_if_noop=1` is not mandatory, but good to have.
23+
* The next picture demonstrates the result of running the daemon for the first time on ~3 years old GraphiteMergeTree table:
24+
<img src="./docs/result.jpg" alt="example"/>
1125

1226
### Details
13-
The next query is executed as search for the partitions to optimize:
27+
The next query is executed with some additional conditions as search for the partitions to optimize:
1428

1529
```sql
1630
SELECT
1731
concat(p.database, '.', p.table) AS table,
32+
p.partition_id AS partition_id,
1833
p.partition AS partition,
1934
max(g.age) AS age,
2035
countDistinct(p.name) AS parts,
@@ -46,7 +61,9 @@ ORDER BY
4661
age ASC
4762
```
4863

49-
Before and after running you could run the next query:
64+
#### The next queries could be executed before and after the daemon running
65+
66+
* Detailed info about each partition of GraphiteMergeTree tables:
5067

5168
```sql
5269
SELECT
@@ -83,7 +100,41 @@ ORDER BY
83100
active ASC
84101
```
85102

86-
It will show general info about every GraphiteMergeTree table on the server.
103+
* Summary about each GraphiteMergeTree table:
104+
105+
```sql
106+
SELECT
107+
database,
108+
table,
109+
count() AS parts,
110+
active,
111+
min(min_date) AS min_date,
112+
max(max_date) AS max_date,
113+
formatReadableSize(sum(bytes_on_disk)) AS size,
114+
sum(rows) AS rows
115+
FROM system.parts
116+
INNER JOIN
117+
(
118+
SELECT
119+
Tables.database AS database,
120+
Tables.table AS table
121+
FROM system.graphite_retentions
122+
ARRAY JOIN Tables
123+
GROUP BY
124+
database,
125+
table
126+
) USING (database, table)
127+
GROUP BY
128+
database,
129+
table,
130+
active
131+
ORDER BY
132+
database ASC,
133+
table ASC,
134+
active ASC
135+
```
136+
137+
They will show general info about every GraphiteMergeTree table on the server.
87138

88139
## Run the graphite-ch-optimizer
89140
If you run the ClickHouse locally, you could just run `graphite-ch-optimizer -n --log-level debug` and see how many partitions on the instance are able to be merged automatically.
@@ -111,6 +162,7 @@ Possible command line arguments:
111162
Usage of graphite-ch-optimizer:
112163
-c, --config string Filename of the custom config. CLI arguments override it
113164
--print-defaults Print default config values and exit
165+
-v, --version Print version and exit
114166
--optimize-interval duration The active partitions won't be optimized more than once per this interval, seconds (default 72h0m0s)
115167
-s, --server-dsn string DSN to connect to ClickHouse server (default "tcp://localhost:9000?&optimize_throw_if_noop=1&read_timeout=3600&debug=true")
116168
-n, --dry-run Will print how many partitions would be merged without actions

docs/result.jpg

41.2 KB
Loading

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2+
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
23
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
34
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
45
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
56
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
67
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
78
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
89
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
10+
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
911
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
1012
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
1113
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
14+
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
1215
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
1316
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
1417
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
1518
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
1619
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
1720
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
1821
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
22+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1923
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2024
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
2125
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
@@ -45,10 +49,13 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
4549
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
4650
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
4751
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
52+
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
4853
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
4954
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
55+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
5056
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
5157
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
58+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
5259
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
5360
github.com/kshvakov/clickhouse v1.3.11 h1:dtzTJY0fCA+MWkLyuKZaNPkmSwdX4gh8+Klic9NB1Lw=
5461
github.com/kshvakov/clickhouse v1.3.11/go.mod h1:/SVBAcqF3u7rxQ9sTWCZwf8jzzvxiZGeQvtmSF2BBEc=
@@ -61,8 +68,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
6168
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
6269
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
6370
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
71+
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
6472
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
6573
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
74+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6675
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6776
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
6877
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
@@ -92,6 +101,7 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y
92101
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
93102
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
94103
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
104+
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
95105
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
96106
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
97107
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
@@ -133,6 +143,7 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
133143
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
134144
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
135145
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
146+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
136147
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
137148
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
138149
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=

graphite-ch-optimizer.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"github.com/spf13/viper"
2121
)
2222

23+
var version = "development"
24+
2325
// SelectUnmerged is the query to create the temporary table with
2426
// partitions and the retention age, which should be applied
2527
const SelectUnmerged = `
@@ -153,6 +155,7 @@ func processFlags() error {
153155
pflag.CommandLine.SortFlags = false
154156
customConfig := pflag.StringP("config", "c", "", "Filename of the custom config. CLI arguments override it")
155157
pflag.Bool("print-defaults", false, "Print default config values and exit")
158+
pflag.BoolP("version", "v", false, "Print version and exit")
156159

157160
// ClickHouse set
158161
fc := pflag.NewFlagSet("clickhouse", 0)
@@ -172,6 +175,7 @@ func processFlags() error {
172175
pflag.CommandLine.AddFlagSet(fd)
173176
pflag.CommandLine.AddFlagSet(fl)
174177

178+
pflag.ErrHelp = fmt.Errorf("\nVersion: %s", version)
175179
pflag.Parse()
176180
// We must read config files before the setting of the config config to flags' values
177181
err := readConfigFile(*customConfig)
@@ -232,6 +236,16 @@ func getConfig() Config {
232236
logrus.Fatalf("Failed to process flags: %v", err)
233237
}
234238

239+
// Prints version and exit
240+
printVersion, err := pflag.CommandLine.GetBool("version")
241+
if err != nil {
242+
logrus.Fatal("Can't get '--version' value")
243+
}
244+
if printVersion {
245+
fmt.Println(version)
246+
os.Exit(0)
247+
}
248+
235249
// Prints default config and exits
236250
printDefaults, err := pflag.CommandLine.GetBool("print-defaults")
237251
if err != nil {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[Unit]
2+
Description=Service to optimize stale GraphiteMergeTree tables
3+
After=network.target
4+
5+
[Service]
6+
Type=simple
7+
ExecStart=/usr/bin/graphite-ch-optimizer
8+
Restart=on-failure
9+
User=nobody
10+
11+
[Install]
12+
WantedBy=multi-user.target

packaging/postinst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
3+
systemctl enable graphite-ch-optimizer.service
4+
systemctl start graphite-ch-optimizer.service

packaging/prerm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
3+
systemctl disable graphite-ch-optimizer.service
4+
systemctl stop graphite-ch-optimizer.service

0 commit comments

Comments
 (0)