rkredis

package module
v1.2.19 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2023 License: Apache-2.0 Imports: 15 Imported by: 2

README

rk-db/redis

Init go-redis from YAML config.

This belongs to rk-boot family. We suggest use this lib from rk-boot.

Supported bootstrap

Bootstrap Description
YAML based Start go-redis from YAML
Code based Start go-redis from code

Supported Instances

All instances could be configured via YAML or Code.

User can enable anyone of those as needed! No mandatory binding!

Instance Description
redis.UniversalClient Compatible with original go-redis
Logger Implementation of logger wrapped by uber-go/zap logger
Tracing Automatically record tracing

Installation

  • rk-boot: Bootstrapper base
  • rk-gin: Bootstrapper for gin-gonic/gin Web Framework for API
  • rk-db/redis: Bootstrapper for go-redis of redis
go get github.com/rookie-ninja/rk-boot/v2
go get github.com/rookie-ninja/rk-gin/v2
go get github.com/rookie-ninja/rk-db/redis

Quick Start

In the bellow example, we will run Redis locally and implement API of Get/Set of K/V.

  • GET /v1/get, get value
  • POST /v1/set, set value

Please refer example at example.

1.Create boot.yaml

boot.yaml

  • Create web server with Gin framework at port 8080
  • Create Redis entry which connects Redis at localhost:6379
---
gin:
  - name: server
    enabled: true
    port: 8080
redis:
  - name: redis                      # Required
    enabled: true                    # Required
    addrs: ["localhost:6379"]        # Required, One addr is for single, multiple is for cluster
2.Create main.go

In the main() function, we implement bellow things.

  • Register APIs into Gin router.
// Copyright (c) 2021 rookie-ninja
//
// Use of this source code is governed by an Apache-style
// license that can be found in the LICENSE file.
package main

import (
	"context"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"github.com/rookie-ninja/rk-boot/v2"
	"github.com/rookie-ninja/rk-db/redis"
	"github.com/rookie-ninja/rk-gin/v2/boot"
	"net/http"
	"time"
)

var redisClient *redis.Client

func main() {
	boot := rkboot.NewBoot()

	boot.Bootstrap(context.TODO())

	// Auto migrate database and init global userDb variable
	redisEntry := rkredis.GetRedisEntry("redis")
	redisClient, _ = redisEntry.GetClient()

	// Register APIs
	ginEntry := rkgin.GetGinEntry("server")
	ginEntry.Router.GET("/v1/get", Get)
	ginEntry.Router.POST("/v1/set", Set)

	boot.WaitForShutdownSig(context.TODO())
}

type KV struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

func Set(ctx *gin.Context) {
	payload := &KV{}

	if err := ctx.BindJSON(payload); err != nil {
		ctx.JSON(http.StatusInternalServerError, err)
		return
	}

	cmd := redisClient.Set(ctx.Request.Context(), payload.Key, payload.Value, time.Minute)

	if cmd.Err() != nil {
		ctx.JSON(http.StatusInternalServerError, cmd.Err())
		return
	}

	ctx.Status(http.StatusOK)
}

func Get(ctx *gin.Context) {
	key := ctx.Query("key")

	cmd := redisClient.Get(ctx.Request.Context(), key)

	if cmd.Err() != nil {
		if cmd.Err() == redis.Nil {
			ctx.JSON(http.StatusNotFound, "Key not found!")
		} else {
			ctx.JSON(http.StatusInternalServerError, cmd.Err())
		}
		return
	}

	payload := &KV{
		Key:   key,
		Value: cmd.Val(),
	}

	ctx.JSON(http.StatusOK, payload)
}

3.Start server
$ go run main.go

2022-01-20T18:59:32.976+0800    INFO    boot/gin_entry.go:596   Bootstrap ginEntry      {"eventId": "8d1ec972-6439-4026-bedf-7e1f62724849", "entryName": "server"}
------------------------------------------------------------------------
endTime=2022-01-20T18:59:32.976769+08:00
startTime=2022-01-20T18:59:32.97669+08:00
elapsedNano=78808
timezone=CST
ids={"eventId":"8d1ec972-6439-4026-bedf-7e1f62724849"}
app={"appName":"rk","appVersion":"","entryName":"server","entryType":"Gin"}
env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"10.8.0.6","os":"darwin","realm":"*","region":"*"}
payloads={"ginPort":8080}
error={}
counters={}
pairs={}
timing={}
remoteAddr=localhost
operation=Bootstrap
resCode=OK
eventStatus=Ended
EOE
2022-01-20T18:59:32.976+0800    INFO    redis/boot.go:298       Bootstrap redis entry   {"entryName": "redis", "clientType": "Single"}
4.Validation
4.1 Set value
$ curl -X POST "localhost:8080/v1/set" -d '{"key":"my-key","value":"my-value"}'
4.2 Get value
$ curl -X GET "localhost:8080/v1/get?key=my-key"
{"key":"my-key","value":"my-value"}

YAML Options

User can start multiple go-redis instances at the same time. Please make sure use different names.

Nearly all the fields were followed fields defined at Option

redis:
  - name: redis                      # Required
    enabled: true                    # Required
    addrs: ["localhost:6379"]        # Required, One addr is for single, multiple is for cluster
#    description: ""                 # Optional
#
#    # For HA
#    mansterName: ""                 # Optional, required when connecting to Sentinel(HA)
#    sentinelPass: ""                # Optional, default: ""
#
#    # For cluster
#    maxRedirects: 3                 # Optional, default: 3
#    readOnly: false                 # Optional, default: false
#    routeByLatency: false           # Optional, default: false
#    routeRandomly: false            # Optional, default: false
#
#    # Common options
#    db: 0                           # Optional, default: 0
#    user: ""                        # Optional, default: ""
#    pass: ""                        # Optional, default: ""
#    maxRetries: 3                   # Optional, default: 3
#    minRetryBackoffMs: 8            # Optional, default: 8
#    maxRetryBackoffMs: 512          # Optional, default: 512
#    dialTimeoutMs: 5000             # Optional, default: 5000 (5 seconds)
#    readTimeoutMs: 3000             # Optional, default: 3000 (3 seconds)
#    writeTimeoutMs: 1               # Optional, default: 3000 (3 seconds)
#    poolFIFO: false                 # Optional, default: false
#    poolSize: 10                    # Optional, default: 10
#    minIdleConn: 0                  # Optional, default: 0
#    maxIdleConn: 0                  # Optional, default: 0
#    connMaxIdleTimeMs: 3000         # Optional, default: 3000 (3 seconds)
#    connMaxLifetimeMs: 3000         # Optional, default: 3000 (3 seconds)
#    poolTimeoutMs: 1300             # Optional, default: 1300 (1.3 seconds)
#    idleTimeoutMs: 1                # Optional, default: 5 minutes
#    idleCheckFrequencyMs: 1         # Optional, default: 1 minutes
#
#    loggerEntry: ""                 # Optional, default: default logger with STDOUT
Usage of domain
RK use <domain> to distinguish different environment.
Variable of <locale> could be composed as form of <domain>
- domain: Stands for different environment, like dev, test, prod and so on, users can define it by themselves.
          Environment variable: DOMAIN
          Eg: prod
          Wildcard: supported

How it works?
Firstly, get environment variable named as  DOMAIN.
Secondly, compare every element in locale variable and environment variable.
If variables in locale represented as wildcard(*), we will ignore comparison step.

Example:
# let's assuming we are going to define DB address which is different based on environment.
# Then, user can distinguish DB address based on locale.
# We recommend to include locale with wildcard.
---
DB:
  - name: redis-default
    domain: "*"
    addr: "192.0.0.1:6379"
  - name: redis-in-test
    domain: "test"
    addr: "192.0.0.1:6379"
  - name: redis-in-prod
    domain: "prod"
    addr: "176.0.0.1:6379"

Documentation

Overview

Package rkredis is an implementation of rkentry.Entry which could be used redis client instance.

Index

Constants

View Source
const (
	RedisEntryType = "RedisEntry"
)

Variables

This section is empty.

Functions

func RegisterRedisEntryYAML added in v1.0.0

func RegisterRedisEntryYAML(raw []byte) map[string]rkentry.Entry

RegisterRedisEntryYAML register RedisEntry based on config file into rkentry.GlobalAppCtx

func ToRedisUniversalOptions

func ToRedisUniversalOptions(config *BootRedisE) *redis.UniversalOptions

ToRedisUniversalOptions convert BootConfigRedis to redis.UniversalOptions

Types

type BootRedis added in v1.0.0

type BootRedis struct {
	Redis []*BootRedisE `yaml:"redis" json:"redis"`
}

BootRedis Redis entry boot config which reflects to YAML config

type BootRedisE added in v1.0.0

type BootRedisE struct {
	Name                  string   `yaml:"name" json:"name"` // Required
	Description           string   `yaml:"description" json:"description"`
	Enabled               bool     `yaml:"enabled" json:"enabled"` // Required
	Domain                string   `yaml:"domain" json:"domain"`
	Addrs                 []string `yaml:"addrs" json:"addrs"` // Required
	MasterName            string   `yaml:"masterName" json:"masterName"`
	SentinelPass          string   `yaml:"sentinelPass" json:"sentinelPass"`
	DB                    int      `yaml:"db" json:"db"`     // Required
	User                  string   `yaml:"user" json:"user"` // Required
	Pass                  string   `yaml:"pass" json:"pass"` // Required
	MaxRetries            int      `yaml:"maxRetries" json:"maxRetries"`
	MinRetryBackoffMs     int      `yaml:"minRetryBackoffMs" json:"minRetryBackoffMs"`
	MaxRetryBackoffMs     int      `yaml:"maxRetryBackoffMs" json:"maxRetryBackoffMs"`
	DialTimeoutMs         int      `yaml:"dialTimeoutMs" json:"dialTimeoutMs"`
	ReadTimeoutMs         int      `yaml:"readTimeoutMs" json:"readTimeoutMs"`
	WriteTimeoutMs        int      `yaml:"writeTimeoutMs" json:"writeTimeoutMs"`
	ContextTimeoutEnabled bool     `yaml:"contextTimeoutEnabled" json:"contextTimeoutEnabled"`
	PoolFIFO              bool     `yaml:"poolFIFO" json:"poolFIFO"`
	PoolSize              int      `yaml:"poolSize" json:"poolSize"`
	MinIdleConn           int      `yaml:"minIdleConn" json:"minIdleConn"`
	MaxIdleConn           int      `yaml:"maxIdleConn" json:"maxIdleConn"`
	ConnMaxIdleTimeMs     int      `yaml:"connMaxIdleTimeMs" json:"connMaxIdleTimeMs"`
	ConnMaxLifetimeMs     int      `yaml:"connMaxLifetimeMs" json:"connMaxLifetimeMs"`
	PoolTimeoutMs         int      `yaml:"poolTimeoutMs" json:"poolTimeoutMs"`
	IdleTimeoutMs         int      `yaml:"idleTimeoutMs" json:"idleTimeoutMs"`
	IdleCheckFrequencyMs  int      `yaml:"idleCheckFrequencyMs" json:"idleCheckFrequencyMs"`
	MaxRedirects          int      `yaml:"maxRedirects" json:"maxRedirects"`
	ReadOnly              bool     `yaml:"readOnly" json:"readOnly"`
	RouteByLatency        bool     `yaml:"routeByLatency" json:"routeByLatency"`
	RouteRandomly         bool     `yaml:"routeRandomly" json:"routeRandomly"`
	LoggerEntry           string   `yaml:"loggerEntry" json:"loggerEntry"`
	CertEntry             string   `yaml:"certEntry" json:"certEntry"`
}

BootRedisE sub struct for BootRedis

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

func NewLogger

func NewLogger(zapLogger *zap.Logger) *Logger

func (Logger) Printf

func (l Logger) Printf(ctx context.Context, format string, v ...interface{})

type Option

type Option func(e *RedisEntry)

Option for RedisEntry

func WithCertEntry

func WithCertEntry(in *rkentry.CertEntry) Option

WithCertEntry provide CertEntry

func WithDescription

func WithDescription(description string) Option

WithDescription provide name.

func WithLoggerEntry added in v1.0.0

func WithLoggerEntry(entry *rkentry.LoggerEntry) Option

WithLoggerEntry provide rkentry.LoggerEntry entry name

func WithName

func WithName(name string) Option

WithName provide name.

func WithUniversalOption

func WithUniversalOption(opt *redis.UniversalOptions) Option

WithUniversalOption provide redis.UniversalOptions

type RedisEntry

type RedisEntry struct {
	ClientType string                  `yaml:"clientType" json:"clientType"`
	Opts       *redis.UniversalOptions `yaml:"-" json:"-"`

	Client redis.UniversalClient `yaml:"-" json:"-"`
	// contains filtered or unexported fields
}

RedisEntry will init redis.Client with provided arguments

func GetRedisEntry

func GetRedisEntry(entryName string) *RedisEntry

GetRedisEntry returns RedisEntry

func RegisterRedisEntry

func RegisterRedisEntry(opts ...Option) *RedisEntry

RegisterRedisEntry will register Entry into GlobalAppCtx

func (*RedisEntry) Bootstrap

func (entry *RedisEntry) Bootstrap(ctx context.Context)

Bootstrap RedisEntry

func (*RedisEntry) GetClient

func (entry *RedisEntry) GetClient() (*redis.Client, bool)

GetClient convert redis.UniversalClient to proper redis.Client

func (*RedisEntry) GetClientCluster

func (entry *RedisEntry) GetClientCluster() (*redis.ClusterClient, bool)

GetClient convert redis.UniversalClient to proper redis.ClusterClient

func (*RedisEntry) GetDescription

func (entry *RedisEntry) GetDescription() string

GetDescription returns entry description

func (*RedisEntry) GetName

func (entry *RedisEntry) GetName() string

GetName returns entry name

func (*RedisEntry) GetType

func (entry *RedisEntry) GetType() string

GetType returns entry type

func (*RedisEntry) Interrupt

func (entry *RedisEntry) Interrupt(ctx context.Context)

Interrupt RedisEntry

func (*RedisEntry) IsTlsEnabled

func (entry *RedisEntry) IsTlsEnabled() bool

IsTlsEnabled checks TLS

func (*RedisEntry) String

func (entry *RedisEntry) String() string

String returns json marshalled string

type RedisTracer

type RedisTracer struct{}

func NewRedisTracer

func NewRedisTracer() *RedisTracer

func (*RedisTracer) DialHook added in v1.2.17

func (t *RedisTracer) DialHook(next redis.DialHook) redis.DialHook

func (*RedisTracer) ProcessHook added in v1.2.17

func (t *RedisTracer) ProcessHook(next redis.ProcessHook) redis.ProcessHook

func (*RedisTracer) ProcessPipelineHook added in v1.2.17

func (t *RedisTracer) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.ProcessPipelineHook

Jump to

Keyboard shortcuts

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