From d7acf10a2283378c4536dd979d4e2095c5455fea Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sun, 18 Nov 2018 23:34:30 +0800 Subject: [PATCH] docs(redis): add redis-cas.md --- docs/high-concurrency/redis-cas.md | 11 ++++++++++- img/zookeeper-distributed-lock.png | Bin 0 -> 16853 bytes 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 img/zookeeper-distributed-lock.png diff --git a/docs/high-concurrency/redis-cas.md b/docs/high-concurrency/redis-cas.md index 4a4cae1..add1469 100644 --- a/docs/high-concurrency/redis-cas.md +++ b/docs/high-concurrency/redis-cas.md @@ -1,7 +1,16 @@ ## 面试题 - +redis 的并发竞争问题是什么?如何解决这个问题?了解 redis 事务的 CAS 方案吗? ## 面试官心理分析 +这个也是线上非常常见的一个问题,就是**多客户端同时并发写**一个 key,可能本来应该先到的数据后到了,导致数据版本错了。或者是多客户端同时获取一个 key,修改值之后再写回去,只要顺序错了,数据就错了。 +而且 redis 自己就有天然解决这个问题的 CAS 类的乐观锁方案。 ## 面试题剖析 +某个时刻,多个系统实例都去更新某个 key。可以基于 zookeeper 实现分布式锁。每个系统通过 zookeeper 获取分布式锁,确保同一时间,只能有一个系统实例在操作某个 key,别人都不允许读和写。 + +![zookeeper-distributed-lock](/img/zookeeper-distributed-lock.png) + +你要写入缓存的数据,都是从 mysql 里查出来的,都得写入 mysql 中,写入 mysql 中的时候必须保存一个时间戳,从 mysql 查出来的时候,时间戳也查出来。 + +每次要**写之前,先判断**一下当前这个 value 的时间戳是否比缓存里的 value 的时间戳要新。如果是的话,那么可以写,否则,就不能用旧的数据覆盖新的数据。 \ No newline at end of file diff --git a/img/zookeeper-distributed-lock.png b/img/zookeeper-distributed-lock.png new file mode 100644 index 0000000000000000000000000000000000000000..807e1931b0d2729b5a226a3acac562a46d5ce857 GIT binary patch literal 16853 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 literal 0 HcmV?d00001