第1章 走进Elasticsearch 1
1.1 基本概念和原理 1
1.1.1 索引结构 2
1.1.2 分片(shard ) 2
1.1.3 动态更新索引 4
1.1.4 近实时搜索 5
1.1.5 段合并 5
1.2 集群内部原理 6
1.2.1 集群节点角色 6
1.2.2 集群健康状态 8
1.2.3 集群状态 8
1.2.4 集群扩容 8
1.3 客户端API 9
1.4 主要内部模块简介 10
1.4.1 模块结构 11
1.4.2 模块管理 12
第2章 准备编译和调试环境 13
2.1 编译源码 13
2.1.1 准备JDK和Gradle 13
2.1.2 下载源代码 13
2.1.3 编译项目,打包 14
2.1.4 将工程导入IntelliJ IDEA 14
2.2 调试Elasticsearch 16
2.2.1 本地运行、调试项目 16
2.2.2 远程调试 18
2.3 代码书签和断点组 19
第3章 集群启动流程 21
3.1 选举主节点 22
3.2 选举集群元信息 22
3.3 allocation过程 23
3.4 index recovery 24
3.5 集群启动日志 25
3.6 小结 26
第4章 节点的启动和关闭 28
4.1 启动流程做了什么 28
4.2 启动流程分析 28
4.2.1 启动脚本 28
4.2.2 解析命令行参数和配置文件 29
4.2.3 加载安全配置 30
4.2.4 检查内部环境 30
4.2.5 检测外部环境 30
4.2.6 启动内部模块 33
4.2.7 启动keepalive线程 33
4.3 节点关闭流程 34
4.4 关闭流程分析 34
4.5 分片读写过程中执行关闭 36
4.6 主节点被关闭 36
4.7 小结 36
第5章 选主流程 38
5.1 设计思想 38
5.2 为什么使用主从模式 38
5.3 选举算法 39
5.4 相关配置 39
5.5 流程概述 41
5.6 流程分析 41
5.6.1 选举临时Master 42
5.6.2 投票与得票的实现 46
5.6.3 确立Master或加入集群 46
5.7 节点失效检测 47
5.7.1 NodesFaultDetection事件处理 47
5.7.2 MasterFaultDetection事件处理 48
5.8 小结 49
第6章 数据模型 50
6.1 PacificA算法 50
6.1.1 数据副本策略 51
6.1.2 配置管理 52
6.1.3 错误检测 52
6.2 ES的数据副本模型 53
6.2.1 基本写入模型 53
6.2.2 写故障处理 54
6.2.3 基本读取模型 54
6.2.4 读故障处理 55
6.2.5 引申的含义 55
6.2.6 系统异常 56
6.3 Allocation IDs 56
6.3.1 安全地分配主分片 56
6.3.2 将分配标记为陈旧 57
6.2.3 一个例子 58
6.3.4 不会丢失全部 63
6.4 Sequence IDs 64
6.4.1 Primary Terms和Sequence Numbers 64
6.4.2 本地及全局检查点 66
6.4.3 用于快速恢复(Recovery) 68
6.5 version 69
第7章 写流程 71
7.1 文档操作的定义 71
7.2 可选参数 72
7.3 Index/Bulk基本流程 72
7.4 Index/Bulk详细流程 73
7.4.1 协调节点流程 74
7.4.2 主分片节点流程 79
7.4.3 副分片节点流程 82
7.5 I/O异常处理 82
7.5.1 Engine关闭过程 83
7.5.2 Master的对应处理 84
7.5.3 异常流程总结 84
7.6 系统特性 84
7.7 思考 85
第8章 GET流程 86
8.1 可选参数 87
8.2 GET基本流程 87
8.3 GET详细分析 88
8.3.1 协调节点 89
8.3.2 数据节点 91
8.4 MGET流程分析 93
8.5 思考 94
第9章 Search流程 95
9.1 索引和搜索 96
9.1.1 建立索引 97
9.1.2 执行搜索 97
9.2 search type 98
9.3 分布式搜索过程 98
9.3.1 协调节点流程 99
9.3.2 执行搜索的数据节点流程 106
9.4 小结 108
第10章 索引恢复流程分析 110
10.1 相关配置 111
10.2 流程概述 111
10.3 主分片恢复流程 112
10.4 副分片恢复流程 116
10.4.1 流程概述 116
10.4.2 synced flush机制 118
10.4.3 副分片节点处理过程 118
10.4.4 主分片节点处理过程 123
10.5 recovery速度优化 127
10.6 如何保证副分片和主分片一致 128
10.7 recovery相关监控命令 131
10.8 小结 133
第11章 gateway模块分析 134
11.1 元数据 134
11.2 元数据的持久化 135
11.3 元数据的恢复 136
11.4 元数据恢复流程分析 137
11.4.1 选举集群级和索引级别的元数据 138
11.4.2 触发allocation 140
11.5 思考 140
第12章 allocation模块分析 141
12.1 什么是allocation 141
12.2 触发时机 142
12.3 allocation模块结构概述 142
12.4 allocators 142
12.5 deciders 143
12.5.1 负载均衡类 144
12.5.2 并发控制类 145
12.5.3 条件限制类 145
12.6 核心reroute实现 146
12.6.1 集群启动时reroute的触发时机 147
12.6.2 流程分析 147
12.6.3 gatewayAllocator 147
12.6.4 shardsAllocator 154
12.7 从gateway到allocation流程的转换 154
12.8 从allocation流程到recovery流程的转换 155
12.9 思考 156
第13章 Snapshot模块分析 157
13.1 仓库 158
13.2 快照 160
13.2.1 创建快照 160
13.2.2 获取快照信息 161
13.2.3 快照status 163
13.2.4 取消、删除快照和恢复操作 163
13.3 从快照恢复 164
13.3.1 部分恢复 165
13.3.2 恢复过程中更改索引设置 165
13.3.3 监控恢复进度 165
13.4 创建快照的实现原理 166
13.4.1 Lucene文件格式简介 167
13.4.2 协调节点流程 168
13.4.3 主节点流程 170
13.4.4 数据节点流程 173
13.5 删除快照实现原理 184
13.5.1 协调节点流程 184
13.5.2 主节点流程 185
13.6 思考与总结 192
第14章 Cluster模块分析 194
14.1 集群状态 194
14.2 内部封装和实现 198
14.2.1 MasterService 198
14.2.2 ClusterApplierService 199
14.2.3 线程池 201
14.3 提交集群任务 202
14.3.1 内部模块如何提交任务 203
14.3.2 任务提交过程实现 205
14.4 集群任务的执行过程 209
14.5 集群状态的发布过程 211
14.5.1 增量发布的实现原理 213
14.5.2 二段提交总流程 214
14.5.3 发布过程 215
14.5.4 提交过程 216
14.5.5 异常处理 217
14.6 应用集群状态 217
14.7 查看等待执行的集群任务 219
14.8 任务管理API 220
14.8.1 列出运行中的任务 221
14.8.2 取消任务 222
14.9 思考与总结 222
第15章 Transport模块分析 223
15.1 配置信息 223
15.1.1 传输模块配置 223
15.1.2 通用网络配置 225
15.2 Transport总体架构 227
15.2.1 网络层 227
15.2.2 服务层 229
15.3 REST解析和处理 234
15.4 RPC实现 235
15.4.1 RPC的注册和映射 236
15.4.2 根据Action获取处理类 240
15.5 思考与总结 241
第16章 ThreadPool模块分析 242
16.1 线程池类型 243
16.1.1 fixed 244
16.1.2 scaling 244
16.1.3 direct 245
16.1.4 fixed_ auto_ queue_ size 245
16.2 处理器设置 245
16.3 查看线程池 246
16.3.1 cat thread pool 246
16.3.2 nodes info 247
16.3.3 nodes stats 248
16.3.4 nodes hot threads 248
16.3.5 Java的线程池结构 250
16.4 ES的线程池实现 252
16.4.1 ThreadPool类结构与初始化 253
16.4.2 fixed类型线程池构建过程 255
16.4.3 scaling类型线程池构建过程 256
16.4.4 direct类型线程池构建过程 256
16.4.5 fixed_ auto_queue_ size类型线程池构建过程 257
16.5 其他线程池 258
16.6 思考与总结 258
第17章 Shrink原理分析 259
17.1 准备源索引 259
17.2 缩小索引 260
17.3 Shrink的工作原理 260
17.3.1 创建新索引 261
17.3.2 创建硬链接 261
17.3.3 硬链接过程源码分析 262
第18章 写入速度优化 264
18.1 translog flush间隔调整 264
18.2 索引刷新间隔refresh_ interval 265
18.3 段合并优化 265
18.4 indexing buffer 266
18.5 使用bulk请求 267
18.5.1 bulk线程池和队列 267
18.5.2 并发执行bulk请求 267
18.6 磁盘间的任务均衡 268
18.7 节点间的任务均衡 268
18.8 索引过程调整和优化 269
18.8.1 自动生成doc ID 269
18.8.2 调整字段Mappings 269
18.8.3 调整_source字段 269
18.8.4 禁用_all字段 270
18.8.5 对Analyzed的字段禁用Norms 271
18.8.6 index_ options设置 271
18.9 参考配置 271
18.10 思考与总结 272
第19章 搜索速度的优化 273
19.1 为文件系统cache预留足够的内存 273
19.2 使用更快的硬件 273
19.3 文档模型 274
19.4 预索引数据 274
19.5 字段映射 276
19.6 避免使用脚本 276
19.7 优化日期搜索 276
19.8 为只读索引执行force-merge 278
19.9 预热全局序号(global ordinals) 279
19.10 execution hint 279
19.11 预热文件系统cache 280
19.12 转换查询表达式 280
19.13 调节搜索请求中的batched reduce size 281
19.14 使用近似聚合 281
19.15 深度优先还是广度优先 281
19.16 限制搜索请求的分片数 281
19.17 利用自适应副本选择(ARS)提升ES响应速度 282
第20章 磁盘使用量优化 285
20.1 预备知识 285
20.1.1 元数据字段 285
20.1.2 索引映射参数 286
20.2 优化措施 287
20.2.1 禁用对你来说不需要的特性 287
20.2.2 禁用doc values 290
20.2.3 不要使用默认的动态字符串映射 290
20.2.4 观察分片大小 291
20.2.5 禁用source 291
20.2.6 使用best_compression 291
20.2.7 Fource Merge 292
20.2.8 Shrink Index 292
20.2.9 数值类型长度够用就好 292
20.2.10 使用索引排序来排列类似的文档 292
20.2.11 在文档中以相同的顺序放置字段 292
20.3 测试数据 293
第21章 综合应用实践 294
21.1 集群层 294
21.1.1 规划集群规模 294
21.1.2 单节点还是多节点部署 295
21.1.3 移除节点 295
21.1.4 独立部署主节点 296
21.2 节点层 296
21.2.1 控制线程池的队列大小 296
21.2.2 为系统cache保留一半物理内存 297
21.3 系统层 297
21.3.1 关闭swap 297
21.3.2 配置Linux OOM Killer 297
21.3.3 优化内核参数 298
21.4 索引层 304
21.4.1 使用全局模板 304
21.4.2 索引轮转 304
21.4.3 避免热索引分片不均 305
21.4.4 副本数选择 306
21.4.5 Force Merge 306
21.4.6 Shrink Index 306
21.4.7 close索引 307
21.4.8 延迟分配分片 307
21.4.9 小心地使用fielddata 307
21.5 客户端 308
21.5.1 使用REST API而非Java API 308
21.5.2 注意429状态码 308
21.5.3 curl的HEAD请求 308
21.5.4 了解你的搜索计划 309
21.5.5 为读写请求设置比较长的超时时间 309
21.6 读写 309
21.6.1 避免搜索操作返回巨大的结果集 309
21.6.2 避免索引巨大的文档 309
21.6.3 避免使用多个type 310
21.6.4 避免使用all字段 310
21.6.5 避免将请求发送到同一个协调节点 310
21.7 控制相关度 311
第22章 故障诊断 316
22.1 使用Profile API定位慢查询 317
22.2 使用Explain API分析未分配的分片(Unassigned Shards) 320
22.2.1 诊断未分配的主分片 320
22.2.2 诊断未分配的副分片 324
22.2.3 诊断已分配的分片 326
22.3 节点CPU使用率高 328
22.4 节点内存使用率高 330
22.5 Slow Logs 333
22.6 分析工具 334
22.6.1 I/O信息 334
22.6.2 内存 335
22.6.3 CPU信息 337
22.6.4 网络连接和流量 339
22.7 小结 341
附录A 重大版本变化 342