redisbp

package
v0.9.16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2024 License: BSD-3-Clause Imports: 15 Imported by: 0

Documentation

Overview

Package redisbp provides Baseplate integrations for go-redis.

See https://pkg.go.dev/github.com/go-redis/redis/v8 for documentation for go-redis.

It's recommended to be used in "use Redis as a DB" scenarios as it provides Wait function to achieve guaranteed write consistency. For other use cases redispipebp is preferred.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrReplicationFactorFailed = errors.New("redisbp: failed to meet the requested replication factor")

ErrReplicationFactorFailed returns when the cluster client wait function returns replica reached count that is less than desired replication factor

Functions

func MonitorPoolStats deprecated

func MonitorPoolStats(ctx context.Context, client PoolStatser, name string, tags metricsbp.Tags)

MonitorPoolStats publishes stats for the underlying Redis client pool at the rate defined by metricsbp.SysStatsTickerInterval using metricsbp.M.

It is recommended that you call this in a separate goroutine as it will run until it is stopped. It will stop when the given context is Done()

Ex:

go factory.MonitorPoolStats(metricsbp.M.Ctx(), tags)

Deprecated: Statsd metrics are deprecated. Prometheus pool stats metrics are always reported with a monitored client.

func NewMonitoredClient

func NewMonitoredClient(name string, opt *redis.Options) *redis.Client

NewMonitoredClient creates a new *redis.Client object with a redisbp.SpanHook attached that connects to a single Redis instance.

Example

This example demonstrates how to use a NewMonitoredClient.

package main

import (
	"context"

	"github.com/go-redis/redis/v8"
	"github.com/opentracing/opentracing-go"

	"github.com/reddit/baseplate.go/redis/db/redisbp"
	"github.com/reddit/baseplate.go/tracing"
)

// Service is an example go-kit service to help demonstrate how to use
// redis.Cmdable in a service.
type Service struct {
	Redis redis.Cmdable
}

// Endpoint is an example endpoint that will use redis.
func (s Service) Endpoint(ctx context.Context) error {
	return EndpointHandler(ctx, s.Redis)
}

// EndpointHandler is the actual handler function for
// Service.Endpoint.
func EndpointHandler(ctx context.Context, client redis.Cmdable) error {
	// Any calls using the injected Redis client will be monitored using Spans.
	client.Ping(ctx)
	return nil
}

// This example demonstrates how to use a NewMonitoredClient.
func main() {
	name := "redis"
	// Create a basic, monitored redis.Client object.
	client := redisbp.NewMonitoredClient(name, &redis.Options{Addr: ":6379"})

	defer client.Close()

	// Create a "service" with a monitored client.
	svc := Service{Redis: client}

	// Create a server span and attach it to a context object.
	//
	// In production, this will be handled by service middleware rather than
	// being called manually.
	_, ctx := opentracing.StartSpanFromContext(
		context.Background(),
		"test",
		tracing.SpanTypeOption{Type: tracing.SpanTypeServer},
	)
	// Calls to this endpoint will use the factory to create a new client and
	// inject it into the actual implementation
	//
	// In production, the service framework will call these endpoints in
	// response to requests from clients rather than you calling it manually.
	svc.Endpoint(ctx)
}
Output:

func NewMonitoredFailoverClient

func NewMonitoredFailoverClient(name string, opt *redis.FailoverOptions) *redis.Client

NewMonitoredFailoverClient creates a new failover *redis.Client using Redis Sentinel with a redisbp.SpanHook attached.

func OptionsMust

func OptionsMust(options *redis.Options, err error) *redis.Options

OptionsMust can be combine with ClientOptions.Options() to either return the *redis.Options object or panic if an error was returned. This allows you to just pass this into redis.NewClient.

Ex:

var opts redisbp.ClientOptions
client := redis.NewClient(redisbp.OptionsMust(opts.Options()))

Types

type ClientConfig

type ClientConfig struct {
	// URL is passed to redis.ParseURL to initialize the client options.  This is
	// a required field.
	//
	// https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#ParseURL
	URL string `yaml:"url"`

	Pool     PoolOptions    `yaml:"pool"`
	Retries  RetryOptions   `yaml:"retries"`
	Timeouts TimeoutOptions `yaml:"timeouts"`
}

ClientConfig can be used to configure a redis-go "Client". See the docs for redis.Options in redis-go for details on what each value means and what its defaults are: https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options

Can be deserialized from YAML.

Examples:

Minimal YAML:

redis:
 url: redis://localhost:6379

Full YAML:

redis:
 url: redis://localhost:6379
 pool:
  size: 10
  minIdleConnections: 5
  maxConnectionAge: 1m
  timeout: 10s
 retries:
  max: 2
  minBackoff: 1ms
  maxBackoff: 10ms
 timeouts:
  dial: 1s
  read: 100ms
  write: 200ms
Example

This example shows how you can embed a redis config in a struct and parse that with `baseplate.New`.

package main

import (
	"context"

	"github.com/reddit/baseplate.go"
	"github.com/reddit/baseplate.go/ecinterface"
	"github.com/reddit/baseplate.go/redis/db/redisbp"
)

type Config struct {
	baseplate.Config `yaml:",inline"`

	Redis redisbp.ClientConfig `yaml:"redis"`
}

// This example shows how you can embed a redis config in a struct and parse
// that with `baseplate.New`.
func main() {
	// In real code this MUST be replaced by the factory from the actual implementation.
	var ecFactory ecinterface.Factory

	var cfg Config
	if err := baseplate.ParseConfigYAML(&cfg); err != nil {
		panic(err)
	}

	ctx, bp, err := baseplate.New(context.Background(), baseplate.NewArgs{
		Config:             cfg,
		EdgeContextFactory: ecFactory,
	})
	if err != nil {
		panic(err)
	}
	defer bp.Close()

	client := redisbp.NewMonitoredClient("redis", redisbp.OptionsMust(cfg.Redis.Options()))
	client.Ping(ctx)
}
Output:

func (ClientConfig) Options

func (cfg ClientConfig) Options() (*redis.Options, error)

Options returns a redis.Options populated using the values from cfg.

type ClusterClient

type ClusterClient struct {
	*redis.ClusterClient
}

ClusterClient extends redis cluster client with a functional Wait function

func NewMonitoredClusterClient

func NewMonitoredClusterClient(name string, opt *redis.ClusterOptions) *ClusterClient

NewMonitoredClusterClient creates a new *redis.ClusterClient object with a redisbp.SpanHook attached.

func (*ClusterClient) Wait

func (cc *ClusterClient) Wait(ctx context.Context, args WaitArgs) (replicas int64, err error)

Wait blocks the current client until all the previous write commands are successfully transferred and acknowledged by at least the specified number of replicas.

type ClusterConfig

type ClusterConfig struct {
	// Addrs is the seed list of cluster nodes in the format "host:port". This is
	// a required field.
	//
	// Maps to Addrs on redis.ClusterClient.
	Addrs []string `yaml:"addrs"`

	Pool     PoolOptions    `yaml:"pool"`
	Retries  RetryOptions   `yaml:"retries"`
	Timeouts TimeoutOptions `yaml:"timeouts"`
}

ClusterConfig can be used to configure a redis-go "ClusterClient". See the docs for redis.ClusterOptions in redis-go for details on what each value means and what its defaults are: https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#ClusterOptions

Can be deserialized from YAML.

Examples:

Minimal YAML:

redis:
 addrs:
  - localhost:6379
  - localhost:6380

Full YAML:

redis:
 addrs:
  - localhost:6379
  - localhost:6380
 pool:
  size: 10
  minIdleConnections: 5
  maxConnectionAge: 1m
  timeout: 10s
 retries:
  max: 2
  minBackoff: 1ms
  maxBackoff: 10ms
 timeouts:
  dial: 1s
  read: 100ms
  write: 200ms

func (ClusterConfig) Options

func (cfg ClusterConfig) Options() *redis.ClusterOptions

Options returns a redis.ClusterOptions populated using the values from cfg.

type PoolOptions

type PoolOptions struct {
	// Maps to PoolSize on the redis-go options.
	Size int `yaml:"size"`

	// Maps to MinIdleConnections on the redis-go options.
	MinIdleConnections int `yaml:"minIdleConnections"`

	// Maps to MaxConnAge on the redis-go options.
	MaxConnectionAge time.Duration `yaml:"maxConnectionAge"`

	// Maps to PoolTimeout on the redis-go options.
	Timeout time.Duration `yaml:"timeout"`
}

PoolOptions is used to configure the pool attributes of a redis-go Client or ClusterClient. If any value is not set, it will use whatever default is defined by redis-go.

See https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options for details on the specific fields.

Can be deserialized from YAML.

func (PoolOptions) ApplyClusterOptions

func (opts PoolOptions) ApplyClusterOptions(options *redis.ClusterOptions)

ApplyClusterOptions applies the PoolOptions to the redis.ClusterOptions.

func (PoolOptions) ApplyOptions

func (opts PoolOptions) ApplyOptions(options *redis.Options)

ApplyOptions applies the PoolOptions to the redis.Options.

type PoolStatser

type PoolStatser interface {
	// PoolStats returns the stats of the underlying connection pool.
	PoolStats() *redis.PoolStats
}

PoolStatser is an interface with PoolStats that reports pool related metrics

type RetryOptions

type RetryOptions struct {
	// Maps to MaxRetries on the redis-go options.
	Max int `yaml:"max"`

	// Maps to MinRetryBackoff on the redis-go options.
	MinBackoff time.Duration `yaml:"minBackoff"`

	// Maps to MaxRetryBackoff on the redis-go options.
	MaxBackoff time.Duration `yaml:"maxBackoff"`
}

RetryOptions is used to configure the retry behavior of a redis-go Client or ClusterClient.

See https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options for details on the specific fields.

Can be deserialized from YAML.

func (RetryOptions) ApplyClusterOptions

func (opts RetryOptions) ApplyClusterOptions(options *redis.ClusterOptions)

ApplyClusterOptions applies the RetryOptions to the redis.ClusterOptions.

func (RetryOptions) ApplyOptions

func (opts RetryOptions) ApplyOptions(options *redis.Options)

ApplyOptions applies the RetryOptions to the redis.Options.

type SpanHook

type SpanHook struct {
	ClientName string
	Type       string
	Deployment string
	Database   string
	// contains filtered or unexported fields
}

SpanHook is a redis.Hook for wrapping Redis commands and pipelines in Client Spans and metrics.

Example

This example demonstrates how to use SpanHook to automatically add Spans around Redis commands using go-redis

Baseplate.go also provides the MonitoredCmdableFactory object that you can use to create Redis clients with a SpanHook already attached.

// variables should be properly initialized in production code
var (
	// baseClient is not actually used to run commands, we register the Hook
	// to it and use it to create clients for each Server Span.
	baseClient redis.Client
)
// Add the Hook onto baseClient
baseClient.AddHook(redisbp.SpanHook{ClientName: "redis"})
// Create a server span and attach it into a context object
_, ctx := opentracing.StartSpanFromContext(
	context.Background(),
	"test",
	tracing.SpanTypeOption{Type: tracing.SpanTypeServer},
)
// Create a new client using the context for the server span
client := baseClient.WithContext(ctx)
// Commands should now be wrapped using Client Spans
client.Ping(ctx)
Output:

func (SpanHook) AfterProcess

func (h SpanHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error

AfterProcess ends the client Span started by BeforeProcess, publishes the time the Redis command took to complete, and a metric indicating whether the command was a "success" or "fail"

func (SpanHook) AfterProcessPipeline

func (h SpanHook) AfterProcessPipeline(ctx context.Context, cmds []redis.Cmder) error

AfterProcessPipeline ends the client span started by BeforeProcessPipeline, publishes the time the Redis pipeline took to complete, and a metric indicating whether the pipeline was a "success" or "fail"

func (SpanHook) BeforeProcess

func (h SpanHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error)

BeforeProcess starts a client Span before processing a Redis command and starts a timer to record how long the command took.

func (SpanHook) BeforeProcessPipeline

func (h SpanHook) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error)

BeforeProcessPipeline starts a client span before processing a Redis pipeline and starts a timer to record how long the pipeline took.

type TimeoutOptions

type TimeoutOptions struct {
	Dial  time.Duration `yaml:"dial"`
	Read  time.Duration `yaml:"read"`
	Write time.Duration `yaml:"write"`
}

TimeoutOptions is used to configure the timeout behavior of a redis-go Client or ClusterClient.

See https://pkg.go.dev/github.com/go-redis/redis/v8?tab=doc#Options for details on the specific fields.

Can be deserialized from YAML.

func (TimeoutOptions) ApplyClusterOptions

func (opts TimeoutOptions) ApplyClusterOptions(options *redis.ClusterOptions)

ApplyClusterOptions applies the TimeoutOptions to the redis.ClusterOptions.

func (TimeoutOptions) ApplyOptions

func (opts TimeoutOptions) ApplyOptions(options *redis.Options)

ApplyOptions applies the TimeoutOptions to the redis.Options.

type WaitArgs

type WaitArgs struct {
	Key         string
	NumReplicas int
	Timeout     time.Duration
}

WaitArgs enclose inputs for Wait command into a struct

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL