Skip to content
This repository was archived by the owner on Sep 3, 2025. It is now read-only.

Commit 1879da0

Browse files
committed
Finalized ru cache for metadata
1 parent ef8a7f5 commit 1879da0

File tree

11 files changed

+141
-214
lines changed

11 files changed

+141
-214
lines changed

README.md

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,11 @@ Building from a source is also easy.
2323
git clone https://github.com/sadoyan/go-webrados.git
2424
cd go-webrados
2525
export GOROOT=/path/to/your/go
26-
./build.sh
27-
28-
./webrados /path/to/config.ini
26+
go mod tidy
27+
do build .
2928
```
3029

3130

32-
3331
### **Configuration**
3432
---------
3533

@@ -42,7 +40,6 @@ listen : 0.0.0.0:8080
4240
dispatchers : 20
4341
serveruser : admin
4442
serverpass : 261a5983599fd57a016122ec85599ec4
45-
uploadmaxpart : 52428800
4643
dangerzone : yes
4744
readonly : no
4845
authread : no
@@ -52,33 +49,35 @@ logfile : no
5249
logpath: /opt/webrados.log
5350
allpools: no
5451
poollist: bublics, donuts, images
55-
database : redis
5652

57-
[redis]
53+
[cache]
54+
shards: 1024
55+
lifewindow: 10
56+
cleanwindow: 1
57+
maxrntriesinwindow: 600000
58+
maxentrysize: 5000
59+
maxcachemb: 1024
60+
61+
[database]
62+
type : ceph
5863
server: 127.0.0.1:6379
5964
username : none
6065
password : none
6166
database : 0
6267

63-
[mysql]
64-
username : ceph
65-
password : ceph
66-
dbname : ceph
67-
server : 127.0.0.1:3306
68-
6968
[monitoring]
7069
enabled : true
7170
url: 127.0.0.1:9090
7271
user: admin
7372
pass: admin
7473
```
74+
7575
### **API**
7676
---------
7777

7878
| **Name** | **Description** |
7979
| ------------- | ------------- |
8080
|**Read File**|HTTP ```GET:``` http://{BINDADDRESS}/{POOLNAME}/{FILENAME}|
81-
|**Read File**|HTTP ```GET:``` http://{BINDADDRESS}/{POOLNAME}/{FILENAME}|
8281
|**Upload File**|HTTP ```POST, PUT:``` http://{BINDADDRESS}/{POOLNAME}/{FILENAME}|
8382
|**Remove File**|HTTP ```DELETE:``` http://{BINDADDRESS}/{POOLNAME}/{FILENAME}|
8483

@@ -87,23 +86,36 @@ Configuration file is pretty simple and intuitive.
8786
### **Section main**
8887
---------
8988

90-
| **Name** | **Description** |
91-
| ------------- | ------------- |
92-
|**listen**|IP port to bind.|
93-
|**dispatchers**|Number of threads for webserver.|
94-
|**serveruser**|Static user.|
95-
|**serverpass**|MD5 hash of password for static user. It can be the output of `echo -n SecretPaSs | md5sum |awk '{print $1}'`|
96-
|**dangerzone**|Enable destructive methods and commands (DELETE).|
97-
|**readonly**|Enable readonly mode. If 'yes' only GET is allowed.|
98-
|**authread**|Require authentication for GET only.|
99-
|**authwrite**|Require authentication for POST/PUT/DELETE.|
100-
|**radoconns**|Number of connection to CEPH.|
101-
|**logfile**|Log to file, if 'no' logs are sent to stdout.|
102-
|**logpath**|Path for log file.|
103-
|**uploadmaxpart**| Maximum file chunk size (Sbould be amaller or erqual ro `osd max object size`).|
104-
|**allpools:**|yes/no . If yes program will scan ceph and enable access via web to all pool.|
105-
|**poollist:**|Works only if **allpools** is set to **no**. Coma separated list of pools which should be accesible via webrados program.|
106-
|**redis**|IP address and port of Redis server.|
89+
| **Name** | **Description** |
90+
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------|
91+
| **listen** | IP port to bind. |
92+
| **dispatchers** | Number of threads for webserver. |
93+
| **serveruser** | Static user. |
94+
| **serverpass** | MD5 hash of password for static user. It can be the output of `echo -n SecretPaSs md5sum |awk '{print $1}'`| |
95+
| **dangerzone** | Enable destructive methods and commands (DELETE). |
96+
| **readonly** | Enable readonly mode. If 'yes' only GET is allowed. |
97+
| **authread** | Require authentication for GET only. |
98+
| **authwrite** | Require authentication for POST/PUT/DELETE. |
99+
| **radoconns** | Number of connection to CEPH. |
100+
| **logfile** | Log to file, if 'no' logs are sent to stdout. |
101+
| **logpath** | Path for log file. |
102+
| **uploadmaxpart** | Maximum file chunk size (Sbould be amaller or erqual ro `osd max object size`). |
103+
| **allpools:** | yes/no . If yes program will scan ceph and enable access via web to all pool. |
104+
| **poollist:** | Works only if **allpools** is set to **no**. Coma separated list of pools which should be accesible via webrados program. |
105+
| **database** | Name of database server for storing metadata of fliles (Ceph, Redis, MySQL). MySQL and Redis are deprecated and will be removed soon |
106+
107+
### **Section cache**
108+
---------
109+
| **Name** | **Description** |
110+
| ------------- |---------------------------------------------------------------------------------------------------|
111+
|**shards**| Number of shards (must be a power of 2) |
112+
|**lifewindow**| Time after which entry can be evicted |
113+
|**cleanwindow**| Interval between removing expired entries (clean up). If set to <= 0 then no action is performed. |
114+
|**maxrntriesinwindow**| rps * lifeWindow, used only in initial memory allocation |
115+
|**maxentrysize**| max entry size in bytes, used only in initial memory allocation |
116+
|**maxcachemb**| Cache will not allocate more memory than this limit, value in MB. 0 value means no size limit |
117+
118+
107119
### **Section monitoring**
108120
---------
109121
| **Name** | **Description** |
@@ -123,9 +135,7 @@ GO-Webrados will periodically read ```uesrs.txt``` file and automatically update
123135
### **Large files**
124136

125137
In order to be able to store large file in RADOS directly files needs to be split to smaller chunks.
126-
GO-WebRados will automatically set maximum chunk size to **uploadmaxpart** and split files in accordance to that.
127-
For this GO-WebRados requires Redis servers to store metadata for big files. (Make sure to keep Redis database safe and periodically back it up.)
128-
Redis will store metadata only for large files. Small files are to split and not require special metadata server.
138+
GO-WebRados will automatically set maximum chunk size to **OSDMaxObjectSize** of Ceph and split files in accordance to that.
129139

130140
### **Special commands**
131141

build.sh

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
#!/bin/bash
22

33
export GOROOT=/usr/local/go
4-
export GOPATH=`pwd`
5-
6-
rm -rf pkg/*
7-
rm -rf src/{github.com,golang.org,gopkg.in}
8-
go get github.com/ceph/go-ceph
9-
go get gopkg.in/ini.v1
10-
go get golang.org/x/sys/unix
11-
go get go.opentelemetry.io/otel
12-
go get github.com/gomodule/redigo/redis
13-
go get github.com/go-sql-driver/mysql
14-
#go get github.com/go-redis/redis
15-
16-
#go build src/webrados.go
4+
go mod tidy
5+
go build webrados.go

config.ini

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@ logfile : no
1212
logpath: /opt/webrados.log
1313
allpools: no
1414
poollist: bublics, donuts, images
15-
database : ceph
16-
cacheitems: 6000000
17-
cachettl : 300
15+
16+
[cache]
17+
shards: 1024
18+
lifewindow: 10
19+
cleanwindow: 1
20+
maxrntriesinwindow: 600000
21+
maxentrysize: 5000
22+
maxcachemb: 1024
23+
1824

1925
[database]
2026
type : ceph

configs/cfg.go

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ import (
55
"github.com/ceph/go-ceph/rados"
66
"gopkg.in/ini.v1"
77
"log"
8-
"math"
98
"os"
109
"strconv"
1110
"strings"
12-
"time"
1311
)
1412

1513
type CfgType struct {
@@ -47,8 +45,14 @@ type CfgType struct {
4745
MySQLUser string
4846
MySQLPassword string
4947
DBType string
50-
CacheItems int
51-
CacheTTL time.Duration
48+
//CacheItems int
49+
//CacheTTL time.Duration
50+
CacheShards int
51+
CacheLifeWindow int
52+
CacheCleanWindow int
53+
CacheMaxEntriesInWindow int
54+
CacheMaxEntrySize int
55+
CacheHardMaxCacheSize int
5256
}
5357

5458
var Conf = &CfgType{
@@ -84,9 +88,15 @@ var Conf = &CfgType{
8488
MySQLDB: "",
8589
MySQLUser: "",
8690
MySQLPassword: "",
87-
DBType: "",
88-
CacheItems: 0,
89-
CacheTTL: math.MaxInt,
91+
DBType: "ceph",
92+
//CacheItems: 0,
93+
//CacheTTL: math.MaxInt,
94+
CacheShards: 1024,
95+
CacheLifeWindow: 1024,
96+
CacheCleanWindow: 20,
97+
CacheMaxEntriesInWindow: 600000,
98+
CacheMaxEntrySize: 5000,
99+
CacheHardMaxCacheSize: 1024,
90100
}
91101

92102
var authorized = make(map[string]string, 10)
@@ -103,6 +113,14 @@ func stringTObool(key string, value string) bool {
103113
return false
104114
}
105115

116+
func stringTOint(key string) int {
117+
a, err := strconv.Atoi(key)
118+
if err != nil {
119+
log.Fatal("\n Value for " + key + " should be numeric\n")
120+
}
121+
return a
122+
}
123+
106124
var Cfgfile = "config.ini"
107125

108126
func SetVarsik() {
@@ -120,26 +138,18 @@ func SetVarsik() {
120138
}
121139

122140
Conf.HttpAddress = cfg.Section("main").Key("listen").String()
123-
Conf.DispatchersCount, _ = cfg.Section("main").Key("dispatchers").Int()
141+
Conf.DispatchersCount = stringTOint(cfg.Section("main").Key("dispatchers").String())
124142
Conf.InternalQueue, _ = cfg.Section("main").Key("internalqueue").Bool()
125143
qs, _ := cfg.Section("main").Key("queuesize").Int()
126144
Conf.queue = make(chan string, qs)
127-
128-
//Conf.Uploadmaxpart, err = cfg.Section("main").Key("uploadmaxpart").Int()
129-
//if err != nil {
130-
// log.Fatal("Please set numeric value to Uploadmaxpart")
131-
//}
132145
vsyo, _ := rados.NewConn()
133146
_ = vsyo.ReadDefaultConfigFile()
134147
_ = vsyo.Connect()
135148
osdMaxObjectSize, _ := vsyo.GetConfigOption("osd max object size")
136149
s, _ := strconv.Atoi(osdMaxObjectSize)
137150
Conf.Uploadmaxpart = s
138151

139-
Conf.Radoconns, err = cfg.Section("main").Key("radoconns").Int()
140-
if err != nil {
141-
log.Fatal("Please set numeric value to Radoconns")
142-
}
152+
Conf.Radoconns = stringTOint(cfg.Section("main").Key("radoconns").String())
143153

144154
Conf.LogStdout = stringTObool("dangerzone", strings.ToLower(cfg.Section("main").Key("logfile").String()))
145155
Conf.Logfile = cfg.Section("main").Key("logpath").String()
@@ -181,19 +191,14 @@ func SetVarsik() {
181191
Conf.DangeZone = stringTObool("dangerzone", strings.ToLower(cfg.Section("main").Key("dangerzone").String()))
182192
}
183193

194+
Conf.CacheShards = stringTOint(cfg.Section("cache").Key("shards").String())
195+
Conf.CacheLifeWindow = stringTOint(cfg.Section("cache").Key("lifewindow").String())
196+
Conf.CacheCleanWindow = stringTOint(cfg.Section("cache").Key("cleanwindow").String())
197+
Conf.CacheMaxEntriesInWindow = stringTOint(cfg.Section("cache").Key("maxrntriesinwindow").String())
198+
Conf.CacheMaxEntrySize = stringTOint(cfg.Section("cache").Key("maxentrysize").String())
199+
Conf.CacheHardMaxCacheSize = stringTOint(cfg.Section("cache").Key("maxcachemb").String())
200+
184201
Conf.DBType = cfg.Section("database").Key("type").String()
185-
cache, cerr := cfg.Section("main").Key("cacheitems").Int()
186-
if cerr != nil {
187-
log.Fatal("Cache capacity should be numeric", cerr)
188-
} else {
189-
Conf.CacheItems = cache
190-
}
191-
cachettl, cttlerr := cfg.Section("main").Key("cachettl").Int()
192-
if cttlerr != nil {
193-
log.Fatal("Cache TTL should be numeric", cttlerr)
194-
} else {
195-
Conf.CacheTTL = time.Duration(cachettl)
196-
}
197202
switch Conf.DBType {
198203
case "redis":
199204
Conf.RedisServer = cfg.Section("database").Key("server").String()
@@ -218,6 +223,7 @@ func SetVarsik() {
218223
Conf.MySQLUser = cfg.Section("database").Key("username").String()
219224
Conf.MySQLPassword = cfg.Section("database").Key("password").String()
220225
case "ceph":
226+
Conf.DBType = "ceph"
221227
}
222228

223229
}

deplohu.sh

Lines changed: 0 additions & 4 deletions
This file was deleted.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
)
1111

1212
require (
13+
github.com/allegro/bigcache/v3 v3.1.0 // indirect
1314
github.com/ceph/go-ceph v0.19.1-0.20230112054424-122159ed21a1 // indirect
1415
github.com/go-sql-driver/mysql v1.7.0 // indirect
1516
github.com/gomodule/redigo v1.8.9 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk=
2+
github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
13
github.com/aws/aws-sdk-go v1.44.151/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
24
github.com/aws/aws-sdk-go v1.44.172/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
35
github.com/ceph/go-ceph v0.19.0/go.mod h1:sdTcqdDeIPWX3TaR5HCi5YtT+BliI6fFvvWP6Io7VQE=

metadata/dbConnect.go

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,43 +19,25 @@ var myConns = 5
1919
//var Cache LRUCache
2020

2121
var config = bigcache.Config{
22-
// number of shards (must be a power of 2)
23-
Shards: 1024,
24-
// time after which entry can be evicted
25-
LifeWindow: 5 * time.Minute,
26-
// Interval between removing expired entries (clean up).
27-
// If set to <= 0 then no action is performed.
28-
// Setting to < 1 second is counterproductive — bigcache has a one second resolution.
29-
CleanWindow: 1 * time.Minute,
30-
// rps * lifeWindow, used only in initial memory allocation
31-
MaxEntriesInWindow: 1000 * 10 * 60,
32-
// max entry size in bytes, used only in initial memory allocation
33-
MaxEntrySize: 5000,
34-
// prints information about additional memory allocation
35-
Verbose: true,
36-
// cache will not allocate more memory than this limit, value in MB
37-
// if value is reached then the oldest entries can be overridden for the new ones
38-
// 0 value means no size limit
39-
HardMaxCacheSize: 1024,
40-
// callback fired when the oldest entry is removed because of its expiration time or no space left
41-
// for the new entry, or because delete was called. A bitmask representing the reason will be returned.
42-
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
43-
OnRemove: nil,
44-
// OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
45-
// for the new entry, or because delete was called. A constant representing the reason will be passed through.
46-
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
47-
// Ignored if OnRemove is specified.
48-
OnRemoveWithReason: nil,
22+
Shards: configs.Conf.CacheShards,
23+
LifeWindow: time.Duration(configs.Conf.CacheLifeWindow) * time.Minute,
24+
CleanWindow: time.Duration(configs.Conf.CacheCleanWindow) * time.Minute,
25+
MaxEntriesInWindow: configs.Conf.CacheMaxEntriesInWindow,
26+
MaxEntrySize: configs.Conf.CacheMaxEntrySize,
27+
Verbose: true,
28+
HardMaxCacheSize: configs.Conf.CacheHardMaxCacheSize,
29+
OnRemove: nil, // callback on remove
30+
OnRemoveWithReason: nil, // callback on remove with reason
4931
}
5032
var Cache, _ = bigcache.New(context.Background(), config)
5133

5234
func DBConnect() {
53-
go func() {
54-
for {
55-
log.Println("[Cache statistics. Len:", Cache.Len(), "Cap:", Cache.Capacity(), "Hits:", Cache.Stats().Hits, "Misses:", strconv.Itoa(int(Cache.Stats().Misses))+"]")
56-
time.Sleep(5 * time.Second)
57-
}
58-
}()
35+
//go func() {
36+
// for {
37+
// log.Println("[Cache statistics. Len:", Cache.Len(), "Cap:", Cache.Capacity(), "Hits:", Cache.Stats().Hits, "Misses:", strconv.Itoa(int(Cache.Stats().Misses))+"]")
38+
// time.Sleep(5 * time.Second)
39+
// }
40+
//}()
5941
switch configs.Conf.DBType {
6042
case "ceph":
6143
log.Println("[Using Rados file xattrs for metadata]")
@@ -103,9 +85,9 @@ func DBClient(filename string, ops string, id string) (string, error) {
10385
file, err = cephget(filename)
10486
if err == nil {
10587

106-
//for i := 1; i <= 100000; i++ {
107-
// _ = Cache.Set(filename+strconv.Itoa(i), []byte(file))
108-
//}
88+
for i := 1; i <= 100000; i++ {
89+
_ = Cache.Set(filename+strconv.Itoa(i), []byte(file))
90+
}
10991

11092
_ = Cache.Set(filename, []byte(file))
11193
//stattemp = "Fresh:"

0 commit comments

Comments
 (0)