部分原理图
1.索引分片 的备份,同一个数据分片不会存在同一个节点上
2.数据写入原理,包含“近实时索引”和“持久化变更”两步
3.结构与mysql的比较
核心组成/介绍
1.shard 索引分片,包含主分片(primary)、索引副本(Replicas)
将数据划分为较小的分片,达到负载、容错、高并发、高可用的目的
2.**metadata **元数据,包含三个部分(_index、_type、_id)
_index:文档存储的地方,类似于关系型数据库里的“数据库”
_type:对象的类,他们数据结构相同
_id:文档的唯一标识
_source: 字段存储代表文档体的JSON字符串
3.倒排索引 正排索引(根据key查找value),倒排索引(根据value查找key,其中value是是经过分词处理)
4.Tokenizer 分词器,将字符流拆分成单个token (通常是单个单词),并输出一个token流
5.routing****路由,默认是_id,可以自定义,通过固定计算公式查找分片
// 路由出单个shard -- 容易造成负载不均衡
shard_num = hash(_routing) % num_primary_shards
// 路由出一组shard
shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards
// 组成部分
num_primary_shards 主分片数量
routing_partition_size 路由出shard的数量
6.脑裂现象 集群中选举出多个Master节点,使得数据更新时出现不一致
# 原因
网络问题:网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片
节点负载:访问量较大时可能会导致ES停止响应(假死状态)造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点
内存回收:当data节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应
# 解决方法
1.discovery.zen.ping_timeout:设置节点状态的响应时间
2.discovery.zen.minimum_master_nodes:主节点资格并互相连接的节点的最小数
3.候选主节点和数据节点进行角色分离,减少对主节点“已死”的误判
7.master选举
1.对所有可以成为master的节点(node.master: true)根据nodeId字典排序,
每次选举每个节点都把自己所知道节点排一次序,
然后选出第一个(第0位)节点,暂且认为它是master节点
2.某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。
否则重新选举一直到满足上述条件
8.上图2中refresh/flush过程 -- 近实时搜索
# 请求步骤1
根据routing路由选择某一个节点后
# 步骤2 refresh步骤
es将请求的数据写入到内存缓冲区(Momery Buffer)
默认每过1秒就会将内存缓冲区写入文件系统缓冲区(Filesystem Cache)
清空内存缓冲区
# 步骤3 flush步骤
在写入内存缓冲区的同时写入到translog文件中
默认每过30分钟会translog写入到磁盘中
删除旧的translog,新建新的translog
9.文档删除和修改
1.es的文档是不可变的
2.文档删除其实都是假删除,文档修改是新建新的文档
3.es中.del文件会标记删除文档/旧文档
4.搜索时会将删除/旧文档都查询出来,结果会被.del里面的文件过滤掉
5.合并 段(segement) 时,不会将删除/旧文档写入新段中
10.上述段(segement)的补充
Lucene索引是由多个段组成
段本身是一个功能齐全的倒排索引
搜索请求而言,索引中的所有段都会被搜索
11.怎么保证读写一致
1.通过版本号来使用乐观锁并发控制
2.写入时:一致性级别支持quorum(默认)/one/all,默认大部分可用时才运行写操作
int( (primary + number_of_replicas) / 2 ) + 1
number_of_replicas:复制分片的数量
3.读取时:同步--主分片和副本分片都完成后才会返回
异步:设置搜索请求参数_preference为primary来查询主分片
简单配置
elasticsearch.yml
cluster.name: es_online_cluster
node.name: ${HOSTNAME}
# 节点是否存储数据
node.data: true
# 节点是否具有成为主节点的资格
node.master: true
path.data: /data/elasticsearch/es_data
path.logs: /data/elasticsearch/es_logs
bootstrap.memory_lock: true
network.host: 10.81.90.235
# 配置有机会参与选举为master的节点
discovery.zen.ping.unicast.hosts: ["10.81.90.235:9300", "10.81.160.31:9300", "10.81.71.23:9300"]
#设置这个集群,有多少个节点有master候选资格,如果集群较大官方建议为2-4个
discovery.zen.minimum_master_nodes
# 设置是否可以通过正则或者_all删除或者关闭索引库,默认true表示必须需要显式指定索引库名称
action.destructive_requires_name: true
后台启动命令
/usr/local/elasticsearch-6.3.2/bin/elasticsearch -d
下篇讲elasticsearch的java应用
网友评论