关于elasticsearch:elasticsearch插件开发概述

26次阅读

共计 4145 个字符,预计需要花费 11 分钟才能阅读完成。

插件的作用和分类

elasticsearch(简称 es)是一款使用宽泛的反对实时搜寻的数据库。罕用于全文检索、时序数据分析等畛域。es 自身基于模块设计,同时反对插件定制,当现有的性能和插件无奈满足需要的时候,咱们能够基于 es 的插件框架和接口,实现本人的插件,实现性能。
常见的插件,有中文分词、hdfs 数据备份还原、云平台主动发现 (ec2, gce, azure) 等。es 的免费模块 xpack 也是基于插件机制开发进去的,xpack 提供了诸如 index 申明周期治理、es 监控、平安认证、告警、机器学习、sql 等实用功能。
应用插件实现这些性能的益处是,可能更好的整合 es 的基础设施,不便部署。

es 的插件次要分为如下几大类:

  • 分词插件
  • 扩大 restful 接口
  • 集群和主动发现
  • Ingest 插件
  • 存储插件
  • 脚本扩大
  • 搜寻相干
  • 个别插件

这个系列将会基于笔者的理论开发教训,介绍其中 扩大 restful 接口 , Ingest 插件个别插件

es 提供的基础设施

在开始开发前,咱们能够先理解一下,作为 es 的插件能够从 es 的中获取哪些可间接应用的根底接口。

  • Client: 相当于 restful Client,但其外部实现并不是简略的 http 申请
  • ClusterService: 集群相干治理接口
  • ScriptService: script 相干
  • ThreadPool: es 治理的线程池,实现多线程或定时工作
  • NodeEnvironment: 节点环境

实时上基础设施还有许多,笔者也不是全副理解。只是列举一下用到过的。es 官网对插件开发的文档反对还是很无限的,所以如果心愿进行插件开发的话,学习已有的插件源码,甚至是跟踪到 es 外围源码简直是必须的。

插件部署

插件在 es 中运行,除了须要实现一些接口,还须要遵循一些约定。这些约定关系到开发和部署。

在 es 中内部插件被部署在 plugins 目录下。有两种形式能够部署插件,一种是通过 es 自带的 elasticsearch-plugin 命令装置打包好的插件 zip 包;另一种是间接复制插件到 plugins 目录下。个别在开发测试阶段应用第二种形式比拟不便。如果心愿他人应用,则最好依照要求公布成 zip 包。

但无论是哪种形式,一个插件最终能被 es 加载必须满足几个条件:

  1. plugins 目录下有对应插件的目录
  2. 目录中蕴含打好的 jar 包和依赖包
  3. 目录中蕴含 plugin-descriptor.properties 插件形容文件
  4. 目录中蕴含 plugin-security.policy 文件,申明插件会用到的 java 平安项

repository-hdfs 插件为例,插件中的蕴含文件如下(省略了依赖的 jar 包):

repository-hdfs
├── plugin-descriptor.properties
├── plugin-security.policy
├── repository-hdfs-7.0.0.jar
...

plugin-descriptor.properties

例如

description=The HDFS repository plugin adds support for Hadoop Distributed File-System (HDFS) repositories.
version=7.0.0
name=repository-hdfs
classname=org.elasticsearch.repositories.hdfs.HdfsPlugin
java.version=1.8
elasticsearch.version=7.0.0
extended.plugins=
has.native.controller=false

plugin-descriptor.properties中最要害的局部是 elasticsearch.versionclassname。前者申明了插件兼容的 es 版本(这个版本必须与正在运行的 es 版本 exactly 统一),后者是插件的入口类

plugin-security.policy

例如

grant {
  permission java.lang.RuntimePermission "getClassLoader";

  permission java.lang.RuntimePermission "accessDeclaredMembers";
  permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

  permission java.lang.RuntimePermission "setContextClassLoader";

  permission java.util.PropertyPermission "*", "read,write";

  permission java.lang.RuntimePermission "shutdownHooks";


  permission javax.security.auth.AuthPermission "getSubject";

  permission javax.security.auth.AuthPermission "doAs";

  permission javax.security.auth.PrivateCredentialPermission "org.apache.hadoop.security.Credentials * \"*\"","read";

  permission java.lang.RuntimePermission "accessClassInPackage.sun.security.krb5";

  permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
  permission javax.security.auth.AuthPermission "modifyPrincipals";
  permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KeyTab * \"*\"","read";
  permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KerberosTicket * \"*\"","read";

  permission java.lang.RuntimePermission "loadLibrary.jaas";
  permission java.lang.RuntimePermission "loadLibrary.jaas_unix";
  permission java.lang.RuntimePermission "loadLibrary.jaas_nt";
  permission javax.security.auth.AuthPermission "modifyPublicCredentials";

  permission java.security.SecurityPermission "putProviderProperty.SaslPlainServer";

  permission java.security.SecurityPermission "insertProvider.SaslPlainServer";

  permission javax.security.auth.kerberos.ServicePermission "*", "initiate";

  permission java.net.SocketPermission "*", "connect";

  permission java.net.SocketPermission "localhost:0", "listen,resolve";
};

plugin-security.policy是插件对敏感资源 (比方本地文件) 或者利用代码 (类的办法) 的拜访申明。因为 es 是在 java.security 开启的状况下运行插件的,所以有很多咱们悉数平时的操作都无奈通过 jvm 的 Access Control 机制的查看(例如读写文件、反射、Classloader 操作、Socket 相干),会报莫名其妙的权限问题。es 要求插件开发者在 plugin-security.policy 中申明对敏感资源的需要,并在代码中应用 AccessController.doPrivileged 包裹蕴含敏感操作的代码。

插件开发的难点

笔者总结了在插件开发过程中遇到的难点:

  1. jar hell。es 对有抵触版本的 jar 包采取了 绝不姑息 的态度。无论是 es 本身依赖的 lib,还是插件的 lib,插件之间的 lib,凡是在加载过程过发现有 jar 包抵触,就会报 jar hell 的谬误。这给插件治理依赖带来了很大的艰难。即便你将 es 本身的依赖排除在外,也无奈保证系统装置的其余插件的依赖 jar 包与你插件的依赖 jar 包没有抵触。
  2. 调试艰难。尽管 es 提供了专门用于单元测试的测试框架,但这块简直没有什么文档,只能本人通过查看官网的插件实现来缓缓摸索。对于具体开发也没有明确的领导,根本只能靠摸索。
  3. 版本强统一。下面也提到了,plugin-descriptor.properties的中的 elasticsearch.version 必须与运行的 es 版本完全一致。这给插件的版本散发带来了艰难。
  4. security.policy 问题。security.policy其实很多开发者不相熟的,往往会呈现插件跑起来各种报权限不够。所以须要在调试阶段一一去尝试,尤其是你如果依赖其余 jar,你可能无法控制这些 jar 的外部行为,从而无奈用 AccessController.doPrivileged 包裹其外部线程须要拜访敏感资源的代码。有的时候,你发现你曾经申明了 plugin-security.policy,也用AccessController.doPrivileged 做了你感觉正确的解决,还是呈现权限不够,那么就要思考是不是你依赖的 jar 包的外部线程有拜访敏感资源。

正文完
 0