Elasticsearch 简介 1. 什么是 Elasticsearch ElasticSearch 是一个基于 Lucene 的搜索服务器。
它了一个分布式多 用户能力的全文搜索引擎,能够达到实时、稳定、可靠、快速搜索。
也可以看做 是布式的实时文件存储,每个字段都能被索引并可被搜索。
目前大多数公司把 elasticsearch 作为 elk 日志系统中日志数据储存和实时 搜索工具。
这一部分用户,他们注重的是数据的实时写入,在大量日志数据产生 时,不堆积。
另一部分公司,把 elasticsearch 作为全文搜索工具,一次会在几 千万上亿条数据中进行搜索、聚合,对数据写入效率要求不高,注重的是搜索效 率。
2. Elasticsearch 的基础概念 Lucene Lucene 是一个开放源代码的全文检索引擎工具包,其中封装了很多建立倒 排索引的规则和搜索排序的算法。
倒排索引 在 Elasticsearch 中, 字段的数据可被分词工具分为多个词, 这些词存在索 引表中都会标记对应的 docID,在进行搜索的时 elasticsearch 根据我们输入的 词(word1)去匹配索引表中的词(word2) ,根据搜索结果返回相应 docID 的数 据。
例如:我们在 Elasticsearch 存入以下数据 id 1 2 3 Field 分词工具 搜索工具 搜索运算工具 分词在索引表中会存入以下数据 Term 工具 分词 搜索 id 1、2 、3 1 1、2
运算 3 当我们查询‘搜索’时,Elasticsearch 就会用‘搜索’去匹配索引表中的 term, 从索引表得知, 1、 2 两条数据包含‘搜索’, 就会返回 1 、 2 两条数据。
ElasticsearchTemplate Elasticsearch Template 用于规定 index 中字段的存储格式、index 的设 置参数等, template 分为两部分, 一是 setting, 主要用于规定 index 的参数, 例如 number_of_shards(分片数) 、number_of_replicas(副本数) 。
还有就是 设置一些优化 index 的参数。
另一部分是 mapping,elasticsearch 的 mapping 类似于数据库的表结构,用于设置字段格式,假如 elasticsearch 不提前设置 mapping,系统会以该字段接收到的第一个数据的类型作为默认字段类型。
新建 elasticsearch template 可以直接在 kibanadev tools 上执行命令 例如: 新建 index 以 test*为名的,都会使用此 template,其中设置新建 index 为 3 个分片 1 个副本。
Location 字段数据为 geo_point 类型, url 为 text 类型, 并 url 使用 ik 分词。
副本与分片 shards(分片)可以看做是 elasticsearch 在物理机上的最大存储单位。
每 个索引有一个或多个分片, 索引的数据被分配到各个分片上, 相当于一桶水用了 N 个杯子装,而 index 默认 shards 为 5。
关于如何规划 shards 的问题,主要从 index 数据量和集群节点数这两方面
来考虑。
一个 shards 最大的数据存储量建议在 20G-50G,在实际规划中就可以 根据此来划分 shards 数量。
当 index 的数据量过小,设置多个 shards 显然没有 任何意义,反而在查询的时候会影响效率。
replicas(副本)可以理解为备份分片,备分片不会同主分片出现在同一个 节点上,当主分片故障,副本分片会自动转化为主分片继续工作。
当有副本分片 无法分配的时候(unassigned),集群健康值会变成 yellow,当主分片无法分配时 (unassigned)集群健康值变为 red,此时集群不可用。
关于如何规划 replicas 的问题,如果单节点 elasticsearch,不用多说,0 副本,不然集群会一直显示为 yellow。
如果是多机集群,建议设置 1 副本,当 主分片 down 掉的时候, 副本分片会自动切换为主分片。
至于为什么不是 2 副本、 3 副本。
因为副本数+1 ,相应的磁盘中的数据量也会+1,副本数过多,浪费磁盘 空间。
如上图所示,source_vid_log_201801,为 3 分片 1 副本,三个主分片(带 黑框)分布于三台 data node 中。
副本分片也分布于不同的 data node 中 Elasticsearch 节点角色 Elasticsearch 节点角色分为三种, node.master、 node.data、 node.ingest, 每个 elasticsearch 节点可以担任多重角色, 但是在生产环节中, 建议角色分离。
node.master:控制 Elasticsearch 集群,负责集群中的操作,比如创建/ 删除一个索引,集群中的节点,分配分片到节点。
主节点处理集群的状态并 广播到其他节点,并接收其他节点的确认响应。
建议 master 节点不参与数据的 接收、处理和存储,避免节点 oom 造成集群瘫痪。
node.master 默认开启,在配 置文件中设置 node.master:false 关闭 node.data:存储数据和倒排索引,进行搜索操作时,data node 接收到路 由节点的请求,在本节点查询数据并做运算、排序,返回给路由节点。
elasticsearch 节点的元数据是存储在各种 data node 上的。
data node 默认开 启,在配置文件中设置 data node:false 关闭 node.ingest:数据转换功能节点,通过定义管道,实现在索引之前对文档 进行预处理。
一般来说这个节点角色很少用到。
node.ingest 默认开启,在配置 文件中设置 node.ingest:false 关闭 Elasticsearch 还有一种角色 node.client,client 是作为数据接收、任务 分发、 返回结果, 是整个集群和外部通讯的中转站。
每个节点都可以作为 client 使用,但是为了避免在聚合时造成节点宕机影响集群的使用,建议 client 节点 关闭上面三个角色。
集群 集群(cluster) :集群中有多个节点(node) ,其中有一个为主节点,这个 主节点是可以通过选举产生的。
节点(node) :就是运行的 Elasticsearch 实例,一台服务器可以部署多个 节点。
索引 (index) : ElasticSearch 将它的数据存储在一个或多个索引 (index) 中。
用 SQL 领域的术语来类比,索引就像数据库。
文 档 ( document ) : 是 ElasticSearch 中 的 主 要 实 体 , 对 所 有 使 用 ElasticSearch 的案例来说, 他们最终都可以归结为对文档的搜索。
每一条数据, 就是一个 document。
3. Elasticsearch 的工作流 数据写入 Client 接收数据,向 master 发出请求,master 根据相应的 template,建 立 index,这里就涉及到 index 的 mapping、副本数、分片数以及分片分别在哪 些节点。
Client 就将数据路由到对应的节点上,写入分片。
这里是先写入主分 片, 主分片写入完成后再写入副本分片。
写入操作结束后, datanode 会向 client 返回结果,client 汇总后再返回给用户。
如果 index 是已存在的,省略建 index 操作,其他同上 数据查询 Client 接收到查询请求,向 master 询问查询的 index 分片分布情况,得到 请求后, 就把查询请求路由给各个 data node, datanode 在各自节点上进行查询、 相关度评分、排序后,将数据返回给 client,client 将数据进行二次聚合、封 装后,返回给用户 4. Elasticsearch 常用配置参数 cluster.name: es52 #集群名 node.name: cloud001 #节点名 path.data: /data3/es52/data #数据路径 path.: /data3/es52/log #日志路径 discovery.zen.ping_timeout: 30s 节点连接 ping 时长 discovery.zen.ping.unicast.hosts: [cloud001,cloud002,cloud003] 向 指定的主机发送单播请求 network.bind_host: 0.0.0.0 # 设置绑定的 ip 地址 network.publish_host: 192.168.23.76 #其它节点和该节点交互的 ip 地址 transport.tcp.port: 9300 #与其他节点通信的端口 gateway.recover_after_nodes: 3 #当节点启动到三个的时候,启动集群 gateway.expected_nodes: 3 # 当集群启动到三个的时候,恢复数据 gateway.recover_after_time: 10m # 时间 10 分钟
cluster.routing.allocation.disk.watermark.low: 90% #这表示磁盘的最 大使用; 此后,无法将其他碎片分配给该磁盘。
cluster.routing.allocation.disk.watermark.high: 10gb #这表示分配时 的最大使用量; 如果在分配时达到这一点,Elasticsearch 将把该碎片分配给另 一个磁盘 cluster.info.update.interval: 1m #这是磁盘用法,检查两个时间之间的 间隔。
bootstrap.system_call_filter: false #禁止系统检测过滤器调用,因为 很多检查项需要 Linux 3.5 以上的内核,管综系统使用的系统为 centos6.8。
bootstrap.memory_lock: ture #锁定内存,防止内存交换。
这里因为管综 系统用的是 centos6.8 。
必须设置为 false,才能启动服务。
暂不设置 indices.breaker.fielddata.limit: 40% #当系统发现 fielddata 的数量达 到一定数量时会触发内存回收.默认值是 JVM heap 的 70% indices.breaker.request.limit: 30% #这种断路器是 elasticsearch 为了 防止 OOM(内存溢出),在每次请求数据时设定了一个固定的内存数量.默认值是 40% indices.queries.cache.size: 5% #查询缓存的内存大小达到 heap 5%就起 用自动清理旧的缓存数据 indices.fielddata.cache.size: 50% #字段数据缓存的内存大小达到 heap 50%就起用自动清理旧的缓存数据 5. Elasticsearch 常用 api Elasticsearch 的 api 可以看做是其他数据库的增删改查命令。
下面所有示 例 均在 kibanadev tools 上执行。
POST/PUT POST/PUT 都可用于 index 和文档的新增和更新操作,但 PUT 是幂等方法, POST 不是。
所以 PUT 用于更新、POST 用于新增比较合适。
例如 使用 POST 新建 index test 并插入一条数据。
--test(索引名) ,log (type) ,1(id) ,下面 json 格式的数据为一条 document。
POST test/log/1 {"first_name":"John",