【问题标题】:How can I create User Defined Functions in Cassandra with Custom Java Class?如何使用自定义 Java 类在 Cassandra 中创建用户定义函数?
【发布时间】:2017-09-25 11:43:07
【问题描述】:

我在网上的任何地方都找不到这个。如何在 cassandra 中创建自定义的用户定义函数?

例如:

CREATE OR REPLACE FUNCTION customfunc(custommap map<text, int>)
CALLED ON NULL INPUT
RETURNS map<int,bigint> 
LANGUAGE java AS 'return MyClass.mymethod(custommap);';

其中“MyClass”是我可以在 Classpath 中注册的类?

【问题讨论】:

标签: cassandra cassandra-2.0 cassandra-2.1


【解决方案1】:

我也有同样的问题。 cassandra 2.2.14 支持 UDF 中的自定义类,但 cassandra 3.11.4 不支持。

查看源代码,cassandra 3.11.4 设置没有父类加载器的 UDF 类加载器,以便它完全控制 UDF 使用的类/资源。在org.apache.cassandra.cql3.functions.UDFunction.java中,使用白名单和黑名单来控制可以访问哪个类/包。

对于您的问题,您应该将MyClass的全名添加到白名单中,然后重新构建cassandra。

【讨论】:

  • 白名单允许访问的包/类:"com/datastax/driver/core/", "com/google/common/reflect/TypeToken", "java/io/IOException.class "、"java/io/Serializable.class"、"java/lang/"、"java/math/"、"java/net/InetAddress.class"、"java/net/Inet4Address.class"、"java/net /Inet6Address.class”、“java/net/UnknownHostException.class”、“java/net/NetworkInterface.class”
  • “java/net/SocketException.class”、“java/nio/Buffer.class”、“java/nio/ByteBuffer.class”、“java/text/”、“java/time/ ”、“java/util/”、“org/apache/cassandra/cql3/functions/JavaUDF.class”、“org/apache/cassandra/cql3/functions/UDFContext.class”、“org/apache/cassandra/exceptions/ ", "org/apache/cassandra/transport/ProtocolVersion.class"
【解决方案2】:

1.首先构建包含您的类的 java 项目。请记住,您必须将包名称添加到您的课程中。

例子:

package exp;

import java.lang.Math;
import java.util.*;

public class MyClass
{
  public static Map<Integer,Long> mymethod(Map<String, Integer> data) {
      Map<Integer,Long> map = new HashMap<>();
      map.put(1, 10L);
      map.put(2, 20L);
      map.put(3, 30L);
      return map;
  }
}

编译和构建后我有 jar test.jar

2。将jar文件复制到所有cassandra节点的$CASSANDRA_HOME/lib目录

3.重启所有 Cassandra 节点

4.创建您的自定义函数

例子:

 CREATE OR REPLACE FUNCTION customfunc(custommap map<text, int>) 
    CALLED ON NULL INPUT 
    RETURNS map<int,bigint>  
    LANGUAGE java 
    AS 'return exp.MyClass.mymethod(custommap);';

现在你可以使用这个功能了:

cassandra@cqlsh:test> SELECT * FROM test_fun ;

 id | data
----+------------------
  1 | {'a': 1, 'b': 2}

(1 rows)
cassandra@cqlsh:test> SELECT customfunc(data) FROM test_fun ;

 test.customfunc(data)
-----------------------
 {1: 10, 2: 20, 3: 30}

(1 rows)

【讨论】:

  • 我试过这个。我收到 InvalidRequest: Error from server: code=2200 [Invalid query] message="Java 源编译失败:第 1 行:exp.MyClass 无法解析为类型
  • 您完成了我列出的所有步骤吗?它应该可以工作,我已经在我的cassandra 2.2.4 中测试过了
  • 好的。在 Cassandra 3.10 中试过但没有用。我会尝试调试
【解决方案3】:

当我尝试构建一个外部类方法来支持类似的东西时,只需将我的 2 美分添加到这个线程。在使用 Datastax Sandbox 5.1 尝试了几个小时后,我无法让它工作,因为它似乎无法找到我的课程并不断引发类型错误。

我的猜测是不支持 UDF 的基于 JAR 的外部代码(请参阅 http://koff.io/posts/hll-in-cassandra/https://issues.apache.org/jira/browse/CASSANDRA-9892)。 Cassandra 4 对“TRUSTED”JAR 的支持正处于规划阶段。它可能在 3.0 之前的早期版本中工作,但我使用的是 Datastax 的最新版本。

为了解决这个问题,我不得不转而使用 Javascript 版本(我试图将 JSON 字符串转换为 Map 对象)。

虽然我意识到 Java UDF 性能更好,但我正在测试的代码仍然使用 Java Nashorn javascript 支持,因此使用 Javascript 可能不是一件坏事。它最终得到了一个更简单的单行 UDF。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2018-01-04
    • 2019-03-31
    • 2018-11-02
    • 2017-10-07
    • 2019-11-05
    • 1970-01-01
    相关资源
    最近更新 更多