Skip to content

Commit 1bb316e

Browse files
committed
fix: update documents about Redis and ElasticSearch
更新 Redis 和 ElasticSearch 文档说明
1 parent ce70118 commit 1bb316e

14 files changed

+79
-79
lines changed

docs/distributed-system/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* [说一下 Dubbo 的工作原理?注册中心挂了可以继续通信吗?](/docs/distributed-system/dubbo-operating-principle.md)
1212
* [Dubbo 支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的?](/docs/distributed-system/dubbo-serialization-protocol.md)
1313
* [Dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?](/docs/distributed-system/dubbo-load-balancing.md)
14-
* [Dubbo 的 spi 思想是什么?](/docs/distributed-system/dubbo-spi.md)
14+
* [Dubbo 的 SPI 思想是什么?](/docs/distributed-system/dubbo-spi.md)
1515
* [如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试?](/docs/distributed-system/dubbo-service-management.md)
1616
* [分布式服务接口的幂等性如何设计(比如不能重复扣款)?](/docs/distributed-system/distributed-system-idempotency.md)
1717
* [分布式服务接口请求的顺序性如何保证?](/docs/distributed-system/distributed-system-request-sequence.md)

docs/distributed-system/distributed-lock-redis-vs-zookeeper.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
## 面试题
2-
一般实现分布式锁都有哪些方式?使用 redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高?
2+
一般实现分布式锁都有哪些方式?使用 Redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高?
33

44
## 面试官心理分析
55

66
其实一般问问题,都是这么问的,先问问你 zk,然后其实是要过渡到 zk 相关的一些问题里去,比如分布式锁。因为在分布式系统开发中,分布式锁的使用场景还是很常见的。
77

88
## 面试题剖析
99

10-
### redis 分布式锁
10+
### Redis 分布式锁
1111

12-
官方叫做 `RedLock` 算法,是 redis 官方支持的分布式锁算法。
12+
官方叫做 `RedLock` 算法,是 Redis 官方支持的分布式锁算法。
1313

1414
这个分布式锁有 3 个重要的考量点:
1515

1616
* 互斥(只能有一个客户端获取锁)
1717
* 不能死锁
18-
* 容错(只要大部分 redis 节点创建了这把锁就可以)
18+
* 容错(只要大部分 Redis 节点创建了这把锁就可以)
1919

20-
#### redis 最普通的分布式锁
20+
#### Redis 最普通的分布式锁
2121

22-
第一个最普通的实现方式,就是在 redis 里使用 `SET key value [EX seconds] [PX milliseconds] NX` 创建一个 key,这样就算加锁。其中:
22+
第一个最普通的实现方式,就是在 Redis 里使用 `SET key value [EX seconds] [PX milliseconds] NX` 创建一个 key,这样就算加锁。其中:
2323

2424
- `NX`:表示只有 `key` 不存在的时候才会设置成功,如果此时 redis 中存在这个 `key`,那么设置失败,返回 `nil`
2525
- `EX seconds`:设置 `key` 的过期时间,精确到秒级。意思是 `seconds` 秒后锁自动释放,别人创建的时候如果发现已经有了就不能加锁了。
@@ -44,11 +44,11 @@ end
4444

4545
为啥要用 `random_value` 随机值呢?因为如果某个客户端获取到了锁,但是阻塞了很长时间才执行完,比如说超过了 30s,此时可能已经自动释放锁了,此时可能别的客户端已经获取到了这个锁,要是你这个时候直接删除 key 的话会有问题,所以得用随机值加上面的 `lua` 脚本来释放锁。
4646

47-
但是这样是肯定不行的。因为如果是普通的 redis 单实例,那就是单点故障。或者是 redis 普通主从,那 redis 主从异步复制,如果主节点挂了(key 就没有了),key 还没同步到从节点,此时从节点切换为主节点,别人就可以 set key,从而拿到锁。
47+
但是这样是肯定不行的。因为如果是普通的 Redis 单实例,那就是单点故障。或者是 Redis 普通主从,那 Redis 主从异步复制,如果主节点挂了(key 就没有了),key 还没同步到从节点,此时从节点切换为主节点,别人就可以 set key,从而拿到锁。
4848

4949
#### RedLock 算法
5050

51-
这个场景是假设有一个 redis cluster,有 5 个 redis master 实例。然后执行如下步骤获取一把锁:
51+
这个场景是假设有一个 Redis cluster,有 5 个 Redis master 实例。然后执行如下步骤获取一把锁:
5252

5353
1. 获取当前时间戳,单位是毫秒;
5454
2. 跟上面类似,轮流尝试在每个 master 节点上创建锁,过期时间较短,一般就几十毫秒;
@@ -196,7 +196,7 @@ public class ZooKeeperSession {
196196

197197
也可以采用另一种方式,创建临时顺序节点:
198198

199-
如果有一把锁,被多个人给竞争,此时多个人会排队,第一个拿到锁的人会执行,然后释放锁;后面的每个人都会去监听**排在自己前面**的那个人创建的 node 上,一旦某个人释放了锁,排在自己后面的人就会被 zookeeper 给通知,一旦被通知了之后,就 ok 了,自己就获取到了锁,就可以执行代码了。
199+
如果有一把锁,被多个人给竞争,此时多个人会排队,第一个拿到锁的人会执行,然后释放锁;后面的每个人都会去监听**排在自己前面**的那个人创建的 node 上,一旦某个人释放了锁,排在自己后面的人就会被 ZooKeeper 给通知,一旦被通知了之后,就 ok 了,自己就获取到了锁,就可以执行代码了。
200200

201201
``` java
202202
public class ZooKeeperDistributedLock implements Watcher {
@@ -330,8 +330,8 @@ public class ZooKeeperDistributedLock implements Watcher {
330330
* redis 分布式锁,其实**需要自己不断去尝试获取锁**,比较消耗性能。
331331
* zk 分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小。
332332

333-
另外一点就是,如果是 redis 获取锁的那个客户端 出现 bug 挂了,那么只能等待超时时间之后才能释放锁;而 zk 的话,因为创建的是临时 znode,只要客户端挂了,znode 就没了,此时就自动释放锁。
333+
另外一点就是,如果是 Redis 获取锁的那个客户端 出现 bug 挂了,那么只能等待超时时间之后才能释放锁;而 zk 的话,因为创建的是临时 znode,只要客户端挂了,znode 就没了,此时就自动释放锁。
334334

335-
redis 分布式锁大家没发现好麻烦吗?遍历上锁,计算时间等等......zk 的分布式锁语义清晰实现简单。
335+
Redis 分布式锁大家没发现好麻烦吗?遍历上锁,计算时间等等......zk 的分布式锁语义清晰实现简单。
336336

337-
所以先不分析太多的东西,就说这两点,我个人实践认为 zk 的分布式锁比 redis 的分布式锁牢靠、而且模型简单易用。
337+
所以先不分析太多的东西,就说这两点,我个人实践认为 zk 的分布式锁比 Redis 的分布式锁牢靠、而且模型简单易用。

docs/distributed-system/distributed-session.md

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
## 面试题
2-
集群部署时的分布式 session 如何实现?
2+
集群部署时的分布式 Session 如何实现?
33

44
## 面试官心理分析
55

6-
面试官问了你一堆 dubbo 是怎么玩儿的,你会玩儿 dubbo 就可以把单块系统弄成分布式系统,然后分布式之后接踵而来的就是一堆问题,最大的问题就是**分布式事务****接口幂等性****分布式锁**,还有最后一个就是**分布式 session**
6+
面试官问了你一堆 Dubbo 是怎么玩儿的,你会玩儿 Dubbo 就可以把单块系统弄成分布式系统,然后分布式之后接踵而来的就是一堆问题,最大的问题就是**分布式事务****接口幂等性****分布式锁**,还有最后一个就是**分布式 Session**
77

88
当然了,分布式系统中的问题何止这么一点,非常之多,复杂度很高,这里只是说一下常见的几个问题,也是面试的时候常问的几个。
99

1010
## 面试题剖析
1111

12-
session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存在,然后每次发请求过来都带上一个特殊的 `jsessionid cookie` ,就根据这个东西,在服务端可以维护一个对应的 session 域,里面可以放点数据。
12+
Session 是啥?浏览器有个 Cookie,在一段时间内这个 Cookie 都存在,然后每次发请求过来都带上一个特殊的 `jsessionid cookie` ,就根据这个东西,在服务端可以维护一个对应的 Session 域,里面可以放点数据。
1313

14-
一般的话只要你没关掉浏览器,cookie 还在,那么对应的那个 session 就在,但是如果 cookie 没了,session 也就没了。常见于什么购物车之类的东西,还有登录状态保存之类的。
14+
一般的话只要你没关掉浏览器,Cookie 还在,那么对应的那个 Session 就在,但是如果 Cookie 没了,Session 也就没了。常见于什么购物车之类的东西,还有登录状态保存之类的。
1515

1616
这个不多说了,懂 Java 的都该知道这个。
1717

18-
单块系统的时候这么玩儿 session 没问题,但是你要是分布式系统呢,那么多的服务,session 状态在哪儿维护啊?
18+
单块系统的时候这么玩儿 Session 没问题,但是你要是分布式系统呢,那么多的服务,Session 状态在哪儿维护啊?
1919

2020
其实方法很多,但是常见常用的是以下几种:
2121

22-
### 完全不用 session
22+
### 完全不用 Session
2323

2424
使用 JWT Token 储存用户身份,然后再从数据库或者 cache 中获取其他的信息。这样无论请求分配到哪个服务器都无所谓。
2525

26-
### tomcat + redis
26+
### Tomcat + Redis
2727

28-
这个其实还挺方便的,就是使用 session 的代码,跟以前一样,还是基于 tomcat 原生的 session 支持即可,然后就是用一个叫做 `Tomcat RedisSessionManager` 的东西,让所有我们部署的 tomcat 都将 session 数据存储到 redis 即可。
28+
这个其实还挺方便的,就是使用 Session 的代码,跟以前一样,还是基于 Tomcat 原生的 Session 支持即可,然后就是用一个叫做 `Tomcat RedisSessionManager` 的东西,让所有我们部署的 Tomcat 都将 Session 数据存储到 Redis 即可。
2929

30-
tomcat 的配置文件中配置:
30+
Tomcat 的配置文件中配置:
3131

3232
``` xml
3333
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
@@ -39,7 +39,7 @@ session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存
3939
maxInactiveInterval="60"/>
4040
```
4141

42-
然后指定 redis 的 host 和 port 就 ok 了。
42+
然后指定 Redis 的 host 和 port 就 ok 了。
4343

4444
```xml
4545
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
@@ -49,15 +49,15 @@ session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存
4949
maxInactiveInterval="60"/>
5050
```
5151

52-
还可以用上面这种方式基于 redis 哨兵支持的 redis 高可用集群来保存 session 数据,都是 ok 的。
52+
还可以用上面这种方式基于 Redis 哨兵支持的 Redis 高可用集群来保存 Session 数据,都是 ok 的。
5353

54-
### spring session + redis
54+
### Spring Session + Redis
5555

56-
上面所说的第二种方式会与 tomcat 容器重耦合,如果我要将 web 容器迁移成 jetty,难道还要重新把 jetty 都配置一遍?
56+
上面所说的第二种方式会与 Tomcat 容器重耦合,如果我要将 Web 容器迁移成 Jetty,难道还要重新把 Jetty 都配置一遍?
5757

58-
因为上面那种 tomcat + redis 的方式好用,但是会**严重依赖于web容器**,不好将代码移植到其他 web 容器上去,尤其是你要是换了技术栈咋整?比如换成了 spring cloud 或者是 spring boot 之类的呢?
58+
因为上面那种 Tomcat + Redis 的方式好用,但是会**严重依赖于 Web 容器**,不好将代码移植到其他 Web 容器上去,尤其是你要是换了技术栈咋整?比如换成了 Spring Cloud 或者是 Spring Boot 之类的呢?
5959

60-
所以现在比较好的还是基于 Java 一站式解决方案,也就是 spring。人家 spring 基本上承包了大部分我们需要使用的框架,spirng cloud 做微服务,spring boot 做脚手架,所以用 sping session 是一个很好的选择。
60+
所以现在比较好的还是基于 Java 一站式解决方案,也就是 Spring。人家 Spring 基本上承包了大部分我们需要使用的框架,Spirng Cloud 做微服务,Spring Boot 做脚手架,所以用 Spring Session 是一个很好的选择。
6161

6262
在 pom.xml 中配置:
6363

@@ -74,7 +74,7 @@ session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存
7474
</dependency>
7575
```
7676

77-
spring 配置文件中配置:
77+
Spring 配置文件中配置:
7878

7979
``` xml
8080
<bean id="redisHttpSessionConfiguration"
@@ -132,6 +132,6 @@ public class TestController {
132132
}
133133
```
134134

135-
上面的代码就是 ok 的,给 sping session 配置基于 redis 来存储 session 数据,然后配置了一个 spring session 的过滤器,这样的话,session 相关操作都会交给 spring session 来管了。接着在代码中,就用原生的 session 操作,就是直接基于 spring sesionredis 中获取数据了。
135+
上面的代码就是 ok 的,给 Spring Session 配置基于 Redis 来存储 Session 数据,然后配置了一个 Spring Session 的过滤器,这样的话,Session 相关操作都会交给 Spring Session 来管了。接着在代码中,就用原生的 Session 操作,就是直接基于 Spring SessionRedis 中获取数据了。
136136

137-
实现分布式的会话有很多种方式,我说的只不过是比较常见的几种方式,tomcat + redis 早期比较常用,但是会重耦合到 tomcat 中;近些年,通过 spring session 来实现。
137+
实现分布式的会话有很多种方式,我说的只不过是比较常见的几种方式,Tomcat + Redis 早期比较常用,但是会重耦合到 Tomcat 中;近些年,通过 Spring Session 来实现。

docs/distributed-system/distributed-system-idempotency.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
* 每次处理完请求之后,必须有一个记录标识这个请求处理过了。常见的方案是在 mysql 中记录个状态啥的,比如支付之前记录一条这个订单的支付流水。
2626
* 每次接收请求需要进行判断,判断之前是否处理过。比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,orderId 已经存在了,唯一键约束生效,报错插入不进去的。然后你就不用再扣款了。
2727

28-
实际运作过程中,你要结合自己的业务来,比如说利用 redis,用 orderId 作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。
28+
实际运作过程中,你要结合自己的业务来,比如说利用 Redis,用 orderId 作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。
2929

30-
要求是支付一个订单,必须插入一条支付流水,order_id 建一个唯一键 `unique key` 。你在支付一个订单之前,先插入一条支付流水,order_id 就已经进去了。你就可以写一个标识到 redis 里面去, `set order_id payed` ,下一次重复请求过来了,先查 redis 的 order_id 对应的 value,如果是 `payed` 就说明已经支付过了,你就别重复支付了。
30+
要求是支付一个订单,必须插入一条支付流水,order_id 建一个唯一键 `unique key` 。你在支付一个订单之前,先插入一条支付流水,order_id 就已经进去了。你就可以写一个标识到 Redis 里面去, `set order_id payed` ,下一次重复请求过来了,先查 Redis 的 order_id 对应的 value,如果是 `payed` 就说明已经支付过了,你就别重复支付了。
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
11
## 分布式系统面试连环炮
2-
有一些同学,之前呢主要是做传统行业,或者外包项目,一直是在那种小的公司,技术一直都搞的比较简单。他们有共同的一个问题,就是都没怎么搞过分布式系统,现在互联网公司,一般都是做分布式的系统,大家都不是做底层的分布式系统、分布式存储系统 hadoop hdfs、分布式计算系统 hadoop mapreduce / spark、分布式流式计算系统 storm
2+
有一些同学,之前呢主要是做传统行业,或者外包项目,一直是在那种小的公司,技术一直都搞的比较简单。他们有共同的一个问题,就是都没怎么搞过分布式系统,现在互联网公司,一般都是做分布式的系统,大家都不是做底层的分布式系统、分布式存储系统 Hadoop HDFS、分布式计算系统 Hadoop MapReduce / Spark、分布式流式计算系统 Storm
33

44
分布式业务系统,就是把原来用 Java 开发的一个大块系统,给拆分成**多个子系统**,多个子系统之间互相调用,形成一个大系统的整体。假设原来你做了一个 OA 系统,里面包含了权限模块、员工模块、请假模块、财务模块,一个工程,里面包含了一堆模块,模块与模块之间会互相去调用,1 台机器部署。现在如果你把这个系统给拆开,权限系统、员工系统、请假系统、财务系统 4 个系统,4 个工程,分别在 4 台机器上部署。一个请求过来,完成这个请求,这个员工系统,调用权限系统,调用请假系统,调用财务系统,4 个系统分别完成了一部分的事情,最后 4 个系统都干完了以后,才认为是这个请求已经完成了。
55

66
![simple-distributed-system-oa](./images/simple-distributed-system-oa.png)
77

8-
> 近几年开始兴起和流行 Spring Cloud,刚流行,还没开始普及,目前普及的是 dubbo,因此这里也主要讲 dubbo
8+
> 近几年开始兴起和流行 Spring Cloud,刚流行,还没开始普及,目前普及的是 Dubbo,因此这里也主要讲 Dubbo
99
1010
面试官可能会问你以下问题。
1111

1212
### 为什么要进行系统拆分?
1313

14-
* 为什么要进行系统拆分?如何进行系统拆分?拆分后不用dubbo可以吗?dubbo和thrift有什么区别呢
14+
* 为什么要进行系统拆分?如何进行系统拆分?拆分后不用 Dubbo 可以吗?Dubbo 和 thrift 有什么区别呢
1515

1616
### 分布式服务框架
1717

18-
* 说一下的 dubbo 的工作原理?注册中心挂了可以继续通信吗?
19-
* dubbo 支持哪些序列化协议?说一下 hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的?
20-
* dubbo 负载均衡策略和高可用策略都有哪些?动态代理策略呢?
21-
* dubbospi 思想是什么?
22-
* 如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试?
18+
* 说一下的 Dubbo 的工作原理?注册中心挂了可以继续通信吗?
19+
* Dubbo 支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的?
20+
* Dubbo 负载均衡策略和高可用策略都有哪些?动态代理策略呢?
21+
* DubboSPI 思想是什么?
22+
* 如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试?
2323
* 分布式服务接口的幂等性如何设计(比如不能重复扣款)?
2424
* 分布式服务接口请求的顺序性如何保证?
25-
* 如何自己设计一个类似 dubborpc 框架?
25+
* 如何自己设计一个类似 DubboRPC 框架?
2626

2727
### 分布式锁
2828

29-
* 使用 redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高?
29+
* 使用 Redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高?
3030

3131
### 分布式事务
3232

3333
* 分布式事务了解吗?你们如何解决分布式事务问题的?TCC 如果出现网络连不通怎么办?XA 的一致性如何保证?
3434

3535
### 分布式会话
3636

37-
* 集群部署时的分布式 session 如何实现?
37+
* 集群部署时的分布式 Session 如何实现?

0 commit comments

Comments
 (0)