如前面在架构思路中的反向思考一样,先通过Client端来看ElasticSearch的设计。
再啰嗦一句:我认为从Client或者说从API用户角度出发来看一个系统最合适的入手点,API的设计是一个非常困难的东西,要平衡易用性,一致性(非数据意义上的一致性),完整性。
简单的代码结构理一下,直接在_client_rest-high-level项目里找到org.elasticsearch.client.RestHighLevelClient这个类,它也是ElasticSearch以后主推的Client,其它的Client,如org.elasticsearch.client.transport.TransportClient会在后续版本7中不建议使用,并在版本8中移除。
org.elasticsearch.client.IndicesClient基于RestHighLevelClient提供了更简单的功能封装,主要包括delete,createIndex等操作,细分析这些方法,发现关键在于Request这个参数,用来清楚地定义Client期望Server所完成的工作,其中有意思的是一些Request继承自org.elasticsearch.action.support.master.MasterNodeRequest,这也说明请求至少可以分为两大类,一类是明确需要MasterNode来完成的,比如delete和create这种操作,还有一类应该是不需要MasterNode来完成的。
这也验证了我前面的分析,就是由MasterNode来负责主要完成数据一致性问题的管理,而由DataNode进行查询等请求。
Request/Response应该是ElasticSearch中不算复杂,但内容特别庞杂的东西,它需要覆盖基本上所有的业务以及管理功能。
顺便吐槽一下,ElasticSearch中的Action,Request,Response太多了,而且很多名字类似,看得极其郁闷。
从client端的定义来看,基本就是通过一个Action来定义行为,Request和Response分别作为Client对Server的输入和输出。这种其实是非常典型的Command设计,即Server端核心轻量化,通过插件化的方式支持扩展,Command对应的扩展会注册很多Handler,然后每个Handler会负责处理相应的Command。非常简单有效的设计,唯一值得吐槽的就是ElasticSearch把Server项目搞得太大,找起来太复杂。
下面带着这个思路再去看Server端代码。