Running Java UDFs

The information below includes all information one needs to know to begin running Java UDFs. For more information on writing Java UDFs, see Java UDF API; for more information on simulating running UDFs, see UDF Simulator. Example Java UDFs can be found here.

Important

Though any of the native APIs can be used for running UDFs written in any UDF API language, all the examples below are written using the native Java API.

Deployment

Calling the createProc() method will deploy the specified UDF to the Kinetica execution environment, to every server in the cluster. The method takes the following parameters:

ParameterDescription
procNameA system-wide unique name for the UDF
executionModeAn execution mode; either distributed or nondistributed
files

A set of files composing the UDF package, including the names of the files and the binary data for those files. The files specified will be created on the target Kinetica servers in the UDF directory (default is the /opt/gpudb/procs/ directory, governed by the proc_directory configuration parameter), with the given data and filenames; if the filenames contain subdirectories, that structure will be copied to the target servers

Files in Kinetica File System (KiFS) can also be used here. To use a KiFS file, pass the KiFS URI as the name of the file and leave the binary data portion empty. In this case, the KiFS files will be copied into the UDF directory for use when executeProc() is called.

Note

Uploading files using the files parameter should be reserved for smaller files; larger files should be uploaded to KiFS and referenced there instead.

commandThe name of the command to run, which can be a file within the deployed UDF fileset, or any command able to be executed within the host environment, e.g., java. If a host environment command is specified, the host environment must be properly configured to support that command's execution.
argsA list of command-line arguments to pass to the specified command; e.g., -cp <class path> <class name> or -jar <file name.jar>
optionsOptional parameters for UDF creation; see createProc() for details

For example, to deploy a Java UDF using the native Java API, a local, compiled proc jar (output/kinetica-udf-table-copy-proc-jar-with-dependencies.jar) will need to be read in as bytes and then passed into the createProc() call as a value paired with the file name as its key inside map files. A Java class path argument (-jar output/kinetica-udf-table-copy-proc-jar-with-dependencies.jar) is also provided.

Create UDF Example - Filename Constants
1
2
3
static String CSV_FILE = "rank_tom.csv";
static String PROC_NAME = "UdfTcJavaProc";
static String PROC_JAR_FILE = "output/kinetica-udf-table-copy-proc-jar-with-dependencies.jar";
Create UDF Example - File Map Loading
1
2
3
4
5
6
7
Map<String, ByteBuffer> filesMap = new HashMap<>();
for (String fileName : Arrays.asList(CSV_FILE, PROC_JAR_FILE))
{
    byte [] fileAsBytes = Files.readAllBytes(new File(fileName).toPath());
    ByteBuffer fileByteBuffer = ByteBuffer.wrap(fileAsBytes);
    filesMap.put(fileName, fileByteBuffer);
}
Create UDF Example - createProc() Call
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
System.out.println("Registering distributed proc...");
CreateProcResponse createProcResponse = hDb.createProc(
        PROC_NAME,
        "distributed",
        filesMap,
        "java",
        Arrays.asList("-jar", PROC_JAR_FILE),
        null
);
System.out.println("Proc created successfully:");
System.out.println(createProcResponse);

To use the same files, located in a KiFS directory named udf instead, initialize files as follows:

Create UDF Example - KiFS Filename Constants & File Map Loading
1
2
3
4
5
6
static String CSV_FILE = "kifs://udf/rank_tom.csv";
static String PROC_JAR_FILE = "kifs://udf/output/kinetica-udf-table-copy-proc-jar-with-dependencies.jar";

Map<String, ByteBuffer> filesMap = new HashMap<>();
for (String fileName : Arrays.asList(CSV_FILE, PROC_JAR_FILE))
    filesMap.put(fileName, null);

Concurrency Limits

The max_concurrency_per_node setting is available in the options map of the /create/proc. This option allows you to define a per-Kinetica- host concurrency limit for a UDF, i.e. no more than n OS processes (UDF instances) in charge of evaluating the UDF will be permitted to execute concurrently on a single Kinetica host. You may want to set a concurrency limit if you have limited resources (like GPUs) and want to avoid the risks of continually exhausting your resources. This setting is particularly useful for distributed UDFs, but it will also work for non-distributed UDFs.

Note

You can also set concurrency limits on the Edit Proc screen in the UDF section of GAdmin

The default value for the setting is 0, which results in no limits. If you set the value to 4, only 4 instances of the UDF will be queued to execute the UDF. This holds true across all invocations of the proc; this means that even if /execute/proc is called eight times, only 4 processes will be running. Another instance will be queued as soon as one instance finishes processing. This process will repeat, only allowing 4 instances of the UDF to run at a time, until all instances have completed or the UDF is killed.

Execution

Calling the executeProc() method will execute the specified UDF within the targeted Kinetica execution environment. The method takes the following parameters:

ParameterDescription
procNameThe system-wide unique name for the UDF
paramsSet of string-to-string key/value paired parameters to pass to the UDF
binParamsSet of string-to-binary key/value paired parameters to pass to the UDF
inputTableNamesInput data table names, to be processed by the UDF
inputColumnNamesMapping of input data table names to their respective column names, to be processed as input data by the UDF
outputTableNamesOutput data table names, where processed data is to be appended
optionsOptional parameters for UDF execution; see executeProc() for details

The call is asynchronous and will return immediately with a run_id, which is a string that can be used in subsequent checks of the execution status.

For example, to execute a proc that's already been created (UdfTcJavaProc) using existing input (udf_tc_java_in_table) and output (udf_tc_java_out_table) tables:

Execute UDF Example - Parameter Constants
1
2
3
4
static String SCHEMA = "tutorial_udf_java";
static String INPUT_TABLE = SCHEMA + ".udf_tc_java_in_table";
static String OUTPUT_TABLE = SCHEMA + ".udf_tc_java_out_table";
static String PROC_NAME = "UdfTcJavaProc";
Create UDF Example - executeProc() Call
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
System.out.println("Executing proc...");
ExecuteProcResponse executeProcResponse = hDb.executeProc(
        PROC_NAME,
        null,
        null,
        Collections.singletonList(INPUT_TABLE),
        null,
        Collections.singletonList(OUTPUT_TABLE),
        null
);
System.out.println("Proc executed successfully:");
System.out.println(executeProcResponse);
System.out.println("Check the system log or 'gpudb-proc.log' for execution information");

Management

UDFs can be managed using either GAdmin or one of the methods below:

  • deleteProc() -- removes the given UDF definition from the system; needs to be called before createProc() when recreating a UDF
  • hasProc() -- returns whether the given UDF exists
  • killProc() -- terminates a running UDF (or UDFs)
  • showProc() -- returns the parameter values used in creating the UDF
  • showProcStatus() -- Returns whether the UDF (or UDFs) is still running, has completed, or has exited with an error, along with any processed results