diff --git a/docs/distributed-system/README.md b/docs/distributed-system/README.md index b2a9e9d7c1ebbbc66cb7a610686ba55eca5911d7..33a79aa0fe6fb51b076d08c2335dc495ccb8f5ae 100644 --- a/docs/distributed-system/README.md +++ b/docs/distributed-system/README.md @@ -11,7 +11,7 @@ * [说一下 Dubbo 的工作原理?注册中心挂了可以继续通信吗?](/docs/distributed-system/dubbo-operating-principle.md) * [Dubbo 支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的?](/docs/distributed-system/dubbo-serialization-protocol.md) * [Dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?](/docs/distributed-system/dubbo-load-balancing.md) -* [Dubbo 的 spi 思想是什么?](/docs/distributed-system/dubbo-spi.md) +* [Dubbo 的 SPI 思想是什么?](/docs/distributed-system/dubbo-spi.md) * [如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试?](/docs/distributed-system/dubbo-service-management.md) * [分布式服务接口的幂等性如何设计(比如不能重复扣款)?](/docs/distributed-system/distributed-system-idempotency.md) * [分布式服务接口请求的顺序性如何保证?](/docs/distributed-system/distributed-system-request-sequence.md) diff --git a/docs/distributed-system/distributed-lock-redis-vs-zookeeper.md b/docs/distributed-system/distributed-lock-redis-vs-zookeeper.md index c18320f6fb9e4e967818dd12c81bdc5f7e6f175b..3f6f4f993b6c039d532ec14d8700f0709f4cb606 100644 --- a/docs/distributed-system/distributed-lock-redis-vs-zookeeper.md +++ b/docs/distributed-system/distributed-lock-redis-vs-zookeeper.md @@ -1,5 +1,5 @@ ## 面试题 -一般实现分布式锁都有哪些方式?使用 redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? +一般实现分布式锁都有哪些方式?使用 Redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? ## 面试官心理分析 @@ -7,19 +7,19 @@ ## 面试题剖析 -### redis 分布式锁 +### Redis 分布式锁 -官方叫做 `RedLock` 算法,是 redis 官方支持的分布式锁算法。 +官方叫做 `RedLock` 算法,是 Redis 官方支持的分布式锁算法。 这个分布式锁有 3 个重要的考量点: * 互斥(只能有一个客户端获取锁) * 不能死锁 -* 容错(只要大部分 redis 节点创建了这把锁就可以) +* 容错(只要大部分 Redis 节点创建了这把锁就可以) -#### redis 最普通的分布式锁 +#### Redis 最普通的分布式锁 -第一个最普通的实现方式,就是在 redis 里使用 `SET key value [EX seconds] [PX milliseconds] NX` 创建一个 key,这样就算加锁。其中: +第一个最普通的实现方式,就是在 Redis 里使用 `SET key value [EX seconds] [PX milliseconds] NX` 创建一个 key,这样就算加锁。其中: - `NX`:表示只有 `key` 不存在的时候才会设置成功,如果此时 redis 中存在这个 `key`,那么设置失败,返回 `nil`。 - `EX seconds`:设置 `key` 的过期时间,精确到秒级。意思是 `seconds` 秒后锁自动释放,别人创建的时候如果发现已经有了就不能加锁了。 @@ -44,11 +44,11 @@ end 为啥要用 `random_value` 随机值呢?因为如果某个客户端获取到了锁,但是阻塞了很长时间才执行完,比如说超过了 30s,此时可能已经自动释放锁了,此时可能别的客户端已经获取到了这个锁,要是你这个时候直接删除 key 的话会有问题,所以得用随机值加上面的 `lua` 脚本来释放锁。 -但是这样是肯定不行的。因为如果是普通的 redis 单实例,那就是单点故障。或者是 redis 普通主从,那 redis 主从异步复制,如果主节点挂了(key 就没有了),key 还没同步到从节点,此时从节点切换为主节点,别人就可以 set key,从而拿到锁。 +但是这样是肯定不行的。因为如果是普通的 Redis 单实例,那就是单点故障。或者是 Redis 普通主从,那 Redis 主从异步复制,如果主节点挂了(key 就没有了),key 还没同步到从节点,此时从节点切换为主节点,别人就可以 set key,从而拿到锁。 #### RedLock 算法 -这个场景是假设有一个 redis cluster,有 5 个 redis master 实例。然后执行如下步骤获取一把锁: +这个场景是假设有一个 Redis cluster,有 5 个 Redis master 实例。然后执行如下步骤获取一把锁: 1. 获取当前时间戳,单位是毫秒; 2. 跟上面类似,轮流尝试在每个 master 节点上创建锁,过期时间较短,一般就几十毫秒; @@ -196,7 +196,7 @@ public class ZooKeeperSession { 也可以采用另一种方式,创建临时顺序节点: -如果有一把锁,被多个人给竞争,此时多个人会排队,第一个拿到锁的人会执行,然后释放锁;后面的每个人都会去监听**排在自己前面**的那个人创建的 node 上,一旦某个人释放了锁,排在自己后面的人就会被 zookeeper 给通知,一旦被通知了之后,就 ok 了,自己就获取到了锁,就可以执行代码了。 +如果有一把锁,被多个人给竞争,此时多个人会排队,第一个拿到锁的人会执行,然后释放锁;后面的每个人都会去监听**排在自己前面**的那个人创建的 node 上,一旦某个人释放了锁,排在自己后面的人就会被 ZooKeeper 给通知,一旦被通知了之后,就 ok 了,自己就获取到了锁,就可以执行代码了。 ``` java public class ZooKeeperDistributedLock implements Watcher { @@ -330,8 +330,8 @@ public class ZooKeeperDistributedLock implements Watcher { * redis 分布式锁,其实**需要自己不断去尝试获取锁**,比较消耗性能。 * zk 分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小。 -另外一点就是,如果是 redis 获取锁的那个客户端 出现 bug 挂了,那么只能等待超时时间之后才能释放锁;而 zk 的话,因为创建的是临时 znode,只要客户端挂了,znode 就没了,此时就自动释放锁。 +另外一点就是,如果是 Redis 获取锁的那个客户端 出现 bug 挂了,那么只能等待超时时间之后才能释放锁;而 zk 的话,因为创建的是临时 znode,只要客户端挂了,znode 就没了,此时就自动释放锁。 -redis 分布式锁大家没发现好麻烦吗?遍历上锁,计算时间等等......zk 的分布式锁语义清晰实现简单。 +Redis 分布式锁大家没发现好麻烦吗?遍历上锁,计算时间等等......zk 的分布式锁语义清晰实现简单。 -所以先不分析太多的东西,就说这两点,我个人实践认为 zk 的分布式锁比 redis 的分布式锁牢靠、而且模型简单易用。 +所以先不分析太多的东西,就说这两点,我个人实践认为 zk 的分布式锁比 Redis 的分布式锁牢靠、而且模型简单易用。 diff --git a/docs/distributed-system/distributed-session.md b/docs/distributed-system/distributed-session.md index d258b682254a19b5978577a34581db73a17bfa65..fd3d87ebbdf4b8080205ff07b50e968cb5600725 100644 --- a/docs/distributed-system/distributed-session.md +++ b/docs/distributed-system/distributed-session.md @@ -1,33 +1,33 @@ ## 面试题 -集群部署时的分布式 session 如何实现? +集群部署时的分布式 Session 如何实现? ## 面试官心理分析 -面试官问了你一堆 dubbo 是怎么玩儿的,你会玩儿 dubbo 就可以把单块系统弄成分布式系统,然后分布式之后接踵而来的就是一堆问题,最大的问题就是**分布式事务**、**接口幂等性**、**分布式锁**,还有最后一个就是**分布式 session**。 +面试官问了你一堆 Dubbo 是怎么玩儿的,你会玩儿 Dubbo 就可以把单块系统弄成分布式系统,然后分布式之后接踵而来的就是一堆问题,最大的问题就是**分布式事务**、**接口幂等性**、**分布式锁**,还有最后一个就是**分布式 Session**。 当然了,分布式系统中的问题何止这么一点,非常之多,复杂度很高,这里只是说一下常见的几个问题,也是面试的时候常问的几个。 ## 面试题剖析 -session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存在,然后每次发请求过来都带上一个特殊的 `jsessionid cookie` ,就根据这个东西,在服务端可以维护一个对应的 session 域,里面可以放点数据。 +Session 是啥?浏览器有个 Cookie,在一段时间内这个 Cookie 都存在,然后每次发请求过来都带上一个特殊的 `jsessionid cookie` ,就根据这个东西,在服务端可以维护一个对应的 Session 域,里面可以放点数据。 -一般的话只要你没关掉浏览器,cookie 还在,那么对应的那个 session 就在,但是如果 cookie 没了,session 也就没了。常见于什么购物车之类的东西,还有登录状态保存之类的。 +一般的话只要你没关掉浏览器,Cookie 还在,那么对应的那个 Session 就在,但是如果 Cookie 没了,Session 也就没了。常见于什么购物车之类的东西,还有登录状态保存之类的。 这个不多说了,懂 Java 的都该知道这个。 -单块系统的时候这么玩儿 session 没问题,但是你要是分布式系统呢,那么多的服务,session 状态在哪儿维护啊? +单块系统的时候这么玩儿 Session 没问题,但是你要是分布式系统呢,那么多的服务,Session 状态在哪儿维护啊? 其实方法很多,但是常见常用的是以下几种: -### 完全不用 session +### 完全不用 Session 使用 JWT Token 储存用户身份,然后再从数据库或者 cache 中获取其他的信息。这样无论请求分配到哪个服务器都无所谓。 -### tomcat + redis +### Tomcat + Redis -这个其实还挺方便的,就是使用 session 的代码,跟以前一样,还是基于 tomcat 原生的 session 支持即可,然后就是用一个叫做 `Tomcat RedisSessionManager` 的东西,让所有我们部署的 tomcat 都将 session 数据存储到 redis 即可。 +这个其实还挺方便的,就是使用 Session 的代码,跟以前一样,还是基于 Tomcat 原生的 Session 支持即可,然后就是用一个叫做 `Tomcat RedisSessionManager` 的东西,让所有我们部署的 Tomcat 都将 Session 数据存储到 Redis 即可。 -在 tomcat 的配置文件中配置: +在 Tomcat 的配置文件中配置: ``` xml @@ -39,7 +39,7 @@ session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存 maxInactiveInterval="60"/> ``` -然后指定 redis 的 host 和 port 就 ok 了。 +然后指定 Redis 的 host 和 port 就 ok 了。 ```xml @@ -49,15 +49,15 @@ session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存 maxInactiveInterval="60"/> ``` -还可以用上面这种方式基于 redis 哨兵支持的 redis 高可用集群来保存 session 数据,都是 ok 的。 +还可以用上面这种方式基于 Redis 哨兵支持的 Redis 高可用集群来保存 Session 数据,都是 ok 的。 -### spring session + redis +### Spring Session + Redis -上面所说的第二种方式会与 tomcat 容器重耦合,如果我要将 web 容器迁移成 jetty,难道还要重新把 jetty 都配置一遍? +上面所说的第二种方式会与 Tomcat 容器重耦合,如果我要将 Web 容器迁移成 Jetty,难道还要重新把 Jetty 都配置一遍? -因为上面那种 tomcat + redis 的方式好用,但是会**严重依赖于web容器**,不好将代码移植到其他 web 容器上去,尤其是你要是换了技术栈咋整?比如换成了 spring cloud 或者是 spring boot 之类的呢? +因为上面那种 Tomcat + Redis 的方式好用,但是会**严重依赖于 Web 容器**,不好将代码移植到其他 Web 容器上去,尤其是你要是换了技术栈咋整?比如换成了 Spring Cloud 或者是 Spring Boot 之类的呢? -所以现在比较好的还是基于 Java 一站式解决方案,也就是 spring。人家 spring 基本上承包了大部分我们需要使用的框架,spirng cloud 做微服务,spring boot 做脚手架,所以用 sping session 是一个很好的选择。 +所以现在比较好的还是基于 Java 一站式解决方案,也就是 Spring。人家 Spring 基本上承包了大部分我们需要使用的框架,Spirng Cloud 做微服务,Spring Boot 做脚手架,所以用 Spring Session 是一个很好的选择。 在 pom.xml 中配置: @@ -74,7 +74,7 @@ session 是啥?浏览器有个 cookie,在一段时间内这个 cookie 都存 ``` -在 spring 配置文件中配置: +在 Spring 配置文件中配置: ``` xml 近几年开始兴起和流行 Spring Cloud,刚流行,还没开始普及,目前普及的是 dubbo,因此这里也主要讲 dubbo。 +> 近几年开始兴起和流行 Spring Cloud,刚流行,还没开始普及,目前普及的是 Dubbo,因此这里也主要讲 Dubbo。 面试官可能会问你以下问题。 ### 为什么要进行系统拆分? -* 为什么要进行系统拆分?如何进行系统拆分?拆分后不用dubbo可以吗?dubbo和thrift有什么区别呢? +* 为什么要进行系统拆分?如何进行系统拆分?拆分后不用 Dubbo 可以吗?Dubbo 和 thrift 有什么区别呢? ### 分布式服务框架 -* 说一下的 dubbo 的工作原理?注册中心挂了可以继续通信吗? -* dubbo 支持哪些序列化协议?说一下 hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的? -* dubbo 负载均衡策略和高可用策略都有哪些?动态代理策略呢? -* dubbo 的 spi 思想是什么? -* 如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试? +* 说一下的 Dubbo 的工作原理?注册中心挂了可以继续通信吗? +* Dubbo 支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的? +* Dubbo 负载均衡策略和高可用策略都有哪些?动态代理策略呢? +* Dubbo 的 SPI 思想是什么? +* 如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试? * 分布式服务接口的幂等性如何设计(比如不能重复扣款)? * 分布式服务接口请求的顺序性如何保证? -* 如何自己设计一个类似 dubbo 的 rpc 框架? +* 如何自己设计一个类似 Dubbo 的 RPC 框架? ### 分布式锁 -* 使用 redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? +* 使用 Redis 如何设计分布式锁?使用 zk 来设计分布式锁可以吗?这两种分布式锁的实现方式哪种效率比较高? ### 分布式事务 @@ -34,4 +34,4 @@ ### 分布式会话 -* 集群部署时的分布式 session 如何实现? +* 集群部署时的分布式 Session 如何实现? diff --git a/docs/distributed-system/distributed-system-request-sequence.md b/docs/distributed-system/distributed-system-request-sequence.md index ce183e8efd84e21f960960092871a1fe0b312623..3c8476fbf818c1769befcba8d4385840b0ceb18b 100644 --- a/docs/distributed-system/distributed-system-request-sequence.md +++ b/docs/distributed-system/distributed-system-request-sequence.md @@ -13,7 +13,7 @@ 首先,一般来说,个人建议是,你们从业务逻辑上设计的这个系统最好是不需要这种顺序性的保证,因为一旦引入顺序性保障,比如使用**分布式锁**,会**导致系统复杂度上升**,而且会带来**效率低下**,热点数据压力过大等问题。 -下面我给个我们用过的方案吧,简单来说,首先你得用 dubbo 的一致性 hash 负载均衡策略,将比如某一个订单 id 对应的请求都给分发到某个机器上去,接着就是在那个机器上,因为可能还是多线程并发执行的,你可能得立即将某个订单 id 对应的请求扔一个**内存队列**里去,强制排队,这样来确保他们的顺序性。 +下面我给个我们用过的方案吧,简单来说,首先你得用 Dubbo 的一致性 hash 负载均衡策略,将比如某一个订单 id 对应的请求都给分发到某个机器上去,接着就是在那个机器上,因为可能还是多线程并发执行的,你可能得立即将某个订单 id 对应的请求扔一个**内存队列**里去,强制排队,这样来确保他们的顺序性。 ![distributed-system-request-sequence](./images/distributed-system-request-sequence.png) diff --git a/docs/high-concurrency/database-shard-dynamic-expand.md b/docs/high-concurrency/database-shard-dynamic-expand.md index 5b93aaea7bcdf0f17d1f69371eb2c312eee9079f..67277dc380c5bd366acf59d4310e384ace0ff854 100644 --- a/docs/high-concurrency/database-shard-dynamic-expand.md +++ b/docs/high-concurrency/database-shard-dynamic-expand.md @@ -52,11 +52,11 @@ | 352 | 0 | 11 | | 4593 | 17 | 15 | -刚开始的时候,这个库可能就是逻辑库,建在一个数据库上的,就是一个 mysql 服务器可能建了 n 个库,比如 32 个库。后面如果要拆分,就是不断在库和 mysql 服务器之间做迁移就可以了。然后系统配合改一下配置即可。 +刚开始的时候,这个库可能就是逻辑库,建在一个数据库上的,就是一个 MySQL 服务器可能建了 n 个库,比如 32 个库。后面如果要拆分,就是不断在库和 MySQL 服务器之间做迁移就可以了。然后系统配合改一下配置即可。 比如说最多可以扩展到 32 个数据库服务器,每个数据库服务器是一个库。如果还是不够?最多可以扩展到 1024 个数据库服务器,每个数据库服务器上面一个库一个表。因为最多是 1024 个表。 -这么搞,是不用自己写代码做数据迁移的,都交给 dba 来搞好了,但是 dba 确实是需要做一些库表迁移的工作,但是总比你自己写代码,然后抽数据导数据来的效率高得多吧。 +这么搞,是不用自己写代码做数据迁移的,都交给 DBA 来搞好了,但是 DBA 确实是需要做一些库表迁移的工作,但是总比你自己写代码,然后抽数据导数据来的效率高得多吧。 哪怕是要减少库的数量,也很简单,其实说白了就是按倍数缩容就可以了,然后修改一下路由规则。 @@ -64,7 +64,7 @@ 1. 设定好几台数据库服务器,每台服务器上几个库,每个库多少个表,推荐是 32 库 * 32 表,对于大部分公司来说,可能几年都够了。 2. 路由的规则,orderId 模 32 = 库,orderId / 32 模 32 = 表 -3. 扩容的时候,申请增加更多的数据库服务器,装好 mysql,呈倍数扩容,4 台服务器,扩到 8 台服务器,再到 16 台服务器。 -4. 由 dba 负责将原先数据库服务器的库,迁移到新的数据库服务器上去,库迁移是有一些便捷的工具的。 +3. 扩容的时候,申请增加更多的数据库服务器,装好 MySQL,呈倍数扩容,4 台服务器,扩到 8 台服务器,再到 16 台服务器。 +4. 由 DBA 负责将原先数据库服务器的库,迁移到新的数据库服务器上去,库迁移是有一些便捷的工具的。 5. 我们这边就是修改一下配置,调整迁移的库所在数据库服务器的地址。 6. 重新发布系统,上线,原先的路由规则变都不用变,直接可以基于 n 倍的数据库服务器的资源,继续进行线上系统的提供服务。 diff --git a/docs/high-concurrency/database-shard-global-id-generate.md b/docs/high-concurrency/database-shard-global-id-generate.md index a0f4584d017f9edfe91264aa415b2d9467f535a1..d8ef356821766385145796745c366d50aa7f7dae 100644 --- a/docs/high-concurrency/database-shard-global-id-generate.md +++ b/docs/high-concurrency/database-shard-global-id-generate.md @@ -45,12 +45,12 @@ UUID.randomUUID().toString().replace("-", "") -> sfsdf23423rr234sfdaf ### snowflake 算法 -snowflake 算法是 twitter 开源的分布式 id 生成算法,采用 Scala 语言实现,是把一个 64 位的 long 型的 id,1 个 bit 是不用的,用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。 +snowflake 算法是 twitter 开源的分布式 id 生成算法,采用 Scala 语言实现,是把一个 64 位的 long 型的 id,1 个 bit 是不用的,用其中的 41 bits 作为毫秒数,用 10 bits 作为工作机器 id,12 bits 作为序列号。 * 1 bit:不用,为啥呢?因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。 -* 41 bit:表示的是时间戳,单位是毫秒。41 bit 可以表示的数字多达 `2^41 - 1` ,也就是可以标识 `2^41 - 1` 个毫秒值,换算成年就是表示69年的时间。 -* 10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10台机器上哪,也就是1024台机器。但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表 `2^5` 个机房(32个机房),每个机房里可以代表 `2^5` 个机器(32台机器)。 -* 12 bit:这个是用来记录同一个毫秒内产生的不同 id,12 bit 可以代表的最大正整数是 `2^12 - 1 = 4096` ,也就是说可以用这个 12 bit 代表的数字来区分**同一个毫秒内**的 4096 个不同的 id。 +* 41 bits:表示的是时间戳,单位是毫秒。41 bits 可以表示的数字多达 `2^41 - 1` ,也就是可以标识 `2^41 - 1` 个毫秒值,换算成年就是表示69年的时间。 +* 10 bits:记录工作机器 id,代表的是这个服务最多可以部署在 2^10 台机器上,也就是 1024 台机器。但是 10 bits 里 5 个 bits 代表机房 id,5 个 bits 代表机器 id。意思就是最多代表 `2^5` 个机房(32 个机房),每个机房里可以代表 `2^5` 个机器(32台机器)。 +* 12 bits:这个是用来记录同一个毫秒内产生的不同 id,12 bits 可以代表的最大正整数是 `2^12 - 1 = 4096` ,也就是说可以用这个 12 bits 代表的数字来区分**同一个毫秒内**的 4096 个不同的 id。 ``` 0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000 diff --git a/docs/high-concurrency/es-architecture.md b/docs/high-concurrency/es-architecture.md index eb15552e3beff01ef7cf7a1b10e3a30f7b067f97..6542c2a02589264d33017c5a0b4ce91c3b89be1f 100644 --- a/docs/high-concurrency/es-architecture.md +++ b/docs/high-concurrency/es-architecture.md @@ -1,21 +1,21 @@ ## 面试题 -es 的分布式架构原理能说一下么(es 是如何实现分布式的啊)? +ES 的分布式架构原理能说一下么(ES 是如何实现分布式的啊)? ## 面试官心理分析 -在搜索这块,lucene 是最流行的搜索库。几年前业内一般都问,你了解 lucene 吗?你知道倒排索引的原理吗?现在早已经 out 了,因为现在很多项目都是直接用基于 lucene 的分布式搜索引擎—— ElasticSearch,简称为 es。 +在搜索这块,lucene 是最流行的搜索库。几年前业内一般都问,你了解 lucene 吗?你知道倒排索引的原理吗?现在早已经 out 了,因为现在很多项目都是直接用基于 lucene 的分布式搜索引擎—— ElasticSearch,简称为 ES。 -而现在分布式搜索基本已经成为大部分互联网行业的 Java 系统的标配,其中尤为流行的就是 es,前几年 es 没火的时候,大家一般用 solr。但是这两年基本大部分企业和项目都开始转向 es 了。 +而现在分布式搜索基本已经成为大部分互联网行业的 Java 系统的标配,其中尤为流行的就是 ES,前几年 ES 没火的时候,大家一般用 solr。但是这两年基本大部分企业和项目都开始转向 ES 了。 -所以互联网面试,肯定会跟你聊聊分布式搜索引擎,也就一定会聊聊 es,如果你确实不知道,那你真的就 out 了。 +所以互联网面试,肯定会跟你聊聊分布式搜索引擎,也就一定会聊聊 ES,如果你确实不知道,那你真的就 out 了。 -如果面试官问你第一个问题,确实一般都会问你 es 的分布式架构设计能介绍一下么?就看看你对分布式搜索引擎架构的一个基本理解。 +如果面试官问你第一个问题,确实一般都会问你 ES 的分布式架构设计能介绍一下么?就看看你对分布式搜索引擎架构的一个基本理解。 ## 面试题剖析 -ElasticSearch 设计的理念就是分布式搜索引擎,底层其实还是基于 lucene 的。核心思想就是在多台机器上启动多个 es 进程实例,组成了一个 es 集群。 +ElasticSearch 设计的理念就是分布式搜索引擎,底层其实还是基于 lucene 的。核心思想就是在多台机器上启动多个 ES 进程实例,组成了一个 ES 集群。 -es 中存储数据的**基本单位是索引**,比如说你现在要在 es 中存储一些订单数据,你就应该在 es 中创建一个索引 `order_idx` ,所有的订单数据就都写到这个索引里面去,一个索引差不多就是相当于是 mysql 里的一张表。 +ES 中存储数据的**基本单位是索引**,比如说你现在要在 ES 中存储一些订单数据,你就应该在 ES 中创建一个索引 `order_idx` ,所有的订单数据就都写到这个索引里面去,一个索引差不多就是相当于是 mysql 里的一张表。 ``` index -> type -> mapping -> document -> field。 @@ -39,7 +39,7 @@ index 相当于 mysql 里的一张表。而 type 没法跟 mysql 里去对比, 通过这个 replica 的方案,每个 shard 的数据都有多个备份,如果某个机器宕机了,没关系啊,还有别的数据副本在别的机器上呢。高可用了吧。 -es 集群多个节点,会自动选举一个节点为 master 节点,这个 master 节点其实就是干一些管理的工作的,比如维护索引元数据、负责切换 primary shard 和 replica shard 身份等。要是 master 节点宕机了,那么会重新选举一个节点为 master 节点。 +ES 集群多个节点,会自动选举一个节点为 master 节点,这个 master 节点其实就是干一些管理的工作的,比如维护索引元数据、负责切换 primary shard 和 replica shard 身份等。要是 master 节点宕机了,那么会重新选举一个节点为 master 节点。 如果是非 master节点宕机了,那么会由 master 节点,让那个宕机节点上的 primary shard 的身份转移到其他机器上的 replica shard。接着你要是修复了那个宕机机器,重启了之后,master 节点会控制将缺失的 replica shard 分配过去,同步后续修改的数据之类的,让集群恢复正常。 diff --git a/docs/high-concurrency/es-introduction.md b/docs/high-concurrency/es-introduction.md index bc2e98b6995b81436f852d994728818516b909d4..d9d42a8a7d2cb1cc0ad138c344f75b18aa58eaae 100644 --- a/docs/high-concurrency/es-introduction.md +++ b/docs/high-concurrency/es-introduction.md @@ -1,19 +1,19 @@ -## lucene 和 es 的前世今生 -lucene 是最先进、功能最强大的搜索库。如果直接基于 lucene 开发,非常复杂,即便写一些简单的功能,也要写大量的 Java 代码,需要深入理解原理。 +## Lucene 和 ES 的前世今生 +Lucene 是最先进、功能最强大的搜索库。如果直接基于 Lucene 开发,非常复杂,即便写一些简单的功能,也要写大量的 Java 代码,需要深入理解原理。 -elasticsearch 基于 lucene,隐藏了 lucene 的复杂性,提供了简单易用的 restful api / Java api 接口(另外还有其他语言的 api 接口)。 +ElasticSearch 基于 Lucene,隐藏了 lucene 的复杂性,提供了简单易用的 RESTful api / Java api 接口(另外还有其他语言的 api 接口)。 * 分布式的文档存储引擎 * 分布式的搜索引擎和分析引擎 * 分布式,支持 PB 级数据 -## es 的核心概念 +## ES 的核心概念 ### Near Realtime 近实时,有两层意思: * 从写入数据到数据可以被搜索到有一个小延迟(大概是 1s) -* 基于 es 执行搜索和分析可以达到秒级 +* 基于 ES 执行搜索和分析可以达到秒级 ### Cluster 集群 @@ -25,7 +25,7 @@ Node 是集群中的一个节点,节点也有一个名称,默认是随机分 ### Document & field -文档是 es 中最小的数据单元,一个 document 可以是一条客户数据、一条商品分类数据、一条订单数据,通常用 json 数据结构来表示。每个 index 下的 type,都可以存储多条 document。一个 document 里面有多个 field,每个 field 就是一个数据字段。 +文档是 ES 中最小的数据单元,一个 document 可以是一条客户数据、一条商品分类数据、一条订单数据,通常用 json 数据结构来表示。每个 index 下的 type,都可以存储多条 document。一个 document 里面有多个 field,每个 field 就是一个数据字段。 ``` json { @@ -47,7 +47,7 @@ Node 是集群中的一个节点,节点也有一个名称,默认是随机分 ### shard -单台机器无法存储大量数据,es 可以将一个索引中的数据切分为多个 shard,分布在多台服务器上存储。有了 shard 就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个 shard 都是一个 lucene index。 +单台机器无法存储大量数据,ES 可以将一个索引中的数据切分为多个 shard,分布在多台服务器上存储。有了 shard 就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个 shard 都是一个 lucene index。 ### replica @@ -57,9 +57,9 @@ Node 是集群中的一个节点,节点也有一个名称,默认是随机分 ![es-cluster-0](./images/es-cluster-0.png) -## es 核心概念 vs. db 核心概念 +## ES 核心概念 vs. DB 核心概念 -| es | db | +| ES | DB | |---|---| | index | 数据库 | | type | 数据表 | diff --git a/docs/high-concurrency/es-optimizing-query-performance.md b/docs/high-concurrency/es-optimizing-query-performance.md index 9cdf2aecfb59609cd98841446bd0f4744e3a7b62..91ec7a386109363391e0cc71e62975cec4192794 100644 --- a/docs/high-concurrency/es-optimizing-query-performance.md +++ b/docs/high-concurrency/es-optimizing-query-performance.md @@ -1,5 +1,5 @@ ## 面试题 -es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊? +ES 在数据量很大的情况下(数十亿级别)如何提高查询效率啊? ## 面试官心理分析 diff --git a/docs/high-concurrency/es-production-cluster.md b/docs/high-concurrency/es-production-cluster.md index 80a9128d7b018c298726956b4417744577b38992..ea64087f02b5ddce9135bf7cb75066adc2c8344b 100644 --- a/docs/high-concurrency/es-production-cluster.md +++ b/docs/high-concurrency/es-production-cluster.md @@ -1,5 +1,5 @@ ## 面试题 -es 生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片? +ES 生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片? ## 面试官心理分析 diff --git a/docs/high-concurrency/es-write-query-search.md b/docs/high-concurrency/es-write-query-search.md index c5665de9f6746cb678dba976ec877df098923305..90a06e5dd2b1e3bf57c240d97ff67ff016ffe6ee 100644 --- a/docs/high-concurrency/es-write-query-search.md +++ b/docs/high-concurrency/es-write-query-search.md @@ -1,5 +1,5 @@ ## 面试题 -es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗? +ES 写入数据的工作原理是什么啊?ES 查询数据的工作原理是什么啊?底层的 Lucene 介绍一下呗?倒排索引了解吗? ## 面试官心理分析 diff --git a/summary.md b/summary.md index 3a44c600b87a24260abcf4ee4f2011c9c5449cb1..25ffec8f3e41c2f52bf6bb04e56cc736da79557b 100644 --- a/summary.md +++ b/summary.md @@ -10,10 +10,10 @@ - [如何设计一个消息队列?](./docs/high-concurrency/mq-design.md) - [搜索引擎](./docs/high-concurrency/es-introduction.md) - - [es 的分布式架构原理是什么?](./docs/high-concurrency/es-architecture.md) - - [es 写入数据的工作原理是什么?](./docs/high-concurrency/es-write-query-search.md) - - [es 在数十亿级别数量下如何提高查询效率?](./docs/high-concurrency/es-optimizing-query-performance.md) - - [es 生产集群的部署架构是什么?](./docs/high-concurrency/es-production-cluster.md) + - [ES 的分布式架构原理是什么?](./docs/high-concurrency/es-architecture.md) + - [ES 写入数据的工作原理是什么?](./docs/high-concurrency/es-write-query-search.md) + - [ES 在数十亿级别数量下如何提高查询效率?](./docs/high-concurrency/es-optimizing-query-performance.md) + - [ES 生产集群的部署架构是什么?](./docs/high-concurrency/es-production-cluster.md) - 缓存 - [在项目中缓存是如何使用的?](./docs/high-concurrency/why-cache.md) @@ -23,7 +23,7 @@ - [如何保证 Redis 高并发、高可用?](./docs/high-concurrency/how-to-ensure-high-concurrency-and-high-availability-of-redis.md) - [Redis 的持久化有哪几种方式?](./docs/high-concurrency/redis-persistence.md) - [Redis 集群模式的工作原理能说一下么?](./docs/high-concurrency/redis-cluster.md) - - [redis 的雪崩、穿透和击穿,如何应对?](./docs/high-concurrency/redis-caching-avalanche-and-caching-penetration.md) + - [Redis 的雪崩、穿透和击穿,如何应对?](./docs/high-concurrency/redis-caching-avalanche-and-caching-penetration.md) - [如何保证缓存与数据库双写一致性?](./docs/high-concurrency/redis-consistence.md) - [如何解决 Redis 的并发竞争问题?](./docs/high-concurrency/redis-cas.md) - [生产环境中的 Redis 是怎么部署的?](./docs/high-concurrency/redis-production-environment.md) @@ -49,7 +49,7 @@ - [说一下 Dubbo 的工作原理?](./docs/distributed-system/dubbo-operating-principle.md) - [Dubbo 支持哪些序列化协议?](./docs/distributed-system/dubbo-serialization-protocol.md) - [Dubbo 负载均衡策略和集群容错策略?](./docs/distributed-system/dubbo-load-balancing.md) - - [Dubbo 的 spi 思想是什么?](./docs/distributed-system/dubbo-spi.md) + - [Dubbo 的 SPI 思想是什么?](./docs/distributed-system/dubbo-spi.md) - [如何基于 Dubbo 进行服务治理?](./docs/distributed-system/dubbo-service-management.md) - [分布式服务接口的幂等性如何设计?](./docs/distributed-system/distributed-system-idempotency.md) - [分布式服务接口请求的顺序性如何保证?](./docs/distributed-system/distributed-system-request-sequence.md)