SoFunction
Updated on 2025-05-12

Sample code used for redis in go

Using Redis for data storage and management in Go can bring efficient and flexible advantages. The following explanation includes the deployment and use of stand-alone mode, sentinel mode and cluster mode.

1. Introduction to Redis

Redis is a high-performance in-memory database that supports a variety of data structures, such as strings, hashs, lists, sets, ordered sets (ZSets), etc. It also supports transactions, batch operations, and streaming data processing. Redis is often used in cache, real-time data processing, counters, message queues and other scenarios.

2. The use of Redis in Go

1. Install the Go Redis package

Recommended use/go-redis/redis/v9, it supports stand-alone, sentinel and cluster modes.

Installation command:

go get /go-redis/redis/v9

2. Standalone mode

Features: Single Redis instance, simple and easy to use, suitable for development and testing environments.

Connection example

package main

import (
	"context"
	"fmt"
	"/go-redis/redis/v9"
)

func main() {
	ctx := ()
	client := (&{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})

	pong, err := (ctx).Result()
	if err != nil {
		("Connection failed: %v\n", err)
		return
	}
	(pong)  // Output: PONG
	// Example: Set and get values	if err := (ctx, "key", "value", 0).Err(); err != nil {
		("Setting failed: %v\n", err)
		return
	}
	val, err := (ctx, "key").Result()
	if err != nil {
		("Fetch failed: %v\n", err)
		return
	}
	("Value: %v\n", val)
}

illustrate

  • useCreate a client.
  • usePingTest the connection.
  • SetSet key value,GetRead the value.

3. Sentinel Mode

Features: Provides high availability and automatically failover when the main library fails.

rely

  • Redis Sentinel service must be installed.

Connection example

package main

import (
	"context"
	"fmt"
	"/go-redis/redis/v9"
)

func main() {
	ctx := ()
	client := (&{
		MasterName:    "mymaster",
		SentinelAddrs: []string{"localhost:26379", "localhost:26380", "localhost:26381"},
	})

	pong, err := (ctx).Result()
	if err != nil {
		("Connection failed: %v\n", err)
		return
	}
	(pong)

	// Example: Set and get values	if err := (ctx, "key", "value", 0).Err(); err != nil {
		("Setting failed: %v\n", err)
		return
	}
	val, err := (ctx, "key").Result()
	if err != nil {
		("Fetch failed: %v\n", err)
		return
	}
	("Value: %v\n", val)
}

illustrate

  • useCreate a client.
  • Specify the main library nameMasterNameand sentinel address.
  • When the main library fails, the sentry will automatically upgrade the slave library to the main library.

3. Redis cluster

1. Cluster mode

Features: horizontal expansion is achieved through sharding, and each node processes part of the data, suitable for high-concurrency scenarios.

Cluster deployment

Deployment Structure

  • 6 nodes: 3 masters and 3 slaves, each master node is responsible for a shard.
  • Each shard has 1 master and 1 slave.

Create a cluster using redis-cli

  • Start 6 Redis instances and specify different ports respectively.
  • useredis-cliCommand to create a cluster.

Create a cluster script: For examplestart_cluster.sh

# Start 6 nodes, with ports from 30001 to 30006 respectivelyfor port in {30001..30006}; do
    redis-server --cluster-enabled yes --cluster-config-file node-${port}.conf --port ${port} --daemonize yes
done

# Create a clusterredis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1

In the script above,node-${port}.confIt is the configuration file of each node in Redis cluster mode, which is used to specify the operating parameters of the node. If these configuration files do not exist, Redis will automatically generate a default configuration file, but to ensure the correctness of cluster deployment, it is best to create these configuration files manually.

For example:

# 
cluster-enabled yes
port 30001
bind 127.0.0.1
daemonize yes
logfile /var/log/redis/redis_30001.log
dir ./data/30001
save 60 1
appendonly yes

explain:

  • cluster-enabled yes: Enable cluster mode.
  • port: Specify the port of the current node.
  • bind: Bind the host address.
  • daemonize yes: Run in the background.
  • logfile: Specify the log file path.
  • dir: Specify the data file storage path.
  • save: Configure data persistence policy.
  • appendonly: Enable AOF persistence.

Then give the script execution permissions and run:

chmod +x start_cluster.sh
./start_cluster.sh

Connection example

package main

import (
	"context"
	"fmt"
	"/go-redis/redis/v9"
)

func main() {
	// Cluster node address	addresses := []string{
		"localhost:30001",
		"localhost:30002",
		"localhost:30003",
		"localhost:30004",
		"localhost:30005",
		"localhost:30006",
	}

	clusterClient := (&{
		Addrs: addresses,
	})

	pong, err := (()).Result()
	if err != nil {
		("Connection failed: %v\n", err)
		return
	}
	(pong)

	// Set key-value pairs	if err := ((), "key", "value", 0).Err(); err != nil {
		("Setting failed: %v\n", err)
		return
	}

	// Get the value	val, err := ((), "key").Result()
	if err != nil {
		("Fetch failed: %v\n", err)
		return
	}
	("Value: %v\n", val)
}

illustrate

  • useCreate a cluster client.
  • All node addresses are provided during initialization.
  • In cluster mode, Redis automatically handles data sharding and request routing.

4. Common data structures and operations

1. String

// Set expiration timeerr = ((), "key", "value", 10*).Err()

// Increment counternum, err := ((), "counter").Result()

// Decrement counternum, err := ((), "counter").Result()

2. Hash

// Set field valueserr = ((), "hashKey", "field", "value").Err()

// Get field valuevalue, err := ((), "hashKey", "field").Result()

3. List

// Push the element from the lefterr = ((), "listKey", "value").Err()

// The first element on the left pops upvalue, err := ((), "listKey").Result()

4. Set

// Add elementserr = ((), "setKey", "element").Err()

// Remove elementserr = ((), "setKey", "element").Err()

// Get all elementsmembers, err := ((), "setKey").Result()

5. Ordered Set (ZSet)

// Add elements and set scoreserr = ((), "zsetKey", &{Member: "element", Score: 100}).Err()

// Get the element's scorescore, err := ((), "zsetKey", "element").Result()

// Get rankingrank, err := ((), "zsetKey", "element").Result()

V. Transactions and batch operations

1. Transactions

// Start a transactionctx := ()
tx, err := (ctx)

// Execute operations in transactions_, err = ()(
	function(ctx ) (_redis.CMDCb, error) {
		_, err := (ctx, "balance").Result()
		if err != nil {
			return nil, err
		}
		_, err := (ctx, "balance").Result()
		if err != nil {
			return nil, err
		}
		return nil, nil
	},
)

if err != nil {
	("Transaction execution failed: %v\n", err)
}

2. Pipeline Technology

// Create a pipelinepipe := ()

// Execute multiple commandscmds, err := ((), "key1", "value1", 0).
	Set((), "key2", "value2", 0).
	Exec(())

if err != nil {
	("Pipe execution failed: %v\n", err)
	return
}

// Print the resultfor _, cmd := range cmds {
	("%v\n", cmd)
}

6. High availability

1. Copy (master and slave)

  • Set master-slave replication to ensure data security.
  • The master library is written and the data is synchronized to the slave library.
  • The slave library can be used for read separation to improve read performance.

2. Failover

  • Use Sentinel mode to achieve automatic failover.
  • In cluster mode, node failures are automatically migrated.

3. Connection pool

// Configure the connection poolpool := &{
	Dial: func() (, error) {
		return (())
	},
	MaxActive:   10,  // Maximum number of active connections	MaxIdle:      5,   // Maximum number of idle connections	IdleTimeout: 5 * ,
}

// Use connection poolconn := (())
defer ()

7. Monitoring and performance tuning

1. Built-in tools

  • redis-cli: Command line tool, execute various Redis commands.
  • redis-benchmark: Performance benchmarking tool.
#Benchmarkredis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 10000 -q

2. Performance indicators

  • Memory usage: useinfo memoryCheck the memory status.
  • Rejection policy: Configurationmaxmemory-policyAvoid memory overflow.
  • Expiration time: Set up reasonablyexpire, control key life cycle.

3. Debugging

  • useslowlogRecord slow query.
  • monitorblocked clientsandmaster_repl_offset

8. Actual cases

1. High concurrency flash sale system

Demand: Under high concurrency, ensure the correct inventory of goods.

Solution

  • Transaction and distribution locks using Redis.
  • Data structure: Hash stores commodity inventory.
package main

import (
	"context"
	"fmt"
	"sync"
	"time"
	"/go-redis/redis/v9"
)

// Flash kill functionfunc doSecKill(ctx , client *, productId string, userId string) (bool, error) {
	// Lock name: flash kill lock	lockKey := "lock:sec:kill"
	// Product inventory Key	stockKey := "stock:" + productId

	// Try to acquire the lock to prevent overselling	lock, err := (lockKey, 100*).Acquire(ctx, *5).Result()
	if err != nil {
		return false, err
	}
	defer (ctx)

	// Check whether the inventory is sufficient	currentStock, err := (ctx, stockKey, "quantity").Int64()
	if err != nil || currentStock <= 0 {
		return false, ("Insufficient Inventory")
	}

	// Reduce inventory	_, err = (ctx, stockKey, "quantity", -1).Result()
	if err != nil {
		return false, ("Flash kill failed: %v", err)
	}

	return true, nil
}

func main() {
	client := (&{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})

	var wg 
	for i := 0; i < 100; i++ {
		(1)
		go func(userId int) {
			defer ()
			ctx := ()
			success, err := doSecKill(ctx, client, "product001", ("user%d", userId))
			if success {
				("User %d flash sale successful\n", userId)
			} else {
				("User %d failed to kill: %v\n", userId, err)
			}
		}(i)
	}
	()
}

illustrate

  • Use Redis's distribution lock to ensure the atomicity of the flash kill process.
  • Use the Hash structure to store inventory information to achieve concurrent and safe deduction operations.

9. Best Practices

1. Data expiration time

  • Set a reasonable TTL for the key to avoid memory bloating.

2. Memory management

  • monitorused_memory, ensure that memory usage is within a controllable range.
  • Configurationmaxmemoryandmaxmemory-policy

3. Log configuration

  • Turn on Redis logs to record operations and error messages.
  • useslowlogTracking slow query.

4. Security

  • Set a strong password.
  • Configure a firewall to limit access to the source.

5. Monitoring

  • Use Prometheus and Grafana to monitor Redis performance.
  • AlertManager configures alarm rules.

6. Backup and restore

  • Regularly back up RDB or AOF files.
  • Configure master-slave replication to ensure data security.

7. Connection pool management

  • Configure the connection pool parameters rationally to avoid connection exhaustion.

8. Data persistence

  • Select RDB or AOF and configure the persistence policy according to your needs.

10. Summary

Using Redis in Go, especially combining sentinel and cluster mode, can achieve high availability and high scalability systems. Rationally selecting data structures and using transaction and pipeline technologies can improve performance. At the same time, we pay attention to monitoring and maintenance to ensure the stable operation of Redis.

This is the end of this article about the sample code used by redis in go. For more related content of using redis, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!