1. 持久化
Redis 提供了两种持久化机制:
RDB (Redis Database Backup)
RDB 持久化是指在指定的间隔时间内将内存中的数据快照保存到磁盘中。这种方式可以快速地将数据恢复到保存点,但在服务器宕机时,可能会丢失最近的一些数据。
配置示例:
save 900 1
save 300 10
save 60 10000
上面的配置表示:如果 900 秒内至少有 1 个 key 被修改,300 秒内至少有 10 个 key 被修改,或者 60 秒内至少有 10000 个 key 被修改,则生成一次 RDB 快照。
AOF (Append Only File)
AOF 通过将每个写操作记录到日志文件中,确保数据的持久化。AOF 提供了更高的数据安全性,因为它能更细粒度地记录每个操作。
配置示例:
appendonly yes
appendfilename "appendonly.aof"
AOF 提供了三种同步方式:
always
:每次写操作后同步到磁盘,性能较差,但数据最安全。everysec
:每秒同步一次,性能与安全性平衡。no
:由操作系统决定何时同步,性能最好,但数据安全性最低。
2. 复制
Redis 复制是主从模式的实现,允许数据从一个主节点复制到一个或多个从节点。复制提高了数据的可用性和读取性能。
配置从节点连接到主节点:
slaveof <master-ip> <master-port>
3. 分区
Redis 分区通过将数据分散到多个实例中来水平扩展数据库。这可以通过客户端分片、代理分片或者 Redis Cluster 来实现。
4. 事务
Redis 事务通过 MULTI, EXEC, DISCARD 和 WATCH 命令实现。事务确保一组命令按顺序执行,不会被其他客户端的命令打断。
Go 代码示例:
package main
import (
"fmt"
"github.com/go-redis/redis/v8"
"context"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
err := rdb.Watch(ctx, func(tx *redis.Tx) error {
_, err := tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Set(ctx, "key", "value", 0)
pipe.Incr(ctx, "counter")
return nil
})
return err
}, "key", "counter")
if err != nil {
fmt.Println("Transaction failed:", err)
} else {
fmt.Println("Transaction succeeded")
}
}
5. Lua脚本
Redis 允许使用 Lua 脚本来原子性地执行一系列操作。
Go 代码示例:
package main
import (
"fmt"
"github.com/go-redis/redis/v8"
"context"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
script := redis.NewScript(`
local current = redis.call("get", KEYS[1])
if current == ARGV[1] then
redis.call("set", KEYS[1], ARGV[2])
return 1
else
return 0
end
`)
result, err := script.Run(ctx, rdb, []string{"mykey"}, "oldvalue", "newvalue").Result()
if err != nil {
fmt.Println("Error running script:", err)
} else {
fmt.Println("Script result:", result)
}
}
6. 发布/订阅
发布/订阅允许消息的发布者和订阅者进行松耦合通信。
Go 代码示例:
package main
import (
"fmt"
"github.com/go-redis/redis/v8"
"context"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
pubsub := rdb.Subscribe(ctx, "mychannel")
go func() {
for msg := range pubsub.Channel() {
fmt.Println("Received message:", msg.Payload)
}
}()
rdb.Publish(ctx, "mychannel", "Hello, World!")
}
7. 流水线(Pipelining)
流水线技术通过将多个命令打包在一起,以减少客户端和服务器之间的往返延迟。
Go 代码示例:
package main
import (
"fmt"
"github.com/go-redis/redis/v8"
"context"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
pipe := rdb.Pipeline()
incr := pipe.Incr(ctx, "counter")
pipe.Expire(ctx, "counter", 3600)
_, err := pipe.Exec(ctx)
if err != nil {
fmt.Println("Pipeline execution failed:", err)
} else {
fmt.Println("Counter value:", incr.Val())
}
}
8. 客户端缓冲区
Redis 提供了客户端缓冲区来管理网络流量,可以设置最大缓冲区大小,以防止客户端占用过多内存。
配置示例:
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60