面试题答案
一键面试Go语言互斥锁在分布式系统中的情况
在分布式系统环境下,Go语言标准库中的 sync.Mutex
并不能直接防止多个进程或节点同时访问共享资源。因为 sync.Mutex
是基于内存的,仅适用于单个Go进程内的并发控制。
分布式环境下实现类似功能的手段及工作机制
- 分布式锁
- 基于Redis实现:
- 工作机制:通过向Redis发送
SETNX
(SET if Not eXists)命令来尝试获取锁。如果键不存在,则设置成功,代表获取到锁;如果键已存在,则获取锁失败。例如,使用如下Go代码:
- 工作机制:通过向Redis发送
- 基于Redis实现:
package main
import (
"fmt"
"github.com/go-redis/redis/v8"
"context"
)
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
ctx := context.Background()
lockKey := "distributed_lock"
lockValue := "unique_value"
success, err := rdb.SetNX(ctx, lockKey, lockValue, 0).Result()
if err != nil {
fmt.Println("Error setting lock:", err)
return
}
if success {
defer rdb.Del(ctx, lockKey)
// 执行临界区代码
fmt.Println("Lock acquired, doing critical section work...")
} else {
fmt.Println("Failed to acquire lock")
}
}
- 基于ZooKeeper实现:
- 工作机制:在ZooKeeper中创建一个临时顺序节点。每个客户端尝试获取锁时,创建一个顺序节点。然后,客户端获取所有子节点列表并排序,检查自己创建的节点是否是最小序号的节点。如果是,则获取到锁;否则,监听比自己序号小的前一个节点的删除事件。当监听到前一个节点被删除时,再次检查自己是否是最小序号的节点,若是则获取到锁。
- 分布式协调服务:例如Etcd,与ZooKeeper类似,通过创建临时节点、比较节点顺序等方式来实现分布式锁,以控制多个进程或节点对共享资源的访问。