visit
Apache Kvrocks is a distributed key-value NoSQL database that uses RocksDB as a storage engine and is compatible with the Redis protocol.
Kvrocks supports most watch
command starting from v2.4.0.
You can launch Kvrocks using Docker:
docker run -it -p 6666:6666 apache/kvrocks
redis-cli -p 6666
127.0.0.1:6666> get foo
(nil)
127.0.0.1:6666> set foo bar
OK
127.0.0.1:6666> get foo
"bar"
You can also
package main
import (
"context"
"github.com/redis/go-redis/v9"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6666",
})
err := rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {
panic(err)
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println("key", val)
}
var incrBy = redis.NewScript(`
local key = KEYS[1]
local change = ARGV[1]
local value = redis.call("GET", key)
if not value then
value = 0
end
value = value + change
redis.call("SET", key, value)
return value
`)
keys := []string{"my_counter"}
values := []interface{}{+1}
num, err := incrBy.Run(ctx, rdb, keys, values...).Int()
With OpenTelemetry, you can instrument your application once and then add or change vendors without changing the instrumentation, for example, here is a list
Uptrace is an
import "github.com/redis/go-redis/extra/redisotel/v9"
rdb := redis.NewClient(&redis.Options{
Addr: ":6666",
})
if err := redisotel.InstrumentTracing(rdb, redisotel.WithDBSystem("kvrocks")); err != nil {
panic(err)
}
if err := redisotel.InstrumentMetrics(rdb, redisotel.WithDBSystem("kvrocks")); err != nil {
panic(err)
}
You can also configure ____to monitor Kvrocks:
receivers:
redis/kvrocks:
endpoint: "kvrocks:6666"
collection_interval: 10s
The receiver works by parsing the output of INFO
command and produces a number of useful metrics:
See
Using OpenTelemetry Metrics API, you can even create custom Kvrocks metrics. For example, the following function parses used_disk_percent
to create kvrocks.used_disk_percent
metric:
var re = regexp.MustCompile(`used_disk_percent:\s(\d+)%`)
func monitorKvrocks(ctx context.Context, rdb *redis.Client) error {
mp := global.MeterProvider()
meter := mp.Meter("github.com/uptrace/uptrace/example/kvrocks")
usedDiskPct, err := meter.AsyncFloat64().Gauge(
"kvrocks.used_disk_percent",
instrument.WithUnit("%"),
)
if err != nil {
return err
}
return meter.RegisterCallback(
[]instrument.Asynchronous{
usedDiskPct,
},
func(ctx context.Context) {
pct, err := getUsedDiskPercent(ctx, rdb)
if err != nil {
otel.Handle(err)
}
usedDiskPct.Observe(ctx, pct, semconv.DBSystemKey.String("kvrocks"))
},
)
}
func getUsedDiskPercent(ctx context.Context, rdb *redis.Client) (float64, error) {
info, err := rdb.Info(ctx, "keyspace").Result()
if err != nil {
return 0, err
}
m := re.FindStringSubmatch(info)
if m == nil {
return 0, errors.New("can't find used_disk_percent metric")
}
n, err := strconv.ParseInt(m[1], 10, 64)
if err != nil {
return 0, err
}
return float64(n) / 100, nil
}
See