Skip to content

Commit 687d154

Browse files
committed
feat: Add Cassandra/Scylla database backend
1 parent 41c4f07 commit 687d154

File tree

4 files changed

+182
-6
lines changed

4 files changed

+182
-6
lines changed

cmd/r3map-benchmark/main.go

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"time"
1616

1717
"github.com/cespare/xxhash/v2"
18+
"github.com/gocql/gocql"
1819
"github.com/minio/minio-go"
1920
"github.com/pojntfx/dudirekta/pkg/rpc"
2021
"github.com/pojntfx/go-nbd/pkg/backend"
@@ -33,10 +34,11 @@ const (
3334
backendTypeDudirekta = "dudirekta"
3435
backendTypeRedis = "redis"
3536
backendTypeS3 = "s3"
37+
backendTypeCassandra = "cassandra"
3638
)
3739

3840
var (
39-
knownBackendTypes = []string{backendTypeFile, backendTypeMemory, backendTypeDirectory, backendTypeDudirekta, backendTypeRedis, backendTypeS3}
41+
knownBackendTypes = []string{backendTypeFile, backendTypeMemory, backendTypeDirectory, backendTypeDudirekta, backendTypeRedis, backendTypeS3, backendTypeCassandra}
4042

4143
errUnknownBackend = errors.New("unknown backend")
4244
errNoPeerFound = errors.New("no peer found")
@@ -63,7 +65,7 @@ func main() {
6365
knownBackendTypes,
6466
),
6567
)
66-
localLocation := flag.String("local-location", filepath.Join(os.TempDir(), "local"), "Local backend's remote address (for dudirekta, e.g. localhost:1337), URI (for redis, e.g. redis://username:password@localhost:6379/0, or S3, e.g. http://accessKey:secretKey@localhost:9000?bucket=bucket&prefix=prefix) or directory (for directory backend)")
68+
localLocation := flag.String("local-location", filepath.Join(os.TempDir(), "local"), "Local backend's remote address (for dudirekta, e.g. localhost:1337), URI (for redis, e.g. redis://username:password@localhost:6379/0, S3, e.g. http://accessKey:secretKey@localhost:9000?bucket=bucket&prefix=prefix or Cassandra/ScyllaDB, e.g. cassandra://username:password@localhost:9042?keyspace=keyspace&table=table&prefix=prefix) or directory (for directory backend)")
6769
localChunking := flag.Bool("local-chunking", true, "Whether the local backend requires to be interfaced with in fixed chunks in tests")
6870

6971
remoteBackend := flag.String(
@@ -74,7 +76,7 @@ func main() {
7476
knownBackendTypes,
7577
),
7678
)
77-
remoteLocation := flag.String("remote-location", filepath.Join(os.TempDir(), "remote"), "Remote backend's remote address (for dudirekta, e.g. localhost:1337), URI (for redis, e.g. redis://username:password@localhost:6379/0, or S3, e.g. http://accessKey:secretKey@localhost:9000?bucket=bucket&prefix=prefix) or directory (for directory backend)")
79+
remoteLocation := flag.String("remote-location", filepath.Join(os.TempDir(), "remote"), "Remote backend's remote address (for dudirekta, e.g. localhost:1337), URI (for redis, e.g. redis://username:password@localhost:6379/0, or S3, e.g. http://accessKey:secretKey@localhost:9000?bucket=bucket&prefix=prefix or Cassandra/ScyllaDB, e.g. cassandra://username:password@localhost:9042?keyspace=keyspace&table=table&prefix=prefix) or directory (for directory backend)")
7880
remoteChunking := flag.Bool("remote-chunking", true, "Whether the remote backend requires to be interfaced with in fixed chunks in tests")
7981

8082
outputBackend := flag.String(
@@ -85,7 +87,7 @@ func main() {
8587
knownBackendTypes,
8688
),
8789
)
88-
outputLocation := flag.String("output-location", filepath.Join(os.TempDir(), "output"), "Output backend's output address (for dudirekta, e.g. localhost:1337), URI (for redis, e.g. redis://username:password@localhost:6379/0, or S3, e.g. http://accessKey:secretKey@localhost:9000?bucket=bucket&prefix=prefix) or directory (for directory backend)")
90+
outputLocation := flag.String("output-location", filepath.Join(os.TempDir(), "output"), "Output backend's output address (for dudirekta, e.g. localhost:1337), URI (for redis, e.g. redis://username:password@localhost:6379/0, or S3, e.g. http://accessKey:secretKey@localhost:9000?bucket=bucket&prefix=prefix or Cassandra/ScyllaDB, e.g. cassandra://username:password@localhost:9042?keyspace=keyspace&table=table&prefix=prefix) or directory (for directory backend)")
8991
outputChunking := flag.Bool("output-chunking", false, "Whether the output backend requires to be interfaced with in fixed chunks in tests")
9092

9193
slice := flag.Bool("slice", false, "Whether to use the slice frontend instead of the file frontend")
@@ -212,7 +214,10 @@ func main() {
212214
panic(err)
213215
}
214216

215-
*config.backendInstance = lbackend.NewRedisBackend(ctx, redis.NewClient(options), *s, false)
217+
client := redis.NewClient(options)
218+
defer client.Close()
219+
220+
*config.backendInstance = lbackend.NewRedisBackend(ctx, client, *s, false)
216221

217222
case backendTypeS3:
218223
u, err := url.Parse(config.backendLocation)
@@ -230,7 +235,7 @@ func main() {
230235
panic(errMissingPassword)
231236
}
232237

233-
client, err := minio.New(net.JoinHostPort(u.Hostname(), u.Port()), user.Username(), pw, u.Scheme == "https")
238+
client, err := minio.New(u.Host, user.Username(), pw, u.Scheme == "https")
234239
if err != nil {
235240
panic(err)
236241
}
@@ -250,6 +255,66 @@ func main() {
250255

251256
*config.backendInstance = lbackend.NewS3Backend(ctx, client, bucketName, u.Query().Get("prefix"), *s, false)
252257

258+
case backendTypeCassandra:
259+
u, err := url.Parse(config.backendLocation)
260+
if err != nil {
261+
panic(err)
262+
}
263+
264+
user := u.User
265+
if user == nil {
266+
panic(errMissingCredentials)
267+
}
268+
269+
pw, ok := user.Password()
270+
if !ok {
271+
panic(errMissingPassword)
272+
}
273+
274+
cluster := gocql.NewCluster(u.Host)
275+
cluster.Consistency = gocql.Quorum
276+
cluster.Authenticator = gocql.PasswordAuthenticator{
277+
Username: user.Username(),
278+
Password: pw,
279+
}
280+
281+
if u.Scheme == "cassandrasecure" {
282+
cluster.SslOpts = &gocql.SslOptions{
283+
EnableHostVerification: true,
284+
}
285+
}
286+
287+
keyspaceName := u.Query().Get("keyspace")
288+
{
289+
setupSession, err := cluster.CreateSession()
290+
if err != nil {
291+
panic(err)
292+
}
293+
294+
if err := setupSession.Query(`create keyspace if not exists ` + keyspaceName + ` with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }`).Exec(); err != nil {
295+
setupSession.Close()
296+
297+
panic(err)
298+
}
299+
300+
setupSession.Close()
301+
}
302+
cluster.Keyspace = keyspaceName
303+
304+
session, err := cluster.CreateSession()
305+
if err != nil {
306+
panic(err)
307+
}
308+
defer session.Close()
309+
310+
tableName := u.Query().Get("table")
311+
312+
if err := session.Query(`create table if not exists ` + tableName + ` (key blob primary key, data blob)`).Exec(); err != nil {
313+
panic(err)
314+
}
315+
316+
*config.backendInstance = lbackend.NewCassandraBackend(session, tableName, u.Query().Get("prefix"), *s, false)
317+
253318
default:
254319
panic(errUnknownBackend)
255320
}

go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.20
55
require (
66
github.com/cespare/xxhash/v2 v2.2.0
77
github.com/edsrzf/mmap-go v1.1.0
8+
github.com/gocql/gocql v1.4.0
89
github.com/minio/minio-go v6.0.14+incompatible
910
github.com/pojntfx/dudirekta v0.5.0
1011
github.com/pojntfx/go-nbd v0.1.9
@@ -14,7 +15,10 @@ require (
1415
require (
1516
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
1617
github.com/go-ini/ini v1.67.0 // indirect
18+
github.com/golang/snappy v0.0.3 // indirect
1719
github.com/google/uuid v1.3.0 // indirect
20+
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
21+
github.com/klauspost/cpuid/v2 v2.0.3 // indirect
1822
github.com/mitchellh/go-homedir v1.1.0 // indirect
1923
github.com/pilebones/go-udev v0.9.0 // indirect
2024
github.com/stretchr/testify v1.8.3 // indirect
@@ -23,4 +27,7 @@ require (
2327
golang.org/x/net v0.4.0 // indirect
2428
golang.org/x/sys v0.8.0 // indirect
2529
golang.org/x/text v0.5.0 // indirect
30+
gopkg.in/inf.v0 v0.9.1 // indirect
2631
)
32+
33+
replace github.com/gocql/gocql => github.com/scylladb/gocql v1.10.0

go.sum

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
1+
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
2+
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
3+
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
4+
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
15
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
26
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
37
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
48
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
9+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
510
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
611
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
712
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
813
github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
914
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
1015
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
1116
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
17+
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
18+
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
19+
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
20+
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
1221
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
1322
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
23+
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
24+
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
25+
github.com/klauspost/cpuid/v2 v2.0.3 h1:DNljyrHyxlkk8139OXIAAauCwV8eQGDD6Z8YqnDXdZw=
26+
github.com/klauspost/cpuid/v2 v2.0.3/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
27+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
28+
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
1429
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
1530
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
31+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
1632
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
1733
github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
1834
github.com/minio/minio-go v6.0.14+incompatible/go.mod h1:7guKYtitv8dktvNUGrhzmNlA5wrAABTQXCoesZdFQO8=
@@ -21,12 +37,17 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
2137
github.com/pilebones/go-udev v0.9.0 h1:N1uEO/SxUwtIctc0WLU0t69JeBxIYEYnj8lT/Nabl9Q=
2238
github.com/pilebones/go-udev v0.9.0/go.mod h1:T2eI2tUSK0hA2WS5QLjXJUfQkluZQu+18Cqvem3CaXI=
2339
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
40+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2441
github.com/pojntfx/dudirekta v0.5.0 h1:oI6uHA0wCVwyLKamt5ECcHyXvgqcEdV83KdDEjnBUYw=
2542
github.com/pojntfx/dudirekta v0.5.0/go.mod h1:2G79XDOe1c3Nz3G+LQfiNZ5K/SS3b2TP1K9JyRt8woI=
2643
github.com/pojntfx/go-nbd v0.1.9 h1:rfk3d0fo92YdKTT9MBqJdglE3j9/YOez7WmXsDaxcbs=
2744
github.com/pojntfx/go-nbd v0.1.9/go.mod h1:SehHnbi2e8NiSAKby42Itm8SIoS7b+wAprsfPH3qgYk=
2845
github.com/redis/go-redis/v9 v9.0.4 h1:FC82T+CHJ/Q/PdyLW++GeCO+Ol59Y4T7R4jbgjvktgc=
2946
github.com/redis/go-redis/v9 v9.0.4/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
47+
github.com/scylladb/gocql v1.10.0 h1:CqBUMPRpgRhNvvWlgcYr5v3Yl42nFY8LKbmpNVQYiV8=
48+
github.com/scylladb/gocql v1.10.0/go.mod h1:OrZ5SWxnPnlOpCawJd0gqfWiP3KkPu624hlXwu+0qOM=
49+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
50+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
3051
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
3152
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
3253
github.com/teivah/broadcast v0.1.0 h1:UMs1tn8w20Xlnod+VbLbwH3dzEH2zfJy4lxdzZjQLL0=
@@ -35,8 +56,12 @@ golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
3556
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
3657
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
3758
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
59+
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3860
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
3961
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
4062
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
4163
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
64+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
65+
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
66+
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
4267
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

pkg/backend/cassandra.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package backend
2+
3+
import (
4+
"log"
5+
"strconv"
6+
7+
"github.com/gocql/gocql"
8+
)
9+
10+
type CassandraBackend struct {
11+
session *gocql.Session
12+
table string
13+
prefix string
14+
size int64
15+
16+
verbose bool
17+
}
18+
19+
func NewCassandraBackend(
20+
session *gocql.Session,
21+
table string,
22+
prefix string,
23+
size int64,
24+
verbose bool,
25+
) *CassandraBackend {
26+
return &CassandraBackend{
27+
session: session,
28+
table: table,
29+
prefix: prefix,
30+
size: size,
31+
32+
verbose: verbose,
33+
}
34+
}
35+
36+
func (b *CassandraBackend) ReadAt(p []byte, off int64) (n int, err error) {
37+
if b.verbose {
38+
log.Printf("ReadAt(len(p) = %v, off = %v)", len(p), off)
39+
}
40+
41+
var val []byte
42+
if err := b.session.Query(`select data from `+b.table+` where key = ? limit 1`, b.prefix+"-"+strconv.FormatInt(off, 10)).Scan(&val); err != nil {
43+
if err == gocql.ErrNotFound {
44+
return len(p), nil
45+
}
46+
47+
return 0, err
48+
}
49+
50+
return copy(p, val), nil
51+
}
52+
53+
func (b *CassandraBackend) WriteAt(p []byte, off int64) (n int, err error) {
54+
if b.verbose {
55+
log.Printf("WriteAt(len(p) = %v, off = %v)", len(p), off)
56+
}
57+
58+
if err := b.session.Query(`insert into `+b.table+` (key, data) values (?, ?)`, b.prefix+"-"+strconv.FormatInt(off, 10), p).Exec(); err != nil {
59+
return 0, err
60+
}
61+
62+
return len(p), nil
63+
}
64+
65+
func (b *CassandraBackend) Size() (int64, error) {
66+
if b.verbose {
67+
log.Println("Size()")
68+
}
69+
70+
return b.size, nil
71+
}
72+
73+
func (b *CassandraBackend) Sync() error {
74+
if b.verbose {
75+
log.Println("Sync()")
76+
}
77+
78+
return nil
79+
}

0 commit comments

Comments
 (0)