在分布式系统中,分布式锁是一种用于控制对共享资源访问的机制,以确保多进程、多线程环境下的数据一致性。分布式锁有多种实现方式,本文将介绍几种常见的分布式锁及其优缺点。
SELECT ... FOR UPDATE
语句。sql复制代码
-- 创建锁表
CREATE TABLE `distributed_lock` (
`resource` VARCHAR(64) NOT NULL PRIMARY KEY,
`locked` TINYINT(1) NOT NULL DEFAULT 0,
`owner` VARCHAR(64) NOT NULL
);
-- 获取锁
INSERT INTO distributed_lock (resource, locked, owner) VALUES ('resource_name', 1, 'node_id')
ON DUPLICATE KEY UPDATE locked = IF(locked = 0, 1, locked), owner = IF(locked = 0, 'node_id', owner);
-- 释放锁
UPDATE distributed_lock SET locked = 0 WHERE resource = 'resource_name' AND owner = 'node_id';
使用 Redis 的 SETNX
命令或 Redisson
等库实现分布式锁。
SETNX
)java复制代码
import redis.clients.jedis.Jedis;
public class RedisLock {
private Jedis jedis;
private String lockKey;
private long lockTimeout;
public RedisLock(Jedis jedis, String lockKey, long lockTimeout) {
this.jedis = jedis;
this.lockKey = lockKey;
this.lockTimeout = lockTimeout;
}
public boolean tryLock(String value) {
long end = System.currentTimeMillis() + lockTimeout;
while (System.currentTimeMillis() < end) {
if (jedis.setnx(lockKey, value) == 1) {
jedis.expire(lockKey, (int) (lockTimeout / 1000));
return true;
}
if (jedis.ttl(lockKey) == -1) {
jedis.expire(lockKey, (int) (lockTimeout / 1000));
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return false;
}
public void unlock(String value) {
if (value.equals(jedis.get(lockKey))) {
jedis.del(lockKey);
}
}
}
使用 Zookeeper 的临时有序节点(Ephemeral Sequential Nodes)实现分布式锁。
java复制代码
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
public class ZookeeperLock {
private InterProcessMutex lock;
public ZookeeperLock(CuratorFramework client, String lockPath) {
this.lock = new InterProcessMutex(client, lockPath);
}
public void lock() throws Exception {
lock.acquire();
}
public void unlock() throws Exception {
lock.release();
}
}
使用 Etcd 的分布式锁 API 或基于租约机制实现分布式锁。
java复制代码
import io.etcd.jetcd.Client;
import io.etcd.jetcd.lock.LockResponse;
import io.etcd.jetcd.options.PutOption;
public class EtcdLock {
private Client client;
private String lockKey;
private long leaseId;
public EtcdLock(Client client, String lockKey) {
this.client = client;
this.lockKey = lockKey;
}
public boolean lock() {
try {
leaseId = client.getLeaseClient().grant(5).get().getID();
LockResponse response = client.getLockClient().lock(lockKey.getBytes(), leaseId).get();
return response != null;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void unlock() {
try {
client.getLockClient().unlock(lockKey.getBytes()).get();
client.getLeaseClient().revoke(leaseId).get();
} catch (Exception e) {
e.printStackTrace();
}
}
}
锁实现方式 | 优点 | 缺点 |
---|---|---|
数据库锁 | 实现简单,易于理解 | 性能低,存在单点故障,扩展性差 |
Redis 锁 | 性能高,支持高并发,社区支持好 | 存在单点故障,需额外依赖和运维成本 |
Zookeeper 锁 | 强一致性,高可靠性,适合大规模系统 | 实现复杂度高,性能可能成为瓶颈 |
Etcd 锁 | 高可用性,强一致性,适合云原生环境 | 实现复杂度高,相对较新,社区支持较少 |
不同的实现方式各有优缺点,具体选择哪种分布式锁实现方式,取决于具体应用场景及系统需求。对于高并发、高性能要求的场景,Redis 锁通常是不错的选择;而对于需要强一致性和高可靠性的场景,Zookeeper 或 Etcd 则更为适合。希望本文的介绍能帮助你在实际项目中更好地选择和应用分布式锁技术。
希望通过本文可以让你了解分布式锁的概念,以及每种分布式锁的优缺点,也希望下次考试,能够答对25分的题目。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。