ES 杂记

ES 适用于大数据,高并发,QPS 5000没问题

ES概念

Index 存储方案,类似特性的文档集合

Type 索引内部的逻辑分区,相当于表

Mapping 表结构定义...name,conten.....

Document 原子单位,包含一个或多个Field的容器,File对应mapping表结构的定义

Inverted Index 倒排索引会按照指定语法对每一个文档进行分词,然后维护一张表,列举所有文档中出现的terms以及它们出现的文档ID和出现频率。搜索时同样会对关键词进行同样的分词分析,然后查表得到结果。

Node:一个实例节点,集群由多个拥有相同cluster.name配置的节点组成:主节点负责管理集群范围内所有的变更,增删索引,增删节点,数据节点存储数据和其对应的倒排索引,默认每一个都是数据节点;协调节点,用来响应客户请求,均衡每个节点的负载

xx_index->n*shard分片 ->primary shard ,读写数据->备份replica shard replica和primary不在一个节点上

自动选举一个master节点,这个master节点其实干一些管理工作,维护索引元数据,负责切换primary shard和replica shard 身份.....

节点宕机->非master节点->让节点上的primary shard 的身份转移到replica shard,重启了之后,master节点会控制将缺失的replica shard分配过去,同步后续修改的数据之类的,让集群恢复正常。

es查询流程

写入的document会对应有一个doc_id,根据id进行hash路由到对应的shard上面去

 

es写入流程(三台机器,每台机器一个es进程,shard01 primary、shard02 replica,shard02primary、shard02replica,shard03 primary、shard01 replica)

假设挑选es02进程,02进程节点为coordinate 协调节点,若hash到shard01primary,协调节点路由到es01进程写入shard01primary,同步到到shard01 replica,协调节点返回写成功给客户端

底层原理:首先写入内存buffer中,默认每隔一秒写入os cache中,此时数据就能搜索到,故称near real-time准实时,1秒钟,每隔 1 秒钟,es 将 buffer 中的数据写入一个新的 segment file,每秒钟会产生一个新的磁盘文件 segment file,这个 segment file 中就存储最近 1 秒内 buffer 中写入的数据。(写入 segment file 之前写入 os cache)refresh操作,当数据refresh到os cache中 buffer久会倍清空

每隔5秒load os cache数据到translog日志文件中,refresh,当translog日志大到一定的阈值就会就会触发commit操作,就是将 buffer 中现有数据 refresh 到 os cache 中去,清空 buffer。然后,将一个 commit point写入磁盘文件,里面标识着这个 commit point 对应的所有 segment file,同时强行将 os cache 中目前所有的数据都 fsync 到磁盘文件中去。最后清空 现有 translog 日志文件,重启一个 translog,此时 commit 操作完成。

这个 commit 操作叫做 flush。默认 30 分钟自动执行一次 flush,但如果 translog 过大,也会触发 flush。flush 操作就对应着 commit 的全过程,我们可以通过 es api,手动执行 flush 操作,手动将 os cache 中的数据 fsync 强刷到磁盘上去。

每隔30分钟flash持久化到segment filesegment file 数量多会merge到一个大的 segment file同时删掉旧的file,如果发现在dell文件中标识就不会写到新的segment file 中,宕机会有5秒的数据丢失,就是os cache 到translog file的间隔。零丢失就是写入buffer的时候同时写到translog file中,效率低了一个数量级
删除数据到.del文件标识被删除

总结

数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到 os cache,到了 os cache 数据就能被搜索到(所以我们才说 es 从写入到能被搜索到,中间有 1s 的延迟)。每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据丢失),translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。

优化filesystem cache,假设从文件中搜索是秒级别的,尽量让搜索落到filesystem cache上,故尽量让filesystem cache 大于等于数据量,主动调热点数据进 filesystem cache中。

事故:三台机器,每台64G es占32G,filesystem cache 32G,上传了1T,每台300G,十分之一在内存,所以效率低

比如由一行数据:id.name.age.....30个字段,但是只有id.name,age三个字段进行搜索,如果往es里写入一行数据,也就是大部分无用但是占了es机器filesystem cache的空间,造成空间浪费,能cache的东西变少,导致效率降低。故仅仅写入需要检索的字段就可以了,其他字段存在mysql里面。建议采用es+hbase的这么一个架构,hbase的特点是适用于海量数据的在线存储,对hbase写入海量数据,不做搜索,就是做很简单的一些根据id或者范围进行查询的操作。

线上部署

  1. 生产集群部署了5台,每台6核64G,集群总内存320G
  2. 日增量数据大概在2000万条,日增量数据大概500M,一个月数据大概6亿,15G,目前系统运行了几个月,现在es集群里数据量大概100G。
  3. 目前线上有3个索引(文档,流程文件,流程图),文档60G,流程图20G,流程文件20G,我们每个索引分配的是8个shard,比默认的5个shard多了3个shard。

AOP过程

  1. @EnableAspectJAutoProxy

  2. import(AspectJAutoProxyRegistrar)->ImportBeanDefinitionRegistrar->registerBeanDefinitions->注册AnnotationAwareAspectJAutoProxyCreator->实现了beanPostProcessor->容器实例化Bean->getBean->createBean->doCreateBean->initializeBean-> applyBeanPostProcessorsAfterInitialization->AnnotationAwareAspectJAutoProxyCreator#applyBeanPostProcessorsAfterInitialization->wrapIfNecessary->getAdvicesAndAdvisorsForBean->获取绑定到@Bean......上的advice列表->获取实现了Advisor接口 & @Aspect->解析这个切面中的规则(Pointcut定义)和拦截方法(Advice)->DefaultAopProxyFactory->JdkDynamicAopProxy(接口) | ObjenesisCglibAopProxy->Invoke->当调用目标对象的指定拦截方法时,就会默认调用对应代理类的代理方法(invoke)

你可能感兴趣的:(分布式)