docs(es/mq): update doc description

更新文档知识点描述
This commit is contained in:
yanglbme 2018-12-05 20:52:54 +08:00
parent 929342d26b
commit 7b8ce84104
6 changed files with 22 additions and 20 deletions

View File

@ -13,7 +13,7 @@ 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。 index -> type -> mapping -> document -> field。
@ -29,10 +29,10 @@ index 相当于 mysql 里的一张表。而 type 没法跟 mysql 里去对比,
![es-index-type-mapping-document-field](/img/es-index-type-mapping-document-field.png) ![es-index-type-mapping-document-field](/img/es-index-type-mapping-document-field.png)
接着你搞一个索引,这个索引可以拆分成多个 `shard`,每个 shard 存储部分数据。 你搞一个索引,这个索引可以拆分成多个 `shard`,每个 shard 存储部分数据。
接着就是这个 shard 的数据实际是有多个备份,就是说每个 shard 都有一个 `primary shard`,负责写入数据,但是还有几个 `replica shard`。primary shard 写入数据之后,会将数据同步到其他几个 replica shard 上去。 接着就是这个 shard 的数据实际是有多个备份,就是说每个 shard 都有一个 `primary shard`,负责写入数据,但是还有几个 `replica shard``primary shard` 写入数据之后,会将数据同步到其他几个 `replica shard` 上去。
![es-cluster](/img/es-cluster.png) ![es-cluster](/img/es-cluster.png)
@ -42,4 +42,6 @@ es 集群多个节点,会自动选举一个节点为 master 节点,这个 ma
如果是非 master节点宕机了那么会由 master 节点,让那个宕机节点上的 primary shard 的身份转移到其他机器上的 replica shard。接着你要是修复了那个宕机机器重启了之后master 节点会控制将缺失的 replica shard 分配过去,同步后续修改的数据之类的,让集群恢复正常。 如果是非 master节点宕机了那么会由 master 节点,让那个宕机节点上的 primary shard 的身份转移到其他机器上的 replica shard。接着你要是修复了那个宕机机器重启了之后master 节点会控制将缺失的 replica shard 分配过去,同步后续修改的数据之类的,让集群恢复正常。
说得更简单一点,就是说如果某个非 master 节点宕机了。那么此节点上的 primary shard 不就没了。那好master 会让 primary shard 对应的 replica shard在其他机器上切换为 primary shard。如果宕机的机器修复了修复后的节点也不再是 primary shard而是 replica shard。
其实上述就是 ElasticSearch 作为一个分布式搜索引擎最基本的一个架构设计。 其实上述就是 ElasticSearch 作为一个分布式搜索引擎最基本的一个架构设计。

View File

@ -19,7 +19,7 @@ es 写入数据的工作原理是什么啊es 查询数据的工作原理是
可以通过 `doc id` 来查询,会根据 `doc id` 进行 hash判断出来当时把 `doc id` 分配到了哪个 shard 上面去,从那个 shard 去查询。 可以通过 `doc id` 来查询,会根据 `doc id` 进行 hash判断出来当时把 `doc id` 分配到了哪个 shard 上面去,从那个 shard 去查询。
- 客户端发送请求到**任意**一个 node成为 `coordinate node` - 客户端发送请求到**任意**一个 node成为 `coordinate node`
- `coordinate node``doc id` 进行哈希路由,将请求转发到对应的 node此时会使用 `round-robin` **随机轮询算法**,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。 - `coordinate node``doc id` 进行哈希路由,将请求转发到对应的 node此时会使用 `round-robin` **随机轮询算法**,在 `primary shard` 以及其所有 replica 中随机选择一个,让读请求负载均衡。
- 接收请求的 node 返回 document 给 `coordinate node` - 接收请求的 node 返回 document 给 `coordinate node`
- `coordinate node` 返回 document 给客户端。 - `coordinate node` 返回 document 给客户端。
@ -34,7 +34,7 @@ j2ee特别牛
你根据 `java` 关键词来搜索,将包含 `java``document` 给搜索出来。es 就会给你返回java真好玩儿啊java好难学啊。 你根据 `java` 关键词来搜索,将包含 `java``document` 给搜索出来。es 就会给你返回java真好玩儿啊java好难学啊。
- 客户端发送请求到一个 `coordinate node` - 客户端发送请求到一个 `coordinate node`
- 协调节点将搜索请求转发到**所有**的 shard 对应的 primary shard 或 replica shard都可以。 - 协调节点将搜索请求转发到**所有**的 shard 对应的 `primary shard``replica shard`,都可以。
- query phase每个 shard 将自己的搜索结果(其实就是一些 `doc id`)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。 - query phase每个 shard 将自己的搜索结果(其实就是一些 `doc id`)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
- fetch phase接着由协调节点根据 `doc id` 去各个节点上**拉取实际**的 `document` 数据,最终返回给客户端。 - fetch phase接着由协调节点根据 `doc id` 去各个节点上**拉取实际**的 `document` 数据,最终返回给客户端。

View File

@ -5,7 +5,7 @@
其实这个也是用 MQ 的时候必问的话题,第一看看你了不了解顺序这个事儿?第二看看你有没有办法保证消息是有顺序的?这是生产系统中常见的问题。 其实这个也是用 MQ 的时候必问的话题,第一看看你了不了解顺序这个事儿?第二看看你有没有办法保证消息是有顺序的?这是生产系统中常见的问题。
## 面试题剖析 ## 面试题剖析
我举个例子,我们以前做过一个 mysql binlog 同步的系统压力还是非常大的日同步数据要达到上亿。mysql -> mysql常见的一点在于说大数据 team就需要同步一个 mysql 库过来,对公司的业务系统的数据做各种复杂的操作。 我举个例子,我们以前做过一个 mysql `binlog` 同步的系统压力还是非常大的日同步数据要达到上亿。mysql -> mysql常见的一点在于说大数据 team就需要同步一个 mysql 库过来,对公司的业务系统的数据做各种复杂的操作。
你在 mysql 里增删改一条数据,对应出来了增删改 3 条 `binlog`,接着这三条 `binlog` 发送到 MQ 里面,到消费出来依次执行,起码得保证人家是按照顺序来的吧?不然本来是:增加、修改、删除;你楞是换了顺序给执行成删除、修改、增加,不全错了么。 你在 mysql 里增删改一条数据,对应出来了增删改 3 条 `binlog`,接着这三条 `binlog` 发送到 MQ 里面,到消费出来依次执行,起码得保证人家是按照顺序来的吧?不然本来是:增加、修改、删除;你楞是换了顺序给执行成删除、修改、增加,不全错了么。
@ -26,5 +26,5 @@
![rabbitmq-order-2](/img/rabbitmq-order-2.png) ![rabbitmq-order-2](/img/rabbitmq-order-2.png)
#### kafka #### kafka
一个 topic一个 partition一个 consumer内部单线程消费写 N 个内存 queue然后 N 个线程分别消费一个内存 queue 即可。 一个 topic一个 partition一个 consumer内部单线程消费写 N 个内存 queue然后对于 N 个线程,每个线程分别消费一个内存 queue 即可。
![kafka-order-2](/img/kafka-order-2.png) ![kafka-order-2](/img/kafka-order-2.png)

View File

@ -14,7 +14,7 @@
#### 生产者弄丢了数据 #### 生产者弄丢了数据
生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络啥的问题,都有可能。 生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题啥的,都有可能。
此时可以选择用 RabbitMQ 提供的事务功能,就是生产者**发送数据之前**开启 RabbitMQ 事务`channel.txSelect`,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务`channel.txRollback`,然后重试发送消息;如果收到了消息,那么可以提交事务`channel.txCommit`。 此时可以选择用 RabbitMQ 提供的事务功能,就是生产者**发送数据之前**开启 RabbitMQ 事务`channel.txSelect`,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务`channel.txRollback`,然后重试发送消息;如果收到了消息,那么可以提交事务`channel.txCommit`。
```java ```java
@ -80,12 +80,12 @@ RabbitMQ 如果丢失了数据,主要是因为你消费的时候,**刚消费
所以此时一般是要求起码设置如下 4 个参数: 所以此时一般是要求起码设置如下 4 个参数:
- 给 topic 设置 replication.factor 参数:这个值必须大于 1要求每个 partition 必须有至少2个副本。 - 给 topic 设置 `replication.factor` 参数:这个值必须大于 1要求每个 partition 必须有至少2个副本。
- 在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于 1这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。 - 在 Kafka 服务端设置 `min.insync.replicas` 参数:这个值必须大于 1这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。
- 在 producer 端设置 acks=all这个是要求每条数据必须是**写入所有 replica 之后,才能认为是写成功了**。 - 在 producer 端设置 `acks=all`:这个是要求每条数据,必须是**写入所有 replica 之后,才能认为是写成功了**。
- 在 producer 端设置 retries=MAX很大很大很大的一个值无限次重试的意思这个是**要求一旦写入失败,就无限重试**,卡在这里了。 - 在 producer 端设置 `retries=MAX`(很大很大很大的一个值,无限次重试的意思):这个是**要求一旦写入失败,就无限重试**,卡在这里了。
我们生产环境就是按照上述要求配置的,这样配置之后,至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障,进行 leader 切换时,数据不会丢失。 我们生产环境就是按照上述要求配置的,这样配置之后,至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障,进行 leader 切换时,数据不会丢失。
#### 生产者会不会弄丢数据? #### 生产者会不会弄丢数据?
如果按照上述的思路设置了 ack=all一定不会丢要求是你的 leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。 如果按照上述的思路设置了 `ack=all`,一定不会丢,要求是,你的 leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。