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:
- use
Create a client.
- use
Ping
Test the connection. -
Set
Set key value,Get
Read 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:
- use
Create a client.
- Specify the main library name
MasterName
and 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.
- use
redis-cli
Command 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}.conf
It 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:
- use
Create 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: use
info memory
Check the memory status. -
Rejection policy: Configuration
maxmemory-policy
Avoid memory overflow. -
Expiration time: Set up reasonably
expire
, control key life cycle.
3. Debugging
- use
slowlog
Record slow query. - monitor
blocked clients
andmaster_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
- monitor
used_memory
, ensure that memory usage is within a controllable range. - Configuration
maxmemory
andmaxmemory-policy
。
3. Log configuration
- Turn on Redis logs to record operations and error messages.
- use
slowlog
Tracking 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!