ES快问快答
replia:副本
在创建某个索引之前,需要指定分配这个索引多少个分片?多少个副本?副本是这个分片的备胎,当分片挂掉了,它的副本就会随时准备上位,副本也是个分片,不负责主要功能。
ES 如何能够提高数据吞吐量或实现高可用性?增加副本个数。
读写分离,读数据的时候从副本上读,写数据的时候只用主分片去写。
主分片的个数在建立索引之前要确定,建立完索引之后,是不能够进行修改的,除非重新建索引。因此在建索引之前,一定要合理的配置分片个数,副本个数的话后期是可以改动的。
PS: 禁止同一个分片的主分片和副本分片在同一个节点上。
ES选举
ZenDiscovery模块负责,主要包含Ping(节点之间通过这个RPC来发现彼此)和Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这两部分
对所有可以成为master的节点(node.master: true)根据nodeId字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。
PS:master节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data节点可以关闭http功能。
脑裂问题
当集群master候选数量不小于3个时,可以通过设置最少投票通过数量(discovery.zen.minimum_master_nodes)超过所有候选节点一半以上来解决脑裂问题;
当候选数量为两个时,只能修改为唯一的一个master候选,其他作为data节点,避免脑裂问题。
更新和删除文档
删除和更新也都是写操作,但是ES中的文档是不可变的,因此不能被删除或者改动以展示其变更;
磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。
当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
在新的文档被创建时,ES会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
读数据
1、通过 doc id 来查询,会根据 doc id 进行 hash,判断出来当时把 doc id 分配到了哪个 shard 上面去,从那个 shard 去查询。
2、客户端发送请求到任意一个 node,成为这些节点叫做协调节点(coordinate node)。
3、协调节点对 doc id 进行哈希路由,将请求转发到对应的 node,此时会使用 round-robin随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。
4、接收请求的 node 返回 document 给协调节点,再返回 document 给客户端。
PS: 写请求是写入 primary shard,然后同步给所有的 replica shard;读请求可以从 primary shard 或 replica shard 读取,采用的是随机轮询算法
搜索
搜索被执行成一个两阶段过程,为 Query Then Fetch
在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。
PS:在搜索的时候是会查询Filesystem Cache的,但是有部分数据还在Memory Buffer,所以搜索是近实时的。
每个分片返回各自优先队列中,所有文档的 ID 和排序值给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并丰富文档,一旦所有的文档都被取回了,协调节点返回结果给客户端。
搜索细节(先拿doc_id再拿doc本身)
1、query phase:每个 shard 将自己的搜索结果(其实就是一些
doc id)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
2、fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际的
document 数据,最终返回给客户端。
大数据量(上亿量级)的聚合
近似聚合是 cardinality 度量。它提供一个字段的基数,即该字段的distinct或者unique值的数目。它是基于HLL算法的。
HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。
其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。
无论数千还是数十亿的唯一值,内存使用量只与配置的精确度相关
唠嗑广场
股票投资的时候,要做到:交易你的计划,计划你的交易。当天不要脑袋一热买卖股票,而是在当天之前就想好。
如果持仓的股票当天暴跌暴涨,如何处理?
答案是如果没有计划,就等着看着。
一个股票分红很低就很难受,一个投资者,并不是所有股票都合适自己的。